import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/models/Authentication/send_activation_request.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; 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'; class ConfirmLogin extends StatefulWidget { @override _ConfirmLogin createState() => _ConfirmLogin(); } class _ConfirmLogin extends State { final LocalAuthentication auth = LocalAuthentication(); var _availableBiometrics; var sharedPref = new AppSharedPreferences(); bool authenticated; final authService = new AuthProvider(); PharmacyModuleViewModel pharmacyModuleViewModel = locator(); int mobileNumber; String errorMsg = ''; SelectDeviceIMEIRES user; bool isLoading = false; var registerd_data; bool isMoreOption = false; var zipCode; var patientOutSA; var loginTokenID; var loginType; var deviceToken; var lastLogin; int selectedOption; bool onlySMSBox = false; var userData; static BuildContext _context; static bool _loading; int fingrePrintBefore; AuthenticatedUserObject authenticatedUserObject = locator(); AppointmentRateViewModel appointmentRateViewModel = locator(); ProjectViewModel projectViewModel; ToDoCountProviderModel toDoProvider; @override void initState() { _getAvailableBiometrics(); setDefault(); super.initState(); } @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); toDoProvider = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).confirm, isShowAppBar: true, isShowDecPage: false, body: SingleChildScrollView( child: Container( padding: EdgeInsets.all(20), height: SizeConfig.realScreenHeight * .9, width: SizeConfig.realScreenWidth, child: Column( children: [ user != null && isMoreOption == false ? Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( 'assets/images/habib-logo.png', height: 90, width: 90, ), Texts( TranslationBase.of(context).welcomeBack + ' ' + user.name, fontSize: SizeConfig.textMultiplier * 3.5, ), SizedBox( height: 20, ), Texts( TranslationBase.of(context).accountInfo, fontSize: SizeConfig.textMultiplier * 2.5, ), SizedBox( height: 20, ), Card( color: Colors.grey[300], child: Row( children: [ Flexible( child: ListTile( title: Text( TranslationBase.of(context).lastLoginAt, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, ), subtitle: Text( user.editedOn != null ? formatDate( DateUtil.convertStringToDate( user.editedOn)) : user.createdOn != null ? 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), )) ], )), ], ) : Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ 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: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ 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: [ onlySMSBox == false ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded(child: getButton(3)), Expanded(child: getButton(2)) ], ) : SizedBox(), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded(child: getButton(1)), Expanded(child: getButton(4)) ], ), ]), Expanded( flex: 1, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ user != null ? Row( children: [ Expanded( child: DefaultButton( TranslationBase.of(context).useAnotherAccount, () => { Navigator.of(context).pushNamed( LOGIN_TYPE, ) }, )), ], ) : SizedBox(), ], ), ) ], ), ), ), ); } Future _getAvailableBiometrics() async { var availableBiometrics; try { availableBiometrics = await auth.getAvailableBiometrics(); } on PlatformException catch (e) { print(e); } if (!mounted) return; setState(() { _availableBiometrics = availableBiometrics; }); } authenticateUser(type, isActive) { GifLoaderDialogUtils.showMyDialog(context); if (type == 2 || type == 3) { fingrePrintBefore = type; } this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; switch (type) { case 1: this.loginWithSMS(type, isActive); break; case 2: this.loginWithFingurePrintFace(type, isActive); break; case 3: this.loginWithFingurePrintFace(type, isActive); break; case 4: this.loginWithSMS(type, isActive); break; default: break; } sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); } loginWithSMS(type, isActive) { //if (!el.disabled) { if (this.user != null && this.registerd_data == null) { this.checkUserAuthentication(type); } else { if (this.loginTokenID != null) { // Future.delayed(Duration(seconds: 1), () { this.sendActivationCode(type); // }); } else { this.checkUserAuthentication(type); } } } checkUserAuthentication(type) { showLoader(true); var req = getCommonRequest(type: type); req.logInTokenID = ""; var request = CheckPatientAuthenticationReq.fromJson(req.toJson()); sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); authService .checkPatientAuthentication(request) .then((value) => { GifLoaderDialogUtils.hideDialog(context), if (value['isSMSSent']) { sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), this.loginTokenID = value['LogInTokenID'], sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), // Future.delayed(Duration(seconds: 1), () { this.sendActivationCode(type) // }) } else { if (value['IsAuthenticated']) {this.checkActivationCode()} } }) .catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); }); } sendActivationCode(type) async { var request = this.getCommonRequest(type: type); request.sMSSignature = await SMSOTP.getSignature(); GifLoaderDialogUtils.showMyDialog(context); await this.authService.sendActivationCode(request).then((result) { GifLoaderDialogUtils.hideDialog(context); if (result != null && result['isSMSSent'] == true) { this.startSMSService(type); } }).catchError((r) { GifLoaderDialogUtils.hideDialog(context); }); } startSMSService(type) { new SMSOTP( context, type, this.mobileNumber, (value) { this.checkActivationCode(value: value); }, () => { Navigator.pop(context), print('Faild..'), }, ).displayDialog(context); } loginWithFingurePrintFace(type, 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'); try { 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()); } if (authenticated == true) { if (user != null && (user.logInType == 2 || user.logInType == 3)) { this.checkActivationCode(); } else { var request = this.getCommonRequest(type: type); this.getMobileInfo(request); } } } } getMobileInfo(request) { // GifLoaderDialogUtils.showMyDialog(context); this.authService.getLoginInfo(request).then((result) { GifLoaderDialogUtils.hideDialog(context); if (result['SMSLoginRequired'] == false) { this.loginTokenID = result.logInTokenID; this.patientOutSA = result.patientOutSA; // sms for register the biometric if (result.isSMSSent) { this.onlySMSBox = false; //this.button(); } else { checkActivationCode(); } } else { if (result['IsAuthenticated'] == true) { setState(() { isMoreOption = true; this.onlySMSBox = true; // this.fingrePrintBefore = true; }); } } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); }); } setDefault() async { 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.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 ? "971" : "966"; this.patientOutSA = this.registerd_data != null ? this.registerd_data.zipCode == "966" ? 0 : 1 : this.user.outSA; if (this.registerd_data != null) { this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); this.loginType = this.registerd_data.searchType; } this.deviceToken = await sharedPref.getString(PUSH_TOKEN); this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null ? await sharedPref.getInt(LAST_LOGIN) : user != null ? user.logInType : null; //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); } getCommonRequest({type}) { var request = SendActivationRequest(); request.patientMobileNumber = this.mobileNumber; request.mobileNo = '0' + this.mobileNumber.toString(); 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.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.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.isRegister = false; } request.deviceTypeID = request.searchType; return request; } checkActivationCode({value}) async { GifLoaderDialogUtils.showMyDialog(context); var request = this.getCommonRequest().toJson(); authService .checkActivationCode(request, value) .then((result) => { if (result is Map) { result = CheckActivationCode.fromJson(result), if (this.registerd_data != null && this.registerd_data.isRegister == true) { Navigator.of(context).pushNamed( REGISTER_INFO, ) } else { sharedPref.remove(FAMILY_FILE), result.list.isFamily = false, userData = result.list, // sharedPref.setString( // BLOOD_TYPE, result['PatientBloodType']), authenticatedUserObject.user = result.list, sharedPref.setObject(MAIN_USER, result.list), sharedPref.setObject(USER_PROFILE, result.list), loginTokenID = result.logInTokenID, sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), sharedPref.setString(TOKEN, result.authenticationTokenID), checkIfUserAgreedBefore(result), } } else { // Navigator.of(context).pop(), GifLoaderDialogUtils.hideDialog(context), Future.delayed(Duration(seconds: 1), () { AppToast.showErrorToast(message: result); }), } }) .catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); Future.delayed(Duration(seconds: 1), () { AppToast.showErrorToast(message: err); }); }); } checkIfUserAgreedBefore(CheckActivationCode result) { if (result.isNeedUserAgreement == true) { //move to agreement page. } else { insertIMEI(); } } insertIMEI() { authService .insertDeviceImei(selectedOption) .then((value) => {goToHome()}) .catchError((err) { print(err); }); } getToDoCount() { toDoProvider.setState(0, true); ClinicListService service = new ClinicListService(); service.getActiveAppointmentNo(context).then((res) { print(res['AppointmentActiveNumber']); if (res['MessageStatus'] == 1) { toDoProvider.setState(res['AppointmentActiveNumber'], true); } else {} }).catchError((err) { print(err); }); } goToHome() { authenticatedUserObject.isLogin = true; appointmentRateViewModel.isLogin = true; projectViewModel.isLogin = true; projectViewModel.user = authenticatedUserObject.user; Provider.of(context, listen: false) .setUser(authenticatedUserObject.user); getToDoCount(); pharmacyModuleViewModel.generatePharmacyToken().then((value) async { if (pharmacyModuleViewModel.error.isNotEmpty) await pharmacyModuleViewModel.createUser(); }); appointmentRateViewModel .getIsLastAppointmentRatedList() .then((value) => { getToDoCount(), // GifLoaderDialogUtils.hideDialog(context), if (appointmentRateViewModel.isHaveAppointmentNotRate) { Navigator.pushAndRemoveUntil( context, FadePage( page: RateAppointmentDoctor(), ), (r) => false) } else { Navigator.pushAndRemoveUntil( context, FadePage( page: LandingPage(), ), (r) => false) } }) .catchError((err) { print(err); //GifLoaderDialogUtils.hideDialog(context); }); // SMSOTP.showLoadingDialog(context, false), } loading(flag) { setState(() { isLoading = flag; }); } Widget getButton(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: [ 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) ], ), ))); 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: [ 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) ], ), ))); 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: [ 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) ], ), ))); 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: [ 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) ], ), ))); break; default: return InkWell( onTap: () => { setState(() { isMoreOption = true; }) }, 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(0, 0, 0, 5), child: Column( children: [ Image.asset( 'assets/images/login/more_icon.png', height: 45, width: SizeConfig.imageSizeMultiplier * 16, ), projectViewModel.isArabic ? SizedBox( height: 15, ) : SizedBox( height: 20, ), Texts(TranslationBase.of(context).moreVerification, fontSize: SizeConfig.textMultiplier * 1.8, textAlign: TextAlign.center, color: Colors.black) ], ), ))); } } getType(type, context) { switch (type) { case 1: return TranslationBase.of(context).verifySMS; break; case 2: return TranslationBase.of(context).verifyFingerprint; break; case 3: return TranslationBase.of(context).verifyFaceID; break; case 4: return TranslationBase.of(context).verifyWhatsApp; break; default: return TranslationBase.of(context).verifySMS; break; } } bool checkIfBiometricAvailable(BiometricType biometricType) { bool isAvailable = false; if (_availableBiometrics != null) { for (var i = 0; i < _availableBiometrics.length; i++) { if (biometricType == _availableBiometrics[i]) isAvailable = true; } } return isAvailable; } formatDate(date) { return DateFormat('MMM dd, yyy, kk:mm').format(date); } showLoader(bool isTrue) { setState(() { isLoading = isTrue; }); } }