last login and login options ui.

merge-requests/390/head
Sikander Saleem 3 years ago
parent 1ec48b9598
commit 8b2feb03ea

@ -213,8 +213,10 @@ const Map localizedValues = {
"verify-with-faceid": {"en": "Face ID", "ar": "معرف الوجه"},
"verify-with-sms": {"en": "SMS", "ar": "الرسائل القصيرة"},
"verify-with-whatsapp": {"en": "Whatsapp", "ar": " الواتس اب"},
"last-login": {"en": "LAST LOGIN AT:", "ar": "آخر تسجيل دخول"},
"last-login-with": {"en": "VERIFICATION TYPE:", "ar": "نوع التحقق:"},
"verify-through": {"en": "Verify Through", "ar": " تحقق من خلال"},
"last-login": {"en": "Last Login Details:", "ar": "آخر تسجيل دخول"},
"last-login-with": {"en": "Verification Type:", "ar": "نوع التحقق:"},
"please-verify": {"en": "Please Verify", "ar": "ارجوك تحقق:"},
"verify-fingerprint": {
"en":
"To activate the fingerprint login service, please verify data by using one of the following options.",
@ -326,7 +328,7 @@ const Map localizedValues = {
},
"welcome-back": {"en": "Welcome back!", "ar": "مرحبا بعودتك!"},
"account-info": {
"en": "Would you like to login with current username?",
"en": "Would you like to login with current Username?",
"ar": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟"
},
"another-acc": {"en": "Use Another Account", "ar": "استخدم حسابا آخر"},

@ -0,0 +1,6 @@
extension CapExtension on String {
String get toCamelCase => "${this[0].toUpperCase()}${this.substring(1)}";
String get inCaps => '${this[0].toUpperCase()}${this.substring(1)}';
String get allInCaps => this.toUpperCase();
String get capitalizeFirstofEach => this.split(" ").map((str) => str.inCaps).join(" ");
}

@ -34,7 +34,7 @@ import 'package:intl/intl.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:provider/provider.dart';
// import 'package:smart_progress_bar/smart_progress_bar.dart';
import 'package:diplomaticquarterapp/extensions/string_extensions.dart';
class ConfirmLogin extends StatefulWidget {
@override
@ -47,8 +47,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
var sharedPref = new AppSharedPreferences();
bool authenticated;
final authService = new AuthProvider();
PharmacyModuleViewModel pharmacyModuleViewModel =
locator<PharmacyModuleViewModel>();
PharmacyModuleViewModel pharmacyModuleViewModel = locator<PharmacyModuleViewModel>();
int mobileNumber;
String errorMsg = '';
SelectDeviceIMEIRES user;
@ -78,10 +77,8 @@ class _ConfirmLogin extends State<ConfirmLogin> {
int fingrePrintBefore;
AuthenticatedUserObject authenticatedUserObject =
locator<AuthenticatedUserObject>();
AppointmentRateViewModel appointmentRateViewModel =
locator<AppointmentRateViewModel>();
AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>();
AppointmentRateViewModel appointmentRateViewModel = locator<AppointmentRateViewModel>();
ProjectViewModel projectViewModel;
ToDoCountProviderModel toDoProvider;
@ -97,6 +94,155 @@ class _ConfirmLogin extends State<ConfirmLogin> {
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
toDoProvider = Provider.of<ToDoCountProviderModel>(context);
return Scaffold(
backgroundColor: Color(0xfff8f8f8),
resizeToAvoidBottomPadding: false,
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
color: Color(0xff2B353E),
onPressed: () => Navigator.pop(context),
),
),
body: Padding(
padding: EdgeInsets.only(bottom: 20, left: 21, right: 21),
child: Column(
children: [
Expanded(
child: ListView(
padding: EdgeInsets.zero,
physics: BouncingScrollPhysics(),
children: [
SizedBox(height: 12), // todo discuss
Text(
TranslationBase.of(context).welcomeBack,
style: TextStyle(fontSize: 12, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64),
),
Text(
user.name.toLowerCase().capitalizeFirstofEach,
style: TextStyle(fontSize: 24, fontFamily: "Poppins", fontWeight: FontWeight.w700, color: Color(0xff2B353E), height: 1, letterSpacing: -1.44),
),
SizedBox(height: 10),
Text(
TranslationBase.of(context).accountInfo,
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16),
),
Container(
height: 72,
margin: EdgeInsets.only(top: 23, bottom: 23),
alignment: Alignment.center,
padding: EdgeInsets.only(left: 17, right: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: Color(0xffefefef),
width: 1,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
TranslationBase.of(context).lastLoginAt.toCamelCase,
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64),
),
Text(
user.editedOn != null
? formatDateToDate(DateUtil.convertStringToDate(user.editedOn))
: user.createdOn != null
? formatDateToDate(DateUtil.convertStringToDate(user.createdOn))
: '--',
style: TextStyle(fontSize: 12, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
TranslationBase.of(context).lastLoginWith.toCamelCase,
style: TextStyle(
fontSize: 10,
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
color: Color(0xff575757),
),
),
Text(
" " + getType(user.logInType, context),
style: TextStyle(
fontSize: 12,
fontFamily: "Poppins",
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
),
),
Expanded(child: SizedBox()),
Text(
user.editedOn != null
? formatDateToTime(DateUtil.convertStringToDate(user.editedOn))
: user.createdOn != null
? formatDateToTime(DateUtil.convertStringToDate(user.createdOn))
: '--',
style: TextStyle(fontSize: 12, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.48),
),
],
)
],
),
),
Text(
TranslationBase.of(context).pleaseVerify,
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64),
),
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9),
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.only(top: 9),
shrinkWrap: true,
children: [
getButton(3),
getButton(2),
getButton(1),
getButton(4),
],
)
],
),
),
SizedBox(
height: 12, // todo discuss
),
SizedBox(
height: 43,
width: double.infinity,
child: FlatButton(
onPressed: () {
Navigator.of(context).pushNamed(LOGIN_TYPE);
},
child: Text(
TranslationBase.of(context).useAnotherAccount,
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.48, height: 35 / 16),
),
color: Color(0xffD02127),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
],
),
),
);
return AppScaffold(
appBarTitle: TranslationBase.of(context).confirm,
isShowAppBar: true,
@ -119,9 +265,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
width: 90,
),
Texts(
TranslationBase.of(context).welcomeBack +
' ' +
user.name,
TranslationBase.of(context).welcomeBack + ' ' + user.name,
fontSize: SizeConfig.textMultiplier * 3.5,
),
SizedBox(
@ -147,93 +291,59 @@ class _ConfirmLogin extends State<ConfirmLogin> {
),
subtitle: Text(
user.editedOn != null
? formatDate(
DateUtil.convertStringToDate(
user.editedOn))
? formatDate(DateUtil.convertStringToDate(user.editedOn))
: user.createdOn != null
? formatDate(
DateUtil.convertStringToDate(
user.createdOn))
? formatDate(DateUtil.convertStringToDate(user.createdOn))
: '--',
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center),
)),
Flexible(
child: ListTile(
title: Text(
TranslationBase.of(context).lastLoginWith,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center),
subtitle: Text(
getType(user.logInType, context),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center),
title: Text(TranslationBase.of(context).lastLoginWith, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center),
subtitle: Text(getType(user.logInType, context), overflow: TextOverflow.ellipsis, textAlign: TextAlign.center),
))
],
)),
],
)
: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.asset(
'assets/images/habib-logo.png',
height: 90,
width: 90,
),
this.onlySMSBox == false
? Texts(
TranslationBase.of(context).verifyLoginWith,
fontSize: SizeConfig.textMultiplier * 3.5,
textAlign: TextAlign.left,
)
: Texts(
TranslationBase.of(context)
.verifyFingerprint2,
fontSize: SizeConfig.textMultiplier * 2.5,
textAlign: TextAlign.start,
),
]),
: Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Image.asset(
'assets/images/habib-logo.png',
height: 90,
width: 90,
),
this.onlySMSBox == false
? Texts(
TranslationBase.of(context).verifyLoginWith,
fontSize: SizeConfig.textMultiplier * 3.5,
textAlign: TextAlign.left,
)
: Texts(
TranslationBase.of(context).verifyFingerprint2,
fontSize: SizeConfig.textMultiplier * 2.5,
textAlign: TextAlign.start,
),
]),
user != null && isMoreOption == false
? Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
? Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Expanded(child: InkWell(onTap: () => {authenticateUser(3, isActive: BiometricType.face.index)}, child: getButton(user.logInType))),
Expanded(child: getButton(5))
])
])
: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
onlySMSBox == false
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: InkWell(
onTap: () => {
authenticateUser(
3, BiometricType.face.index)
},
child: getButton(user.logInType))),
Expanded(child: getButton(5))
])
])
: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
onlySMSBox == false
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(child: getButton(3)),
Expanded(child: getButton(2))
],
)
: SizedBox(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(child: getButton(1)),
Expanded(child: getButton(4))
],
),
]),
children: <Widget>[Expanded(child: getButton(3)), Expanded(child: getButton(2))],
)
: SizedBox(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Expanded(child: getButton(1)), Expanded(child: getButton(4))],
),
]),
Expanded(
flex: 1,
child: Column(
@ -278,7 +388,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
});
}
authenticateUser(type, isActive) {
authenticateUser(int type, {int isActive}) {
GifLoaderDialogUtils.showMyDialog(context);
if (type == 2 || type == 3) {
fingrePrintBefore = type;
@ -287,7 +397,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
switch (type) {
case 1:
this.loginWithSMS(type, isActive);
this.loginWithSMS(type);
break;
case 2:
this.loginWithFingurePrintFace(type, isActive);
@ -296,16 +406,15 @@ class _ConfirmLogin extends State<ConfirmLogin> {
this.loginWithFingurePrintFace(type, isActive);
break;
case 4:
this.loginWithSMS(type, isActive);
this.loginWithSMS(type);
break;
default:
break;
}
sharedPref.setInt(LAST_LOGIN,
this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN);
sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN);
}
loginWithSMS(type, isActive) {
loginWithSMS(type) {
//if (!el.disabled) {
if (this.user != null && this.registerd_data == null) {
this.checkUserAuthentication(type);
@ -381,21 +490,14 @@ class _ConfirmLogin extends State<ConfirmLogin> {
).displayDialog(context);
}
loginWithFingurePrintFace(type, isActive) async {
loginWithFingurePrintFace(type, int isActive) async {
if (isActive == 1) {
// this.startBiometricLoginIfAvailable();
const iosStrings = const IOSAuthMessages(
cancelButton: 'cancel',
goToSettingsButton: 'settings',
goToSettingsDescription: 'Please set up your Touch ID.',
lockOut: 'Please reenable your Touch ID');
const iosStrings =
const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID');
try {
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
useErrorDialogs: true,
stickyAuth: true,
iOSAuthStrings: iosStrings);
authenticated = await auth.authenticateWithBiometrics(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings);
} on PlatformException catch (e) {
AppToast.showErrorToast(message: e.toString());
}
@ -441,19 +543,14 @@ class _ConfirmLogin extends State<ConfirmLogin> {
}
setDefault() async {
if (await sharedPref.getObject(IMEI_USER_DATA) != null)
user = SelectDeviceIMEIRES.fromJson(
await sharedPref.getObject(IMEI_USER_DATA));
if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA));
if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) {
isMoreOption = true;
this.registerd_data = CheckPatientAuthenticationReq.fromJson(
await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN));
this.registerd_data = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN));
}
this.mobileNumber = this.registerd_data != null
? this.registerd_data.patientMobileNumber
: int.parse(this.user.mobile);
this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.mobile);
this.zipCode = this.registerd_data != null
? this.registerd_data.zipCode
: this.user.outSA == true
@ -485,33 +582,22 @@ class _ConfirmLogin extends State<ConfirmLogin> {
request.deviceToken = this.deviceToken;
request.projectOutSA = this.patientOutSA == true ? true : false;
request.loginType = this.selectedOption;
request.oTPSendType =
type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2;
request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2;
request.zipCode = this.zipCode;
request.logInTokenID = this.loginTokenID ?? "";
if (this.registerd_data != null) {
request.searchType = this.registerd_data.searchType != null
? this.registerd_data.searchType
: 1;
request.patientID = this.registerd_data.patientID != null
? this.registerd_data.patientID
: 0;
request.patientIdentificationID = request.nationalID =
this.registerd_data.patientIdentificationID != null
? this.registerd_data.patientIdentificationID
: '0';
request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1;
request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0;
request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0';
request.isRegister = this.registerd_data.isRegister;
} else {
request.searchType = request.searchType != null ? request.searchType : 2;
request.patientID = this.user.patientID != null ? this.user.patientID : 0;
request.nationalID =
request.nationalID != null ? request.nationalID : '0';
request.patientIdentificationID = request.patientIdentificationID != null
? request.patientIdentificationID
: '0';
request.nationalID = request.nationalID != null ? request.nationalID : '0';
request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0';
request.isRegister = false;
}
request.deviceTypeID = request.searchType;
@ -528,8 +614,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
if (result is Map)
{
result = CheckActivationCode.fromJson(result),
if (this.registerd_data != null &&
this.registerd_data.isRegister == true)
if (this.registerd_data != null && this.registerd_data.isRegister == true)
{
Navigator.of(context).pushNamed(
REGISTER_INFO,
@ -578,10 +663,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
}
insertIMEI() {
authService
.insertDeviceImei(selectedOption)
.then((value) => {goToHome()})
.catchError((err) {
authService.insertDeviceImei(selectedOption).then((value) => {goToHome()}).catchError((err) {
print(err);
});
}
@ -604,13 +686,11 @@ class _ConfirmLogin extends State<ConfirmLogin> {
appointmentRateViewModel.isLogin = true;
projectViewModel.isLogin = true;
projectViewModel.user = authenticatedUserObject.user;
Provider.of<ProjectViewModel>(context, listen: false)
.setUser(authenticatedUserObject.user);
Provider.of<ProjectViewModel>(context, listen: false).setUser(authenticatedUserObject.user);
getToDoCount();
pharmacyModuleViewModel.generatePharmacyToken().then((value) async {
if (pharmacyModuleViewModel.error.isNotEmpty)
await pharmacyModuleViewModel.createUser();
if (pharmacyModuleViewModel.error.isNotEmpty) await pharmacyModuleViewModel.createUser();
});
appointmentRateViewModel
@ -650,124 +730,90 @@ class _ConfirmLogin extends State<ConfirmLogin> {
});
}
Widget getButton(flag) {
Widget _loginOptionButton(String _title, String _icon, int _flag, int _loginIndex) {
return InkWell(
onTap: () {
if (_flag == 0) {
setState(() {
isMoreOption = true;
});
} else {
authenticateUser(4, isActive: _loginIndex);
}
},
child: Container(
padding: EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
border: Border.all(
color: Color(0xffefefef),
width: 1,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Image.asset(
_icon,
height: 38,
width: 38,
),
Text(
TranslationBase.of(context).verifyThrough + " " + _title,
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48, height: 20 / 16),
),
],
),
),
);
return InkWell(
onTap: () {
if (_flag == 0) {
setState(() {
isMoreOption = true;
});
} else {
authenticateUser(4, isActive: _loginIndex);
}
},
child: RoundedContainer(
height: 150,
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 15, 30, 15),
child: Column(
children: <Widget>[
Image.asset(
_icon,
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
SizedBox(
height: 20,
),
Texts(_title, fontSize: SizeConfig.textMultiplier * 2, color: Colors.black)
],
),
)));
}
Widget getButton(int flag) {
switch (flag) {
case 4:
return InkWell(
onTap: () => {authenticateUser(4, true)},
child: RoundedContainer(
height: 150,
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 15, 30, 15),
child: Column(
children: <Widget>[
Image.asset(
'assets/images/login/104.png',
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
SizedBox(
height: 20,
),
Texts(TranslationBase.of(context).verifyWhatsApp,
fontSize: SizeConfig.textMultiplier * 2,
color: Colors.black)
],
),
)));
return _loginOptionButton(TranslationBase.of(context).verifyWhatsApp, 'assets/images/login/104.png', flag, null);
break;
case 1:
return InkWell(
onTap: () => {authenticateUser(1, true)},
child: RoundedContainer(
height: 150,
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 15, 30, 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/login/103.png',
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
projectViewModel.isArabic
? SizedBox(
height: 0,
)
: SizedBox(
height: 20,
),
Texts(TranslationBase.of(context).verifySMS,
fontSize: SizeConfig.textMultiplier * 2,
textAlign: TextAlign.center,
color: Colors.black)
],
),
)));
return _loginOptionButton(TranslationBase.of(context).verifySMS, 'assets/images/login/103.png', flag, null);
break;
case 2:
return InkWell(
onTap: () => {authenticateUser(2, BiometricType.fingerprint.index)},
child: RoundedContainer(
height: 150,
backgroundColor: BiometricType.fingerprint.index == 1
? Colors.white
: Colors.white.withOpacity(.7),
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 15, 30, 15),
child: Column(
children: <Widget>[
Image.asset(
'assets/images/login/102.png',
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
SizedBox(
height: 20,
),
Texts(TranslationBase.of(context).verifyFingerprint,
fontSize: SizeConfig.textMultiplier * 2,
color: Colors.black)
],
),
)));
return _loginOptionButton(TranslationBase.of(context).verifyFingerprint, 'assets/images/login/102.png', flag, BiometricType.fingerprint.index);
break;
case 3:
return InkWell(
onTap: () => {authenticateUser(3, BiometricType.face.index)},
child: RoundedContainer(
height: 150,
backgroundColor: checkIfBiometricAvailable(BiometricType.face)
? Colors.white
: Colors.white.withOpacity(.7),
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 15, 30, 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/login/101.png',
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
SizedBox(
height: 20,
),
Texts(TranslationBase.of(context).verifyFaceID,
fontSize: SizeConfig.textMultiplier * 2,
color: Colors.black)
],
),
)));
return _loginOptionButton(TranslationBase.of(context).verifyFaceID, 'assets/images/login/101.png', flag, BiometricType.face.index);
break;
default:
@ -779,9 +825,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
},
child: RoundedContainer(
height: 150,
backgroundColor: BiometricType.fingerprint.index == 1
? Colors.white
: Colors.white.withOpacity(.7),
backgroundColor: BiometricType.fingerprint.index == 1 ? Colors.white : Colors.white.withOpacity(.7),
borderColor: Colors.grey,
showBorder: true,
child: Padding(
@ -800,10 +844,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
: SizedBox(
height: 20,
),
Texts(TranslationBase.of(context).moreVerification,
fontSize: SizeConfig.textMultiplier * 1.8,
textAlign: TextAlign.center,
color: Colors.black)
Texts(TranslationBase.of(context).moreVerification, fontSize: SizeConfig.textMultiplier * 1.8, textAlign: TextAlign.center, color: Colors.black)
],
),
)));
@ -844,6 +885,14 @@ class _ConfirmLogin extends State<ConfirmLogin> {
return DateFormat('MMM dd, yyy, kk:mm').format(date);
}
formatDateToDate(date) {
return DateFormat('dd MMM yyy').format(date);
}
formatDateToTime(date) {
return DateFormat('kk:mm a').format(date);
}
showLoader(bool isTrue) {
setState(() {
isLoading = isTrue;

File diff suppressed because it is too large Load Diff

@ -11,6 +11,8 @@ import 'package:provider/provider.dart';
import 'package:sms_otp_auto_verify/sms_otp_auto_verify.dart';
import '../otp_widget.dart';
class SMSOTP {
final type;
final mobileNo;
@ -36,6 +38,8 @@ class SMSOTP {
final verifyAccountForm = GlobalKey<FormState>();
final TextEditingController _pinPutController = TextEditingController();
TextEditingController digit1 = TextEditingController(text: "");
TextEditingController digit2 = TextEditingController(text: "");
TextEditingController digit3 = TextEditingController(text: "");
@ -60,9 +64,139 @@ class SMSOTP {
displayDialog(BuildContext context) async {
return showDialog(
context: context,
barrierColor: Colors.black.withOpacity(0.63),
builder: (context) {
projectProvider = Provider.of(context);
return AlertDialog(
return Dialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(),
insetPadding: EdgeInsets.only(left: 21, right: 21),
child: StatefulBuilder(builder: (context, setState) {
if (displayTime == '') {
startTimer(setState);
}
return Container(
padding: EdgeInsets.only(left: 21, right: 18, top: 39, bottom: 59),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
type == 1 ? 'assets/images/login/103.png' : 'assets/images/login/104.png',
height: 50,
width: 50,
),
IconButton(
padding: EdgeInsets.zero,
icon: Icon(Icons.close),
constraints: BoxConstraints(),
onPressed: () {
Navigator.pop(context);
this.onFailure();
},
)
],
),
SizedBox(height: 22),
Text(
TranslationBase.of(context).pleaseEnterTheVerificationCode + ' xxxxxxxx' + mobileNo.toString().substring(mobileNo.toString().length - 3),
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48),
),
SizedBox(height: 18),
Directionality(
textDirection: TextDirection.ltr,
child: OTPWidget(
autoFocus: true,
controller: _pinPutController,
defaultBorderColor: Color(0xffD8D8D8),
maxLength: 4,
onTextChanged: (text) {},
pinBoxColor: Colors.white,
onDone: (code) => _onOtpCallBack(code, null),
textBorderColor: Color(0xffD8D8D8),
pinBoxWidth: 68,
pinBoxHeight: 75,
pinTextStyle: TextStyle(
fontSize: 24.0,
color: Color(0xff2B353E),
),
pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition,
pinTextAnimatedSwitcherDuration: Duration(milliseconds: 300),
pinBoxRadius: 10,
keyboardType: TextInputType.number,
),
),
SizedBox(height: 30),
RichText(
text: TextSpan(
text: TranslationBase.of(context).validationMessage + '\n',
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.48),
children: <TextSpan>[
TextSpan(
text: displayTime,
style: TextStyle(fontSize: 16, fontFamily: "Poppins", fontWeight: FontWeight.w600, color: Color(0xffD02127), letterSpacing: -0.48),
),
],
),
),
],
),
);
return Container(
color: Colors.white,
height: SizeConfig.realScreenHeight * 0.5,
width: SizeConfig.realScreenWidth,
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
type == 1 ? Image.asset('assets/images/login/103.png') : Image.asset('assets/images/login/104.png'),
Padding(
padding: EdgeInsets.only(top: 5),
child: AppText(
TranslationBase.of(context).pleaseEnterTheVerificationCode + ' XXXXXX' + mobileNo.toString().substring(mobileNo.toString().length - 3),
textAlign: TextAlign.center,
)),
Directionality(
textDirection: TextDirection.ltr,
child: TextFieldPin(
filled: true,
filledColor: Colors.grey[100],
codeLength: 4,
filledAfterTextChange: true,
boxSize: 50,
margin: 10,
borderStyeAfterTextChange: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
borderStyle: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
onOtpCallback: (code, isAutofill) => _onOtpCallBack(code, isAutofill),
)),
SizedBox(height: 20),
Padding(
padding: EdgeInsets.only(top: 10),
child: AppText(
TranslationBase.of(context).validationMessage + ' ' + displayTime,
color: Colors.red,
textAlign: TextAlign.center,
))
],
)),
);
}),
);
AlertDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
@ -75,8 +209,7 @@ class SMSOTP {
)
],
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))),
content: StatefulBuilder(builder: (context, setState) {
if (displayTime == '') {
startTimer(setState);
@ -90,17 +223,11 @@ class SMSOTP {
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
type == 1
? Image.asset('assets/images/login/103.png')
: Image.asset('assets/images/login/104.png'),
type == 1 ? Image.asset('assets/images/login/103.png') : Image.asset('assets/images/login/104.png'),
Padding(
padding: EdgeInsets.only(top: 5),
child: AppText(
TranslationBase.of(context).verificationMessage +
' XXXXXX' +
mobileNo
.toString()
.substring(mobileNo.toString().length - 3),
TranslationBase.of(context).pleaseEnterTheVerificationCode + ' XXXXXX' + mobileNo.toString().substring(mobileNo.toString().length - 3),
textAlign: TextAlign.center,
)),
@ -121,8 +248,7 @@ class SMSOTP {
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
onOtpCallback: (code, isAutofill) =>
_onOtpCallBack(code, isAutofill),
onOtpCallback: (code, isAutofill) => _onOtpCallBack(code, isAutofill),
)),
// Form(
// key: verifyAccountForm,
@ -251,9 +377,7 @@ class SMSOTP {
Padding(
padding: EdgeInsets.only(top: 10),
child: AppText(
TranslationBase.of(context).validationMessage +
' ' +
displayTime,
TranslationBase.of(context).validationMessage + ' ' + displayTime,
color: Colors.red,
textAlign: TextAlign.center,
))
@ -308,25 +432,19 @@ class SMSOTP {
checkValue() {
//print(verifyAccountFormValue);
if (verifyAccountForm.currentState.validate()) {
onSuccess(digit1.text.toString() +
digit2.text.toString() +
digit3.text.toString() +
digit4.text.toString());
onSuccess(digit1.text.toString() + digit2.text.toString() + digit3.text.toString() + digit4.text.toString());
}
}
getSecondsAsDigitalClock(int inputSeconds) {
var sec_num =
int.parse(inputSeconds.toString()); // don't forget the second param
var sec_num = int.parse(inputSeconds.toString()); // don't forget the second param
var hours = (sec_num / 3600).floor();
var minutes = ((sec_num - hours * 3600) / 60).floor();
var seconds = sec_num - hours * 3600 - minutes * 60;
var minutesString = "";
var secondsString = "";
minutesString =
minutes < 10 ? "0" + minutes.toString() : minutes.toString();
secondsString =
seconds < 10 ? "0" + seconds.toString() : seconds.toString();
minutesString = minutes < 10 ? "0" + minutes.toString() : minutes.toString();
secondsString = seconds < 10 ? "0" + seconds.toString() : seconds.toString();
return minutesString + ":" + secondsString;
}

@ -0,0 +1,373 @@
import 'dart:async';
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
typedef OnDone = void Function(String text);
class ProvidedPinBoxTextAnimation {
static AnimatedSwitcherTransitionBuilder scalingTransition = (child, animation) {
return ScaleTransition(
child: child,
scale: animation,
);
};
static AnimatedSwitcherTransitionBuilder defaultNoTransition = (Widget child, Animation<double> animation) {
return child;
};
}
class OTPWidget extends StatefulWidget {
final int maxLength;
final TextEditingController controller;
final Color defaultBorderColor;
final Color pinBoxColor;
final double pinBoxBorderWidth;
final double pinBoxRadius;
final bool hideDefaultKeyboard;
final TextStyle pinTextStyle;
final double pinBoxHeight;
final double pinBoxWidth;
final OnDone onDone;
final bool hasError;
final Color errorBorderColor;
final Color textBorderColor;
final Function(String) onTextChanged;
final bool autoFocus;
final FocusNode focusNode;
final AnimatedSwitcherTransitionBuilder pinTextAnimatedSwitcherTransition;
final Duration pinTextAnimatedSwitcherDuration;
final TextDirection textDirection;
final TextInputType keyboardType;
final EdgeInsets pinBoxOuterPadding;
const OTPWidget({
Key key,
this.maxLength: 4,
this.controller,
this.pinBoxWidth: 70.0,
this.pinBoxHeight: 70.0,
this.pinTextStyle,
this.onDone,
this.defaultBorderColor: Colors.black,
this.textBorderColor: Colors.black,
this.pinTextAnimatedSwitcherTransition,
this.pinTextAnimatedSwitcherDuration: const Duration(),
this.hasError: false,
this.errorBorderColor: Colors.red,
this.onTextChanged,
this.autoFocus: false,
this.focusNode,
this.textDirection: TextDirection.ltr,
this.keyboardType: TextInputType.number,
this.pinBoxOuterPadding = const EdgeInsets.symmetric(horizontal: 4.0),
this.pinBoxColor = Colors.white,
this.pinBoxBorderWidth = 2.0,
this.pinBoxRadius = 0,
this.hideDefaultKeyboard = false,
}) : super(key: key);
@override
State<StatefulWidget> createState() {
return OTPWidgetState();
}
}
class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixin {
AnimationController _highlightAnimationController;
FocusNode focusNode;
String text = "";
int currentIndex = 0;
List<String> strList = [];
bool hasFocus = false;
@override
void didUpdateWidget(OTPWidget oldWidget) {
super.didUpdateWidget(oldWidget);
focusNode = widget.focusNode ?? focusNode;
if (oldWidget.maxLength < widget.maxLength) {
setState(() {
currentIndex = text.length;
});
widget.controller?.text = text;
widget.controller?.selection = TextSelection.collapsed(offset: text.length);
} else if (oldWidget.maxLength > widget.maxLength && widget.maxLength > 0 && text.length > 0 && text.length > widget.maxLength) {
setState(() {
text = text.substring(0, widget.maxLength);
currentIndex = text.length;
});
widget.controller?.text = text;
widget.controller?.selection = TextSelection.collapsed(offset: text.length);
}
}
_calculateStrList() {
if (strList.length > widget.maxLength) {
strList.length = widget.maxLength;
}
while (strList.length < widget.maxLength) {
strList.add("");
}
}
@override
void initState() {
super.initState();
focusNode = widget.focusNode ?? FocusNode();
_initTextController();
_calculateStrList();
widget.controller?.addListener(_controllerListener);
focusNode?.addListener(_focusListener);
}
void _controllerListener() {
if (mounted == true) {
setState(() {
_initTextController();
});
var onTextChanged = widget.onTextChanged;
if (onTextChanged != null) {
onTextChanged(widget.controller?.text ?? "");
}
}
}
void _focusListener() {
if (mounted == true) {
setState(() {
hasFocus = focusNode?.hasFocus ?? false;
});
}
}
void _initTextController() {
if (widget.controller == null) {
return;
}
strList.clear();
var text = widget.controller?.text ?? "";
if (text.isNotEmpty) {
if (text.length > widget.maxLength) {
throw Exception("TextEditingController length exceeded maxLength!");
}
}
for (var i = 0; i < text.length; i++) {
strList.add(text[i]);
}
}
double get _width {
var width = 0.0;
for (var i = 0; i < widget.maxLength; i++) {
width += widget.pinBoxWidth;
if (i == 0) {
width += widget.pinBoxOuterPadding.left;
} else if (i + 1 == widget.maxLength) {
width += widget.pinBoxOuterPadding.right;
} else {
width += widget.pinBoxOuterPadding.left;
}
}
return width;
}
@override
void dispose() {
if (widget.focusNode == null) {
focusNode?.dispose();
} else {
focusNode?.removeListener(_focusListener);
}
_highlightAnimationController?.dispose();
widget.controller?.removeListener(_controllerListener);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
_otpTextInput(),
_touchPinBoxRow(),
],
);
}
Widget _touchPinBoxRow() {
return widget.hideDefaultKeyboard
? _pinBoxRow(context)
: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (hasFocus) {
FocusScope.of(context).requestFocus(FocusNode());
Future.delayed(Duration(milliseconds: 100), () {
FocusScope.of(context).requestFocus(focusNode);
});
} else {
FocusScope.of(context).requestFocus(focusNode);
}
},
child: _pinBoxRow(context),
);
}
Widget _otpTextInput() {
var transparentBorder = OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
width: 0.0,
),
);
return Container(
width: _width,
height: widget.pinBoxHeight,
child: TextField(
autofocus: !kIsWeb ? widget.autoFocus : false,
enableInteractiveSelection: false,
focusNode: focusNode,
controller: widget.controller,
keyboardType: widget.keyboardType,
inputFormatters: widget.keyboardType == TextInputType.number ? <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly] : null,
style: TextStyle(
height: 0.1,
color: Colors.transparent,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0),
focusedErrorBorder: transparentBorder,
errorBorder: transparentBorder,
disabledBorder: transparentBorder,
enabledBorder: transparentBorder,
focusedBorder: transparentBorder,
counterText: null,
counterStyle: null,
helperStyle: TextStyle(
height: 0.0,
color: Colors.transparent,
),
labelStyle: TextStyle(height: 0.1),
fillColor: Colors.transparent,
border: InputBorder.none,
),
cursorColor: Colors.transparent,
showCursor: false,
maxLength: widget.maxLength,
onChanged: _onTextChanged,
),
);
}
void _onTextChanged(text) {
var onTextChanged = widget.onTextChanged;
if (onTextChanged != null) {
onTextChanged(text);
}
setState(() {
this.text = text;
if (text.length >= currentIndex) {
for (int i = currentIndex; i < text.length; i++) {
strList[i] = text[i];
}
}
currentIndex = text.length;
});
if (text.length == widget.maxLength) {
FocusScope.of(context).requestFocus(FocusNode());
var onDone = widget.onDone;
if (onDone != null) {
onDone(text);
}
}
}
Widget _pinBoxRow(BuildContext context) {
_calculateStrList();
List<Widget> pinCodes = List.generate(widget.maxLength, (int i) {
return _buildPinCode(i, context);
});
return Row(children: pinCodes, mainAxisSize: MainAxisSize.min);
}
Widget _buildPinCode(int i, BuildContext context) {
Color borderColor;
Color pinBoxColor = widget.pinBoxColor;
if (widget.hasError) {
borderColor = widget.errorBorderColor;
} else if (i < text.length) {
borderColor = widget.textBorderColor;
} else {
borderColor = widget.defaultBorderColor;
pinBoxColor = widget.pinBoxColor;
}
EdgeInsets insets;
if (i == 0) {
insets = EdgeInsets.only(
left: 0,
top: widget.pinBoxOuterPadding.top,
right: widget.pinBoxOuterPadding.right,
bottom: widget.pinBoxOuterPadding.bottom,
);
} else if (i == strList.length - 1) {
insets = EdgeInsets.only(
left: widget.pinBoxOuterPadding.left,
top: widget.pinBoxOuterPadding.top,
right: 0,
bottom: widget.pinBoxOuterPadding.bottom,
);
} else {
insets = widget.pinBoxOuterPadding;
}
return Container(
key: ValueKey<String>("container$i"),
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 1.0),
margin: insets,
child: _animatedTextBox(strList[i], i),
decoration: BoxDecoration(
border: Border.all(
color: borderColor,
width: widget.pinBoxBorderWidth,
),
color: pinBoxColor,
borderRadius: BorderRadius.circular(widget.pinBoxRadius),
),
width: widget.pinBoxWidth,
height: widget.pinBoxHeight,
);
}
Widget _animatedTextBox(String text, int i) {
if (widget.pinTextAnimatedSwitcherTransition != null) {
return AnimatedSwitcher(
duration: widget.pinTextAnimatedSwitcherDuration,
transitionBuilder: widget.pinTextAnimatedSwitcherTransition ??
(Widget child, Animation<double> animation) {
return child;
},
child: Text(
text,
key: ValueKey<String>("$text$i"),
style: widget.pinTextStyle,
),
);
} else {
return Text(
text,
key: ValueKey<String>("${strList[i]}$i"),
style: widget.pinTextStyle,
);
}
}
}
Loading…
Cancel
Save