add pin login and add pin code
This commit is contained in:
@@ -203,9 +203,27 @@ class _HomePageState extends State<HomePage> {
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
User? user = Provider.of<MainModel>(context).user;
|
||||
var mainModel = context.watch<MainModel>();
|
||||
User? user = mainModel.user;
|
||||
|
||||
if (user == null) {
|
||||
Future.microtask(
|
||||
@@ -213,7 +231,7 @@ class _HomePageState extends State<HomePage> {
|
||||
return Container();
|
||||
}
|
||||
|
||||
login = Provider.of<MainModel>(context).isLogin();
|
||||
login = mainModel.isLogin();
|
||||
LanguageModel languageModel = Provider.of<LanguageModel>(context);
|
||||
|
||||
final faqBtn = TaskButton("faq.btn",
|
||||
@@ -357,7 +375,7 @@ class _HomePageState extends State<HomePage> {
|
||||
selectedColor: Colors.white,
|
||||
color: Colors.blue,
|
||||
children: <Widget>[
|
||||
Icon(MaterialCommunityIcons.account_tie,size: 25),
|
||||
Icon(MaterialCommunityIcons.account_tie, size: 25),
|
||||
],
|
||||
onPressed: (i) => this.setState(() {
|
||||
isFcs[0] = !isFcs[0];
|
||||
@@ -387,11 +405,14 @@ class _HomePageState extends State<HomePage> {
|
||||
color: buttonColor,
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
final pinLoginBtn = IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.push(CupertinoPageRoute(builder: (context) => PinLoginPage()));
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) => PinLoginPage()),
|
||||
(r) => false);
|
||||
},
|
||||
iconSize: 25,
|
||||
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: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
@@ -478,7 +512,7 @@ class _HomePageState extends State<HomePage> {
|
||||
profileBtn,
|
||||
]
|
||||
: <Widget>[
|
||||
pinLoginBtn,
|
||||
mainModel.isPinLogin ? pinLogoutBtn : pinLoginBtn,
|
||||
fcsToggle,
|
||||
profileBtn,
|
||||
]
|
||||
|
||||
@@ -17,6 +17,7 @@ class MainModel extends ChangeNotifier {
|
||||
|
||||
String? messagingToken;
|
||||
User? user;
|
||||
User? _fbUser;
|
||||
PackageInfo? packageInfo;
|
||||
|
||||
set setMessaginToken(token) {
|
||||
@@ -29,6 +30,9 @@ class MainModel extends ChangeNotifier {
|
||||
bool isLoaded = false;
|
||||
bool isOnline = false;
|
||||
bool isFirstLaunch = false;
|
||||
bool isLockOn = false;
|
||||
|
||||
bool get isPinLogin => user?.isPinLogin ?? false;
|
||||
|
||||
MainModel() {
|
||||
NetworkConnectivity.instance.statusStream.listen((data) {
|
||||
@@ -83,6 +87,7 @@ class MainModel extends ChangeNotifier {
|
||||
await _listenSetting();
|
||||
this.isFirstLaunch = await SharedPref.isFirstLaunch() ?? true;
|
||||
this.packageInfo = await PackageInfo.fromPlatform();
|
||||
this.isLockOn = await SharedPref.getPinLockOn() ?? false;
|
||||
|
||||
userListener?.cancel();
|
||||
userListener =
|
||||
@@ -91,6 +96,17 @@ class MainModel extends ChangeNotifier {
|
||||
bool diffPrivilege =
|
||||
_user != null && (user == null || user!.diffPrivileges(_user));
|
||||
bool loggingOut = user != null && _user == null;
|
||||
|
||||
if (_user != null) {
|
||||
if (!_user.isPinLogin) {
|
||||
_fbUser = _user;
|
||||
}
|
||||
}
|
||||
|
||||
if ((_fbUser?.id == _user?.id)) {
|
||||
_user?.pinToken = null;
|
||||
}
|
||||
|
||||
user = _user;
|
||||
|
||||
if (_user != null) {
|
||||
@@ -101,6 +117,7 @@ class MainModel extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loggingOut) {
|
||||
for (final m in models) {
|
||||
m.logout();
|
||||
@@ -196,4 +213,13 @@ class MainModel extends ChangeNotifier {
|
||||
Future<void> deleteAccount() async {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,11 @@ class _SplashScreenState extends State<SplashScreen> {
|
||||
if (mainModel.isFirstLaunch) {
|
||||
page = "/language_selection";
|
||||
} else if (mainModel.isLogin()) {
|
||||
page = "/home";
|
||||
if (mainModel.isLockOn) {
|
||||
page = "/pin_login";
|
||||
} else {
|
||||
page = "/home";
|
||||
}
|
||||
} else {
|
||||
page = "/welcome";
|
||||
}
|
||||
|
||||
@@ -129,12 +129,17 @@ class _ProfileState extends State<Profile> {
|
||||
],
|
||||
);
|
||||
|
||||
final logoutbutton = fcsButton(
|
||||
context, getLocalString(context, "profile.logout"), callack: () {
|
||||
showConfirmDialog(context, "profile.logout.confirm", () async {
|
||||
await _logout();
|
||||
});
|
||||
}, iconData: Icons.exit_to_app);
|
||||
final logoutbutton =
|
||||
fcsButton(context, getLocalString(context, "profile.logout"),
|
||||
callack: mainModel.isPinLogin
|
||||
? null
|
||||
: () {
|
||||
showConfirmDialog(context, "profile.logout.confirm",
|
||||
() async {
|
||||
await _logout();
|
||||
});
|
||||
},
|
||||
iconData: Icons.exit_to_app);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
@@ -355,8 +360,12 @@ class _ProfileState extends State<Profile> {
|
||||
}
|
||||
|
||||
_showToast(String title) {
|
||||
final ScaffoldMessengerState scaffold =
|
||||
key.currentState as ScaffoldMessengerState;
|
||||
ScaffoldMessengerState? scaffold = key.currentState;
|
||||
|
||||
if (scaffold == null) {
|
||||
scaffold = ScaffoldMessenger.of(context);
|
||||
}
|
||||
|
||||
scaffold.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('copied "$title" data to clipboard'),
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
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/widgets/local_button.dart';
|
||||
import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.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 {
|
||||
//final User user;
|
||||
const PinLoginPage({super.key});
|
||||
|
||||
@override
|
||||
@@ -18,10 +23,77 @@ class _PinLoginPageState extends State<PinLoginPage> {
|
||||
bool _isLoading = false;
|
||||
String pin = "";
|
||||
String prefixText = "FCS-";
|
||||
//late User _user;
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
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) {
|
||||
final fcsIdBox = TextFormField(
|
||||
controller: _fcsIdCtl,
|
||||
@@ -48,7 +120,7 @@ class _PinLoginPageState extends State<PinLoginPage> {
|
||||
prefixText,
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
|
||||
prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
labelStyle: newLabelStyle(color: Colors.black54, fontSize: 17),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
@@ -121,42 +193,47 @@ class _PinLoginPageState extends State<PinLoginPage> {
|
||||
callBack: _login,
|
||||
),
|
||||
);
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: new Scaffold(
|
||||
body: Form(
|
||||
key: _formKey,
|
||||
child: ListView(
|
||||
padding: EdgeInsets.only(top: 80, left: 15, right: 15, bottom: 20),
|
||||
children: [
|
||||
pinLoginLogo,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 20),
|
||||
child: Center(
|
||||
child: LocalText(context, "welcome.pinlogin",
|
||||
color: Colors.black, fontSize: 18),
|
||||
|
||||
// ignore: deprecated_member_use
|
||||
return WillPopScope(
|
||||
onWillPop: _onWillPop,
|
||||
child: LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: new Scaffold(
|
||||
body: Form(
|
||||
key: _formKey,
|
||||
child: ListView(
|
||||
padding: EdgeInsets.only(top: 80, left: 15, right: 15, bottom: 20),
|
||||
children: [
|
||||
pinLoginLogo,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 20),
|
||||
child: Center(
|
||||
child: LocalText(context, "welcome.pinlogin",
|
||||
color: Colors.black, fontSize: 18),
|
||||
),
|
||||
),
|
||||
),
|
||||
LocalText(
|
||||
context,
|
||||
"welcome.pinlogin.fcsid",
|
||||
color: Colors.black54,
|
||||
fontSize: 15,
|
||||
),
|
||||
fcsIdBox,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 25, bottom: 20),
|
||||
child: LocalText(
|
||||
context,
|
||||
"welcome.pinlogin.pin",
|
||||
color: Colors.black54,
|
||||
fontSize: 15,
|
||||
)),
|
||||
pinInputBox,
|
||||
loginBtn,
|
||||
],
|
||||
),
|
||||
)),
|
||||
LocalText(
|
||||
context,
|
||||
"welcome.pinlogin.fcsid",
|
||||
color: Colors.black54,
|
||||
fontSize: 15,
|
||||
),
|
||||
fcsIdBox,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 25, bottom: 20),
|
||||
child: LocalText(
|
||||
context,
|
||||
"welcome.pinlogin.pin",
|
||||
color: Colors.black54,
|
||||
fontSize: 15,
|
||||
)),
|
||||
pinInputBox,
|
||||
loginBtn,
|
||||
],
|
||||
),
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -171,14 +248,14 @@ class _PinLoginPageState extends State<PinLoginPage> {
|
||||
return;
|
||||
}
|
||||
String fcsId = "$prefixText${_fcsIdCtl.text}";
|
||||
print(fcsId);
|
||||
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
Navigator.pop(context, true);
|
||||
await context.read<MainModel>().pinLogin(fcsID: fcsId, pin: pin);
|
||||
Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
|
||||
@@ -81,7 +81,7 @@ class StaffModel extends BaseModel {
|
||||
Future<void> updatePin(
|
||||
{required String userID,
|
||||
required bool enablePin,
|
||||
required int? pin}) async {
|
||||
required String? pin}) async {
|
||||
await request("/employee/pin", "PUT",
|
||||
payload: {"id": userID, "enable_pin_login": enablePin, "pin": pin},
|
||||
token: await getToken());
|
||||
|
||||
@@ -310,7 +310,7 @@ class _StaffPinEditorState extends State<StaffPinEditor> {
|
||||
await context.read<StaffModel>().updatePin(
|
||||
userID: _staff.id!,
|
||||
enablePin: _enablePinLogin,
|
||||
pin: _enablePinLogin ? int.parse(_confirmPin) : null);
|
||||
pin: _enablePinLogin ? _confirmPin : null);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
|
||||
Reference in New Issue
Block a user