import ' dart:io ' ;
import ' package:easy_localization/src/public_ext.dart ' ;
import ' package:flutter/material.dart ' ;
import ' package:flutter/services.dart ' ;
import ' package:flutter_svg/svg.dart ' ;
import ' package:local_auth/auth_strings.dart ' ;
import ' package:local_auth/local_auth.dart ' ;
import ' package:mohem_flutter_app/api/login_api_client.dart ' ;
import ' package:mohem_flutter_app/app_state/app_state.dart ' ;
import ' package:mohem_flutter_app/classes/colors.dart ' ;
import ' package:mohem_flutter_app/classes/date_uitl.dart ' ;
import ' package:mohem_flutter_app/classes/utils.dart ' ;
import ' package:mohem_flutter_app/config/routes.dart ' ;
import ' package:mohem_flutter_app/dialogs/otp_dialog.dart ' ;
import ' package:mohem_flutter_app/extensions/int_extensions.dart ' ;
import ' package:mohem_flutter_app/extensions/string_extensions.dart ' ;
import ' package:mohem_flutter_app/extensions/widget_extensions.dart ' ;
import ' package:mohem_flutter_app/generated/locale_keys.g.dart ' ;
import ' package:mohem_flutter_app/models/basic_member_information_model.dart ' ;
import ' package:mohem_flutter_app/models/generic_response_model.dart ' ;
import ' package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart ' ;
import ' package:mohem_flutter_app/ui/dialogs/id/business_card_dialog.dart ' ;
import ' package:mohem_flutter_app/ui/dialogs/id/employee_digital_id_dialog.dart ' ;
import ' package:mohem_flutter_app/widgets/button/default_button.dart ' ;
import ' package:mohem_flutter_app/widgets/dialogs/dialogs.dart ' ;
// WhatsApp 4
// SMS 1
// Face ID 3
// Finger Print 2
class VerifyLastLoginScreen extends StatefulWidget {
VerifyLastLoginScreen ( { Key ? key } ) : super ( key: key ) ;
@ override
_VerifyLastLoginScreenState createState ( ) {
return _VerifyLastLoginScreenState ( ) ;
}
}
class _VerifyLastLoginScreenState extends State < VerifyLastLoginScreen > {
final LocalAuthentication auth = LocalAuthentication ( ) ;
List < BiometricType > _availableBioMetricType = [ ] ;
GetMobileLoginInfoListModel ? mobileLoginInfoListModel ;
//For face and finger print verification
int selectedFlag = 0 ;
bool isNeedVerifyWithFaceIDAndBiometrics = false ;
@ override
void initState ( ) {
_getAvailableBiometrics ( ) ;
// setDefault();
super . initState ( ) ;
}
@ override
Widget build ( BuildContext context ) {
mobileLoginInfoListModel ? ? = ModalRoute . of ( context ) ! . settings . arguments as GetMobileLoginInfoListModel ;
// String empName = AppState().isArabic(context) ? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr! : AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!;
String empName = mobileLoginInfoListModel ! . employeeName ! ;
return Scaffold (
appBar: AppBar (
backgroundColor: Colors . transparent ,
automaticallyImplyLeading: false ,
title: ( mobileLoginInfoListModel ? . businessCardPrivilege ? ? false )
? LocaleKeys . viewBusinessCard . tr ( ) . toText12 ( color: MyColors . textMixColor , isUnderLine: true ) . onPress ( ( ) {
showMDialog ( context , child: BusinessCardDialog ( ) ) ;
} )
: Container ( ) ,
actions: [
Center (
child: LocaleKeys . employeeDigitalID . tr ( ) . toText12 ( color: MyColors . textMixColor , isUnderLine: true ) . onPress ( ( ) {
showMDialog ( context , child: EmployeeDigitialIdDialog ( ) ) ;
} ) ) ,
21. width
] ,
) ,
body: Column (
children: [
ListView (
padding: const EdgeInsets . all ( 21 ) ,
physics: const BouncingScrollPhysics ( ) ,
children: [
//12.height,
if ( true )
Column (
mainAxisSize: MainAxisSize . min ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
LocaleKeys . welcomeBack . tr ( ) . toText12 ( ) ,
mobileLoginInfoListModel ! . employeeName ! . toText24 ( isBold: true ) ,
10. height ,
LocaleKeys . wouldYouLikeToLoginWithCurrentUsername . tr ( ) . toText16 ( ) ,
Container (
height: 72 ,
margin: const EdgeInsets . only ( top: 23 , bottom: 23 ) ,
alignment: Alignment . center ,
padding: const EdgeInsets . only ( left: 17 , right: 12 ) ,
decoration: BoxDecoration (
borderRadius: BorderRadius . circular ( 10 ) ,
color: Colors . white ,
border: Border . all (
color: const Color ( 0xffefefef ) ,
width: 1 ,
) ,
) ,
child: Column (
mainAxisSize: MainAxisSize . min ,
children: [
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
crossAxisAlignment: CrossAxisAlignment . center ,
children: [
LocaleKeys . lastLoginDetails . tr ( ) . toText16 ( ) ,
DateUtil . formatDateToDate ( DateUtil . convertStringToDate ( mobileLoginInfoListModel ! . editedOn ! ) , false ) . toText12 ( ) ,
] ,
) ,
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
crossAxisAlignment: CrossAxisAlignment . center ,
children: [
LocaleKeys . verificationType . tr ( ) . toText10 ( color: MyColors . grey57Color ) ,
getVerificationType ( mobileLoginInfoListModel ! . loginType ! ) . toText12 ( ) ,
Expanded ( child: SizedBox ( ) ) ,
DateUtil . formatDateToTime ( DateUtil . convertStringToDate ( mobileLoginInfoListModel ! . editedOn ! ) ) . toText12 ( ) ,
] ,
)
] ,
) ,
) ,
LocaleKeys . pleaseVerify . tr ( ) . toText16 ( ) ,
if ( isNeedVerifyWithFaceIDAndBiometrics ) LocaleKeys . pleaseVerifyForBio . tr ( ) . toText12 ( ) ,
GridView (
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount ( crossAxisCount: 2 , crossAxisSpacing: 13 , mainAxisSpacing: 9 ) ,
physics: const NeverScrollableScrollPhysics ( ) ,
padding: const EdgeInsets . only ( top: 9 ) ,
shrinkWrap: true ,
children: [
if ( ! isNeedVerifyWithFaceIDAndBiometrics ) getButton ( 3 ) ,
if ( ! isNeedVerifyWithFaceIDAndBiometrics ) getButton ( 4 ) ,
getButton ( 2 ) ,
getButton ( 1 ) ,
] ,
)
] ,
)
// else
// Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
// Image.asset(
// 'assets/images/habib-logo.png',
// height: 90,
// width: 90,
// ),
// SizedBox(height: 23),
// this.onlySMSBox == false
// ? Text(
// TranslationBase.of(context).verifyLoginWith,
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16),
// )
// : Text(
// TranslationBase.of(context).verifyFingerprint2,
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 25 / 16),
// ),
// SizedBox(height: 23),
// Text(
// TranslationBase.of(context).pleaseVerify,
// style: TextStyle(fontSize: 16, 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: [
// if (onlySMSBox == false) getButton(3),
// if (onlySMSBox == false) getButton(2),
// getButton(1),
// getButton(4),
// ],
// ),
// ]),
] ,
) . expanded ,
DefaultButton (
LocaleKeys . useAnotherAccount . tr ( ) ,
( ) {
Navigator . pushNamedAndRemoveUntil ( context , AppRoutes . login , ( Route < dynamic > route ) = > false , arguments: false ) ;
} ,
) . insideContainer ,
] ,
) ,
) ;
}
Future < void > _getAvailableBiometrics ( ) async {
try {
_availableBioMetricType = await auth . getAvailableBiometrics ( ) ;
} on PlatformException catch ( e ) {
// AppToast.showErrorToast(message: e.message);
print ( e ) ;
}
if ( mounted ) setState ( ( ) { } ) ;
}
String getVerificationType ( int type ) {
if ( type = = 1 ) {
return LocaleKeys . sms . tr ( ) ;
} else if ( type = = 2 ) {
return LocaleKeys . whatsapp . tr ( ) ;
} else if ( type = = 3 ) {
return LocaleKeys . face . tr ( ) ;
} else if ( type = = 4 ) {
return LocaleKeys . fingerPrint . tr ( ) ;
}
return " " ;
}
Future < bool > loginWithFaceIDAndBiometrics ( ) async {
IOSAuthMessages iosStrings =
const IOSAuthMessages ( cancelButton: ' cancel ' , goToSettingsButton: ' settings ' , goToSettingsDescription: ' Please set up your Touch ID. ' , lockOut: ' Please reenable your Touch ID ' ) ;
bool authenticated = false ;
try {
authenticated = await auth . authenticate ( localizedReason: ' Scan your fingerprint to authenticate ' , useErrorDialogs: true , stickyAuth: true , biometricOnly: true , iOSAuthStrings: iosStrings ) ;
} on PlatformException catch ( e ) {
print ( e ) ;
Utils . hideLoading ( context ) ;
Utils . showToast ( " Please enable your Touch or Face ID " ) ;
}
return authenticated ;
}
Widget _loginOptionButton ( String _title , String _icon , int _flag , int ? _loginIndex ) {
bool isDisable = ( ( _flag = = 3 & & ! checkBiometricIsAvailable ( BiometricType . face ) ) | | ( _flag = = 4 & & ! checkBiometricIsAvailable ( BiometricType . fingerprint ) ) ) ;
return InkWell (
onTap: isDisable
? null
: ( ) async {
if ( _flag = = 0 ) {
setState ( ( ) {
// isMoreOption = true;
} ) ;
} else {
if ( _flag = = 3 | | _flag = = 4 ) {
bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics ( ) ;
if ( ! authenticateWithFaceAndTouchID ) {
return ;
} else {
if ( mobileLoginInfoListModel ! . loginType = = 3 | | mobileLoginInfoListModel ! . loginType = = 4 ) {
// bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics();
// if (!authenticateWithFaceAndTouchID) {
// return;
// } else {
// performApiCall(_title, _icon, _flag, isDirectLogin: true);
// }
performApiCall ( _title , _icon , _flag , _flag , isDirectLogin: true ) ;
} else {
isNeedVerifyWithFaceIDAndBiometrics = true ;
selectedFlag = _flag ;
setState ( ( ) {
return ;
} ) ;
}
}
} else {
if ( isNeedVerifyWithFaceIDAndBiometrics )
performApiCall ( _title , _icon , selectedFlag , _flag ) ;
else
performApiCall ( _title , _icon , _flag , _flag ) ;
}
}
} ,
child: Container (
padding: const EdgeInsets . only ( left: 20 , right: 20 , bottom: 15 , top: 28 ) ,
decoration: BoxDecoration (
borderRadius: BorderRadius . circular ( 15 ) ,
color: isDisable ? Colors . grey . withOpacity ( 0.3 ) : Colors . white ,
border: Border . all ( color: MyColors . lightGreyEFColor , width: 1 ) ,
) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: < Widget > [
SvgPicture . asset (
_icon ,
height: 38 ,
width: 38 ,
color: isDisable ? MyColors . darkTextColor . withOpacity ( 0.7 ) : null ,
) ,
_title . toText16 ( height: 20 / 16 )
] ,
) ,
) ,
) ;
}
Widget getButton ( int flag ) {
switch ( flag ) {
case 1 :
return _loginOptionButton ( LocaleKeys . verifyThroughSMS . tr ( ) , ' assets/images/login/verify_sms.svg ' , flag , null ) ;
case 2 :
return _loginOptionButton ( LocaleKeys . verifyThroughWhatsapp . tr ( ) , ' assets/images/login/verify_whatsapp.svg ' , flag , null ) ;
case 3 :
return _loginOptionButton ( LocaleKeys . verifyThroughFace . tr ( ) , ' assets/images/login/verify_face.svg ' , flag , BiometricType . face . index ) ;
case 4 :
return _loginOptionButton ( LocaleKeys . verifyThroughFingerprint . tr ( ) , ' assets/images/login/verify_thumb.svg ' , flag , BiometricType . fingerprint . index ) ;
default :
return const SizedBox ( ) ;
}
}
bool checkBiometricIsAvailable ( BiometricType biometricType ) {
bool isAvailable = false ;
for ( int i = 0 ; i < _availableBioMetricType . length ; i + + ) {
if ( biometricType = = _availableBioMetricType [ i ] ) {
isAvailable = true ;
break ;
}
}
return isAvailable ;
}
Future < void > performApiCall ( String _title , String _icon , int _flag , int sendVerificationFlat , { bool isDirectLogin = false } ) async {
try {
if ( isDirectLogin ) {
setState ( ( ) {
Utils . showLoading ( context ) ;
} ) ;
} else {
Utils . showLoading ( context ) ;
}
await LoginApiClient ( ) . checkMobileAppVersion ( ) ;
await LoginApiClient ( ) . memberLogin ( AppState ( ) . getUserName ! , AppState ( ) . password ! ) ;
if ( ! isDirectLogin ) {
BasicMemberInformationModel ? memberInformationModel =
await LoginApiClient ( ) . mohemmSendActivationCodeByOTPNotificationType ( 0 , AppState ( ) . memberLoginList ? . pMOBILENUMBER , sendVerificationFlat , AppState ( ) . getUserName ) ;
}
if ( isDirectLogin ) performDirectApiCall ( _title , _icon , _flag , " " , null ) ;
if ( ! isDirectLogin ) Utils . hideLoading ( context ) ;
if ( ! isDirectLogin ) {
OtpDialog (
context ,
sendVerificationFlat ,
int . tryParse ( AppState ( ) . memberLoginList ? . pMOBILENUMBER ? ? " " ) ,
( value , TextEditingController _pinPutController ) async {
Utils . showLoading ( context ) ;
performDirectApiCall ( _title , _icon , _flag , value , _pinPutController ) ;
} ,
( ) = > {
Navigator . pop ( context ) ,
} ,
onResendCode: ( ) {
performApiCall ( _title , _icon , _flag , sendVerificationFlat , isDirectLogin: isDirectLogin ) ;
} ,
) . displayDialog ( context ) ;
}
} catch ( ex ) {
Utils . hideLoading ( context ) ;
Utils . handleException ( ex , context , null ) ;
}
}
Future < void > performDirectApiCall ( String _title , String _icon , int _flag , String value , TextEditingController ? _pinPutController , { bool isDirectLogin = false } ) async {
try {
GenericResponseModel ? genericResponseModel = await LoginApiClient ( ) . checkActivationCode ( true , AppState ( ) . memberLoginList ? . pMOBILENUMBER , value , AppState ( ) . getUserName ) ;
GenericResponseModel ? genericResponseModel1 = await LoginApiClient ( ) . insertMobileLoginInfoNEW (
AppState ( ) . memberLoginList ? . pEMAILADDRESS ? ? " " ,
genericResponseModel ? . pSESSIONID ? ? 0 ,
genericResponseModel ? . memberInformationList ! [ 0 ] . eMPLOYEENAME ? ? " " ,
_flag ,
AppState ( ) . memberLoginList ? . pMOBILENUMBER ? ? " " ,
AppState ( ) . getUserName ! ,
AppState ( ) . getIsHuawei ? AppState ( ) . getHuaweiPushToken : mobileLoginInfoListModel ! . deviceToken ! ,
Platform . isAndroid ? " android " : " ios " ) ;
AppState ( ) . setMemberInformationListModel = genericResponseModel ! . memberInformationList ? . first ;
AppState ( ) . setPrivilegeListModel = genericResponseModel ! . privilegeList ? ? [ ] ;
if ( genericResponseModel . errorMessage ! = null ) {
Utils . showToast ( genericResponseModel . errorMessage ? ? " " ) ;
// Navigator.pop(context);
}
Utils . hideLoading ( context ) ;
Navigator . pop ( context ) ;
Navigator . pushNamedAndRemoveUntil ( context , AppRoutes . dashboard , ( Route < dynamic > route ) = > false ) ;
} catch ( ex ) {
if ( _pinPutController ! = null ) {
_pinPutController . clear ( ) ;
otpFieldClear . value = " " ;
}
Utils . hideLoading ( context ) ;
Utils . handleException ( ex , context , null ) ;
}
}
//
// formatDate(date) {
// return date;
// return DateFormat('MMM dd, yyy, kk:mm').format(date);
// }
//
// showLoader(bool isTrue) {
// setState(() {
// // isLoading = isTrue;
// });
// }
}