Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
Dolan SelfService Topup
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Faizol
Dolan SelfService Topup
Commits
52f12f5e
Commit
52f12f5e
authored
Oct 16, 2023
by
Faizol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
phase 1
parent
27b799c0
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
1779 additions
and
118 deletions
+1779
-118
misc.xml
.idea/misc.xml
+4
-2
README.md
README.md
+16
-0
compiler.xml
android/.idea/compiler.xml
+1
-1
jarRepositories.xml
android/.idea/jarRepositories.xml
+5
-0
misc.xml
android/.idea/misc.xml
+1
-2
output-metadata.json
android/app/debug/output-metadata.json
+1
-1
output-metadata.json
android/app/profile/output-metadata.json
+1
-1
app-release.apk
android/app/release/app-release.apk
+0
-0
output-metadata.json
android/app/release/output-metadata.json
+2
-2
GeneratedPluginRegistrant.java
...in/java/io/flutter/plugins/GeneratedPluginRegistrant.java
+8
-8
MainActivity.kt
...rc/main/kotlin/com/example/self_service_3/MainActivity.kt
+2
-1
build.gradle
android/build.gradle
+1
-1
Generated.xcconfig
ios/Flutter/Generated.xcconfig
+3
-3
flutter_export_environment.sh
ios/Flutter/flutter_export_environment.sh
+3
-3
text_controller.dart
lib/controller/text_controller.dart
+6
-0
main.dart
lib/main.dart
+2
-0
api_helpert.dart
lib/services/api_helpert.dart
+27
-2
preference_constant.dart
lib/shared/preference_constant.dart
+7
-0
home_page.dart
lib/ui/pages/home_page.dart
+75
-45
home_page_check_balance.dart
lib/ui/pages/home_page_check_balance.dart
+1244
-0
set_merchant.dart
lib/ui/pages/set_merchant.dart
+266
-5
splash_page.dart
lib/ui/pages/splash_page.dart
+6
-3
backgroundBalanceCheck.dart
lib/ui/widgets/backgroundBalanceCheck.dart
+41
-0
tap_card_aktivasi.dart
lib/ui/widgets/tap_card_aktivasi.dart
+11
-1
connectivity_plus
linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus
+1
-1
device_info_plus
linux/flutter/ephemeral/.plugin_symlinks/device_info_plus
+1
-1
package_info_plus
linux/flutter/ephemeral/.plugin_symlinks/package_info_plus
+1
-1
path_provider_linux
linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux
+1
-1
sentry_flutter
linux/flutter/ephemeral/.plugin_symlinks/sentry_flutter
+1
-1
shared_preferences_linux
...utter/ephemeral/.plugin_symlinks/shared_preferences_linux
+1
-1
pubspec.lock
pubspec.lock
+37
-29
pubspec.yaml
pubspec.yaml
+3
-2
No files found.
.idea/misc.xml
View file @
52f12f5e
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_11"
default=
"true"
project-jdk-name=
"11"
project-jdk-type=
"JavaSDK"
/>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_17"
default=
"true"
project-jdk-name=
"11"
project-jdk-type=
"JavaSDK"
/>
<component
name=
"ProjectType"
>
<option
name=
"id"
value=
"io.flutter"
/>
</component>
</project>
\ No newline at end of file
README.md
View file @
52f12f5e
...
...
@@ -6,3 +6,19 @@ A new Flutter project Self Service.
This project is a starting point for a Flutter application.
## Version App Change Log 1.6.10
**
Added mode by config topup dan check balance ✅
**
Added wording title following the selected mode ✅
**
Added Logo following app version prefix & default no merchant logo ✅
**
Added Timer can be set in config ✅
**
Adjust Funtion Timer to ui ✅
**
Added Home Page Check Balance ✅
**
Added Card history endpoint ticket & balance ✅
**
Added UI Card history endpoint ticket & balance ✅
**
Adjust Ui check balance ✅
**
Added function print card history
**
Added Ui print card history
**
Update mifare mdd lib to version version: 0.1.36 ✅
**
Added isCheckHistory to getcardinfo ✅
android/.idea/compiler.xml
View file @
52f12f5e
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"CompilerConfiguration"
>
<bytecodeTargetLevel
target=
"1
1
"
/>
<bytecodeTargetLevel
target=
"1
7
"
/>
</component>
</project>
\ No newline at end of file
android/.idea/jarRepositories.xml
View file @
52f12f5e
...
...
@@ -41,5 +41,10 @@
<option
name=
"name"
value=
"maven"
/>
<option
name=
"url"
value=
"https://mobile-repo.mdd.co.id:8081/artifactory/android-library/"
/>
</remote-repository>
<remote-repository>
<option
name=
"id"
value=
"maven"
/>
<option
name=
"name"
value=
"maven"
/>
<option
name=
"url"
value=
"https://mobile-repo.mdd.co.id/artifactory/android-library/"
/>
</remote-repository>
</component>
</project>
\ No newline at end of file
android/.idea/misc.xml
View file @
52f12f5e
<?xml version="1.0" encoding="UTF-8"?>
<project
version=
"4"
>
<component
name=
"ExternalStorageConfigurationManager"
enabled=
"true"
/>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_1
1"
default=
"true"
project-jdk-name=
"Android Studio default JDK
"
project-jdk-type=
"JavaSDK"
>
<component
name=
"ProjectRootManager"
version=
"2"
languageLevel=
"JDK_1
7"
default=
"true"
project-jdk-name=
"jbr-17
"
project-jdk-type=
"JavaSDK"
>
<output
url=
"file://$PROJECT_DIR$/build/classes"
/>
</component>
<component
name=
"ProjectType"
>
...
...
android/app/debug/output-metadata.json
View file @
52f12f5e
...
...
@@ -12,7 +12,7 @@
"filters"
:
[],
"attributes"
:
[],
"versionCode"
:
1
,
"versionName"
:
"
1.0.0
"
,
"versionName"
:
"
SS.23.1.WWW.SB
"
,
"outputFile"
:
"app-debug.apk"
}
],
...
...
android/app/profile/output-metadata.json
View file @
52f12f5e
...
...
@@ -12,7 +12,7 @@
"filters"
:
[],
"attributes"
:
[],
"versionCode"
:
1
,
"versionName"
:
"
1.0.0
"
,
"versionName"
:
"
SS.23.1.WWW.SB
"
,
"outputFile"
:
"app-profile.apk"
}
],
...
...
android/app/release/app-release.apk
View file @
52f12f5e
No preview for this file type
android/app/release/output-metadata.json
View file @
52f12f5e
...
...
@@ -11,8 +11,8 @@
"type"
:
"SINGLE"
,
"filters"
:
[],
"attributes"
:
[],
"versionCode"
:
1
,
"versionName"
:
"SS.
3.WHO
"
,
"versionCode"
:
1
6
,
"versionName"
:
"SS.
23.1.WWW.SB
"
,
"outputFile"
:
"app-release.apk"
}
],
...
...
android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
View file @
52f12f5e
...
...
@@ -17,42 +17,42 @@ public final class GeneratedPluginRegistrant {
public
static
void
registerWith
(
@NonNull
FlutterEngine
flutterEngine
)
{
try
{
flutterEngine
.
getPlugins
().
add
(
new
dev
.
fluttercommunity
.
plus
.
connectivity
.
ConnectivityPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin connectivity_plus, dev.fluttercommunity.plus.connectivity.ConnectivityPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
dev
.
fluttercommunity
.
plus
.
device_info
.
DeviceInfoPlusPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin device_info_plus, dev.fluttercommunity.plus.device_info.DeviceInfoPlusPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
dev
.
fluttercommunity
.
plus
.
packageinfo
.
PackageInfoPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin package_info_plus, dev.fluttercommunity.plus.packageinfo.PackageInfoPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
io
.
flutter
.
plugins
.
pathprovider
.
PathProviderPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
com
.
baseflow
.
permissionhandler
.
PermissionHandlerPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin permission_handler_android, com.baseflow.permissionhandler.PermissionHandlerPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
io
.
sentry
.
flutter
.
SentryFlutterPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin sentry_flutter, io.sentry.flutter.SentryFlutterPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
io
.
flutter
.
plugins
.
sharedpreferences
.
SharedPreferencesPlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin shared_preferences_android, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"
,
e
);
}
try
{
flutterEngine
.
getPlugins
().
add
(
new
com
.
tekartik
.
sqflite
.
SqflitePlugin
());
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"Error registering plugin sqflite, com.tekartik.sqflite.SqflitePlugin"
,
e
);
}
}
...
...
android/app/src/main/kotlin/com/example/self_service_3/MainActivity.kt
View file @
52f12f5e
...
...
@@ -168,7 +168,8 @@ class MainActivity : MethodChannel.MethodCallHandler, FlutterActivity(), MifareT
mifareTicketingV3
.
getCardInfo
(
isSync
=
true
,
isCheckValidation
=
false
,
isCheckMin
=
true
isCheckMin
=
true
,
isCheckListHistory
=
true
)
}
}
...
...
android/build.gradle
View file @
52f12f5e
...
...
@@ -44,6 +44,6 @@ subprojects {
project
.
evaluationDependsOn
(
':app'
)
}
task
clean
(
type:
Delete
)
{
task
s
.
register
(
"clean"
,
Delete
)
{
delete
rootProject
.
buildDir
}
ios/Flutter/Generated.xcconfig
View file @
52f12f5e
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=
/Users/macbookpro/Developments/
flutter
FLUTTER_APPLICATION_PATH=
/Users/macbookpro/Desktop/MDD Project /flutter app/
dolan-selfservice-topup
FLUTTER_ROOT=
C:\Users\MDD HP\
flutter
FLUTTER_APPLICATION_PATH=
C:\Users\MDD HP\Documents\
dolan-selfservice-topup
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=lib
/
main.dart
FLUTTER_TARGET=lib
\
main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=1.0.0
FLUTTER_BUILD_NUMBER=1
...
...
ios/Flutter/flutter_export_environment.sh
View file @
52f12f5e
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export
"FLUTTER_ROOT=
/Users/macbookpro/Developments/
flutter"
export
"FLUTTER_APPLICATION_PATH=
/Users/macbookpro/Desktop/MDD Project /flutter app/
dolan-selfservice-topup"
export
"FLUTTER_ROOT=
C:
\U
sers
\M
DD HP
\
f
lutter"
export
"FLUTTER_APPLICATION_PATH=
C:
\U
sers
\M
DD HP
\D
ocuments
\
d
olan-selfservice-topup"
export
"COCOAPODS_PARALLEL_CODE_SIGN=true"
export
"FLUTTER_TARGET=lib
/
main.dart"
export
"FLUTTER_TARGET=lib
\
m
ain.dart"
export
"FLUTTER_BUILD_DIR=build"
export
"FLUTTER_BUILD_NAME=1.0.0"
export
"FLUTTER_BUILD_NUMBER=1"
...
...
lib/controller/text_controller.dart
View file @
52f12f5e
...
...
@@ -18,3 +18,9 @@ TextEditingController maxTapController = TextEditingController(text: Preferences
TextEditingController
validate
=
TextEditingController
(
text:
PreferencesHelper
.
getString
(
kUserData
));
TextEditingController
?
amountController
=
TextEditingController
(
text:
''
);
TextEditingController
outletName
=
TextEditingController
(
text:
''
);
// text Controller check balance
TextEditingController
urlDolanCheckBalanceController
=
TextEditingController
(
text:
PreferencesHelper
.
getString
(
kUrlDolanCheckBalance
));
TextEditingController
urlCloseLoopCheckBalanceController
=
TextEditingController
(
text:
PreferencesHelper
.
getString
(
kUrlCloseLoopCheckBalance
));
TextEditingController
urlPrepaidCheckBalanceController
=
TextEditingController
(
text:
PreferencesHelper
.
getString
(
kUrlPrePaidCheckBalance
));
TextEditingController
idleCheckBalanceController
=
TextEditingController
(
text:
PreferencesHelper
.
getString
(
kIdleCheckBalance
));
lib/main.dart
View file @
52f12f5e
...
...
@@ -11,6 +11,7 @@ import 'dart:convert';
import
'package:flutter/foundation.dart'
;
import
'package:logging/logging.dart'
;
import
'package:provider/provider.dart'
;
import
'package:self_service_3/ui/pages/home_page_check_balance.dart'
;
import
'package:self_service_3/ui/pages/topup/top_up_page.dart'
;
import
'package:self_service_3/ui/pages/home_page.dart'
;
...
...
@@ -106,6 +107,7 @@ class _MyAppState extends State<MyApp> {
'/set-merchant'
:
(
context
)
=>
const
SetMerchant
(),
'/input-url'
:
(
context
)
=>
const
Dialog
(),
'/home'
:
(
context
)
=>
const
HomePage
(),
'/home-check-balance'
:
(
context
)
=>
const
HomePageCheckBalance
(),
'/tap-card'
:
(
context
)
=>
const
TapCard
(),
'/tap-card-aktivasi'
:
(
context
)
=>
const
TapCardAktivasi
(),
// '/top-up': (context) => const TopUpPage(),
...
...
lib/services/api_helpert.dart
View file @
52f12f5e
...
...
@@ -13,6 +13,7 @@ import '../shared/preferences_helper.dart';
import
'exception_service.dart'
;
class
ServiceApi
{
Future
<
Map
<
String
,
dynamic
>>
getMultiOutlet
(
String
url
,
String
companyName
,
...
...
@@ -69,8 +70,6 @@ class ServiceApi {
}
}
static
String
_getBaseUrl
()
{
String
_protocol
=
PreferencesHelper
.
getString
(
kProtocol
);
String
_host
=
PreferencesHelper
.
getString
(
kHost
);
...
...
@@ -257,4 +256,30 @@ class ServiceApi {
print
(
"
${response.body.toString()}
"
);
return
json
.
decode
(
response
.
body
.
toString
());
}
static
Future
<
Map
<
String
,
dynamic
>>
fetchAuditHistory
(
String
cardUid
,
String
regDb
,
String
type
)
async
{
print
(
"fetchAuditHistory dipanggil dengan cardUid:
$cardUid
, regDb:
$regDb
, type:
$type
"
);
final
String
baseUrlAudit
=
"https://oss.dev.dolanapp.com/library/v1/audit-history"
;
final
url
=
Uri
.
parse
(
baseUrlAudit
);
final
body
=
{
"card_uid"
:
cardUid
,
"reg_db"
:
regDb
,
"type"
:
type
,
};
final
response
=
await
http
.
post
(
url
,
headers:
<
String
,
String
>{
'Content-Type'
:
'application/json; charset=UTF-8'
,
},
body:
jsonEncode
(
body
),
).
timeout
(
Duration
(
seconds:
10
));
if
(
response
.
statusCode
==
200
)
{
return
jsonDecode
(
response
.
body
);
}
else
{
throw
Exception
(
'Gagal mengambil data dari API:
${response.statusCode}
'
);
}
}
}
lib/shared/preference_constant.dart
View file @
52f12f5e
// ignore_for_file: unnecessary_nullable_for_final_variable_declarations
const
kUrlDolan
=
"url_dolan"
;
const
kMode
=
"mode"
;
const
kIsHashMode
=
"is_hash_mode"
;
const
kUrlDolanCheckBalance
=
"url_dolan_check_balance"
;
const
kTerminalId
=
"terminal_id"
;
const
kUrlCorePayment
=
"core_payment"
;
// const kUrlStatusQr = "url_status_qr";
const
kUrlCloseLoop
=
"url_close_loop"
;
const
kUrlCloseLoopCheckBalance
=
"url_close_loop_check_balance"
;
const
kMerchantName
=
"merchant_name"
;
const
kUserName
=
"user_name"
;
const
kUserData
=
"user_data"
;
const
kUrlPrePaid
=
"url_prepaid"
;
const
kUrlPrePaidCheckBalance
=
"url_prepaid_check_balance"
;
const
kVersionApp
=
"version_app"
;
const
kMax
=
"max"
;
const
kMin
=
"min"
;
const
kIdle
=
"idle"
;
const
kIdleCheckBalance
=
"idle_check_balance"
;
const
kMaxTap
=
"maxTap"
;
const
kMultiOutletName
=
"multioutletname"
;
const
kMultiOutletServiceCharge
=
"multioutletservicecharge"
;
...
...
@@ -37,6 +43,7 @@ const kUrlTopup = "url_topup";
const
kIsDoneActivation
=
"is_done_activation"
;
const
kIsDoneConfig
=
"is_done_config"
;
const
kIsDoneConfigCheckBalance
=
"is_done_config_check_balance"
;
const
kIsTap
=
"is_tap_config"
;
const
kIsLoad
=
"is_load_config"
;
const
kIsGetOutlet
=
"is_get_outlet"
;
...
...
lib/ui/pages/home_page.dart
View file @
52f12f5e
...
...
@@ -18,6 +18,7 @@ import 'package:flutter/material.dart';
import
'package:flutter/services.dart'
;
import
'package:lottie/lottie.dart'
;
import
'package:package_info_plus/package_info_plus.dart'
;
import
'package:self_service_3/blocs/api_bloc.dart'
;
import
'package:self_service_3/database/database_helper.dart'
;
...
...
@@ -103,25 +104,11 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
late
Timer
timerPageHome
;
var
infoCard
,
prevInfoCard
,
balance
,
cardExpirity
,
cardType
,
deposit
,
cardNumber
,
name
,
lastBalance
,
approvalCode
,
trxId
,
amount
,
report
,
infoM
,
dateTimeCardExpirity
,
infoMulti
,
companyAddress
,
num
,
reffNo
,
var
infoCard
,
prevInfoCard
,
balance
,
cardExpirity
,
cardType
,
deposit
,
cardNumber
,
name
,
lastBalance
,
approvalCode
,
trxId
,
amount
,
report
,
infoM
,
dateTimeCardExpirity
,
infoMulti
,
companyAddress
,
num
,
reffNo
,
plainCardExpirity
;
Map
<
String
,
dynamic
>?
dataQris
;
...
...
@@ -133,9 +120,12 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
var
message
=
"Silakan Letakkan Wristband Anda Di Reader"
;
var
success
=
"Tempel dan tahan wristband anda di reader"
;
var
wordingTap
=
"Mesin Isi Ulang Wristband Dengan Pembayaran "
;
// var wordingTap = "Mesin Isi Ulang Wristband Dengan Pembayaran ";
late
String
wordingTap
;
late
String
imageLogoShowTap
;
Timer
?
timerCheckStatus
;
// String idle = PreferencesHelper.getString("idle");
String
idle
=
PreferencesHelper
.
getString
(
"idle"
);
bool
isHitApi
=
false
;
bool
_isLoading
=
false
;
...
...
@@ -940,14 +930,10 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
2
,
);
// NOTE merubah tanggal
var
change
=
DateTime
.
fromMillisecondsSinceEpoch
(
int
.
parse
(
infoMap
[
'cardExpirity'
])
*
1000
);
var
change
=
DateTime
.
fromMillisecondsSinceEpoch
(
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
);
...
...
@@ -987,6 +973,7 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
}
// ValueNotifier<int> idleDuration = ValueNotifier<int>(0); // buat ValueNotifier untuk idleDuration
// int _maxDuration = int.parse(PreferencesHelper.getString("idle"));
int
_maxDuration
=
int
.
parse
(
PreferencesHelper
.
getString
(
"idle"
));
int
_minDuration
=
3
;
late
ValueNotifier
<
int
>
idleDuration
;
...
...
@@ -1309,7 +1296,37 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
});
}
Future
<
void
>
_showTap
()
{
Future
<
String
>
_getSelectMode
()
async
{
String
selectMode
=
await
PreferencesHelper
.
getString
(
kMode
);
return
selectMode
;
}
Future
<
String
>
_getImageLogoShowTap
()
async
{
PackageInfo
packageInfo
=
await
PackageInfo
.
fromPlatform
();
String
appVersion
=
packageInfo
.
version
;
print
(
'APP VERSION SELFSERVICE:
$appVersion
'
);
RegExp
regExp
=
RegExp
(
r'www'
,
caseSensitive:
false
);
String
imageLogoShowTap
=
regExp
.
hasMatch
(
appVersion
)
?
'assets/wahoo.png'
:
''
;
print
(
'imageLogoShowTap:
$imageLogoShowTap
'
);
return
imageLogoShowTap
;
}
Future
<
String
>
_getWordingTap
(
String
selectMode
)
async
{
if
(
selectMode
==
"topup"
)
{
return
"Mesin Isi Ulang Wristband Dengan Pembayaran"
;
}
else
if
(
selectMode
==
"checkbalance"
)
{
return
"Customer Balance Check"
;
}
else
{
return
"Default Wording"
;
}
}
Future
<
void
>
_showTap
()
async
{
String
imageLogoShowTap
=
await
_getImageLogoShowTap
();
String
selectMode
=
await
_getSelectMode
();
String
wordingTap
=
await
_getWordingTap
(
selectMode
);
print
(
'imageLogoShowTap before _showTap:
$imageLogoShowTap
'
);
return
showDialog
<
void
>(
context:
context
,
barrierDismissible:
false
,
// user must tap button!
...
...
@@ -1341,13 +1358,19 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
width:
120
,
// fit:,
),
SizedBox
(
width:
90
,
Visibility
(
visible:
imageLogoShowTap
.
isNotEmpty
,
child:
SizedBox
(
width:
90
,
),
),
Image
.
asset
(
"assets/wahoo.png"
,
height:
90
,
width:
115
,
Visibility
(
visible:
imageLogoShowTap
.
isNotEmpty
,
child:
Image
.
asset
(
imageLogoShowTap
,
height:
90
,
width:
115
,
),
),
],
),
...
...
@@ -1363,24 +1386,30 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
),
textAlign:
TextAlign
.
center
,
),
Image
.
asset
(
"assets/qris.png"
,
width:
60
,
height:
60
,
Visibility
(
visible:
selectMode
!=
"checkbalance"
,
child:
Image
.
asset
(
"assets/qris.png"
,
width:
60
,
height:
60
,
),
),
],
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
"wristband topup machine with qr payment"
,
style:
greyTextStyle
.
copyWith
(
fontSize:
15
,
fontStyle:
FontStyle
.
italic
,
fontWeight:
light
,
Visibility
(
visible:
selectMode
!=
"checkbalance"
,
child:
Text
(
"wristband topup machine with qr payment"
,
style:
greyTextStyle
.
copyWith
(
fontSize:
15
,
fontStyle:
FontStyle
.
italic
,
fontWeight:
light
,
),
textAlign:
TextAlign
.
center
,
),
textAlign:
TextAlign
.
center
,
),
]),
Column
(
...
...
@@ -2614,7 +2643,8 @@ class _HomePageState extends State<HomePage> implements AlertDialogCallback {
),
],
);
}),
},
),
SizedBox
(
height:
2
),
Text
(
"
${getDate()}
"
,
...
...
lib/ui/pages/home_page_check_balance.dart
0 → 100644
View file @
52f12f5e
import
'dart:async'
;
import
'dart:convert'
;
import
'package:awesome_dialog/awesome_dialog.dart'
;
import
'package:connectivity_plus/connectivity_plus.dart'
;
import
'package:easy_localization/easy_localization.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_spinkit/flutter_spinkit.dart'
;
import
'package:package_info_plus/package_info_plus.dart'
;
import
'package:self_service_3/AlertDialogCallback.dart'
;
import
'package:self_service_3/services/api_helpert.dart'
;
import
'package:self_service_3/shared/theme.dart'
;
import
'package:self_service_3/ui/widgets/backgroundBalanceCheck.dart'
;
import
'package:timer_builder/timer_builder.dart'
;
import
'../../reader/reader_flutter.dart'
;
import
'../../shared/preference_constant.dart'
;
import
'../../shared/preferences_helper.dart'
;
import
'../widgets/currency.dart'
;
class
HomePageCheckBalance
extends
StatefulWidget
{
final
Map
<
String
,
dynamic
>?
cardInfo
;
const
HomePageCheckBalance
({
Key
?
key
,
this
.
cardInfo
})
:
super
(
key:
key
);
@override
State
<
HomePageCheckBalance
>
createState
()
=>
_HomePageCheckBalanceState
();
}
class
_HomePageCheckBalanceState
extends
State
<
HomePageCheckBalance
>
implements
AlertDialogCallback
{
var
regDb
,
cardUid
,
balance
,
cardNumber
,
name
,
cardType
,
cardExpirity
,
deposit
,
infoCard
,
plainCardExpirity
,
dateTimeCardExpirity
;
String
?
prevBalance
,
maskedText
,
getRegDb
;
late
Timer
?
timerPage
;
late
Timer
?
timer
;
String
idle
=
PreferencesHelper
.
getString
(
"idle_check_balance"
);
int
_maxDuration
=
0
;
late
ValueNotifier
<
int
>
idleDuration
;
bool
isShowingDialog
=
false
;
bool
checkCountZero
=
false
;
bool
isDenomDialogShowing
=
false
;
var
message
=
"Silakan Letakkan Wristband Anda Di Reader"
;
late
ConnectivityResult
_connectivityResult
;
int
_activeContainerIndex
=
1
;
List
<
Map
<
String
,
dynamic
>>
balanceHistoryData
=
[];
List
<
Map
<
String
,
dynamic
>>
ticketHistoryData
=
[];
@override
void
initState
()
{
super
.
initState
();
WidgetsBinding
.
instance
.
addPostFrameCallback
((
_
)
{
isShowingDialog
=
true
;
checkCountZero
=
false
;
_showTap
(
context
);
tapDial
(
context
);
});
_maxDuration
=
int
.
parse
(
idle
);
idleDuration
=
ValueNotifier
<
int
>(
_maxDuration
);
double
_maxDurationPage
=
5
;
// Durasi maksimum (dalam detik)
ValueNotifier
<
double
>
progressValue
=
ValueNotifier
<
double
>(
0
);
ValueNotifier
<
int
>
displayValue
=
ValueNotifier
<
int
>(
0
);
timerPage
=
Timer
.
periodic
(
Duration
(
seconds:
1
),
(
timer
)
{
if
(
progressValue
.
value
<
_maxDurationPage
)
{
progressValue
.
value
+=
1
;
displayValue
.
value
-=
1
;
}
else
{
timer
.
cancel
();
}
});
Connectivity
()
.
onConnectivityChanged
.
listen
((
ConnectivityResult
connectivityResult
)
{
_checkInternetStatus
();
});
}
@override
void
dispose
()
{
timerPage
?.
cancel
();
idleDuration
.
dispose
();
// timer?.cancel();
super
.
dispose
();
}
String
getSystemTime
()
{
var
now
=
DateTime
.
now
();
return
DateFormat
(
"HH:mm:ss"
).
format
(
now
);
}
String
getDate
()
{
var
nowt
=
new
DateTime
.
now
();
return
DateFormat
(
'dd-MMM-yyyy'
).
format
(
nowt
);
}
_getInfoCard
(
var
info
,
BuildContext
context
)
{
setState
((){
if
(
info
.
toString
().
toLowerCase
().
contains
(
'failed'
))
{
print
(
'ini pesan salah'
);
message
=
"Silakan Tempel Wristband Anda Di Reader"
;
tapDial
(
context
);
if
(
timer
!=
null
)
timer
?.
cancel
();
// tapIdle();
}
else
{
infoCard
=
info
;
var
infoMap
=
jsonDecode
(
info
);
switch
(
infoMap
[
"cardType"
])
{
case
1
:
// Perubahan cardType 1 baru menjadi
cardType
=
"Kartu Belum Aktif"
;
break
;
case
2
:
// Perubahan cardType 2 Belum aktif menjadi
cardType
=
"Kartu Aktif"
;
break
;
case
3
:
// Perubahan cardType 3 aktif menjadi
cardType
=
"Binding Customer"
;
break
;
case
4
:
cardType
=
"On Customer"
;
break
;
case
5
:
cardType
=
"Refund"
;
break
;
default
:
cardType
=
"Tidak Terdaftar"
;
break
;
}
balance
=
CurrencyFormat
.
convertToIdr
(
infoMap
[
"balance"
],
2
,
);
// NOTE merubah tanggal
var
change
=
DateTime
.
fromMillisecondsSinceEpoch
(
int
.
parse
(
infoMap
[
'cardExpirity'
])
*
1000
);
final
DateFormat
formatter
=
DateFormat
(
'dd-MMM-yyyy'
);
cardExpirity
=
formatter
.
format
(
change
);
deposit
=
CurrencyFormat
.
convertToIdr
(
infoMap
[
"deposit"
],
2
,
);
cardNumber
=
infoMap
[
"cardNumber"
];
String
cardNo
=
cardNumber
.
toString
();
String
targetMasked
=
cardNo
.
substring
(
0
,
12
);
maskedText
=
cardNo
.
replaceAll
(
targetMasked
,
'************'
);
name
=
infoMap
[
"name"
].
toString
().
split
(
"-"
)[
0
];
cardUid
=
infoMap
[
"cardUid"
];
regDb
=
infoMap
[
"regDb"
];
}
});
}
Future
<
void
>
getAuditHistoryBalance
(
String
cardUid
,
String
regDb
)
async
{
try
{
var
auditHistory
=
await
ServiceApi
.
fetchAuditHistory
(
cardUid
,
regDb
,
"balance"
);
print
(
"AUDIT HISTORY BALANCE:
$auditHistory
"
);
// Your data is already a Map, so you don't need to decode it
List
<
dynamic
>
data
=
auditHistory
[
'data'
];
// Tambahkan data dari respons ke dalam balanceHistoryData
for
(
var
item
in
data
)
{
balanceHistoryData
.
add
(
item
);
}
}
catch
(
error
)
{
print
(
"AUDIT BALANCE ERROR:
$error
"
);
}
}
Future
<
void
>
getAuditHistoryTicket
(
String
cardUid
,
String
regDb
)
async
{
try
{
var
auditHistory
=
await
ServiceApi
.
fetchAuditHistory
(
cardUid
,
regDb
,
"ticket"
);
print
(
"AUDIT HISTORY TICKET:
$auditHistory
"
);
List
<
dynamic
>
data
=
auditHistory
[
'data'
];
for
(
var
item
in
data
)
{
ticketHistoryData
.
add
(
item
);
}
}
catch
(
error
)
{
print
(
"AUDIT TICKET ERROR:
$error
"
);
}
}
void
tapIdle
(
BuildContext
context
)
{
var
connectivityResult
=
Connectivity
().
checkConnectivity
();
if
(
connectivityResult
==
ConnectivityResult
.
none
)
{
AwesomeDialog
(
context:
context
,
dialogType:
DialogType
.
error
,
animType:
AnimType
.
rightSlide
,
dismissOnTouchOutside:
false
,
headerAnimationLoop:
true
,
title:
'Internet Tidak Tersedia'
,
desc:
'Tidak ada koneksi internet. Pastikan Anda terhubung ke internet untuk melanjutkan.'
,
btnOkOnPress:
()
{
tapIdle
(
context
);
},
btnOkIcon:
Icons
.
error
,
btnOkColor:
Colors
.
red
,
).
show
();
return
;
// Exit the method if no internet
}
int
duration
=
int
.
parse
(
idle
);
idleDuration
.
value
=
duration
;
// set nilai awal untuk idleDuration
int
count
=
0
;
// tambahkan variabel untuk menghitung durasi
timer
=
Timer
.
periodic
(
Duration
(
seconds:
1
),
(
timer
)
{
// set timer dengan durasi 1 detik
duration
-=
1
;
idleDuration
.
value
=
duration
;
count
+=
1
;
if
(
duration
==
0
&&
!
isShowingDialog
)
{
isShowingDialog
=
true
;
timer
.
cancel
();
_showTap
(
context
);
tapDial
(
context
);
}
});
}
void
tapDial
(
BuildContext
context
)
async
{
var
connectivityResult
=
await
Connectivity
().
checkConnectivity
();
if
(
connectivityResult
==
ConnectivityResult
.
none
)
{
AwesomeDialog
(
context:
context
,
dialogType:
DialogType
.
error
,
animType:
AnimType
.
rightSlide
,
dismissOnTouchOutside:
false
,
headerAnimationLoop:
true
,
title:
'Internet Tidak Tersedia'
,
desc:
'Tidak ada koneksi internet. Pastikan Anda terhubung ke internet untuk melanjutkan.'
,
btnOkOnPress:
()
{
tapDial
(
context
);
},
btnOkIcon:
Icons
.
error
,
btnOkColor:
Colors
.
red
,
).
show
();
return
;
// Exit the method if no internet
}
Future
.
delayed
(
const
Duration
(
milliseconds:
500
),
()
async
{
var
isTap
=
await
StartService
.
getCard
();
try
{
_getInfoCard
(
isTap
,
context
);
await
Future
.
wait
([
getAuditHistoryTicket
(
cardUid
,
regDb
),
getAuditHistoryBalance
(
cardUid
,
regDb
),
]);
isShowingDialog
=
false
;
isDenomDialogShowing
=
false
;
checkCountZero
=
false
;
tapIdle
(
context
);
Navigator
.
pop
(
context
);
}
catch
(
e
)
{
print
(
"Error
$isTap
"
);
tapDial
(
context
);
}
});
}
Future
<
String
>
_getSelectMode
()
async
{
String
selectMode
=
await
PreferencesHelper
.
getString
(
kMode
);
return
selectMode
;
}
Future
<
String
>
_getImageLogoShowTap
()
async
{
PackageInfo
packageInfo
=
await
PackageInfo
.
fromPlatform
();
String
appVersion
=
packageInfo
.
version
;
print
(
'APP VERSION SELFSERVICE:
$appVersion
'
);
RegExp
regExp
=
RegExp
(
r'www'
,
caseSensitive:
false
);
String
imageLogoShowTap
=
regExp
.
hasMatch
(
appVersion
)
?
'assets/wahoo.png'
:
''
;
print
(
'imageLogoShowTap:
$imageLogoShowTap
'
);
return
imageLogoShowTap
;
}
Future
<
String
>
_getWordingTap
(
String
selectMode
)
async
{
if
(
selectMode
==
"topup"
)
{
return
"Mesin Isi Ulang Wristband Dengan Pembayaran"
;
}
else
if
(
selectMode
==
"checkbalance"
)
{
return
"Customer Balance Check"
;
}
else
{
return
"Default Wording"
;
}
}
Future
<
void
>
_showTap
(
BuildContext
context
)
async
{
String
imageLogoShowTap
=
await
_getImageLogoShowTap
();
String
selectMode
=
await
_getSelectMode
();
String
wordingTap
=
await
_getWordingTap
(
selectMode
);
print
(
'imageLogoShowTap before _showTap:
$imageLogoShowTap
'
);
return
showDialog
<
void
>(
context:
context
,
barrierDismissible:
false
,
// user must tap button!
builder:
(
BuildContext
context
)
{
var
message
=
"Silakan Letakkan Wristband Anda Di Reader"
;
return
Center
(
child:
Container
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
70
,
vertical:
50
),
decoration:
BoxDecoration
(
image:
const
DecorationImage
(
fit:
BoxFit
.
cover
,
image:
AssetImage
(
'assets/img_bg_card.png'
,
),
),
),
child:
AlertDialog
(
title:
SizedBox
(
width:
1000
,
height:
520
,
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Image
.
asset
(
"assets/logo.png"
,
height:
60
,
width:
120
,
// fit:,
),
Visibility
(
visible:
imageLogoShowTap
.
isNotEmpty
,
child:
SizedBox
(
width:
90
,
),
),
Visibility
(
visible:
imageLogoShowTap
.
isNotEmpty
,
child:
Image
.
asset
(
imageLogoShowTap
,
height:
90
,
width:
115
,
),
),
],
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
wordingTap
,
style:
blackTextStyle
.
copyWith
(
fontSize:
30
,
fontWeight:
bold
,
/* letterSpacing: 2,*/
),
textAlign:
TextAlign
.
center
,
),
Visibility
(
visible:
selectMode
!=
"checkbalance"
,
child:
Image
.
asset
(
"assets/qris.png"
,
width:
60
,
height:
60
,
),
),
],
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Visibility
(
visible:
selectMode
!=
"checkbalance"
,
child:
Text
(
"wristband topup machine with qr payment"
,
style:
greyTextStyle
.
copyWith
(
fontSize:
15
,
fontStyle:
FontStyle
.
italic
,
fontWeight:
light
,
),
textAlign:
TextAlign
.
center
,
),
),
]),
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Image
.
asset
(
"assets/wristband.gif"
,
width:
230
,
height:
230
,
),
Text
(
message
,
style:
blackTextStyle
.
copyWith
(
fontSize:
30
,
fontWeight:
semiBold
,
),
textAlign:
TextAlign
.
center
,
),
SizedBox
(
height:
10
,
),
Text
(
"Please put your wristband in reader"
,
style:
greyTextStyle
.
copyWith
(
fontSize:
15
,
fontWeight:
light
,
fontStyle:
FontStyle
.
italic
,
),
textAlign:
TextAlign
.
center
,
),
SizedBox
(
height:
20
,
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
SpinKitDoubleBounce
(
color:
Colors
.
greenAccent
,
size:
20
,
duration:
const
Duration
(
milliseconds:
1000
),
),
SizedBox
(
width:
20
),
SpinKitDoubleBounce
(
color:
Colors
.
blueAccent
,
size:
20
,
duration:
const
Duration
(
milliseconds:
2000
),
),
SizedBox
(
width:
20
),
SpinKitDoubleBounce
(
color:
Colors
.
redAccent
,
size:
20
,
duration:
const
Duration
(
milliseconds:
3000
),
),
],
),
],
),
],
),
),
content:
SizedBox
(
height:
20
,
),
),
),
);
});
}
void
_changeColor
()
{
if
(
_activeContainerIndex
==
1
)
{
setState
(()
{
_activeContainerIndex
=
2
;
});
}
else
if
(
_activeContainerIndex
==
2
)
{
setState
(()
{
_activeContainerIndex
=
3
;
});
}
else
if
(
_activeContainerIndex
==
3
)
{
setState
(()
{
_activeContainerIndex
=
1
;
});
}
}
Future
<
void
>
_checkInternetStatus
()
async
{
final
connectivityResult
=
await
Connectivity
().
checkConnectivity
();
setState
(()
{
_connectivityResult
=
connectivityResult
;
if
(
_connectivityResult
==
ConnectivityResult
.
none
)
{
_activeContainerIndex
=
1
;
}
else
if
(
_connectivityResult
==
ConnectivityResult
.
mobile
||
_connectivityResult
==
ConnectivityResult
.
wifi
)
{
_changeColor
();
}
else
{
_activeContainerIndex
=
2
;
}
});
}
Future
<
bool
>
onWillPop
()
{
return
Future
.
value
(
false
);
}
@override
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
(
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
()]),
),
],
),
SizedBox
(
height:
20
),
SizedBox
(
height:
20
),
buildTicketSection
(),
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:
30.0
,
// Adjust the position as needed
child:
buildTimerSection
(
context
),
),
],
),
),
);
}
buildWellcomeCustomer
(){
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
double
textScaleFactor
=
screenWidth
/
1700
;
return
Column
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
Text
(
'Halo
${name != null ? '$name' : 'Teman Dolan'}
'
,
style:
TextStyle
(
fontSize:
26
,
fontWeight:
FontWeight
.
bold
,
),
textAlign:
TextAlign
.
start
,
),
Text
(
'Selamat datang di mesin point check balance'
,
style:
TextStyle
(
fontSize:
24
,
fontWeight:
FontWeight
.
bold
,
),
),
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
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Nomor Wristband/wristband no'
),
subtitle:
Text
((
maskedText
!=
null
)
?
':
$maskedText
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Status'
),
subtitle:
Text
((
cardType
!=
null
)
?
':
$cardType
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Masa Berlaku/expirity'
),
subtitle:
Text
((
cardExpirity
!=
null
)
?
':
$cardExpirity
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Deposit'
),
subtitle:
Text
((
deposit
!=
null
)
?
':
$deposit
'
:
': -'
),
),
Divider
(),
Text
(
'Saldo dan deposit wristband bisa dikembalikan di Refund Center'
,
style:
TextStyle
(
fontSize:
16
*
textScaleFactor
,
fontWeight:
FontWeight
.
w500
,
),
),
Text
(
'Wristband balance and deposit can be returned at the Refund Center'
,
style:
TextStyle
(
fontSize:
12
*
textScaleFactor
,
fontStyle:
FontStyle
.
italic
,
),
),
],
),
],
);
}
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
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
Image
.
asset
(
"assets/logo.png"
,
height:
50
,
width:
100
,
),
SizedBox
(
width:
31
,
),
Column
(
children:
[
TimerBuilder
.
periodic
(
Duration
(
seconds:
1
),
builder:
(
context
)
{
return
Row
(
children:
[
Text
(
"
${getSystemTime()}
"
,
style:
TextStyle
(
color:
darkBackgroundColor
,
fontSize:
27
,
fontWeight:
bold
,
),
),
],
);
},
),
SizedBox
(
height:
2
),
Text
(
"
${getDate()}
"
,
style:
TextStyle
(
color:
blackColor
,
fontSize:
20
,
fontWeight:
semiBold
,
),
),
],
),
SizedBox
(
width:
31
,
),
Image
.
asset
(
"assets/wahoo.png"
,
height:
70
,
width:
100
,
),
],
),
width:
double
.
infinity
,
),
);
}
// 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
()
{
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
double
textScaleFactor
=
screenWidth
/
1700
;
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
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Nomor Wristband/wristband no'
),
subtitle:
Text
((
maskedText
!=
null
)
?
':
$maskedText
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Status'
),
subtitle:
Text
((
cardType
!=
null
)
?
':
$cardType
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Masa Berlaku/expirity'
),
subtitle:
Text
((
cardExpirity
!=
null
)
?
':
$cardExpirity
'
:
': -'
),
),
ListTile
(
title:
Text
(
'Deposit'
),
subtitle:
Text
((
deposit
!=
null
)
?
':
$deposit
'
:
': -'
),
),
Divider
(),
Text
(
'Saldo dan deposit wristband bisa dikembalikan di Refund Center'
,
style:
TextStyle
(
fontSize:
16
*
textScaleFactor
,
fontWeight:
FontWeight
.
w500
,
),
),
Text
(
'Wristband balance and deposit can be returned at the Refund Center'
,
style:
TextStyle
(
fontSize:
12
*
textScaleFactor
,
fontStyle:
FontStyle
.
italic
,
),
),
],
),
),
),
);
}
Widget
buildBalanceSection
()
{
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
double
textScaleFactor
=
screenWidth
/
1700
;
return
Visibility
(
visible:
balanceHistoryData
.
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'
),
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
mainAxisAlignment:
MainAxisAlignment
.
start
,
children:
[
SizedBox
(
height:
20
),
Text
(
"History Saldo Kartu"
,
style:
whiteTextStyle
.
copyWith
(
fontSize:
28
,
fontWeight:
medium
,
letterSpacing:
3
,
),
),
Text
(
'history card balance'
,
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:
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
),
],
),
),
);
},
),
),
),
],
),
),
),
);
}
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
(
height:
80
,
margin:
const
EdgeInsets
.
only
(
top:
25
,
bottom:
25
,
),
child:
Stack
(
children:
[
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
GestureDetector
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Stack
(
alignment:
Alignment
.
center
,
children:
[
ValueListenableBuilder
(
valueListenable:
idleDuration
,
builder:
(
context
,
value
,
child
)
=>
CircularProgressIndicator
(
strokeWidth:
5
,
value:
value
/
_maxDuration
,
// Menggunakan nilai langsung dari value
valueColor:
AlwaysStoppedAnimation
<
Color
>(
Colors
.
blue
),
),
),
RotatedBox
(
quarterTurns:
4
,
// Menggunakan nilai bulat dari value
child:
ValueListenableBuilder
(
valueListenable:
idleDuration
,
builder:
(
context
,
value
,
child
)
=>
Text
(
(
value
.
toInt
()
%
_maxDuration
).
toString
(),
// Menggunakan nilai bulat dari value
style:
TextStyle
(
fontSize:
19
),
),
),
),
],
),
],
),
)
],
),
],
),
);
}
@override
void
onNegative
()
{
// TODO: implement onNegative
}
@override
void
onPositive
(
Object
object
)
{
// TODO: implement onPositive
}
}
lib/ui/pages/set_merchant.dart
View file @
52f12f5e
...
...
@@ -65,6 +65,8 @@ class _SetMerchantState extends State<SetMerchant> {
ServiceApi
service
=
ServiceApi
();
String
get
newRouteName
=>
'/tap-card-aktivasi'
;
bool
isSet
=
false
;
String
selectMode
=
""
;
void
setConfig
()
{
String
urlDolan
=
urlDolanController
.
text
;
...
...
@@ -112,7 +114,7 @@ class _SetMerchantState extends State<SetMerchant> {
PreferencesHelper
.
setString
(
kMaxTap
,
maxTap
);
PreferencesHelper
.
setBool
(
kIsDoneConfig
,
true
);
//
PreferencesHelper
.
setBool
(
kIsTap
,
true
);
bool
isDoneConfig
=
PreferencesHelper
.
getBool
(
kIsDoneConfig
,
false
);
...
...
@@ -137,6 +139,36 @@ class _SetMerchantState extends State<SetMerchant> {
}
}
void
setConfigCheckBalance
()
{
String
urlDolan
=
urlDolanController
.
text
;
String
urlCloseLoop
=
urlCloseLoopController
.
text
;
String
urlPrepaid
=
urlPrePaidController
.
text
;
String
idleCheckBalance
=
idleCheckBalanceController
.
text
;
if
(
urlDolan
.
isNotEmpty
&&
urlCloseLoop
.
isNotEmpty
&&
urlPrepaid
.
isNotEmpty
&&
idleCheckBalance
.
isNotEmpty
)
{
PreferencesHelper
.
setString
(
kUrlDolan
,
urlDolan
);
PreferencesHelper
.
setString
(
kUrlPrePaid
,
urlPrepaid
);
PreferencesHelper
.
setString
(
kUrlCloseLoop
,
urlCloseLoop
);
PreferencesHelper
.
setString
(
kIdleCheckBalance
,
idleCheckBalance
);
PreferencesHelper
.
setBool
(
kIsDoneConfigCheckBalance
,
true
);
PreferencesHelper
.
setBool
(
kIsTap
,
true
);
bool
isDoneConfigCheckBalance
=
PreferencesHelper
.
getBool
(
kIsDoneConfigCheckBalance
,
false
);
StartService
.
baseUrl
(
urlDolan
,
urlCloseLoop
,
urlPrepaid
);
print
(
'CONFIGURATION MESSAGE :
$isDoneConfigCheckBalance
'
);
if
(
isDoneConfigCheckBalance
){
_showDialSuccessCheckBalance
();
}
else
{
_showDialFail
();
}
}
else
{
_showDialFail
();
}
}
void
getListOutlet
()
async
{
String
urlDolan
=
urlDolanController
.
text
;
String
corePayment
=
urlCorePaymentController
.
text
;
...
...
@@ -242,6 +274,74 @@ class _SetMerchantState extends State<SetMerchant> {
);
}
Future
<
void
>
_showDialSuccessCheckBalance
()
async
{
return
showDialog
<
void
>(
context:
context
,
barrierDismissible:
false
,
// user must tap button!
builder:
(
BuildContext
context
)
{
return
Center
(
child:
Container
(
decoration:
BoxDecoration
(
border:
Border
.
all
(
color:
Colors
.
white10
.
withAlpha
(
80
),
),
borderRadius:
BorderRadius
.
circular
(
20
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
white10
.
withAlpha
(
100
),
blurRadius:
10
,
spreadRadius:
0
,
),
],
color:
Colors
.
white10
.
withAlpha
(
2
),
),
child:
AlertDialog
(
title:
Center
(
child:
IconButton
(
icon:
Icon
(
Icons
.
done_all_rounded
,
color:
purpleColor
,
),
onPressed:
()
{},
),
),
content:
SingleChildScrollView
(
child:
ListBody
(
children:
<
Widget
>[
Center
(
child:
Text
(
'Data Berhasil Tersimpan'
,
style:
blackTextStyle
.
copyWith
(
fontSize:
16
,
fontWeight:
semiBold
,
),
),
),
SizedBox
(
height:
20
),
Text
(
'URL/HOST/TREND :
${urlDolanController.text}
'
),
Text
(
'URL/HOST/DOLAN :
${urlCloseLoopController.text}
'
),
Text
(
'URL/HOST/PREPAID :
${urlPrePaidController.text}
'
),
Text
(
'IDLE/PERDETIK :
${idleCheckBalanceController.text}
'
),
],
),
),
actions:
<
Widget
>[
Center
(
child:
TextButton
(
child:
const
Text
(
'Ok'
),
onPressed:
()
{
Navigator
.
pushNamedAndRemoveUntil
(
context
,
newRouteName
,
(
route
)
=>
false
);
},
),
),
],
),
),
);
},
);
}
Future
<
void
>
_showDialFail
()
async
{
return
showDialog
<
void
>(
context:
context
,
...
...
@@ -322,7 +422,7 @@ class _SetMerchantState extends State<SetMerchant> {
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
"Konfigurasi Self-Service
!
"
,
"Konfigurasi Self-Service
Topup
"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
fontSize:
20
,
...
...
@@ -371,7 +471,6 @@ class _SetMerchantState extends State<SetMerchant> {
title:
"Minimal isi ulang topup"
,
isShowTitle:
false
,
),
],
),
),
...
...
@@ -434,6 +533,7 @@ class _SetMerchantState extends State<SetMerchant> {
const
SizedBox
(
height:
40
,
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
end
,
children:
[
...
...
@@ -486,13 +586,174 @@ class _SetMerchantState extends State<SetMerchant> {
);
}
Future
<
void
>
showDialMode
()
async
{
showDialog
<
String
>(
barrierDismissible:
false
,
context:
context
,
builder:
(
BuildContext
context
)
{
return
AlertDialog
(
title:
Text
(
"Pilih Mode"
),
content:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
ElevatedButton
(
onPressed:
()
{
selectMode
=
"topup"
;
PreferencesHelper
.
setBool
(
kIsHashMode
,
true
);
PreferencesHelper
.
setString
(
kMode
,
selectMode
);
Navigator
.
pop
(
context
);
showDialConfig
();
// Tampilkan konfigurasi topup
},
child:
Text
(
"Topup"
),
),
SizedBox
(
width:
20
),
ElevatedButton
(
onPressed:
()
{
selectMode
=
"checkbalance"
;
PreferencesHelper
.
setBool
(
kIsHashMode
,
true
);
PreferencesHelper
.
setString
(
kMode
,
selectMode
);
Navigator
.
pop
(
context
);
showDialBalance
();
// Tampilkan dialog balance
},
child:
Text
(
"Check Balance"
),
),
],
),
backgroundColor:
lightBackgroundColor
,
elevation:
50
,
);
},
);
}
Future
<
void
>
showDialBalance
()
async
{
showDialog
<
String
>(
// Tambahkan dialog balance
barrierDismissible:
false
,
context:
context
,
builder:
(
BuildContext
context
)
=>
Center
(
child:
SingleChildScrollView
(
physics:
AlwaysScrollableScrollPhysics
(),
child:
Center
(
child:
SingleChildScrollView
(
physics:
AlwaysScrollableScrollPhysics
(),
child:
AlertDialog
(
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
30
)),
title:
Center
(),
actions:
<
Widget
>[
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
"Konfigurasi Self-Service Check Balance"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
fontSize:
20
,
fontWeight:
FontWeight
.
bold
,
color:
blackColor
,
),
),
SizedBox
(
height:
20
),
SingleChildScrollView
(
physics:
AlwaysScrollableScrollPhysics
(),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceAround
,
children:
[
Expanded
(
child:
Column
(
children:
[
CustomFormField
(
controller:
urlDolanController
,
title:
'Url Host Trend'
,
isShowTitle:
false
,
validator:
(
value
)
{},
),
SizedBox
(
height:
20
),
CustomFormField
(
controller:
urlCloseLoopController
,
title:
'Url Host Dolan'
,
isShowTitle:
false
,
validator:
(
value
)
{},
),
SizedBox
(
height:
20
),
],
),
),
SizedBox
(
width:
30
),
Expanded
(
child:
Column
(
children:
[
CustomFormField
(
controller:
urlPrePaidController
,
title:
'Url Host Prepaid'
,
isShowTitle:
false
,
validator:
(
value
)
{},
),
SizedBox
(
height:
20
),
CustomNumberField
(
controller:
idleCheckBalanceController
,
title:
"Waktu siaga beranda (detik)"
,
isShowTitle:
false
,
),
SizedBox
(
height:
20
),
],
),
),
],
),
)
],
),
const
SizedBox
(
height:
40
,
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
end
,
children:
[
TextButton
(
onPressed:
(){
setState
(()
{
Navigator
.
pop
(
context
);
setConfigCheckBalance
();
});
},
style:
TextButton
.
styleFrom
(
padding:
EdgeInsets
.
zero
,
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
'Lanjut'
,
style:
greyTextStyle
.
copyWith
(
color:
purpleColor
,
fontSize:
17
,
fontWeight:
semiBold
,
),
),
],
),
),
],
),
],
backgroundColor:
lightBackgroundColor
,
elevation:
50
,
),
),
),
),
),
);
}
@override
void
initState
()
{
StartService
.
initLibrary
();
_initPackageInfo
();
getListOutlet
();
super
.
initState
();
WidgetsBinding
.
instance
.
addPostFrameCallback
((
_
)
=>
showDial
Config
());
WidgetsBinding
.
instance
.
addPostFrameCallback
((
_
)
=>
showDial
Mode
());
}
@override
...
...
@@ -539,7 +800,7 @@ class _SetMerchantState extends State<SetMerchant> {
Icons
.
settings
,
color:
purpleColor
,
),
onPressed:
()
=>
showDial
Config
()),
onPressed:
()
=>
showDial
Mode
()),
],
),
),
...
...
lib/ui/pages/splash_page.dart
View file @
52f12f5e
...
...
@@ -125,11 +125,14 @@ class _SplashPageState extends State<SplashPage> with TickerProviderStateMixin{
}
void
checkActivation
()
{
bool
isDoneConfig
=
PreferencesHelper
.
getBool
(
kIsDoneConfig
);
// bool isDoneConfig = PreferencesHelper.getBool(kIsDoneConfig);
// bool isDoneConfigCheckBalance = PreferencesHelper.getBool(kIsDoneConfigCheckBalance);
bool
isTapConfig
=
PreferencesHelper
.
getBool
(
kIsTap
);
String
isMode
=
PreferencesHelper
.
getString
(
kMode
);
bool
isHasMode
=
PreferencesHelper
.
getBool
(
kIsHashMode
);
if
(
is
DoneConfig
)
{
if
(
isTapConfig
&&
isDoneConfig
)
{
if
(
is
HasMode
)
{
if
(
isTapConfig
)
{
navigationToActivation
();
}
else
{
navigationToGetOutlet
();
...
...
lib/ui/widgets/backgroundBalanceCheck.dart
0 → 100644
View file @
52f12f5e
import
'dart:ui'
;
import
'package:flutter/material.dart'
;
class
GlassMorphism
extends
StatelessWidget
{
final
Widget
child
;
final
double
start
;
final
double
end
;
const
GlassMorphism
({
Key
?
key
,
required
this
.
child
,
required
this
.
start
,
required
this
.
end
,
})
:
super
(
key:
key
);
@override
Widget
build
(
BuildContext
context
)
{
return
ClipRRect
(
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
3
,
sigmaY:
3
),
child:
Container
(
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
colors:
[
Colors
.
blue
.
withOpacity
(
start
),
Colors
.
blue
.
withOpacity
(
end
),
],
begin:
AlignmentDirectional
.
topStart
,
end:
AlignmentDirectional
.
bottomEnd
,
),
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
10
)),
border:
Border
.
all
(
width:
1.5
,
color:
Colors
.
white
.
withOpacity
(
0.2
),
),
),
child:
child
,
),
),
);
}
}
\ No newline at end of file
lib/ui/widgets/tap_card_aktivasi.dart
View file @
52f12f5e
...
...
@@ -11,6 +11,7 @@ import 'package:self_service_3/services/api_helpert.dart';
import
'package:self_service_3/shared/theme.dart'
;
import
'package:self_service_3/ui/widgets/buttons.dart'
;
import
'package:self_service_3/ui/widgets/glassmorphism.dart'
;
import
'../../shared/preference_constant.dart'
;
import
'../../shared/theme.dart'
;
import
'../../shared/preferences_helper.dart'
;
import
'forms.dart'
;
...
...
@@ -29,7 +30,6 @@ class TapCardAktivasi extends StatefulWidget {
class
_TapCardAktivasiState
extends
State
<
TapCardAktivasi
>
with
TickerProviderStateMixin
{
String
newRouteName
=
'/home'
;
ServiceApi
service
=
ServiceApi
();
bool
isDoneActivateKey
=
PreferencesHelper
.
getBool
(
"IS_DONE_ACTIVATE_WORKING_KEY"
);
...
...
@@ -140,6 +140,16 @@ class _TapCardAktivasiState extends State<TapCardAktivasi>
}
Future
<
void
>
_showDialSuccess
()
async
{
String
mode
=
PreferencesHelper
.
getString
(
kMode
);
// Mengambil mode dari Shared Preferences
String
newRouteName
;
if
(
mode
==
'topup'
)
{
newRouteName
=
'/home'
;
}
else
if
(
mode
==
'checkbalance'
)
{
newRouteName
=
'/home-check-balance'
;
}
else
{
// Mode default jika tidak sesuai dengan 'topup' atau 'checkbalance'
newRouteName
=
'/default-route'
;
// Ganti dengan rute default yang sesuai
}
return
showDialog
<
void
>(
context:
context
,
barrierDismissible:
false
,
// user must tap button!
...
...
linux/flutter/ephemeral/.plugin_symlinks/connectivity_plus
View file @
52f12f5e
/Users/macbookpro/.pub-cache/hosted/pub.dev/connectivity_plus-3.0.3/
\ No newline at end of file
C:/Users/MDD HP/AppData/Local/Pub/Cache/hosted/pub.dev/connectivity_plus-3.0.3/
\ No newline at end of file
linux/flutter/ephemeral/.plugin_symlinks/device_info_plus
View file @
52f12f5e
/Users/macbookpro/.pub-cache/hosted/pub.dev/device_info_plus-8.1.0/
\ No newline at end of file
C:/Users/MDD HP/AppData/Local/Pub/Cache/hosted/pub.dev/device_info_plus-8.1.0/
\ No newline at end of file
linux/flutter/ephemeral/.plugin_symlinks/package_info_plus
View file @
52f12f5e
/Users/macbookpro/.pub-cache/hosted/pub.dev/package_info_plus-3.0.3/
\ No newline at end of file
C:/Users/MDD HP/AppData/Local/Pub/Cache/hosted/pub.dev/package_info_plus-3.0.3/
\ No newline at end of file
linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux
View file @
52f12f5e
/Users/macbookpro/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.10/
\ No newline at end of file
C:/Users/MDD HP/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_linux-2.1.10/
\ No newline at end of file
linux/flutter/ephemeral/.plugin_symlinks/sentry_flutter
View file @
52f12f5e
/Users/macbookpro/.pub-cache/hosted/pub.dev/sentry_flutter-7.2.0/
\ No newline at end of file
C:/Users/MDD HP/AppData/Local/Pub/Cache/hosted/pub.dev/sentry_flutter-7.10.1/
\ No newline at end of file
linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux
View file @
52f12f5e
/Users/macbookpro/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.1.5/
\ No newline at end of file
C:/Users/MDD HP/AppData/Local/Pub/Cache/hosted/pub.dev/shared_preferences_linux-2.1.5/
\ No newline at end of file
pubspec.lock
View file @
52f12f5e
...
...
@@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: async
sha256:
bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
sha256:
"947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.1
0
.0"
version: "2.1
1
.0"
awesome_dialog:
dependency: "direct main"
description:
...
...
@@ -149,10 +149,10 @@ packages:
dependency: transitive
description:
name: characters
sha256:
e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
sha256:
"04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.
2.1
"
version: "1.
3.0
"
checked_yaml:
dependency: transitive
description:
...
...
@@ -197,10 +197,10 @@ packages:
dependency: transitive
description:
name: collection
sha256:
cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
sha256:
f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.17.
0
"
version: "1.17.
2
"
connectivity_plus:
dependency: "direct main"
description:
...
...
@@ -386,10 +386,10 @@ packages:
dependency: "direct main"
description:
name: flutter_layout_grid
sha256: "
1df27a2e9cd34faa0c0a33148c8bb9d9259e87cc5b934c989a59a77e1a4c0d6b
"
sha256: "
3529b7aa7ed2cb9861a0bbaa5c14d4be2beaf5a070ce0176077159f80c5de094
"
url: "https://pub.dev"
source: hosted
version: "2.0.
1
"
version: "2.0.
5
"
flutter_localizations:
dependency: "direct main"
description: flutter
...
...
@@ -497,10 +497,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: "
910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91
"
sha256: "
3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d
"
url: "https://pub.dev"
source: hosted
version: "0.1
7.0
"
version: "0.1
8.1
"
io:
dependency: transitive
description:
...
...
@@ -513,10 +513,10 @@ packages:
dependency: transitive
description:
name: js
sha256:
"5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
sha256:
f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.
5
"
version: "0.6.
7
"
json_annotation:
dependency: transitive
description:
...
...
@@ -553,26 +553,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "1
6db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72
"
sha256: "1
803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e
"
url: "https://pub.dev"
source: hosted
version: "0.12.1
3
"
version: "0.12.1
6
"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256:
d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256:
"9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.
2
.0"
version: "0.
5
.0"
meta:
dependency: transitive
description:
name: meta
sha256: "
6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42
"
sha256: "
3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3
"
url: "https://pub.dev"
source: hosted
version: "1.
8.0
"
version: "1.
9.1
"
mime:
dependency: transitive
description:
...
...
@@ -641,10 +641,10 @@ packages:
dependency: transitive
description:
name: path
sha256:
db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
sha256:
"8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.
2
"
version: "1.8.
3
"
path_parsing:
dependency: transitive
description:
...
...
@@ -857,18 +857,18 @@ packages:
dependency: transitive
description:
name: sentry
sha256:
faecda9087cd6d1c2b95bd5e16cce0adeef2e9aa34b8016b150b314be7b5c642
sha256:
"830667eadc0398fea3a3424ed1b74568e2db603a42758d0922e2f2974ce55a60"
url: "https://pub.dev"
source: hosted
version: "7.
2.0
"
version: "7.
10.1
"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: "
038607c578d2601c63ced78a503c23d7b25f24bd3c24492cadfc47bc9cbb6636
"
sha256: "
6730f41b304c6fb0fa590dacccaf73ba11082fc64b274cfe8a79776f2b95309c
"
url: "https://pub.dev"
source: hosted
version: "7.
2.0
"
version: "7.
10.1
"
shared_preferences:
dependency: "direct main"
description:
...
...
@@ -966,10 +966,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256:
dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256:
"53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.
9.1
"
version: "1.
10.0
"
sqflite:
dependency: "direct main"
description:
...
...
@@ -1062,10 +1062,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256:
ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
sha256:
"75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
version: "0.
4.16
"
version: "0.
6.0
"
timer_builder:
dependency: "direct main"
description:
...
...
@@ -1170,6 +1170,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
web:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
web_socket_channel:
dependency: transitive
description:
...
...
@@ -1211,5 +1219,5 @@ packages:
source: hosted
version: "3.1.1"
sdks:
dart: ">=
2.19.0 <3
.0.0"
dart: ">=
3.1.0-185.0.dev <4
.0.0"
flutter: ">=3.7.0-0"
pubspec.yaml
View file @
52f12f5e
...
...
@@ -55,7 +55,7 @@ dependencies:
flutter_spinkit
:
^5.1.0
simple_animations
:
^5.0.0+2
flutter_svg
:
^2.0.4
flutter_layout_grid
:
^2.0.
1
flutter_layout_grid
:
^2.0.
5
flutter_staggered_grid_view
:
^0.6.2
timer_count_down
:
^2.2.1
easy_localization
:
^3.0.0
...
...
@@ -70,7 +70,7 @@ dependencies:
package_info_plus
:
^3.0.3
otp_text_field
:
^1.1.3
timer_builder
:
^2.0.0
sentry_flutter
:
^7.
2.0
sentry_flutter
:
^7.
10.1
dev_dependencies
:
...
...
@@ -108,6 +108,7 @@ flutter:
assets
:
-
assets/
-
assets/translate/
-
assets/wahoo.png
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment