import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/view_state.dart'; import 'package:doctor_app_flutter/core/service/authentication_service.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/landing_page.dart'; import 'package:doctor_app_flutter/utils/date-utils.dart'; import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart'; import 'package:doctor_app_flutter/widgets/auth/sms-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import '../../config/size_config.dart'; import '../../utils/dr_app_shared_pref.dart'; import '../../utils/utils.dart'; import '../../widgets/auth/verification_methods_list.dart'; import 'login_screen.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Utils helpers = Utils(); ///TODO Elham* check if this still in user or not class VerificationMethodsScreen extends StatefulWidget { final password; final isMoreOption; VerificationMethodsScreen({ this.password, this.isMoreOption = false, }); @override _VerificationMethodsScreenState createState() => _VerificationMethodsScreenState(); } class _VerificationMethodsScreenState extends State { late ProjectViewModel projectsProvider; bool isMoreOption = false; bool onlySMSBox = false; AuthMethodTypes? fingerPrintBefore; AuthMethodTypes? selectedOption; late AuthenticationViewModel authenticationViewModel; @override void initState() { this.isMoreOption = widget.isMoreOption; super.initState(); } @override Widget build(BuildContext context) { projectsProvider = Provider.of(context); authenticationViewModel = Provider.of(context); return AppScaffold( isShowAppBar: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SingleChildScrollView( child: Center( child: FractionallySizedBox( widthFactor: 0.9, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: SizeConfig.heightMultiplier! * (SizeConfig.isHeightVeryShort ? 6 : 4), ), if (authenticationViewModel.isFromLogin) InkWell( onTap: () { authenticationViewModel.setUnverified(false, isFromLogin: false); authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); }, child: Icon( Icons.arrow_back_ios, color: AppGlobal.appTextColor, )), Column( children: [ SizedBox( height: SizeConfig.heightMultiplier! * (SizeConfig.isHeightVeryShort ? 3 : 4), ), authenticationViewModel.user != null && authenticationViewModel.user!.logInTypeID != null && isMoreOption == false ? Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( TranslationBase.of(context).welcomeBack, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, fontWeight: FontWeight.w600, color: AppGlobal.appTextColor, letterSpacing: -0.72, ), AppText( Utils.convertToTitleCase(authenticationViewModel.user!.doctorName), fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 6, color: AppGlobal.appTextColor, fontWeight: FontWeight.bold, letterSpacing: -1.44, ), SizedBox( height: SizeConfig.heightMultiplier! * 4, ), AppText( TranslationBase.of(context).accountInfo, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.5, color: Color(0xFF2E303A), fontWeight: FontWeight.w600, letterSpacing: -0.64, ), SizedBox(height: SizeConfig.heightMultiplier! * 4), Container( padding: EdgeInsets.all(15), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all( Radius.circular(10), ), border: Border.all(color: HexColor('#707070'), width: 0.1), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: SizeConfig.realScreenWidth! * .5, padding: EdgeInsets.all(0), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( TranslationBase.of(context).lastLoginAt, overflow: TextOverflow.ellipsis, style: TextStyle( fontFamily: 'Poppins', fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.5, color: Color(0xFF2E303A), fontWeight: FontWeight.w600, letterSpacing: -0.4), ), Container( width: MediaQuery.of(context).size.width * 0.55, child: RichText( text: TextSpan( text: TranslationBase.of(context).verifyWith + ':', style: TextStyle( color: Color(0xFF575757), fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, fontFamily: 'Poppins', fontWeight: FontWeight.w600, letterSpacing: -0.4), children: [ TextSpan( text: authenticationViewModel.getType(authenticationViewModel.user!.logInTypeID, context), style: TextStyle( color: AppGlobal.appTextColor, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, fontFamily: 'Poppins', fontWeight: FontWeight.w600, letterSpacing: -0.48), ) ]), ), ), ], crossAxisAlignment: CrossAxisAlignment.start, ), ), Column( mainAxisAlignment: MainAxisAlignment.start, children: [ AppText( authenticationViewModel.user!.editedOn != null ? AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(authenticationViewModel.user!.editedOn!), isMonthShort: true) : authenticationViewModel.user!.createdOn != null ? AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.convertStringToDate(authenticationViewModel.user!.createdOn!), isMonthShort: true) : '--', textAlign: TextAlign.right, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.5, color: Color(0xFF2E303A), fontWeight: FontWeight.w700, letterSpacing: -0.48, ), AppText( authenticationViewModel.user!.editedOn != null ? AppDateUtils.getHour(AppDateUtils.convertStringToDate(authenticationViewModel.user!.editedOn!)) : authenticationViewModel.user!.createdOn != null ? AppDateUtils.getHour(AppDateUtils.convertStringToDate(authenticationViewModel.user!.createdOn!)) : '--', textAlign: TextAlign.right, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3.5, fontWeight: FontWeight.w600, letterSpacing: -0.48, color: Color(0xFF575757), ) ], crossAxisAlignment: CrossAxisAlignment.end, ) ], ), ), SizedBox( height: SizeConfig.heightMultiplier! * 3, ), Row( children: [ //todo add translation AppText( "Please Verify", fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4.5, color: AppGlobal.appTextColor, fontWeight: FontWeight.w600, letterSpacing: -.64, ), ], ), SizedBox( height: SizeConfig.heightMultiplier! * 2, ), ], ) : Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ this.onlySMSBox == false ? Container( margin: EdgeInsets.only(bottom: 20, top: 30), child: AppText( TranslationBase.of(context).verifyLoginWith, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4, color: Color(0xFF2E303A), fontWeight: FontWeight.bold, textAlign: TextAlign.left, ), ) : AppText( TranslationBase.of(context).verifyFingerprint2, fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 4, textAlign: TextAlign.start, ), ]), authenticationViewModel.user != null && authenticationViewModel.user!.logInTypeID != null && isMoreOption == false ? Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: InkWell( onTap: () => { print("Fingerprint"), // TODO check this logic it seem it will create bug to us authenticateUser(AuthMethodTypes.Fingerprint, true) }, child: VerificationMethodsList( authenticationViewModel: authenticationViewModel, authMethodType: SelectedAuthMethodTypesService.getMethodsTypeService(authenticationViewModel.user!.logInTypeID!), authenticateUser: (AuthMethodTypes authMethodType, isActive) => authenticateUser(authMethodType, isActive), onShowMore: () {}, )), ), Expanded( child: VerificationMethodsList( authenticationViewModel: authenticationViewModel, authMethodType: AuthMethodTypes.MoreOptions, onShowMore: () { setState(() { isMoreOption = true; }); }, )) ]), ]) : Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ onlySMSBox == false ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: VerificationMethodsList( authenticationViewModel: authenticationViewModel, authMethodType: AuthMethodTypes.Fingerprint, authenticateUser: (AuthMethodTypes authMethodType, isActive) => authenticateUser(authMethodType, isActive), onShowMore: () {}, )), Expanded( child: VerificationMethodsList( authenticationViewModel: authenticationViewModel, authMethodType: AuthMethodTypes.FaceID, authenticateUser: (AuthMethodTypes authMethodType, isActive) => authenticateUser(authMethodType, isActive), onShowMore: () {}, )) ], ) : SizedBox(), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: VerificationMethodsList( authenticationViewModel: authenticationViewModel, authMethodType: AuthMethodTypes.SMS, authenticateUser: (AuthMethodTypes authMethodType, isActive) => authenticateUser(authMethodType, isActive), onShowMore: () {}, )), Expanded( child: VerificationMethodsList( authenticationViewModel: authenticationViewModel, authMethodType: AuthMethodTypes.WhatsApp, authenticateUser: (AuthMethodTypes authMethodType, isActive) => authenticateUser(authMethodType, isActive), onShowMore: () {}, )) ], ), ]), // ) ], ), ], ), ), ), ), ), bottomSheet: authenticationViewModel.user == null ? SizedBox( height: 0, ) : Container( height: 90, width: double.infinity, child: Center( child: FractionallySizedBox( widthFactor: 0.9, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ AppButton( title: TranslationBase.of(context).useAnotherAccount ?? '', color: Color(0xFFD02127), //fontWeight: FontWeight.w700, onPressed: () { authenticationViewModel.deleteUser(); // authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => LoginScreen()), ); }, ), SizedBox( height: 25, ) ], ), ), ), ), ); } sendActivationCodeByOtpNotificationType(AuthMethodTypes authMethodType) async { if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.showMyDialog(context); await authenticationViewModel.sendActivationCodeForDoctorApp(authMethodType: authMethodType, password: authenticationViewModel.userInfo.password!); if (authenticationViewModel.state == ViewState.ErrorLocal) { Utils.showErrorToast(authenticationViewModel.error); GifLoaderDialogUtils.hideDialog(context); } else { GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType); } } else { // TODO route to this page with parameters to inicate we should present 2 option if (Platform.isAndroid && authMethodType == AuthMethodTypes.Fingerprint) { Utils.showErrorToast('Your device not support this feature'); } else {} } } sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { GifLoaderDialogUtils.showMyDialog(context); await authenticationViewModel.sendActivationCodeVerificationScreen(authMethodType); if (authenticationViewModel.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); Utils.showErrorToast(authenticationViewModel.error); } else { await sharedPref.setString(TOKEN, authenticationViewModel.activationCodeVerificationScreenRes.logInTokenID!); if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.hideDialog(context); this.startSMSService(authMethodType, isSilentLogin: true); } else { checkActivationCode(isSilentLogin: true); } } } authenticateUser(AuthMethodTypes authMethodType, isActive) { if (authMethodType == AuthMethodTypes.Fingerprint || authMethodType == AuthMethodTypes.FaceID) { fingerPrintBefore = authMethodType; } this.selectedOption = fingerPrintBefore != null ? fingerPrintBefore : authMethodType; switch (authMethodType) { case AuthMethodTypes.SMS: sendActivationCode(authMethodType); break; case AuthMethodTypes.WhatsApp: sendActivationCode(authMethodType); break; case AuthMethodTypes.Fingerprint: this.loginWithFingerPrintOrFaceID(AuthMethodTypes.Fingerprint, isActive); break; case AuthMethodTypes.FaceID: this.loginWithFingerPrintOrFaceID(AuthMethodTypes.FaceID, isActive); break; default: break; } sharedPref.setInt(OTP_TYPE, selectedOption!.getTypeIdService()); } sendActivationCode(AuthMethodTypes authMethodType) async { if (authenticationViewModel.user != null && authenticationViewModel.user!.logInTypeID != null) { sendActivationCodeVerificationScreen(authMethodType); } else { sendActivationCodeByOtpNotificationType(authMethodType); } } startSMSService(AuthMethodTypes type, {isSilentLogin = false}) { new SMSOTP( context, type, authenticationViewModel.loggedUser != null ? authenticationViewModel.loggedUser!.mobileNumber : authenticationViewModel.user!.mobile, (value) { showDialog( context: context, builder: (BuildContext context) { return AppLoaderWidget(); }); this.checkActivationCode(value: value, isSilentLogin: isSilentLogin); }, () => { print('Faild..'), }, ).displayDialog(context); } loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { if (isActive) { await authenticationViewModel.showIOSAuthMessages(); if (!mounted) return; if (authenticationViewModel.user != null && authenticationViewModel.user!.logInTypeID !=null && (SelectedAuthMethodTypesService.getMethodsTypeService(authenticationViewModel.user!.logInTypeID!) == AuthMethodTypes.Fingerprint || SelectedAuthMethodTypesService.getMethodsTypeService(authenticationViewModel.user!.logInTypeID!) == AuthMethodTypes.FaceID)) { this.sendActivationCode(authMethodTypes); } else { setState(() { this.onlySMSBox = true; }); } } } checkActivationCode({String? value, bool isSilentLogin = false}) async { await authenticationViewModel.checkActivationCodeForDoctorApp(activationCode: value, isSilentLogin: isSilentLogin); if (authenticationViewModel.state == ViewState.ErrorLocal) { Navigator.pop(context); Utils.showErrorToast(authenticationViewModel.error); if (authenticationViewModel.errorCode == '699') { Navigator.pop(context); authenticationViewModel.deleteUser(); authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); } } else { await authenticationViewModel.onCheckActivationCodeSuccess(); if (value != null) { if (Navigator.canPop(context)) Navigator.pop(context); } if (Navigator.canPop(context)) Navigator.pop(context); navigateToLandingPage(); } } navigateToLandingPage() { if (authenticationViewModel.state == ViewState.ErrorLocal) { Utils.showErrorToast(authenticationViewModel.error); } else { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (BuildContext context) => LandingPage( // password: authenticationViewModel.userInfo.password, // isMoreOption: true, // isFromLogin: true, ), ), ); // authenticationViewModel.setAppStatus(APP_STATUS.AUTHENTICATED); } } }