Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Hoàng Văn Đạt
mypoint_flutter_app
Commits
5fb93f2d
Commit
5fb93f2d
authored
Apr 23, 2025
by
DatHV
Browse files
update logic authen
parent
73074efa
Changes
39
Hide whitespace changes
Inline
Side-by-side
ios/Runner.xcodeproj/project.pbxproj
View file @
5fb93f2d
...
...
@@ -105,7 +105,6 @@
4095AD98D6AA41A025D05981
/* Pods-RunnerTests.release.xcconfig */
,
40F35D12C549F03EDF2680DB
/* Pods-RunnerTests.profile.xcconfig */
,
);
name
=
Pods
;
path
=
Pods
;
sourceTree
=
"<group>"
;
};
...
...
@@ -470,16 +469,20 @@
buildSettings
=
{
ASSETCATALOG_COMPILER_APPICON_NAME
=
AppIcon
;
CLANG_ENABLE_MODULES
=
YES
;
CODE_SIGN_STYLE
=
Manual
;
CURRENT_PROJECT_VERSION
=
"$(FLUTTER_BUILD_NUMBER)"
;
DEVELOPMENT_TEAM
=
T3AV8NC2D4
;
DEVELOPMENT_TEAM
=
""
;
"DEVELOPMENT_TEAM[sdk=iphoneos*]"
=
Z99P65VHXA
;
ENABLE_BITCODE
=
NO
;
INFOPLIST_FILE
=
Runner/Info.plist
;
LD_RUNPATH_SEARCH_PATHS
=
(
"$(inherited)"
,
"@executable_path/Frameworks"
,
);
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
myp
oint
FlutterApp
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
MyP
oint
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"
=
"MyPoint development"
;
SWIFT_OBJC_BRIDGING_HEADER
=
"Runner/Runner-Bridging-Header.h"
;
SWIFT_VERSION
=
5.0
;
VERSIONING_SYSTEM
=
"apple-generic"
;
...
...
@@ -491,12 +494,16 @@
baseConfigurationReference
=
DEA7D70911C640B733B46F56
/* Pods-RunnerTests.debug.xcconfig */
;
buildSettings
=
{
BUNDLE_LOADER
=
"$(TEST_HOST)"
;
CODE_SIGN_STYLE
=
Automatic
;
CODE_SIGN_STYLE
=
Manual
;
CURRENT_PROJECT_VERSION
=
1
;
DEVELOPMENT_TEAM
=
""
;
"DEVELOPMENT_TEAM[sdk=iphoneos*]"
=
Z99P65VHXA
;
GENERATE_INFOPLIST_FILE
=
YES
;
MARKETING_VERSION
=
1.0
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
myp
oint
FlutterApp.RunnerTests
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
MyP
oint
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"
=
"MyPoint development"
;
SWIFT_ACTIVE_COMPILATION_CONDITIONS
=
DEBUG
;
SWIFT_OPTIMIZATION_LEVEL
=
"-Onone"
;
SWIFT_VERSION
=
5.0
;
...
...
@@ -509,12 +516,16 @@
baseConfigurationReference
=
4095AD98D6AA41A025D05981
/* Pods-RunnerTests.release.xcconfig */
;
buildSettings
=
{
BUNDLE_LOADER
=
"$(TEST_HOST)"
;
CODE_SIGN_STYLE
=
Automatic
;
CODE_SIGN_STYLE
=
Manual
;
CURRENT_PROJECT_VERSION
=
1
;
DEVELOPMENT_TEAM
=
""
;
"DEVELOPMENT_TEAM[sdk=iphoneos*]"
=
Z99P65VHXA
;
GENERATE_INFOPLIST_FILE
=
YES
;
MARKETING_VERSION
=
1.0
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
myp
oint
FlutterApp.RunnerTests
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
MyP
oint
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"
=
"MyPoint development"
;
SWIFT_VERSION
=
5.0
;
TEST_HOST
=
"$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"
;
};
...
...
@@ -525,12 +536,16 @@
baseConfigurationReference
=
40F35D12C549F03EDF2680DB
/* Pods-RunnerTests.profile.xcconfig */
;
buildSettings
=
{
BUNDLE_LOADER
=
"$(TEST_HOST)"
;
CODE_SIGN_STYLE
=
Automatic
;
CODE_SIGN_STYLE
=
Manual
;
CURRENT_PROJECT_VERSION
=
1
;
DEVELOPMENT_TEAM
=
""
;
"DEVELOPMENT_TEAM[sdk=iphoneos*]"
=
Z99P65VHXA
;
GENERATE_INFOPLIST_FILE
=
YES
;
MARKETING_VERSION
=
1.0
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
myp
oint
FlutterApp.RunnerTests
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
MyP
oint
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"
=
"MyPoint development"
;
SWIFT_VERSION
=
5.0
;
TEST_HOST
=
"$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"
;
};
...
...
@@ -653,16 +668,20 @@
buildSettings
=
{
ASSETCATALOG_COMPILER_APPICON_NAME
=
AppIcon
;
CLANG_ENABLE_MODULES
=
YES
;
CODE_SIGN_STYLE
=
Manual
;
CURRENT_PROJECT_VERSION
=
"$(FLUTTER_BUILD_NUMBER)"
;
DEVELOPMENT_TEAM
=
T3AV8NC2D4
;
DEVELOPMENT_TEAM
=
""
;
"DEVELOPMENT_TEAM[sdk=iphoneos*]"
=
Z99P65VHXA
;
ENABLE_BITCODE
=
NO
;
INFOPLIST_FILE
=
Runner/Info.plist
;
LD_RUNPATH_SEARCH_PATHS
=
(
"$(inherited)"
,
"@executable_path/Frameworks"
,
);
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
myp
oint
FlutterApp
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
MyP
oint
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"
=
"MyPoint development"
;
SWIFT_OBJC_BRIDGING_HEADER
=
"Runner/Runner-Bridging-Header.h"
;
SWIFT_OPTIMIZATION_LEVEL
=
"-Onone"
;
SWIFT_VERSION
=
5.0
;
...
...
@@ -676,16 +695,20 @@
buildSettings
=
{
ASSETCATALOG_COMPILER_APPICON_NAME
=
AppIcon
;
CLANG_ENABLE_MODULES
=
YES
;
CODE_SIGN_STYLE
=
Manual
;
CURRENT_PROJECT_VERSION
=
"$(FLUTTER_BUILD_NUMBER)"
;
DEVELOPMENT_TEAM
=
T3AV8NC2D4
;
DEVELOPMENT_TEAM
=
""
;
"DEVELOPMENT_TEAM[sdk=iphoneos*]"
=
Z99P65VHXA
;
ENABLE_BITCODE
=
NO
;
INFOPLIST_FILE
=
Runner/Info.plist
;
LD_RUNPATH_SEARCH_PATHS
=
(
"$(inherited)"
,
"@executable_path/Frameworks"
,
);
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
myp
oint
FlutterApp
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.icom.vn.
MyP
oint
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]"
=
"MyPoint development"
;
SWIFT_OBJC_BRIDGING_HEADER
=
"Runner/Runner-Bridging-Header.h"
;
SWIFT_VERSION
=
5.0
;
VERSIONING_SYSTEM
=
"apple-generic"
;
...
...
ios/Runner/Info.plist
View file @
5fb93f2d
...
...
@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist
version=
"1.0"
>
<dict>
<key>
CADisableMinimumFrameDurationOnPhone
</key>
<true/>
<key>
CFBundleDevelopmentRegion
</key>
<string>
$(DEVELOPMENT_LANGUAGE)
</string>
<key>
CFBundleDisplayName
</key>
...
...
@@ -24,6 +26,12 @@
<string>
$(FLUTTER_BUILD_NUMBER)
</string>
<key>
LSRequiresIPhoneOS
</key>
<true/>
<key>
NSFaceIDUsageDescription
</key>
<string>
We need Face ID to authenticate your identity
</string>
<key>
NSLocalAuthenticationUseFaceID
</key>
<string>
true
</string>
<key>
UIApplicationSupportsIndirectInputEvents
</key>
<true/>
<key>
UILaunchStoryboardName
</key>
<string>
LaunchScreen
</string>
<key>
UIMainStoryboardFile
</key>
...
...
@@ -41,13 +49,5 @@
<string>
UIInterfaceOrientationLandscapeLeft
</string>
<string>
UIInterfaceOrientationLandscapeRight
</string>
</array>
<key>
CADisableMinimumFrameDurationOnPhone
</key>
<true/>
<key>
UIApplicationSupportsIndirectInputEvents
</key>
<true/>
<key>
NSFaceIDUsageDescription
</key>
<string>
We need Face ID to authenticate your identity
</string>
<key>
NSLocalAuthenticationUseFaceID
</key>
<string>
true
</string>
</dict>
</plist>
lib/base/base_screen.dart
View file @
5fb93f2d
...
...
@@ -97,10 +97,15 @@ abstract class BaseState<Screen extends BaseScreen> extends State<Screen> {
context
.
showConfirmAlertDialog
(
message
,
cancel:
cancel
,
confirm:
confirm
,
callback:
callback
);
}
showAlert
({
required
DataAlertModel
data
,
bool
?
barrierDismissibl
})
{
showAlert
({
required
DataAlertModel
data
,
bool
?
barrierDismissibl
,
bool
showCloseButton
=
true
,
ButtonsDirection
direction
=
ButtonsDirection
.
column
})
{
Get
.
dialog
(
CustomAlertDialog
(
alertData:
data
,
showCloseButton:
showCloseButton
,
direction:
direction
,
),
barrierDismissible:
barrierDismissibl
??
false
,
);
...
...
lib/configs/api_paths.dart
View file @
5fb93f2d
...
...
@@ -19,4 +19,10 @@ class APIPaths {
static
const
String
bioCredential
=
"/iam/v1/account/me/bio-credential"
;
static
const
String
accountLoginForPasswordChange
=
"/accountLoginForPasswordChange/1.0.0"
;
static
const
String
accountPasswordChange
=
"/accountPasswordChange/1.0.0"
;
static
const
String
registerBiometric
=
"/iam/v1/account/me/bio-credential"
;
static
const
String
unRegisterBiometric
=
"/iam/v1/account/me/bio-credential"
;
static
const
String
customerBalanceGetDetail
=
"/customerBalanceGetDetail/1.0.0"
;
static
const
String
headerHome
=
"/dynamic-home/api/v1.0/header-home"
;
static
const
String
otpDeleteAccountRequest
=
"/user/api/v2.0/me/delete/request"
;
static
const
String
verifyDeleteAccount
=
"/user/api/v2.0/me/delete/verify"
;
}
lib/main.dart
View file @
5fb93f2d
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/preference/data_preference.dart'
;
import
'package:mypoint_flutter_app/screen/login/login_screen.dart'
;
import
'package:mypoint_flutter_app/screen/main_tab_screen/main_tab_screen.dart'
;
import
'package:mypoint_flutter_app/screen/onboarding/onboarding_screen.dart'
;
import
'package:mypoint_flutter_app/screen/onboarding/onboarding_viewmodel.dart'
;
import
'package:mypoint_flutter_app/screen/splash/splash_screen.dart'
;
import
'package:mypoint_flutter_app/shared/router_gage.dart'
;
void
main
(
)
async
{
WidgetsFlutterBinding
.
ensureInitialized
();
await
DataPreference
.
instance
.
loadLoginToken
();
Get
.
put
(
OnboardingViewModel
());
await
DataPreference
.
instance
.
init
();
runApp
(
const
MyApp
());
}
...
...
@@ -21,17 +16,13 @@ class MyApp extends StatelessWidget {
Widget
build
(
BuildContext
context
)
{
return
GetMaterialApp
(
debugShowCheckedModeBanner:
false
,
initialRoute:
'/
login
'
,
initialRoute:
'/
splash
'
,
theme:
ThemeData
(
colorScheme:
ColorScheme
.
fromSwatch
(
primarySwatch:
Colors
.
deepPurple
),
primaryColor:
Colors
.
deepPurple
,
),
home:
SplashScreen
(),
getPages:
[
GetPage
(
name:
'/login'
,
page:
()
=>
const
LoginScreen
(
phoneNumber:
'091212121'
,)),
GetPage
(
name:
'/main'
,
page:
()
=>
const
MainTabScreen
()),
GetPage
(
name:
'/onboarding'
,
page:
()
=>
const
OnboardingScreen
()),
],
// home: SplashScreen(),
getPages:
RouterPage
.
pages
(),
);
}
}
\ No newline at end of file
lib/model/update_response_model.dart
View file @
5fb93f2d
...
...
@@ -6,7 +6,7 @@ part 'update_response_model.g.dart';
@JsonSerializable
()
class
UpdateResponseModel
{
@JsonKey
(
name:
'update_request'
)
List
<
CheckUpdateResponseModel
?
>?
updateRequest
;
List
<
CheckUpdateResponseModel
>?
updateRequest
;
UpdateResponseModel
({
this
.
updateRequest
});
...
...
lib/model/update_response_model.g.dart
View file @
5fb93f2d
...
...
@@ -6,20 +6,16 @@ part of 'update_response_model.dart';
// JsonSerializableGenerator
// **************************************************************************
UpdateResponseModel
_$UpdateResponseModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
UpdateResponseModel
(
updateRequest:
(
json
[
'update_request'
]
as
List
<
dynamic
>?)
?.
map
(
(
e
)
=>
e
==
null
?
null
:
CheckUpdateResponseModel
.
fromJson
(
e
as
Map
<
String
,
dynamic
>,
),
)
.
toList
(),
);
UpdateResponseModel
_$UpdateResponseModelFromJson
(
Map
<
String
,
dynamic
>
json
,
)
=>
UpdateResponseModel
(
updateRequest:
(
json
[
'update_request'
]
as
List
<
dynamic
>?)
?.
map
(
(
e
)
=>
CheckUpdateResponseModel
.
fromJson
(
e
as
Map
<
String
,
dynamic
>),
)
.
toList
(),
);
Map
<
String
,
dynamic
>
_$UpdateResponseModelToJson
(
UpdateResponseModel
instance
,
...
...
lib/model/update_response_object.dart
deleted
100644 → 0
View file @
73074efa
import
'package:json_annotation/json_annotation.dart'
;
import
'package:mypoint_flutter_app/model/update_response_model.dart'
;
part
'update_response_object.g.dart'
;
@JsonSerializable
()
class
UpdateResponseObject
{
UpdateResponseModel
?
data
;
UpdateResponseObject
({
this
.
data
});
factory
UpdateResponseObject
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$UpdateResponseObjectFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$UpdateResponseObjectToJson
(
this
);
}
\ No newline at end of file
lib/model/update_response_object.g.dart
deleted
100644 → 0
View file @
73074efa
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'update_response_object.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
UpdateResponseObject
_$UpdateResponseObjectFromJson
(
Map
<
String
,
dynamic
>
json
,
)
=>
UpdateResponseObject
(
data:
json
[
'data'
]
==
null
?
null
:
UpdateResponseModel
.
fromJson
(
json
[
'data'
]
as
Map
<
String
,
dynamic
>),
);
Map
<
String
,
dynamic
>
_$UpdateResponseObjectToJson
(
UpdateResponseObject
instance
,
)
=>
<
String
,
dynamic
>{
'data'
:
instance
.
data
};
lib/networking/restful_api_request.dart
View file @
5fb93f2d
...
...
@@ -9,7 +9,8 @@ import '../configs/device_info.dart';
import
'../model/auth/biometric_register_response_model.dart'
;
import
'../model/auth/login_token_response_model.dart'
;
import
'../model/auth/profile_response_model.dart'
;
import
'../model/update_response_object.dart'
;
import
'../model/update_response_model.dart'
;
import
'../preference/point/header_home_model.dart'
;
import
'../screen/faqs/faqs_model.dart'
;
import
'../screen/onboarding/model/check_phone_response_model.dart'
;
import
'../screen/onboarding/model/onboarding_info_model.dart'
;
...
...
@@ -21,14 +22,14 @@ import '../screen/splash/splash_screen_viewmodel.dart';
import
'model_maker.dart'
;
extension
RestfullAPIClientAllApi
on
RestfulAPIClient
{
Future
<
BaseResponseModel
<
UpdateResponse
Object
>>
checkUpdateApp
()
async
{
Future
<
BaseResponseModel
<
UpdateResponse
Model
>>
checkUpdateApp
()
async
{
String
version
=
Platform
.
version
;
final
body
=
{
"operating_system"
:
"iOS"
,
"software_model"
:
"MyPoint"
,
"version"
:
"1.
12.1
"
,
"build_number"
:
"1"
};
final
body
=
{
"operating_system"
:
"iOS"
,
"software_model"
:
"MyPoint"
,
"version"
:
"1.
21.7
"
,
"build_number"
:
"1"
};
return
requestNormal
(
APIPaths
.
checkUpdate
,
Method
.
POST
,
body
,
(
data
)
=>
UpdateResponse
Object
.
fromJson
(
data
as
Json
),
(
data
)
=>
UpdateResponse
Model
.
fromJson
(
data
as
Json
),
);
}
...
...
@@ -73,6 +74,24 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
);
}
Future
<
BaseResponseModel
<
CreateOTPResponseModel
>>
requestOtpDeleteAccount
()
async
{
return
requestNormal
(
APIPaths
.
otpDeleteAccountRequest
,
Method
.
POST
,
{},
(
data
)
=>
CreateOTPResponseModel
.
fromJson
(
data
as
Json
),
);
}
Future
<
BaseResponseModel
<
CreateOTPResponseModel
>>
verifyDeleteAccount
(
String
otp
)
async
{
return
requestNormal
(
APIPaths
.
verifyDeleteAccount
,
Method
.
POST
,
{
"otp"
:
otp
},
(
data
)
=>
CreateOTPResponseModel
.
fromJson
(
data
as
Json
),
);
}
Future
<
BaseResponseModel
<
EmptyCodable
>>
signup
(
String
phone
,
String
password
)
async
{
var
deviceKey
=
await
DeviceInfo
.
getDeviceId
();
final
body
=
{
"username"
:
phone
,
"password"
:
password
.
toSha256
(),
"device_key"
:
deviceKey
};
...
...
@@ -91,12 +110,13 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
Future
<
BaseResponseModel
<
LoginTokenResponseModel
>>
loginWithBiometric
(
String
phone
)
async
{
var
deviceKey
=
await
DeviceInfo
.
getDeviceId
();
var
bioToken
=
await
DataPreference
.
instance
.
getBioToken
(
phone
)
??
""
;
final
body
=
{
"username"
:
phone
,
"bioToken"
:
DataPreference
.
instance
.
getBioToken
(
phone
)
??
""
,
"bioToken"
:
bioToken
,
"deviceKey"
:
deviceKey
,
"workspaceCode"
:
"8854"
};
return
requestNormal
(
APIPaths
.
login
,
Method
.
POST
,
body
,
(
data
)
=>
LoginTokenResponseModel
.
fromJson
(
data
as
Json
));
return
requestNormal
(
APIPaths
.
login
WithBiometric
,
Method
.
POST
,
body
,
(
data
)
=>
LoginTokenResponseModel
.
fromJson
(
data
as
Json
));
}
Future
<
BaseResponseModel
<
ProfileResponseModel
>>
getUserProfile
()
async
{
...
...
@@ -176,7 +196,8 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
}
Future
<
BaseResponseModel
<
EmptyCodable
>>
accountPasswordChange
(
String
phone
,
String
password
)
async
{
final
body
=
{
"login_name"
:
phone
,
"password"
:
password
.
toSha256
(),
"access_token"
:
DataPreference
.
instance
.
token
??
""
};
String
?
token
=
await
DataPreference
.
instance
.
token
??
""
;
final
body
=
{
"login_name"
:
phone
,
"password"
:
password
.
toSha256
(),
"access_token"
:
token
};
return
requestNormal
(
APIPaths
.
accountPasswordChange
,
Method
.
POST
,
...
...
@@ -185,6 +206,17 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
);
}
Future
<
BaseResponseModel
<
EmptyCodable
>>
accountLoginForPasswordChange
(
String
phone
,
String
password
)
async
{
String
?
token
=
await
DataPreference
.
instance
.
token
??
""
;
final
body
=
{
"login_name"
:
phone
,
"password"
:
password
.
toSha256
(),
"access_token"
:
token
};
return
requestNormal
(
APIPaths
.
accountLoginForPasswordChange
,
Method
.
POST
,
body
,
(
data
)
=>
EmptyCodable
.
fromJson
(
data
as
Json
),
);
}
Future
<
BaseResponseModel
<
BiometricRegisterResponseModel
>>
accountBioCredential
()
async
{
var
deviceKey
=
await
DeviceInfo
.
getDeviceId
();
final
body
=
{
"deviceKey"
:
deviceKey
};
...
...
@@ -196,13 +228,35 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
);
}
Future
<
BaseResponseModel
<
EmptyCodable
>>
accountCheckForPasswordChange
(
String
password
)
async
{
final
body
=
{
"password"
:
password
.
toSha256
()};
Future
<
BaseResponseModel
<
BiometricRegisterResponseModel
>>
registerBiometric
()
async
{
var
deviceKey
=
await
DeviceInfo
.
getDeviceId
();
final
body
=
{
"deviceKey"
:
deviceKey
};
return
requestNormal
(
APIPaths
.
accountLoginForPasswordChange
,
APIPaths
.
registerBiometric
,
Method
.
POST
,
body
,
(
data
)
=>
BiometricRegisterResponseModel
.
fromJson
(
data
as
Json
),
);
}
Future
<
BaseResponseModel
<
EmptyCodable
>>
unRegisterBiometric
()
async
{
var
deviceKey
=
await
DeviceInfo
.
getDeviceId
();
final
path
=
"
${APIPaths.unRegisterBiometric}
/
$deviceKey
"
;
final
body
=
{
"deviceKey"
:
deviceKey
};
return
requestNormal
(
path
,
Method
.
POST
,
body
,
(
data
)
=>
EmptyCodable
.
fromJson
(
data
as
Json
),
);
}
Future
<
BaseResponseModel
<
HeaderHomeModel
>>
getHomeHeaderData
()
async
{
return
requestNormal
(
APIPaths
.
headerHome
,
Method
.
GET
,
{},
(
data
)
=>
HeaderHomeModel
.
fromJson
(
data
as
Json
),
);
}
}
lib/permission/biometric_manager.dart
View file @
5fb93f2d
...
...
@@ -49,7 +49,10 @@ class BiometricManager {
try
{
final
didAuthenticate
=
await
_localAuth
.
authenticate
(
localizedReason:
localizedReason
,
options:
const
AuthenticationOptions
(
biometricOnly:
true
),
options:
const
AuthenticationOptions
(
biometricOnly:
false
,
// ✅ cho phép passcode hoặc vân tay / face ID
stickyAuth:
true
,
// ✅ giữ lại phiên nếu app vào background
),
);
return
didAuthenticate
;
}
catch
(
e
)
{
...
...
lib/preference/data_preference.dart
View file @
5fb93f2d
...
...
@@ -10,55 +10,35 @@ class DataPreference {
LoginTokenResponseModel
?
_loginToken
;
ProfileResponseModel
?
_profile
;
ProfileResponseModel
?
get
profile
=>
_profile
;
LoginTokenResponseModel
?
get
loginToken
=>
_loginToken
;
String
?
get
phone
=>
_profile
?.
workerSite
?.
phoneNumber
;
Future
<
bool
>
get
logged
async
{
final
currentToken
=
await
token
;
return
(
currentToken
??
""
).
isNotEmpty
;
}
Future
<
String
?>
get
token
async
{
if
(
_loginToken
!=
null
)
{
return
_loginToken
?.
accessToken
;
}
else
{
await
loadLoginToken
();
return
_loginToken
?.
accessToken
;
}
}
Future
<
void
>
saveUserProfile
(
ProfileResponseModel
profile
)
async
{
_profile
=
profile
;
Future
<
void
>
init
()
async
{
final
prefs
=
await
SharedPreferences
.
getInstance
();
final
jsonString
=
jsonEncode
(
profile
.
toJson
());
await
prefs
.
setString
(
'user_profile'
,
jsonString
);
}
final
tokenJson
=
prefs
.
getString
(
'login_token'
);
if
(
tokenJson
!=
null
)
{
_loginToken
=
LoginTokenResponseModel
.
fromJson
(
jsonDecode
(
tokenJson
));
}
Future
<
void
>
loadProfile
()
async
{
final
prefs
=
await
SharedPreferences
.
getInstance
();
final
jsonString
=
prefs
.
getString
(
'user_profile'
);
if
(
jsonString
!=
null
)
{
final
jsonMap
=
jsonDecode
(
jsonString
);
_profile
=
ProfileResponseModel
.
fromJson
(
jsonMap
);
final
profileJson
=
prefs
.
getString
(
'user_profile'
);
if
(
profileJson
!=
null
)
{
_profile
=
ProfileResponseModel
.
fromJson
(
jsonDecode
(
profileJson
));
}
}
String
?
get
token
=>
_loginToken
?.
accessToken
;
String
?
get
phone
=>
_profile
?.
workerSite
?.
phoneNumber
;
bool
get
logged
=>
(
token
??
""
).
isNotEmpty
;
ProfileResponseModel
?
get
profile
=>
_profile
;
Future
<
void
>
saveLoginToken
(
LoginTokenResponseModel
token
)
async
{
_loginToken
=
token
;
final
prefs
=
await
SharedPreferences
.
getInstance
();
final
jsonString
=
jsonEncode
(
token
.
toJson
());
await
prefs
.
setString
(
'login_token'
,
jsonString
);
await
prefs
.
setString
(
'login_token'
,
jsonEncode
(
token
.
toJson
()));
}
Future
<
void
>
loadLoginToken
()
async
{
Future
<
void
>
saveUserProfile
(
ProfileResponseModel
profile
)
async
{
_profile
=
profile
;
final
prefs
=
await
SharedPreferences
.
getInstance
();
final
jsonString
=
prefs
.
getString
(
'login_token'
);
if
(
jsonString
!=
null
)
{
final
jsonMap
=
jsonDecode
(
jsonString
);
_loginToken
=
LoginTokenResponseModel
.
fromJson
(
jsonMap
);
}
await
prefs
.
setString
(
'user_profile'
,
jsonEncode
(
profile
.
toJson
()));
}
Future
<
void
>
clearLoginToken
()
async
{
...
...
@@ -67,23 +47,31 @@ class DataPreference {
await
prefs
.
remove
(
'login_token'
);
}
Future
<
void
>
clearBioToken
(
String
phone
)
async
{
Future
<
void
>
clearUserProfile
()
async
{
_profile
=
null
;
final
prefs
=
await
SharedPreferences
.
getInstance
();
await
prefs
.
remove
(
'biometric_login_token_
$phone
'
);
await
prefs
.
remove
(
'user_profile'
);
}
Future
<
void
>
clearData
()
async
{
await
clearLoginToken
();
await
clearUserProfile
();
}
Future
<
void
>
saveBioToken
(
String
bioToken
)
async
{
if
(
phone
==
null
)
return
;
final
prefs
=
await
SharedPreferences
.
getInstance
();
final
jsonString
=
jsonEncode
(
bioToken
);
await
prefs
.
setString
(
'biometric_login_token_
$phone
'
,
jsonString
);
await
prefs
.
setString
(
'biometric_login_token_
$phone
'
,
jsonEncode
(
bioToken
));
}
Future
<
String
?>
getBioToken
(
String
phone
)
async
{
final
prefs
=
await
SharedPreferences
.
getInstance
();
final
jsonString
=
prefs
.
getString
(
'biometric_login_token_
$phone
'
);
if
(
jsonString
!=
null
)
{
return
jsonDecode
(
jsonString
);
}
return
jsonString
!=
null
?
jsonDecode
(
jsonString
)
:
null
;
}
Future
<
void
>
clearBioToken
(
String
phone
)
async
{
final
prefs
=
await
SharedPreferences
.
getInstance
();
await
prefs
.
remove
(
'biometric_login_token_
$phone
'
);
}
}
\ No newline at end of file
lib/preference/point/header_home_model.dart
0 → 100644
View file @
5fb93f2d
import
'package:json_annotation/json_annotation.dart'
;
part
'header_home_model.g.dart'
;
@JsonSerializable
()
class
HeaderHomeModel
{
final
String
?
greeting
;
@JsonKey
(
name:
'total_voucher'
)
final
int
?
totalVoucher
;
@JsonKey
(
name:
'total_point_active'
)
final
int
?
totalPointActive
;
final
String
?
background
;
HeaderHomeModel
({
this
.
greeting
,
this
.
totalVoucher
,
this
.
totalPointActive
,
this
.
background
,
});
factory
HeaderHomeModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$HeaderHomeModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$HeaderHomeModelToJson
(
this
);
}
lib/preference/point/header_home_model.g.dart
0 → 100644
View file @
5fb93f2d
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'header_home_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
HeaderHomeModel
_$HeaderHomeModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
HeaderHomeModel
(
greeting:
json
[
'greeting'
]
as
String
?,
totalVoucher:
(
json
[
'total_voucher'
]
as
num
?)?.
toInt
(),
totalPointActive:
(
json
[
'total_point_active'
]
as
num
?)?.
toInt
(),
background:
json
[
'background'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$HeaderHomeModelToJson
(
HeaderHomeModel
instance
)
=>
<
String
,
dynamic
>{
'greeting'
:
instance
.
greeting
,
'total_voucher'
:
instance
.
totalVoucher
,
'total_point_active'
:
instance
.
totalPointActive
,
'background'
:
instance
.
background
,
};
lib/preference/point/point_manager.dart
0 → 100644
View file @
5fb93f2d
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api_request.dart'
;
import
'../../base/restful_api_viewmodel.dart'
;
import
'header_home_model.dart'
;
class
UserPointManager
extends
RestfulApiViewModel
{
static
final
UserPointManager
_instance
=
UserPointManager
.
_internal
();
factory
UserPointManager
()
=>
_instance
;
UserPointManager
.
_internal
();
final
RxInt
_userPoint
=
0
.
obs
;
HeaderHomeModel
?
_headerInfo
;
get
point
=>
_userPoint
.
value
;
Future
<
int
>
fetchUserPoint
()
async
{
try
{
final
response
=
await
client
.
getHomeHeaderData
();
if
(
response
.
isSuccess
&&
response
.
data
!=
null
)
{
_headerInfo
=
response
.
data
;
_userPoint
.
value
=
_headerInfo
?.
totalPointActive
??
0
;
}
else
{
_userPoint
.
value
=
0
;
}
}
catch
(
e
)
{
_userPoint
.
value
=
0
;
}
return
_userPoint
.
value
;
}
}
lib/resouce/button_style.dart
0 → 100644
View file @
5fb93f2d
import
'package:flutter/material.dart'
;
class
AppButtonStyle
{
static
ButtonStyle
primary
=
ElevatedButton
.
styleFrom
(
backgroundColor:
Colors
.
red
,
foregroundColor:
Colors
.
white
,
minimumSize:
const
Size
.
fromHeight
(
32
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
8
)),
);
static
ButtonStyle
secondary
=
ElevatedButton
.
styleFrom
(
backgroundColor:
Colors
.
grey
.
shade300
,
foregroundColor:
Colors
.
black
,
minimumSize:
const
Size
.
fromHeight
(
32
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
8
)),
);
}
lib/resouce/text_style.dart
View file @
5fb93f2d
...
...
@@ -84,31 +84,40 @@ TextStyle getTextStyle(TextStyleIconAndText? textType) {
}
}
final
BorderRadius
_borderRadius
=
BorderRadius
.
circular
(
8.0
);
final
BorderSide
_defaultBorderSide
=
BorderSide
(
color:
BaseColor
.
second400
);
final
BorderSide
_focusedBorderSide
=
BorderSide
(
color:
Colors
.
blue
);
final
EdgeInsets
_contentPadding
=
EdgeInsets
.
symmetric
(
vertical:
16.0
,
horizontal:
16.0
);
class
PTTextStyles
{
static
final
InputDecoration
textFieldDecoration
=
InputDecoration
(
border:
OutlineInputBorder
(
borderRadius:
_borderRadius
,
borderSide:
_defaultBorderSide
,
),
enabledBorder:
OutlineInputBorder
(
borderRadius:
_borderRadius
,
borderSide:
_defaultBorderSide
,
),
focusedBorder:
OutlineInputBorder
(
borderRadius:
_borderRadius
,
borderSide:
_focusedBorderSide
,
),
labelText:
'Enter text'
,
labelStyle:
TextStyle
(
color:
Colors
.
grey
),
hintText:
'Hint text'
,
hintStyle:
TextStyle
(
color:
Colors
.
grey
),
filled:
true
,
fillColor:
Colors
.
white
,
contentPadding:
_contentPadding
,
class
AppTextStyle
{
static
const
TextStyle
title
=
TextStyle
(
fontSize:
18
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
black87
,
);
static
const
TextStyle
content
=
TextStyle
(
fontSize:
14
,
color:
Colors
.
black87
,
);
static
const
TextStyle
boldContent
=
TextStyle
(
fontSize:
14
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
black87
,
);
static
const
TextStyle
link
=
TextStyle
(
fontSize:
14
,
color:
Colors
.
blue
,
decoration:
TextDecoration
.
underline
,
);
static
const
TextStyle
buttonPrimary
=
TextStyle
(
fontSize:
14
,
fontWeight:
FontWeight
.
w500
,
color:
Colors
.
white
,
);
static
const
TextStyle
buttonSecondary
=
TextStyle
(
fontSize:
14
,
fontWeight:
FontWeight
.
w500
,
color:
Colors
.
black
,
);
}
lib/screen/change_pass/change_pass_screen.dart
View file @
5fb93f2d
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/widgets/alert/data_alert_model.dart'
;
import
'../../base/base_screen.dart'
;
import
'../../base/basic_state.dart'
;
import
'../../preference/data_preference.dart'
;
import
'../../resouce/base_color.dart'
;
import
'../../shared/router_gage.dart'
;
import
'../../widgets/back_button.dart'
;
import
'../../widgets/support_button.dart'
;
import
'../login/login_viewmodel.dart'
;
...
...
@@ -28,6 +30,10 @@ class _ChangePassScreenState extends BaseState<ChangePassScreen> with BasicState
WidgetsBinding
.
instance
.
addPostFrameCallback
((
_
)
{
_focusNode
.
requestFocus
();
});
viewModel
.
onShowAlertError
=
(
message
)
{
showAlertError
(
content:
message
);
};
}
@override
...
...
@@ -155,7 +161,29 @@ class _ChangePassScreenState extends BaseState<ChangePassScreen> with BasicState
children:
[
TextButton
(
onPressed:
()
{
viewModel
.
onForgotPassPressed
(
_phone
);
final
dataAlert
=
DataAlertModel
(
title:
"Quên mật khẩu"
,
content:
"Bạn cần đăng xuất khỏi tài khoản này để đặt lại mật khẩu. Bạn chắc chứ?."
,
background:
"assets/images/ic_pipi_03.png"
,
buttons:
[
AlertButton
(
text:
"Đồng ý"
,
onPressed:
()
{
DataPreference
.
instance
.
clearLoginToken
();
_safeBackToLogin
();
},
bgColor:
BaseColor
.
primary500
,
textColor:
Colors
.
white
,
isPrimary:
true
,
),
AlertButton
(
text:
"Huỷ"
,
onPressed:
()
=>
Get
.
back
(),
bgColor:
Colors
.
white
,
textColor:
BaseColor
.
second500
,
isPrimary:
false
,
),],
);
showAlert
(
data:
dataAlert
);
},
child:
const
Text
(
"Quên mật khẩu?"
,
style:
TextStyle
(
fontSize:
14
,
color:
Color
(
0xFF3662FE
))),
),
...
...
@@ -204,4 +232,22 @@ class _ChangePassScreenState extends BaseState<ChangePassScreen> with BasicState
);
});
}
void
_safeBackToLogin
()
{
bool
found
=
false
;
Navigator
.
popUntil
(
Get
.
context
!,
(
route
)
{
final
matched
=
route
.
settings
.
name
==
loginScreen
;
if
(
matched
)
found
=
true
;
return
matched
;
});
final
phone
=
DataPreference
.
instance
.
phone
;
if
(
phone
!=
null
)
{
if
(!
found
)
{
Get
.
offAllNamed
(
loginScreen
,
arguments:
phone
);
}
}
else
{
DataPreference
.
instance
.
clearData
();
Get
.
offAllNamed
(
onboardingScreen
);
}
}
}
lib/screen/change_pass/change_pass_viewmodel.dart
View file @
5fb93f2d
...
...
@@ -39,10 +39,10 @@ class ChangePassViewModel extends RestfulApiViewModel {
});
}
void
accountCheckForPasswordChange
()
{
Future
<
void
>
accountCheckForPasswordChange
()
async
{
showLoading
();
final
phone
=
DataPreference
.
instance
.
phone
??
""
;
client
.
accountPasswordChange
(
phone
,
password
.
value
).
then
((
value
)
{
final
phone
=
await
DataPreference
.
instance
.
phone
??
""
;
client
.
account
LoginFor
PasswordChange
(
phone
,
password
.
value
).
then
((
value
)
{
hideLoading
();
if
(
value
.
isSuccess
)
{
Get
.
to
(
CreatePasswordScreen
(
repository:
ChangePasswordRepository
(
phone
)));
...
...
lib/screen/create_pass/change_pass_repository.dart
View file @
5fb93f2d
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api_request.dart'
;
import
'package:mypoint_flutter_app/screen/create_pass/signup_create_password_repository.dart'
;
import
'package:mypoint_flutter_app/widgets/custom_toast_message.dart'
;
import
'../../base/base_response_model.dart'
;
import
'../../base/restful_api_viewmodel.dart'
;
import
'../login/login_screen.dart'
;
import
'../main_tab_screen/main_tab_screen.dart'
;
import
'../splash/splash_screen_viewmodel.dart'
;
class
ChangePasswordRepository
extends
RestfulApiViewModel
implements
ICreatePasswordRepository
{
...
...
@@ -18,7 +20,8 @@ class ChangePasswordRepository extends RestfulApiViewModel implements ICreatePas
return
client
.
accountPasswordChange
(
phoneNumber
,
password
).
then
((
value
)
{
hideLoading
();
if
(
value
.
status
==
"success"
||
value
.
code
==
200
)
{
print
(
"Change password success"
);
showToastMessage
(
"Đổi mật khẩu thành công."
);
Get
.
off
(()
=>
MainTabScreen
());
}
return
value
;
});
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
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