add pin login and add pin code

This commit is contained in:
tzw
2024-10-04 13:55:59 +06:30
parent b5023a4171
commit 81dfeb037d
18 changed files with 340 additions and 68 deletions

View File

@@ -18,6 +18,7 @@
"back.button_confirm":"Are you sure you want to continue without submitting changes?", "back.button_confirm":"Are you sure you want to continue without submitting changes?",
"btn.clear":"Clear Filter", "btn.clear":"Clear Filter",
"btn.filter":"Filter", "btn.filter":"Filter",
"btn.exit_confirm":"Are you sure you want to exit?",
"Buttons End ================================================================":"", "Buttons End ================================================================":"",
"Offline Start ================================================================":"", "Offline Start ================================================================":"",
@@ -104,6 +105,7 @@
"home.invitation.request.msg":"We are working on your invitation request!", "home.invitation.request.msg":"We are working on your invitation request!",
"home.search":"Enter tracking number", "home.search":"Enter tracking number",
"home.search.btn":"Search", "home.search.btn":"Search",
"home.pin.logout.confirm":"Are you sure want to logout?",
"Home End ================================================================":"", "Home End ================================================================":"",
"Invite Start ================================================================":"", "Invite Start ================================================================":"",

View File

@@ -17,6 +17,7 @@
"back.button_confirm":"Are you sure you want to continue without submitting changes?", "back.button_confirm":"Are you sure you want to continue without submitting changes?",
"btn.clear":"Clear Filter", "btn.clear":"Clear Filter",
"btn.filter":"Filter", "btn.filter":"Filter",
"btn.exit_confirm":"Are you sure you want to exit?",
"Buttons End ================================================================":"", "Buttons End ================================================================":"",
"Offline Start ================================================================":"", "Offline Start ================================================================":"",
@@ -104,6 +105,7 @@
"home.invitation.request.msg":"ဖိတ်ကြားမှု တောင်းဆိုသည်ကို လုပ်ဆောင်နေပါသည်!", "home.invitation.request.msg":"ဖိတ်ကြားမှု တောင်းဆိုသည်ကို လုပ်ဆောင်နေပါသည်!",
"home.search":"Tracking number ရိုက်ထည့်ပါ", "home.search":"Tracking number ရိုက်ထည့်ပါ",
"home.search.btn":"ရှာမည်", "home.search.btn":"ရှာမည်",
"home.pin.logout.confirm":"အကောင့်ထွက်ရန်သေချာပြီလား?",
"Home End ================================================================":"", "Home End ================================================================":"",
"Invite Start ================================================================":"", "Invite Start ================================================================":"",

View File

@@ -35,6 +35,7 @@ import 'pages/carton/model/package_selection_model.dart';
import 'pages/carton/model/sender_selection_model.dart'; import 'pages/carton/model/sender_selection_model.dart';
import 'pages/carton/model/shipment_selection_model.dart'; import 'pages/carton/model/shipment_selection_model.dart';
import 'pages/delivery/model/delivery_model.dart'; import 'pages/delivery/model/delivery_model.dart';
import 'pages/signin/pinlogin_page.dart';
class App extends StatefulWidget { class App extends StatefulWidget {
final String title; final String title;
@@ -121,6 +122,7 @@ class _AppState extends State<App> {
'/welcome': (_) => WelcomePage(), '/welcome': (_) => WelcomePage(),
'/home': (_) => HomePage(), '/home': (_) => HomePage(),
'/language_selection': (context) => InitialLanguageSelectionPage(), '/language_selection': (context) => InitialLanguageSelectionPage(),
'/pin_login': (_) => PinLoginPage()
}; };
return routes; return routes;
} }

View File

@@ -83,6 +83,7 @@ const privilege_receiving = "rc";
const privilege_pickup = "pku"; const privilege_pickup = "pku";
const privilege_collect = "col"; const privilege_collect = "col";
const privilege_report = "rpt"; const privilege_report = "rpt";
const privilege_pin ="pin";
// Pickup types // Pickup types
const shipment_local_pickup = "Local pickup"; const shipment_local_pickup = "Local pickup";

View File

@@ -12,6 +12,7 @@ import 'package:fcs/helpers/firebase_helper.dart';
import 'package:firebase_auth/firebase_auth.dart' as fb; import 'package:firebase_auth/firebase_auth.dart' as fb;
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import '../../helpers/shared_pref.dart';
import '../services/services.dart'; import '../services/services.dart';
class AuthFb { class AuthFb {
@@ -108,13 +109,15 @@ class AuthFb {
Future<void> signoutStart() async { Future<void> signoutStart() async {
await userListener?.cancel(); await userListener?.cancel();
await userAuthListener?.cancel(); await userAuthListener?.cancel();
await _pinUserListener?.cancel();
} }
Future<void> signoutEnd() async { Future<void> signoutEnd() async {
await SharedPref.setPinLockOn(false);
await _fb.signOut(); await _fb.signOut();
} }
Future<void> _addUserToStream({bool refreshIdToken = false}) async { Future<User?> _addUserToStream({bool refreshIdToken = false}) async {
fb.User? firebaseUser = _fb.currentUser; fb.User? firebaseUser = _fb.currentUser;
if (firebaseUser == null) return null; if (firebaseUser == null) return null;
Map<dynamic, dynamic>? claims = Map<dynamic, dynamic>? claims =
@@ -128,15 +131,20 @@ class AuthFb {
user = await _getUserFromFirestore(cid); user = await _getUserFromFirestore(cid);
} }
if (user == null) { if (user == null) {
controller.add(null); _addUser(null);
return; return null;
} }
loadUserClaim(claims, user); loadUserClaim(claims, user);
controller.add(user); _addUser(user);
return user;
} }
loadUserClaim(Map claims, User user) { loadUserClaim(Map claims, User user) {
if (pinLoginUser != null) {
user.fcsID = pinLoginUser?.fcsID;
}
// add privileges // add privileges
String? privileges = claims["pr"]; String? privileges = claims["pr"];
if (privileges != null && privileges != "") { if (privileges != null && privileges != "") {
@@ -252,9 +260,9 @@ class AuthFb {
// get privilege from claim // get privilege from claim
Map<dynamic, dynamic> claims = await getClaims(refreshIdToken: true); Map<dynamic, dynamic> claims = await getClaims(refreshIdToken: true);
loadUserClaim(claims, user); loadUserClaim(claims, user);
controller.add(user); _addUser(user);
} catch (e) { } catch (e) {
controller.add(null); _addUser(null);
} }
}); });
} }
@@ -286,12 +294,23 @@ class AuthFb {
log.info("_startAuthListener: $user"); log.info("_startAuthListener: $user");
if (_logIn) { if (_logIn) {
controller.add(user); _addUser(user);
} }
} }
}); });
} }
_addUser(User? user) {
if (user == null) {
pinLoginUser = null;
}
if (pinLoginUser != null) {
controller.add(pinLoginUser);
} else {
controller.add(user);
}
}
Stream<User?> user() { Stream<User?> user() {
// ignore: close_sinks // ignore: close_sinks
StreamSubscription<fb.User?>? authListener; StreamSubscription<fb.User?>? authListener;
@@ -301,7 +320,7 @@ class AuthFb {
authListener = _fb.authStateChanges().listen((firebaseUser) async { authListener = _fb.authStateChanges().listen((firebaseUser) async {
_logIn = firebaseUser != null; _logIn = firebaseUser != null;
if (firebaseUser == null) { if (firebaseUser == null) {
controller.add(null); _addUser(null);
} else { } else {
_addUserToStream(refreshIdToken: true); _addUserToStream(refreshIdToken: true);
_startUserListener(); _startUserListener();
@@ -319,4 +338,51 @@ class AuthFb {
return controller.stream; return controller.stream;
} }
User? pinLoginUser;
StreamSubscription<DocumentSnapshot>? _pinUserListener;
Future<void> pinLogin(
{required String currentUserId,
required String fcsID,
required String pin}) async {
var data = await requestAPI("/pin/login", "POST",
token: await getToken(), payload: {'fcs_id': fcsID, 'pin': pin});
var userId = data['user_id'] ?? '';
if (userId == currentUserId) {
//logout
logoutPinAccount();
await SharedPref.setPinLockOn(false);
}
var pinToken = data['pin_token'] ?? '';
// Get user for pin login
_listenPinUser(userId: userId, pinToken: pinToken);
}
Future<void> _listenPinUser(
{required String userId, required String pinToken}) async {
Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
.collection(user_collection)
.doc(userId)
.snapshots();
_pinUserListener?.cancel();
_pinUserListener = snapshot.listen((snap) async {
User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
pinLoginUser = user;
if (pinLoginUser != null) {
pinLoginUser!.pinToken = pinToken;
}
await _addUserToStream(refreshIdToken: true);
});
}
Future<void> logoutPinAccount() async {
_pinUserListener?.cancel();
pinLoginUser = null;
await _addUserToStream(refreshIdToken: true);
}
} }

View File

@@ -74,4 +74,23 @@ class AuthServiceImp implements AuthService {
Future<void> deleteAccount() { Future<void> deleteAccount() {
return authFb.deleteAccount(); return authFb.deleteAccount();
} }
@override
Future<void> pinLogin(
{required String currentUserId,
required String fcsID,
required String pin}) {
return authFb.pinLogin(
currentUserId: currentUserId, fcsID: fcsID, pin: pin);
}
@override
User? getPinLoginUser() {
return authFb.pinLoginUser;
}
@override
Future<void> logoutPinAccount() {
return authFb.logoutPinAccount();
}
} }

View File

@@ -15,4 +15,10 @@ abstract class AuthService {
Stream<User?> getUserStream(); Stream<User?> getUserStream();
Stream<Setting> getSetting(); Stream<Setting> getSetting();
Future<void> deleteAccount(); Future<void> deleteAccount();
Future<void> pinLogin(
{required String currentUserId,
required String fcsID,
required String pin});
User? getPinLoginUser();
Future<void> logoutPinAccount();
} }

View File

@@ -21,6 +21,7 @@ class User {
String? preferCurrency; String? preferCurrency;
bool enablePinLogin; bool enablePinLogin;
String? pinDigit; String? pinDigit;
List<String> privileges = [];
String get initial => String get initial =>
name != null && name != "" ? name!.substring(0, 1) : "?"; name != null && name != "" ? name!.substring(0, 1) : "?";
@@ -48,7 +49,9 @@ class User {
String get getFcsUnseenCount => String get getFcsUnseenCount =>
fcsUnseenCount > 100 ? "99+" : fcsUnseenCount.toString(); fcsUnseenCount > 100 ? "99+" : fcsUnseenCount.toString();
List<String> privileges = []; // for pin login
String? pinToken;
bool get isPinLogin => pinToken!=null;
String get phone => phoneNumber != null && phoneNumber!.startsWith("959") String get phone => phoneNumber != null && phoneNumber!.startsWith("959")
? "0${phoneNumber!.substring(2)}" ? "0${phoneNumber!.substring(2)}"
@@ -117,7 +120,9 @@ class User {
userUnseenCount: map['user_unseen_count'] ?? 0, userUnseenCount: map['user_unseen_count'] ?? 0,
fcsUnseenCount: map['fcs_unseen_count'] ?? 0, fcsUnseenCount: map['fcs_unseen_count'] ?? 0,
preferCurrency: map['preferred_currency'], preferCurrency: map['preferred_currency'],
lastMessageTime: _date == null ? null : _date.toDate()); lastMessageTime: _date == null ? null : _date.toDate(),
enablePinLogin: map['enable_pin_login'] ?? false,
pinDigit: map['pin'] ?? '');
} }
bool diffPrivileges(User another) { bool diffPrivileges(User another) {

View File

@@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart'; import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:flutter_vector_icons/flutter_vector_icons.dart' as vector;
class Privilege { class Privilege {
String id; String id;
@@ -49,6 +50,8 @@ class Privilege {
iconData = MaterialCommunityIcons.layers; iconData = MaterialCommunityIcons.layers;
} else if (this.id == privilege_report) { } else if (this.id == privilege_report) {
iconData = Feather.file_text; iconData = Feather.file_text;
} else if (this.id == privilege_pin) {
iconData = vector.MaterialCommunityIcons.account_lock_outline;
} else { } else {
iconData = MaterialCommunityIcons.account_question; iconData = MaterialCommunityIcons.account_question;
} }

View File

@@ -4,6 +4,8 @@ import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:fcs/data/services/services.dart';
import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/vo/status.dart'; import 'package:fcs/domain/vo/status.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@@ -28,6 +30,10 @@ Future<dynamic> requestAPI(String path, method,
if (token != null) { if (token != null) {
headers["Token"] = token; headers["Token"] = token;
} }
User? pinLoginUser = Services.instance.authService.getPinLoginUser();
if (pinLoginUser != null) {
headers["pin_token"] = pinLoginUser.pinToken;
}
if (devInfo.deviceID != null) { if (devInfo.deviceID != null) {
headers["Device"] = devInfo.deviceID ?? "" + ":" + deviceName; headers["Device"] = devInfo.deviceID ?? "" + ":" + deviceName;
} }

View File

@@ -108,4 +108,14 @@ class SharedPref {
static Future<void> clearRecentSearch(String key) async { static Future<void> clearRecentSearch(String key) async {
return await _remove(key); return await _remove(key);
} }
static Future<bool?> getPinLockOn() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getBool('pin_lock');
}
static Future<void> setPinLockOn(bool isLockOn) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool('pin_lock', isLockOn);
}
} }

View File

@@ -203,9 +203,27 @@ class _HomePageState extends State<HomePage> {
super.dispose(); super.dispose();
} }
_logoutPinAccount() async {
setState(() {
_isLoading = true;
});
try {
await context.read<MainModel>().logoutPinAccount();
Navigator.pushNamedAndRemoveUntil(context, "/pin_login", (r) => false);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
User? user = Provider.of<MainModel>(context).user; var mainModel = context.watch<MainModel>();
User? user = mainModel.user;
if (user == null) { if (user == null) {
Future.microtask( Future.microtask(
@@ -213,7 +231,7 @@ class _HomePageState extends State<HomePage> {
return Container(); return Container();
} }
login = Provider.of<MainModel>(context).isLogin(); login = mainModel.isLogin();
LanguageModel languageModel = Provider.of<LanguageModel>(context); LanguageModel languageModel = Provider.of<LanguageModel>(context);
final faqBtn = TaskButton("faq.btn", final faqBtn = TaskButton("faq.btn",
@@ -390,8 +408,11 @@ class _HomePageState extends State<HomePage> {
final pinLoginBtn = IconButton( final pinLoginBtn = IconButton(
onPressed: () { onPressed: () {
Navigator.of(context) Navigator.pushAndRemoveUntil(
.push(CupertinoPageRoute(builder: (context) => PinLoginPage())); context,
CupertinoPageRoute(
builder: (BuildContext context) => PinLoginPage()),
(r) => false);
}, },
iconSize: 25, iconSize: 25,
icon: Icon( icon: Icon(
@@ -400,6 +421,19 @@ class _HomePageState extends State<HomePage> {
), ),
); );
final pinLogoutBtn = IconButton(
onPressed: () {
showConfirmDialog(context, "home.pin.logout.confirm", () async {
await _logoutPinAccount();
});
},
iconSize: 25,
icon: Icon(
MaterialCommunityIcons.lock_open_variant_outline,
color: buttonColor,
),
);
var searchInput = Row(children: [ var searchInput = Row(children: [
Expanded( Expanded(
child: Padding( child: Padding(
@@ -478,7 +512,7 @@ class _HomePageState extends State<HomePage> {
profileBtn, profileBtn,
] ]
: <Widget>[ : <Widget>[
pinLoginBtn, mainModel.isPinLogin ? pinLogoutBtn : pinLoginBtn,
fcsToggle, fcsToggle,
profileBtn, profileBtn,
] ]

View File

@@ -17,6 +17,7 @@ class MainModel extends ChangeNotifier {
String? messagingToken; String? messagingToken;
User? user; User? user;
User? _fbUser;
PackageInfo? packageInfo; PackageInfo? packageInfo;
set setMessaginToken(token) { set setMessaginToken(token) {
@@ -29,6 +30,9 @@ class MainModel extends ChangeNotifier {
bool isLoaded = false; bool isLoaded = false;
bool isOnline = false; bool isOnline = false;
bool isFirstLaunch = false; bool isFirstLaunch = false;
bool isLockOn = false;
bool get isPinLogin => user?.isPinLogin ?? false;
MainModel() { MainModel() {
NetworkConnectivity.instance.statusStream.listen((data) { NetworkConnectivity.instance.statusStream.listen((data) {
@@ -83,6 +87,7 @@ class MainModel extends ChangeNotifier {
await _listenSetting(); await _listenSetting();
this.isFirstLaunch = await SharedPref.isFirstLaunch() ?? true; this.isFirstLaunch = await SharedPref.isFirstLaunch() ?? true;
this.packageInfo = await PackageInfo.fromPlatform(); this.packageInfo = await PackageInfo.fromPlatform();
this.isLockOn = await SharedPref.getPinLockOn() ?? false;
userListener?.cancel(); userListener?.cancel();
userListener = userListener =
@@ -91,6 +96,17 @@ class MainModel extends ChangeNotifier {
bool diffPrivilege = bool diffPrivilege =
_user != null && (user == null || user!.diffPrivileges(_user)); _user != null && (user == null || user!.diffPrivileges(_user));
bool loggingOut = user != null && _user == null; bool loggingOut = user != null && _user == null;
if (_user != null) {
if (!_user.isPinLogin) {
_fbUser = _user;
}
}
if ((_fbUser?.id == _user?.id)) {
_user?.pinToken = null;
}
user = _user; user = _user;
if (_user != null) { if (_user != null) {
@@ -101,6 +117,7 @@ class MainModel extends ChangeNotifier {
} }
} }
} }
if (loggingOut) { if (loggingOut) {
for (final m in models) { for (final m in models) {
m.logout(); m.logout();
@@ -196,4 +213,13 @@ class MainModel extends ChangeNotifier {
Future<void> deleteAccount() async { Future<void> deleteAccount() async {
return await Services.instance.authService.deleteAccount(); return await Services.instance.authService.deleteAccount();
} }
Future<void> pinLogin({required String fcsID, required String pin}) async {
await Services.instance.authService
.pinLogin(fcsID: fcsID, pin: pin, currentUserId: _fbUser?.id ?? '');
}
Future<void> logoutPinAccount() async {
await Services.instance.authService.logoutPinAccount();
}
} }

View File

@@ -53,7 +53,11 @@ class _SplashScreenState extends State<SplashScreen> {
if (mainModel.isFirstLaunch) { if (mainModel.isFirstLaunch) {
page = "/language_selection"; page = "/language_selection";
} else if (mainModel.isLogin()) { } else if (mainModel.isLogin()) {
if (mainModel.isLockOn) {
page = "/pin_login";
} else {
page = "/home"; page = "/home";
}
} else { } else {
page = "/welcome"; page = "/welcome";
} }

View File

@@ -129,12 +129,17 @@ class _ProfileState extends State<Profile> {
], ],
); );
final logoutbutton = fcsButton( final logoutbutton =
context, getLocalString(context, "profile.logout"), callack: () { fcsButton(context, getLocalString(context, "profile.logout"),
showConfirmDialog(context, "profile.logout.confirm", () async { callack: mainModel.isPinLogin
? null
: () {
showConfirmDialog(context, "profile.logout.confirm",
() async {
await _logout(); await _logout();
}); });
}, iconData: Icons.exit_to_app); },
iconData: Icons.exit_to_app);
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
@@ -355,8 +360,12 @@ class _ProfileState extends State<Profile> {
} }
_showToast(String title) { _showToast(String title) {
final ScaffoldMessengerState scaffold = ScaffoldMessengerState? scaffold = key.currentState;
key.currentState as ScaffoldMessengerState;
if (scaffold == null) {
scaffold = ScaffoldMessenger.of(context);
}
scaffold.showSnackBar( scaffold.showSnackBar(
SnackBar( SnackBar(
content: Text('copied "$title" data to clipboard'), content: Text('copied "$title" data to clipboard'),

View File

@@ -1,13 +1,18 @@
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/model/language_model.dart';
import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pin_input_text_field/pin_input_text_field.dart'; import 'package:pin_input_text_field/pin_input_text_field.dart';
import 'package:provider/provider.dart';
import '../../helpers/shared_pref.dart';
import '../../localization/app_translations.dart';
class PinLoginPage extends StatefulWidget { class PinLoginPage extends StatefulWidget {
//final User user;
const PinLoginPage({super.key}); const PinLoginPage({super.key});
@override @override
@@ -18,10 +23,77 @@ class _PinLoginPageState extends State<PinLoginPage> {
bool _isLoading = false; bool _isLoading = false;
String pin = ""; String pin = "";
String prefixText = "FCS-"; String prefixText = "FCS-";
//late User _user;
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
TextEditingController _fcsIdCtl = new TextEditingController(); TextEditingController _fcsIdCtl = new TextEditingController();
@override
void initState() {
_init();
super.initState();
}
_init() async {
await SharedPref.setPinLockOn(true);
}
Future<bool> _onWillPop() async {
// Show the confirmation dialog
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Center(
child:
LocalText(context, 'btn.exit_confirm', color: primaryColor),
),
content: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0))),
child: Text(
AppTranslations.of(context)!.text('btn.cancel'),
style: Provider.of<LanguageModel>(context).isEng
? TextStyle(color: primaryColor)
: TextStyle(
fontFamily: 'Myanmar3', color: primaryColor),
),
onPressed: () {
Navigator.of(context).pop(false);
}),
SizedBox(
width: 0,
),
TextButton(
style: TextButton.styleFrom(
backgroundColor: primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0))),
child: Text(AppTranslations.of(context)!.text('btn.ok'),
style: Provider.of<LanguageModel>(context).isEng
? TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold)
: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'Myanmar3')),
onPressed: () {
Navigator.of(context).pop(true);
})
],
),
),
),
)) ??
false;
}
Widget build(BuildContext context) { Widget build(BuildContext context) {
final fcsIdBox = TextFormField( final fcsIdBox = TextFormField(
controller: _fcsIdCtl, controller: _fcsIdCtl,
@@ -121,7 +193,11 @@ class _PinLoginPageState extends State<PinLoginPage> {
callBack: _login, callBack: _login,
), ),
); );
return LocalProgress(
// ignore: deprecated_member_use
return WillPopScope(
onWillPop: _onWillPop,
child: LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: new Scaffold( child: new Scaffold(
body: Form( body: Form(
@@ -157,6 +233,7 @@ class _PinLoginPageState extends State<PinLoginPage> {
], ],
), ),
)), )),
),
); );
} }
@@ -171,14 +248,14 @@ class _PinLoginPageState extends State<PinLoginPage> {
return; return;
} }
String fcsId = "$prefixText${_fcsIdCtl.text}"; String fcsId = "$prefixText${_fcsIdCtl.text}";
print(fcsId);
setState(() { setState(() {
_isLoading = true; _isLoading = true;
}); });
try { try {
Navigator.pop(context, true); await context.read<MainModel>().pinLogin(fcsID: fcsId, pin: pin);
Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false);
} catch (e) { } catch (e) {
showMsgDialog(context, "Error", e.toString()); showMsgDialog(context, "Error", e.toString());
} finally { } finally {

View File

@@ -81,7 +81,7 @@ class StaffModel extends BaseModel {
Future<void> updatePin( Future<void> updatePin(
{required String userID, {required String userID,
required bool enablePin, required bool enablePin,
required int? pin}) async { required String? pin}) async {
await request("/employee/pin", "PUT", await request("/employee/pin", "PUT",
payload: {"id": userID, "enable_pin_login": enablePin, "pin": pin}, payload: {"id": userID, "enable_pin_login": enablePin, "pin": pin},
token: await getToken()); token: await getToken());

View File

@@ -310,7 +310,7 @@ class _StaffPinEditorState extends State<StaffPinEditor> {
await context.read<StaffModel>().updatePin( await context.read<StaffModel>().updatePin(
userID: _staff.id!, userID: _staff.id!,
enablePin: _enablePinLogin, enablePin: _enablePinLogin,
pin: _enablePinLogin ? int.parse(_confirmPin) : null); pin: _enablePinLogin ? _confirmPin : null);
Navigator.pop(context, true); Navigator.pop(context, true);
} catch (e) { } catch (e) {
showMsgDialog(context, "Error", e.toString()); showMsgDialog(context, "Error", e.toString());