Commit af2930c1 authored by Faizol's avatar Faizol

phase 2 done (point check balance mode)

parent 52f12f5e
......@@ -6,7 +6,8 @@ A new Flutter project Self Service.
This project is a starting point for a Flutter application.
## Version App Change Log 1.6.10
## Version App Change Log SS.23.1.WWW.SB
## Version Code 16
** Added mode by config topup dan check balance ✅
** Added wording title following the selected mode ✅
......@@ -19,6 +20,9 @@ This project is a starting point for a Flutter application.
** Adjust Ui check balance ✅
** Added function print card history
** Added Ui print card history
** Update mifare mdd lib to version version: 0.1.42 ✅
** Disable print history ✅
** Update version ✅
** Update mifare mdd lib to version version: 0.1.36 ✅
** Added isCheckHistory to getcardinfo ✅
## Version App Change Log SS.23.2.WWW.SB.PC
## Version Code 17
......@@ -13,12 +13,12 @@ if (flutterRoot == null) {
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
flutterVersionCode = '17'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
flutterVersionName = 'SS.23.2.WWW.SB.PC'
}
apply plugin: 'com.android.application'
......@@ -96,7 +96,7 @@ dependencies {
// library mdd
// change 11
implementation(group: 'com.mdd.topup', name: 'mifare_mdd_lib', version: '0.1.24', ext: 'aar')
implementation(group: 'com.mdd.topup', name: 'mifare_mdd_lib', version: '0.1.42', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'aar-deviceid-release', version: '2.0.6', ext: 'aar')
implementation(group: 'com.mdd.library', name: 'android-escpos-receipt', version: '1.0.1', ext: 'aar')
implementation(group: 'com.mdd.payment', name: 'nativecripto-release', version: '2.0.1', ext: 'aar')
......
......@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "SS.23.1.WWW.SB",
"versionCode": 17,
"versionName": "SS.23.2.WWW.SB.PC",
"outputFile": "app-debug.apk"
}
],
......
......@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "SS.23.1.WWW.SB",
"versionCode": 17,
"versionName": "SS.23.2.WWW.SB.PC",
"outputFile": "app-profile.apk"
}
],
......
......@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 16,
"versionName": "SS.23.1.WWW.SB",
"versionCode": 17,
"versionName": "SS.23.2.WWW.SB.PC",
"outputFile": "app-release.apk"
}
],
......
......@@ -25,6 +25,11 @@ public final class GeneratedPluginRegistrant {
} catch (Exception e) {
Log.e(TAG, "Error registering plugin device_info_plus, dev.fluttercommunity.plus.device_info.DeviceInfoPlusPlugin", e);
}
try {
flutterEngine.getPlugins().add(new io.github.ponnamkarthik.toast.fluttertoast.FlutterToastPlugin());
} catch (Exception e) {
Log.e(TAG, "Error registering plugin fluttertoast, io.github.ponnamkarthik.toast.fluttertoast.FlutterToastPlugin", e);
}
try {
flutterEngine.getPlugins().add(new dev.fluttercommunity.plus.packageinfo.PackageInfoPlugin());
} catch (Exception e) {
......
......@@ -8,8 +8,10 @@ import android.graphics.drawable.Drawable
import android.os.Build
import android.util.DisplayMetrics
import android.util.Log
import androidx.annotation.RequiresApi
import com.github.danielfelgar.drawreceiptlib.ReceiptBuilder
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import id.mdd.mifare_mdd_lib.*
import id.mdd.mifare_mdd_lib.model.Ticket
import io.flutter.embedding.android.FlutterActivity
......@@ -19,18 +21,23 @@ import io.flutter.plugin.common.MethodChannel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.text.NumberFormat
import java.text.SimpleDateFormat
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import kotlin.concurrent.thread
class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareTicketingCallback {
val gson = Gson()
private var _mifareTicketing: MifareTicketingPresenter? = null
private lateinit var mifareTicketingV3: MifareTicketingV3
private lateinit var lastCardUI: Ticket
private var result: MethodChannel.Result? = null
private val coroutineScope = CoroutineScope(Dispatchers.IO)
@RequiresApi(Build.VERSION_CODES.O)
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
......@@ -50,9 +57,6 @@ class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareT
}
}.start()
}
// "activation_key" -> {
// _mifareTicketing?.activateKey()
// }
"print_topup" -> {
this.result = result
val ticketJson = call.argument<String>("ticket_json")
......@@ -81,6 +85,28 @@ class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareT
status!!
)
}
"print_history" -> {
this.result = result
val jsonbalance = call.argument<String>("json_balance")
val name = call.argument<String>("name")
val cardNumber = call.argument<String>("card_number")
val cardExpirity = call.argument<String>("card_expirity")
val cardType = call.argument<String>("card_type")
val deposit = call.argument<String>("deposit")
val balance = call.argument<String>("balance")
generateReceiptHistory(
jsonbalance!!,
name!!,
cardNumber!!,
cardExpirity!!,
cardType!!,
deposit!!,
balance!!,
)
}
"init_mifare_lib" -> {
this.result = result
call.argument<String>("debug_response")
......@@ -169,7 +195,7 @@ class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareT
isSync = true,
isCheckValidation = false,
isCheckMin = true,
isCheckListHistory = true
isCheckListHistory = false,
)
}
}
......@@ -283,6 +309,151 @@ class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareT
result?.success(Gson().toJson(ticket))
}
fun formatDeciToPrice(value: Double): String? {
val formatter: NumberFormat = DecimalFormat("#,###")
return "Rp" + formatter.format(value)
}
@RequiresApi(Build.VERSION_CODES.O)
fun generateReceiptHistory(
jsonbalance: String,
name : String,
cardNumber : String,
cardExpirity : String,
cardType : String,
deposit : String,
balance : String
){
data class DataModel(
val card_uid: String,
val card_number: String,
val reg_db: String,
val terminal: String,
val ticket: String,
val type: String,
val reff_no: String,
val amount: Int,
val prev_balance: Int,
val last_balance: Int,
val datetime: String
)
val listTypeBalance = object : TypeToken<List<DataModel>>() {}.type
// Parse the JSON into a list of Transaction objects
val modelBalance: List<DataModel> = gson.fromJson(jsonbalance, listTypeBalance)
val currentDateTime = LocalDateTime.now()
val outputFormatter = DateTimeFormatter.ofPattern("yyyy/dd/MM HH:mm")
val formattedCurrentDateTime = currentDateTime.format(outputFormatter)
var bitmapIcon: Drawable? = this.getResources()?.getDrawableForDensity(
R.drawable.wahoo_print,
DisplayMetrics.DENSITY_LOW, getTheme()
)
print("model ${Build.MODEL}")
var receiptLayoutHistory = ReceiptBuilder(570)
.setMarginTop(30)
.setMarginLeft(30)
.setMarginLeft(30)
val resizedBitmap = Bitmap.createScaledBitmap(
(bitmapIcon as BitmapDrawable).bitmap,
300,
150,
false
)
receiptLayoutHistory = receiptLayoutHistory
.setAlign(Paint.Align.CENTER)
.setColor(Color.BLACK)
.setTextSize(50F)
.addText("HISTORI SALDO")
.setTextSize(25F)
.addText("history balance")
.addBlankSpace(15)
.setAlign(Paint.Align.CENTER)
.setTextSize(20F)
.addLine()
.setAlign(Paint.Align.LEFT)
.addText("Nama", false)
.setAlign(Paint.Align.CENTER)
.addText(":", false)
.setAlign(Paint.Align.RIGHT)
.addText(name, true)
.setAlign(Paint.Align.LEFT)
.addText("Wristband", false)
.setAlign(Paint.Align.CENTER)
.addText(":",false)
.setAlign(Paint.Align.RIGHT)
.addText(cardNumber,true)
.setAlign(Paint.Align.LEFT)
.addText("Tanngal Cetak",false)
.setAlign(Paint.Align.CENTER)
.addText(":",false)
.setAlign(Paint.Align.RIGHT)
.addText(formattedCurrentDateTime,true)
.setAlign(Paint.Align.LEFT)
.addText("Rincian Transaksi",false)
.setAlign(Paint.Align.CENTER)
.addText(":",false)
.setAlign(Paint.Align.RIGHT)
.addText("",true)
.addLine(10)
.addBlankSpace(10)
.setAlign(Paint.Align.LEFT)
.setColor(Color.BLACK)
.setAlign(Paint.Align.LEFT)
.addLine()
.addText("TIPE TGL TID JUMLAH", false)
.setAlign(Paint.Align.RIGHT)
.addText("SALDO", true)
.addLine()
for (dataBalance in modelBalance){
val inputDateStr = dataBalance.datetime
val amount = dataBalance.amount
val lastBalance = dataBalance.last_balance
val decimalFormatSymbols = DecimalFormatSymbols()
decimalFormatSymbols.groupingSeparator = '.'
val decimalFormat = DecimalFormat("#,###.##", decimalFormatSymbols)
val inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val outputFormatter = DateTimeFormatter.ofPattern("yyyy/dd/MM HH:mm")
val inputDate = LocalDateTime.parse(inputDateStr, inputFormatter)
val formattedDate = inputDate.format(outputFormatter)
val terminalId = dataBalance.terminal.takeLast(4).replace(",".toRegex()," ")
val formattedTerminalId = String.format("%04d", terminalId.toInt())
val space = StringBuilder()
for (x in 0 until 20 - lastBalance.toString().length) {
space.append(" ")
}
receiptLayoutHistory = receiptLayoutHistory
.setTextSize(20F)
.setAlign(Paint.Align.LEFT)
.addText("${dataBalance.type.substring(0,3)} $formattedDate ${(formattedTerminalId)} ${decimalFormat.format(amount)}",false)
.setAlign(Paint.Align.RIGHT)
.addText( "${space.append(decimalFormat.format(lastBalance))}",true)
}
receiptLayoutHistory = receiptLayoutHistory
.addLine()
.addBlankSpace(10)
.setAlign(Paint.Align.LEFT)
.addText("** TOP : TOPUP")
.addText("** REF : REFUND")
.addText("** PUR : PURCHASE")
.addBlankSpace(10)
.setAlign(Paint.Align.CENTER)
.setTextSize(20F)
.addText("Terima kasih atas kunjungan Anda", true)
.addText("powered by dolanapp.com", true)
.addText("v-" + BuildConfig.VERSION_NAME)
val finalReceiptLayoutHistory: ReceiptBuilder = receiptLayoutHistory
_mifareTicketing?.generateReceiptTopup(finalReceiptLayoutHistory, "", null, paperWidth = 570F, isBluetooth = false)
}
fun generateReceipt(
ticketJson: String,
companyName: String,
......@@ -305,6 +476,7 @@ class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareT
R.drawable.wahoo_print,
DisplayMetrics.DENSITY_LOW, getTheme()
)
print("model ${Build.MODEL}")
// if (Build.MODEL == "T2s" || Build.MODEL == "T2Mini" || Build.MODEL == "T2mini") {
var receiptLayout = ReceiptBuilder(570)
......
sdk.dir=/Users/macbookpro/Library/Android/sdk
flutter.sdk=/Users/macbookpro/Developer/flutter
sdk.dir=C:\\Users\\MDD HP\\AndroidSDK
flutter.sdk=C:\\Users\\MDD HP\\flutter
flutter.buildMode=debug
flutter.versionName=SS.23.1.WWW.SB
flutter.versionCode=16
\ No newline at end of file
flutter.versionName=SS.23.2.WWW.SB.PC
flutter.versionCode=17
\ No newline at end of file
......@@ -18,6 +18,12 @@
@import device_info_plus;
#endif
#if __has_include(<fluttertoast/FluttertoastPlugin.h>)
#import <fluttertoast/FluttertoastPlugin.h>
#else
@import fluttertoast;
#endif
#if __has_include(<package_info_plus/FLTPackageInfoPlusPlugin.h>)
#import <package_info_plus/FLTPackageInfoPlusPlugin.h>
#else
......@@ -59,6 +65,7 @@
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
[ConnectivityPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"ConnectivityPlusPlugin"]];
[FLTDeviceInfoPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTDeviceInfoPlusPlugin"]];
[FluttertoastPlugin registerWithRegistrar:[registry registrarForPlugin:@"FluttertoastPlugin"]];
[FLTPackageInfoPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTPackageInfoPlusPlugin"]];
[PathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"PathProviderPlugin"]];
[PermissionHandlerPlugin registerWithRegistrar:[registry registrarForPlugin:@"PermissionHandlerPlugin"]];
......
// ignore_for_file: prefer_typing_uninitialized_variables, avoid_print
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:self_service_3/shared/preference_constant.dart';
......@@ -47,6 +48,32 @@ class StartService {
return result;
}
static Future<String> printHistory(
String jsonbalance,
String name,
String cardNumber,
String cardExpirity,
String cardType,
String deposit,
String balance
)async{
var result;
try{
result = await platform.invokeMethod("print_history", <String, dynamic>{
"json_balance" : jsonbalance,
"name" : name,
"card_number" : cardNumber,
"card_expirity": cardExpirity,
"card_type" : cardType,
"deposit" : deposit,
"balance" : balance
});
}catch(e){
result = e.toString();
}
return result;
}
static Future<String> print(
String ticketJson,
// String bitmapLogo,
......
import 'dart:async';
import 'dart:convert';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:easy_localization/easy_localization.dart';
......@@ -142,10 +142,7 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
int.parse(infoMap['cardExpirity']) * 1000);
final DateFormat formatter = DateFormat('dd-MMM-yyyy');
cardExpirity = formatter.format(change);
deposit = CurrencyFormat.convertToIdr(
infoMap["deposit"],
2,
);
deposit = CurrencyFormat.convertToIdr(infoMap["deposit"], 2,);
cardNumber = infoMap["cardNumber"];
String cardNo = cardNumber.toString();
String targetMasked = cardNo.substring(0, 12);
......@@ -159,16 +156,21 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
Future<void> getAuditHistoryBalance(String cardUid, String regDb) async {
try {
var auditHistory = await ServiceApi.fetchAuditHistory(cardUid, regDb, "balance");
print("AUDIT HISTORY BALANCE: $auditHistory");
var auditHistoryBalance = await ServiceApi.fetchAuditHistory(cardUid, regDb, "balance");
print("AUDIT HISTORY BALANCE: $auditHistoryBalance");
balanceHistoryData.clear();
// Your data is already a Map, so you don't need to decode it
List<dynamic> data = auditHistory['data'];
List<dynamic> dataBalance = auditHistoryBalance['data'];
// Tambahkan data dari respons ke dalam balanceHistoryData
for (var item in data) {
balanceHistoryData.add(item);
for (var itemBalance in dataBalance) {
// print("isi dari $item");
balanceHistoryData.add(itemBalance);
}
balanceHistoryData = balanceHistoryData.reversed.toList();
} catch (error) {
print("AUDIT BALANCE ERROR: $error");
}
......@@ -176,13 +178,15 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
Future<void> getAuditHistoryTicket(String cardUid, String regDb) async {
try {
var auditHistory = await ServiceApi.fetchAuditHistory(cardUid, regDb, "ticket");
print("AUDIT HISTORY TICKET: $auditHistory");
var auditHistoryTicket = await ServiceApi.fetchAuditHistory(cardUid, regDb, "ticket");
print("AUDIT HISTORY TICKET: $auditHistoryTicket");
List<dynamic> data = auditHistory['data'];
for (var item in data) {
ticketHistoryData.add(item);
ticketHistoryData.clear();
List<dynamic> dataTicket = auditHistoryTicket['data'];
for (var itemTicket in dataTicket) {
ticketHistoryData.add(itemTicket);
}
ticketHistoryData = ticketHistoryData.reversed.toList();
} catch (error) {
print("AUDIT TICKET ERROR: $error");
}
......@@ -485,6 +489,18 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
});
}
void showToastMessage(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT, // Durasi toast
gravity: ToastGravity.BOTTOM, // Posisi toast (dalam hal ini, di bawah)
timeInSecForIosWeb: 1, // Durasi untuk iOS (dalam detik)
backgroundColor: Colors.grey, // Warna latar belakang toast
textColor: Colors.white, // Warna teks
);
}
Future<bool> onWillPop() {
return Future.value(false);
}
......@@ -493,42 +509,42 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return WillPopScope(
onWillPop: onWillPop,
child: Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
if (timer != null) timer?.cancel();
tapIdle(context);
},
child: Column(
return Listener(
onPointerDown: (details) {
if (timer != null) timer?.cancel();
tapIdle(context);
},
onPointerMove: (details) {
if (timer != null) timer?.cancel();
tapIdle(context);
},
child: WillPopScope(
onWillPop: onWillPop,
child: Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: screenWidth * 0.01, // Container untuk spasi di kiri
),
Container(
width: screenWidth * 0.45,
height: screenHeight * 6,
child: buildWellcomeCustomer(),
),
Container(
margin: EdgeInsets.fromLTRB(0,50,0,80 ),
width: screenWidth * 0.45,
height: screenHeight * 6, // Container untuk "balance section"
child: Column(children: [buildBalanceSection(),buildTicketSection()]),
),
],
Container(
width: screenWidth * 0.01, // Container untuk spasi di kiri
),
Container(
width: screenWidth * 0.70,
height: screenHeight * 0.80,
child: buildWalletSection(),
),
Container(
margin: EdgeInsets.fromLTRB(0,0,0,0 ),
width: screenWidth * 0.95,
height: screenHeight * 0.70, // Container untuk "balance section"
child: buildBalanceSection(),
),
SizedBox(height: 20),
SizedBox(height: 20),
......@@ -536,30 +552,60 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
SizedBox(height: 20),
],
),
),
],
],
),
),
),
Positioned(
bottom: 20.0, // Adjust the position as needed
right: 20.0, // Adjust the position as needed
child: FloatingActionButton(
onPressed: () {
// Add the action for your floating button
isShowingDialog = true;
timer?.cancel();
_showTap(context);
tapDial(context);
},
child: Icon(Icons.search),
Positioned(
bottom: 20.0, // Adjust the position as needed
right: 20.0, // Adjust the position as needed
child: FloatingActionButton(
onPressed: () {
// Add the action for your floating button
isShowingDialog = true;
timer?.cancel();
_showTap(context);
tapDial(context);
},
child: Icon(Icons.search),
),
),
),
Positioned(
bottom: 20.0, // Adjust the position as needed
right: 30.0, // Adjust the position as needed
child: buildTimerSection(context),
),
],
Positioned(
bottom: 100.0, // Adjust the position as needed
right: 20.0, // Adjust the position as needed
child: FloatingActionButton(
onPressed: () {
showToastMessage('Maaf , fitur tidak tersedia');
//Nyalakan kembali jika dibutuhkan
// Konversi data ke JSON
// String jsonBalance = json.encode(balanceHistoryData);
// name;
// cardNumber;
// cardExpirity;
// cardType;
// deposit;
// balance;
// Memanggil metode printHistory dengan data yang sudah diperbarui
// StartService.printHistory(
// jsonBalance,
// name,
// cardNumber,
// cardExpirity,
// cardType,
// deposit,
// balance
// );
},
child: Icon(Icons.print),
),
),
Positioned(
bottom: 120.0, // Adjust the position as needed
right: 30.0, // Adjust the position as needed
child: buildTimerSection(context),
),
],
),
),
),
);
......@@ -648,54 +694,6 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
);
}
buildNewCard(){
return Container(
child: Column(
children: [
Text(
"Informasi History Balance",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SingleChildScrollView(
child: Container(
child: ListView.builder(
shrinkWrap: true, // Make sure to set shrinkWrap to true
itemCount: balanceHistoryData.length,
itemBuilder: (context, index) {
final data = balanceHistoryData[index];
return Card(
// Customize card appearance as needed
child:
ListTile(
title: Text('Card UID: ${data['card_uid']}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Card Number: ${data['card_number']}'),
Text('Terminal: ${data['terminal']}'),
Text('Reff Number: ${data['reff_no']}'),
Text('Ticket: ${data['ticket']}'),
Text('Type: ${data['type']}'),
Text('Previous Balance: ${data['prev_balance']}'),
Text('Last Balance: ${data['last_balance']}'),
SizedBox(height: 20),
],
),
),
);
},
),
),
),
]
),
);
}
buildCardInfoSection() {
return Center(
child: Container(
......@@ -754,427 +752,471 @@ class _HomePageCheckBalanceState extends State<HomePageCheckBalance> implements
);
}
// buildWalletSection() {
// double screenWidth = MediaQuery.of(context).size.width;
// double screenHeight = MediaQuery.of(context).size.height;
// double textScaleFactor = screenWidth / 1700;
// return
// Center(
// child: Padding(
// padding: const EdgeInsets.all(8.0),
// child: Container(
// width: screenWidth * 0.9,
// height: screenHeight * 0.5,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(28),
// image: const DecorationImage(
// fit: BoxFit.cover,
// image: AssetImage('assets/img_bg_card.png'),
// ),
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Text(
// (balance != null) ? 'Saldo $balance' : 'Saldo 0',
// style: whiteTextStyle.copyWith(
// fontSize: 28 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// 'balance',
// style: whiteTextStyle.copyWith(
// fontSize: 15 * textScaleFactor,
// fontWeight: light,
// fontStyle: FontStyle.italic,
// letterSpacing: 3,
// ),
// ),
// const SizedBox(
// height: 10,
// ),
// Text(
// '-----------------------------',
// style: whiteTextStyle.copyWith(
// fontSize: 30 * textScaleFactor,
// fontWeight: semiBold,
// letterSpacing: 16,
// ),
// ),
// const SizedBox(
// height: 15,
// ),
// Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Text(
// 'Nama/name' ,
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// 'Nomor Wristband/wristband no',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// 'Status',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// 'Masa Berlaku/expirity',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// 'Deposit',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// letterSpacing: 3,
// fontWeight: medium,
// ),
// ),
// ],
// ),
// const SizedBox(
// width: 50,
// ),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Text(
// (name != null) ? ': $name' : ': -',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// (maskedText != null) ? ': $maskedText' : ': -',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// (cardType != null) ? ': $cardType' : ': -',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// (cardExpirity != null) ? ': $cardExpirity' : ': -',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// letterSpacing: 3,
// ),
// ),
// Text(
// (deposit != null) ? ': $deposit' : ': -',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// letterSpacing: 3,
// fontWeight: medium,
// ),
// ),
// ],
// ),
// ],
// ),
// const SizedBox(
// height: 25,
// ),
// Text(
// '-----------------------------',
// style: whiteTextStyle.copyWith(
// fontSize: 30 * textScaleFactor,
// fontWeight: semiBold,
// letterSpacing: 16,
// ),
// ),
// Text(
// 'Saldo dan deposit wristband bisa dikembalikan di Refund Center',
// style: whiteTextStyle.copyWith(
// fontSize: 20 * textScaleFactor,
// fontWeight: medium,
// ),
// ),
// Text(
// 'Wristband balance and deposit can be returned at the Refund Center',
// style: greyTextStyle.copyWith(
// fontSize: 15 * textScaleFactor,
// fontWeight: light,
// fontStyle: FontStyle.italic,
// ),
// ),
// const SizedBox(
// height: 25,
// ),
// ],
// ),
// ),
// ),
// );
// }
Widget buildWalletSection() {
buildWalletSection() {
double screenWidth = MediaQuery.of(context).size.width;
double textScaleFactor = screenWidth / 1700;
double screenHeight = MediaQuery.of(context).size.height;
double textScaleFactor = screenHeight / 800;
return Center(
child: Card(
elevation: 8, // Add a shadow to the card
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: Container(
width: screenWidth * 0.9,
padding: const EdgeInsets.all(16),
child:
Column(
children: [
ListTile(
title: Text(
(balance != null) ? 'Saldo $balance' : 'Saldo 0',
style: TextStyle(
fontSize: 28 * textScaleFactor,
fontWeight: FontWeight.w500,
),
),
subtitle: Text(
'balance',
style: TextStyle(
fontSize: 15 * textScaleFactor,
fontStyle: FontStyle.italic,
),
),
),
Divider(),
ListTile(
title: Text('Nama/name'),
subtitle: Text((name != null) ? ': $name' : ': -'),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
SizedBox(height: 40),
Text(
"Informasi Wristband",
style: blackTextStyle.copyWith(
fontSize: 28,
fontWeight: medium,
letterSpacing: 3,
),
ListTile(
title: Text('Nomor Wristband/wristband no'),
subtitle: Text((maskedText != null) ? ': $maskedText' : ': -'),
),
Text(
'information wristband',
style: blackTextStyle.copyWith(
fontSize: 15,
fontWeight: light,
fontStyle: FontStyle.italic,
letterSpacing: 3,
),
ListTile(
title: Text('Status'),
subtitle: Text((cardType != null) ? ': $cardType' : ': -'),
),
SizedBox(height: 20,),
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(28),
image: const DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/img_bg_card.png'),
),
),
ListTile(
title: Text('Masa Berlaku/expirity'),
subtitle: Text((cardExpirity != null) ? ': $cardExpirity' : ': -'),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 10,),
Text(
(balance != null) ? 'Saldo $balance' : 'Saldo 0',
style: whiteTextStyle.copyWith(
fontSize: 28 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'balance',
style: whiteTextStyle.copyWith(
fontSize: 15 * textScaleFactor,
fontWeight: light,
fontStyle: FontStyle.italic,
letterSpacing: 3,
),
),
const SizedBox(
height: 10,
),
Text(
'-----------------------------',
style: whiteTextStyle.copyWith(
fontSize: 30 * textScaleFactor,
fontWeight: semiBold,
letterSpacing: 16,
),
),
const SizedBox(
height: 15,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Nama/name' ,
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'Nomor Wristband/wristband no',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'Status',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'Masa Berlaku/expirity',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'Deposit',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
letterSpacing: 3,
fontWeight: medium,
),
),
],
),
const SizedBox(
width: 50,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
(name != null) ? ': $name' : ': -',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
(maskedText != null) ? ': $maskedText' : ': -',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
(cardType != null) ? ': $cardType' : ': -',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
(cardExpirity != null) ? ': $cardExpirity' : ': -',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
(deposit != null) ? ': $deposit' : ': -',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
letterSpacing: 3,
fontWeight: medium,
),
),
],
),
],
),
const SizedBox(
height: 25,
),
Text(
'-----------------------------',
style: whiteTextStyle.copyWith(
fontSize: 30 * textScaleFactor,
fontWeight: semiBold,
letterSpacing: 16,
),
),
Text(
'Saldo dan deposit wristband bisa dikembalikan di Refund Center',
style: whiteTextStyle.copyWith(
fontSize: 20 * textScaleFactor,
fontWeight: medium,
),
),
Text(
'Wristband balance and deposit can be returned at the Refund Center',
style: greyTextStyle.copyWith(
fontSize: 15 * textScaleFactor,
fontWeight: light,
fontStyle: FontStyle.italic,
),
),
const SizedBox(
height: 25,
),
],
),
ListTile(
title: Text('Deposit'),
subtitle: Text((deposit != null) ? ': $deposit' : ': -'),
),
],
),
),
);
}
Widget buildBalanceSection() {
double screenWidth = MediaQuery.of(context).size.width;
double textScaleFactor = screenWidth / 1700;
return Visibility(
visible: balanceHistoryData.isNotEmpty,
child: Container(
width: screenWidth ,
height: 500,
padding: EdgeInsets.only(bottom: 20),//
margin: EdgeInsets.all(20), // Add margin to the outer Container
child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 20),
Center(
child: Column(
children: [
Text(
"History Saldo Wristband",
style: blackTextStyle.copyWith(
fontSize: 28,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'history wristband balance',
style: blackTextStyle.copyWith(
fontSize: 15,
fontWeight: light,
fontStyle: FontStyle.italic,
letterSpacing: 3,
),
),
],
),
Divider(),
Text(
'Saldo dan deposit wristband bisa dikembalikan di Refund Center',
style: TextStyle(
fontSize: 16 * textScaleFactor,
fontWeight: FontWeight.w500,
),
SizedBox(height: 20,),
Center(
child: Container(
height: 80,
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(10,10,10,10),
child: Row(
children: [
Expanded(
child: Table(
children: [
TableRow(
children: [
TableCell(child: Text('Terminal',style: TextStyle(fontWeight: FontWeight.bold),)), // Judul untuk sel pertama
TableCell(child: Text('Tipe', style: TextStyle(fontWeight: FontWeight.bold))), // Judul untuk sel kedua
TableCell(child: Text('Jumlah',style: TextStyle(fontWeight: FontWeight.bold))), // Judul untuk sel kedua
TableCell(child: Text('Saldo Akhir',style: TextStyle(fontWeight: FontWeight.bold))), // Judul untuk sel kedua
],
),
TableRow(
children: [
TableCell(child: Text('-',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel pertama
TableCell(child: Text('type',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel kedua
TableCell(child: Text('amount',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel kedua
TableCell(child: Text('last balance',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel kedua
],
),
],
),
),
],
),
),
),
),
Text(
'Wristband balance and deposit can be returned at the Refund Center',
style: TextStyle(
fontSize: 12 * textScaleFactor,
fontStyle: FontStyle.italic,
),
Expanded(
child: Container(
child:
ListView.builder(
shrinkWrap: true, // Make sure to set shrinkWrap to true
itemCount: balanceHistoryData.length,
itemBuilder: (context, index) {
final data = balanceHistoryData[index];
int amount = data['amount'];
int lastBalance = data['last_balance'];
String fAmount = NumberFormat.decimalPattern().format(amount);
String fLastBalance = NumberFormat.decimalPattern().format(lastBalance);
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
child:
Card(
margin: EdgeInsets.fromLTRB(20,0,20,12),
child: Padding(
padding: const EdgeInsets.fromLTRB(20,10,20,10),
child: Column(
children: [
Row(
children: [
Expanded(
child: Table(
children: [
TableRow(
children: [
TableCell(child: Text(data['terminal'])),
TableCell(child: Text(data['type'])),
TableCell(child: Text(fAmount.toString())),
TableCell(child: Text(fLastBalance.toString())),
],
),
],
),
),
],
),
],
),
),
),
);
},
),
),
],
),
),
],
),
),
);
}
Widget buildBalanceSection() {
Widget buildTicketSection() {
double screenWidth = MediaQuery.of(context).size.width;
double textScaleFactor = screenWidth / 1700;
return Visibility(
visible: balanceHistoryData.isNotEmpty,
visible: ticketHistoryData.isNotEmpty,
child: SingleChildScrollView(
child: Container(
width: screenWidth * 40,
height: 500,
padding: EdgeInsets.only(bottom: 20),//
margin: EdgeInsets.all(20), // Add margin to the outer Container
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(28),
image: const DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/img_bg_card.png'),
),
),
margin: EdgeInsets.all(20),
padding: EdgeInsets.only(bottom: 20),// Add margin to the outer Container
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 20),
Text(
"History Saldo Kartu",
style: whiteTextStyle.copyWith(
"History Card Ticket",
style: blackTextStyle.copyWith(
fontSize: 28,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'history card balance',
style: whiteTextStyle.copyWith(
'history card ticket',
style: blackTextStyle.copyWith(
fontSize: 15,
fontWeight: light,
fontStyle: FontStyle.italic,
letterSpacing: 3,
),
),
SizedBox(height: 20,),
Center(
child: Container(
height: 80,
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(20,10,20,10),
child: Row(
children: [
Expanded(
child: Table(
children: [
TableRow(
children: [
TableCell(child: Text('Terminal',style: TextStyle(fontWeight: FontWeight.bold),)), // Judul untuk sel pertama
TableCell(child: Text('Tipe', style: TextStyle(fontWeight: FontWeight.bold))), // Judul untuk sel kedua
TableCell(child: Text('Kuantitas',style: TextStyle(fontWeight: FontWeight.bold))), // Judul untuk sel kedua
TableCell(child: Text('Tiket Akhir',style: TextStyle(fontWeight: FontWeight.bold))), // Judul untuk sel kedua
],
),
TableRow(
children: [
TableCell(child: Text('-',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel pertama
TableCell(child: Text('type',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel kedua
TableCell(child: Text('quantity',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel kedua
TableCell(child: Text('last ticket',style: TextStyle(fontWeight: light , fontStyle: FontStyle.italic))), // Judul untuk sel kedua
],
),
],
),
),
],
),
),
),
),
),
Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 10), // Add margin to the ListView.builder
child:
ListView.builder(
shrinkWrap: true, // Make sure to set shrinkWrap to true
itemCount: balanceHistoryData.length,
itemCount: ticketHistoryData.length,
itemBuilder: (context, index) {
final data = balanceHistoryData[index];
return Card(
// Customize card appearance as needed
final data = ticketHistoryData[index];
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
child:
ListTile(
title: Text('Card UID: ${data['card_uid']}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Card Number: ${data['card_number']}'),
Text('Terminal: ${data['terminal']}'),
Text('Reff Number: ${data['reff_no']}'),
Text('Ticket: ${data['ticket']}'),
Text('Type: ${data['type']}'),
Text('Previous Balance: ${data['prev_balance']}'),
Text('Last Balance: ${data['last_balance']}'),
SizedBox(height: 20),
],
Card(
margin: EdgeInsets.fromLTRB(20,0,20,12),
child: Padding(
padding: const EdgeInsets.fromLTRB(10,10,10,10),
child: Column(
children: [
Row(
children: [
Expanded(
child: Table(
children: [
TableRow(
children: [
TableCell(child: Text(data['terminal'])),
TableCell(child: Text(data['type'])),
TableCell(child: Text(data['amount'].toString())),
TableCell(child: Text(data['last_balance'].toString())),
],
),
],
),
),
],
),
],
),
),
),
);
},
),
),
),
],
),
),
),
);
}
Widget buildTicketSection() {
double screenWidth = MediaQuery.of(context).size.width;
double textScaleFactor = screenWidth / 1700;
return SingleChildScrollView(
child: Container(
width: screenWidth * 40,
height: 500,
margin: EdgeInsets.all(20),
padding: EdgeInsets.only(bottom: 20),// Add margin to the outer Container
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(28),
image: const DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/img_bg_card.png'),
), ],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 20),
Text(
"History Card Ticket",
style: whiteTextStyle.copyWith(
fontSize: 28,
fontWeight: medium,
letterSpacing: 3,
),
),
Text(
'history card ticket',
style: whiteTextStyle.copyWith(
fontSize: 15,
fontWeight: light,
fontStyle: FontStyle.italic,
letterSpacing: 3,
),
),
Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 10), // Add margin to the ListView.builder
child: ListView.builder(
shrinkWrap: true, // Make sure to set shrinkWrap to true
itemCount: ticketHistoryData.length,
itemBuilder: (context, index) {
final data = ticketHistoryData[index];
return Card(
// Customize card appearance as needed
child: ListTile(
title: Text('Card UID: ${data['card_uid']}'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Card Number: ${data['card_number']}'),
Text('Terminal: ${data['terminal']}'),
Text('Reff Number: ${data['reff_no']}'),
Text('Ticket: ${data['ticket']}'),
Text('Type: ${data['type']}'),
Text('Previous Balance: ${data['prev_balance']}'),
Text('Last Balance: ${data['last_balance']}'),
SizedBox(height: 20),
],
),
),
);
},
),
),
),
],
),
),
);
}
buildTimerSection(BuildContext context) {
return Container(
......
......@@ -429,6 +429,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
name: fluttertoast
sha256: "474f7d506230897a3cd28c965ec21c5328ae5605fc9c400cd330e9e9d6ac175c"
url: "https://pub.dev"
source: hosted
version: "8.2.2"
frontend_server_client:
dependency: transitive
description:
......
......@@ -68,6 +68,7 @@ dependencies:
transparent_image: ^2.0.0
permission_handler: ^10.2.0
package_info_plus: ^3.0.3
fluttertoast: ^8.0.8
otp_text_field: ^1.1.3
timer_builder: ^2.0.0
sentry_flutter: ^7.10.1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment