diff --git a/lib/config/config.dart b/lib/config/config.dart index b21ee8ed..ec8efe26 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -337,7 +337,7 @@ const TRANSACTION_NO = 0; const LANGUAGE_ID = 2; const STAMP = '2020-04-27T12:17:17.721Z'; const IP_ADDRESS = '9.9.9.9'; -const VERSION_ID = 5.9; +const VERSION_ID = 6.0; const CHANNEL = 9; const SESSION_ID = 'BlUSkYymTt'; const IS_LOGIN_FOR_DOCTOR_APP = true; diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index 54a06c04..474b91fe 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -13,6 +13,8 @@ import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/user_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:intl/intl.dart'; class AuthenticationViewModel extends BaseViewModel { AuthenticationService _authService = locator(); @@ -25,6 +27,8 @@ class AuthenticationViewModel extends BaseViewModel { get activationCodeForDoctorAppRes => _authService.activationCodeForDoctorAppRes; get checkActivationCodeForDoctorAppRes => _authService.checkActivationCodeForDoctorAppRes; + var loggedUser; + GetIMEIDetailsModel user; Future selectDeviceImei(imei) async { setState(ViewState.Busy); await _authService.selectDeviceImei(imei); @@ -127,4 +131,56 @@ class AuthenticationViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + + + getDate(DateTime date) { + final DateFormat formatter = DateFormat('dd MMM yyyy'); + + return formatter.format(date); + } + + getTime(DateTime date) { + final DateFormat formatter = DateFormat('HH:mm a'); + + return formatter.format(date); + } + + + getType(type, context) { + switch (type) { + case 1: + return TranslationBase + .of(context) + .verifySMS; + break; + case 3: + return TranslationBase + .of(context) + .verifyFingerprint; + break; + case 4: + return TranslationBase + .of(context) + .verifyFaceID; + break; + case 2: + return TranslationBase.of(context).verifyWhatsApp; + break; + default: + return TranslationBase.of(context).verifySMS; + break; + } + } + + getInitUserInfo()async{ + setState(ViewState.Busy); + loggedUser = await sharedPref.getObj(LOGGED_IN_USER); + var lastLogin = await sharedPref.getObj(LAST_LOGIN_USER); + if (lastLogin != null) { + user = GetIMEIDetailsModel.fromJson(lastLogin); + } + setState(ViewState.Idle); + + } } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 3d44d726..e4d2603d 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -28,29 +28,15 @@ class _VerificationMethodsScreenState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) async {}, builder: (_, model, w) => AppScaffold( isLoading: _isLoading, isShowAppBar: false, isHomeIcon: false, backgroundColor: HexColor('#F8F8F8'), - body: ListView(children: [ - Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, - ), - VerificationMethods( - password: widget.password, - changeLoadingState: changeLoadingState, - model:model - ), - ], - ), - ), - ]))); + body:VerificationMethods( + password: widget.password, + changeLoadingState: changeLoadingState, + // model:model + ))); } } diff --git a/lib/widgets/auth/method_card.dart b/lib/widgets/auth/method_card.dart new file mode 100644 index 00000000..94bd261b --- /dev/null +++ b/lib/widgets/auth/method_card.dart @@ -0,0 +1,242 @@ +import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; + +class MethodCard extends StatefulWidget { + final AuthMethodTypes authMethodType; + final Function ( AuthMethodTypes type, bool isActive) authenticateUser; + final Function onShowMore; + + const MethodCard({Key key, this.authMethodType, this.authenticateUser, this.onShowMore}) : super(key: key); + + @override + _MethodCardState createState() => _MethodCardState(); +} + +class _MethodCardState extends State { + + var _availableBiometrics; + + final LocalAuthentication auth = LocalAuthentication(); + ProjectViewModel projectsProvider; + + + + @override + void initState() { + super.initState(); + _getAvailableBiometrics(); + } + + + 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; + } + + Future _getAvailableBiometrics() async { + var availableBiometrics; + try { + availableBiometrics = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + print(e); + } + if (!mounted) return; + + setState(() { + _availableBiometrics = availableBiometrics; + }); + } + @override + Widget build(BuildContext context) { + projectsProvider = Provider.of(context); + + switch (widget.authMethodType) { + case AuthMethodTypes.WhatsApp: + return InkWell( + onTap: () => {widget.authenticateUser(AuthMethodTypes.WhatsApp, true)}, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + 'assets/images/verify-whtsapp.png', + height: 60, + width: 60, + ), + ], + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifyWhatsApp, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + case AuthMethodTypes.SMS: + return InkWell( + onTap: () => {widget.authenticateUser(AuthMethodTypes.SMS, true)}, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/verify-sms.png', + height: 60, + width: 60, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifySMS, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + case AuthMethodTypes.Fingerprint: + return InkWell( + onTap: () => { + if (checkIfBiometricAvailable(BiometricType.fingerprint)) + {widget.authenticateUser(AuthMethodTypes.Fingerprint, true)} + }, + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/verification_fingerprint_icon.png', + height: 60, + width: 60, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifyFingerprint, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + case AuthMethodTypes.FaceID: + return InkWell( + onTap: () { + if (checkIfBiometricAvailable(BiometricType.face)) { + widget.authenticateUser(AuthMethodTypes.FaceID, true); + } + }, + child: + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + margin: EdgeInsets.all(10), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/verification_faceid_icon.png', + height: 60, + width: 60, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).verifyFaceID, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + break; + + default: + return InkWell( + onTap: widget.onShowMore, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Padding( + padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/login/more_icon.png', + height: 60, + width: 60, + ), + projectsProvider.isArabic + ? SizedBox( + height: 20, + ) + : SizedBox( + height: 10, + ), + AppText( + TranslationBase.of(context).moreVerification, + fontSize: 14, + fontWeight: FontWeight.w600, + ) + ], + ), + ))); + }; + } +} diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index 50674138..61329758 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -61,9 +61,6 @@ class SMSOTP { projectProvider = Provider.of(context); return AlertDialog( contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 0.0, 24.0), - - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.all(Radius.circular(10.0))), content: StatefulBuilder(builder: (context, setState) { if (displayTime == '') { startTimer(setState); diff --git a/lib/widgets/auth/verification_methods.dart b/lib/widgets/auth/verification_methods.dart index 6c7142c4..faadbf9e 100644 --- a/lib/widgets/auth/verification_methods.dart +++ b/lib/widgets/auth/verification_methods.dart @@ -7,22 +7,23 @@ import 'package:doctor_app_flutter/core/model/imei_details.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/models/auth/activation_Code_req_model.dart'; -import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_code_for_verification_screen_model.dart'; +import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/auth/sms-popup.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:doctor_app_flutter/widgets/transitions/fade_page.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'; @@ -33,30 +34,23 @@ import '../../landing_page.dart'; import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../util/helpers.dart'; -import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart'; +import 'method_card.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); class VerificationMethods extends StatefulWidget { - VerificationMethods({this.changeLoadingState, this.password, this.model}); + VerificationMethods({this.changeLoadingState, this.password}); final password; final Function changeLoadingState; - final AuthenticationViewModel model; @override _VerificationMethodsState createState() => _VerificationMethodsState(); } class _VerificationMethodsState extends State { - MainAxisAlignment spaceBetweenMethods = MainAxisAlignment.spaceBetween; - Future _loggedUserFuture; - var _loggedUser; - var verificationMethod; - GetIMEIDetailsModel user; - final LocalAuthentication auth = LocalAuthentication(); - var _availableBiometrics; + ProjectViewModel projectsProvider; bool isMoreOption = false; bool onlySMSBox = false; @@ -65,564 +59,404 @@ class _VerificationMethodsState extends State { bool authenticated; - AuthMethodTypes fingrePrintBefore; + AuthMethodTypes fingerPrintBefore; AuthMethodTypes selectedOption; + AuthenticationViewModel model; + + final LocalAuthentication auth = LocalAuthentication(); @override void initState() { super.initState(); - _loggedUserFuture = getSharedPref(); - _getAvailableBiometrics(); - } - - Future getSharedPref() async { - sharedPref.getObj(LOGGED_IN_USER).then((userInfo) { - _loggedUser = userInfo; - }); - sharedPref.getObj(LAST_LOGIN_USER).then((lastLogin) { - if (lastLogin != null) { - user = GetIMEIDetailsModel.fromJson(lastLogin); - } - }); - - print(user); } + @override - void didChangeDependencies() { + void didChangeDependencies() async{ super.didChangeDependencies(); - final routeArgs = ModalRoute.of(context).settings.arguments as Map; - verificationMethod = - routeArgs != null ? routeArgs['verificationMethod'] : null; + } @override Widget build(BuildContext context) { doctorProfileViewModel = Provider.of(context); projectsProvider = Provider.of(context); - return FutureBuilder( - future: Future.wait([_loggedUserFuture]), - builder: (BuildContext context, AsyncSnapshot snapshot) { - switch (snapshot.connectionState) { - case ConnectionState.waiting: - return DrAppCircularProgressIndeicator(); - default: - if (snapshot.hasError) { - Helpers.showErrorToast('Error: ${snapshot.error}'); - return Text('Error: ${snapshot.error}'); - } else { - return SingleChildScrollView( - child: Container( - height: SizeConfig.realScreenHeight * .87, - width: SizeConfig.realScreenWidth, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - child: Column( - children: [ - user != null && isMoreOption == false - ? Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText(TranslationBase.of(context) - .welcomeBack), - AppText( - Helpers.capitalize(user.doctorName), - fontSize: - SizeConfig.textMultiplier * 3.5, - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).accountInfo, - fontSize: - SizeConfig.textMultiplier * 2.5, - fontWeight: FontWeight.w600, - ), - SizedBox( - height: 20, - ), - Card( - color: Colors.white, - child: Row( - children: [ - Flexible( - flex: 3, - child: ListTile( - title: Text( - TranslationBase.of( - context) - .lastLoginAt, - overflow: TextOverflow - .ellipsis, - style: TextStyle( - fontFamily: - 'Poppins', - fontWeight: - FontWeight.w800, - fontSize: 14), - ), - subtitle: AppText( - getType( - user.logInTypeID, - context), - fontSize: 14, - ))), - Flexible( - flex: 2, - child: ListTile( - title: AppText( - user.editedOn != null - ? getDate(DateUtils + return BaseView( + onModelReady: (model) async { + this.model = model; + await model.getInitUserInfo(); + }, + builder: (_, model, w) => AppScaffold( + isShowAppBar: false, + baseViewModel: model, + body: SingleChildScrollView( + child: Center( + child: FractionallySizedBox( + // widthFactor: 0.9, + child: Container( + margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), + + height: SizeConfig.realScreenHeight * .95, + width: SizeConfig.realScreenWidth, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + child: Column( + + children: [ + SizedBox( + height: 100, + ), + model.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).welcomeBack), + AppText( + Helpers.capitalize(model.user.doctorName), + fontSize: SizeConfig.textMultiplier * 3.5, + fontWeight: FontWeight.bold, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context).accountInfo, + fontSize: SizeConfig.textMultiplier * 2.5, + fontWeight: FontWeight.w600, + ), + SizedBox( + height: 20, + ), + Card( + color: Colors.white, + child: Row( + children: [ + Flexible( + flex: 3, + child: ListTile( + title: Text( + TranslationBase.of(context) + .lastLoginAt, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + fontFamily: 'Poppins', + fontWeight: + FontWeight.w800, + fontSize: 14), + ), + subtitle: AppText( + model.getType( + model.user.logInTypeID, + context), + fontSize: 14, + ))), + Flexible( + flex: 2, + child: ListTile( + title: AppText( + model.user.editedOn != null + ? model.getDate( + DateUtils .convertStringToDate( - user + model.user .editedOn)) - : user.createdOn != - null - ? getDate(DateUtils + : model.user.createdOn != null + ? model + .getDate(DateUtils .convertStringToDate( - user.createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - fontWeight: - FontWeight.w800, - ), - subtitle: AppText( - user.editedOn != null - ? getTime(DateUtils + model.user.createdOn)) + : '--', + textAlign: TextAlign.right, + fontSize: 14, + fontWeight: FontWeight.w800, + ), + subtitle: AppText( + model.user.editedOn != null + ? model.getTime( + DateUtils .convertStringToDate( - user + model.user .editedOn)) - : user.createdOn != - null - ? getTime(DateUtils + : model.user.createdOn != null + ? model + .getTime(DateUtils .convertStringToDate( - user.createdOn)) - : '--', - textAlign: - TextAlign.right, - fontSize: 14, - ), - )) - ], - )), - ], - ) - : Column( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - this.onlySMSBox == false - ? AppText( - TranslationBase.of(context) - .verifyLoginWith, - fontSize: - SizeConfig.textMultiplier * - 3.5, - textAlign: TextAlign.left, - ) - : AppText( - 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( + model.user.createdOn)) + : '--', + textAlign: TextAlign.right, + fontSize: 14, + ), + )) + ], + )), + ], + ) + : Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + this.onlySMSBox == false + ? AppText( + TranslationBase.of(context) + .verifyLoginWith, + fontSize: + SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ) + : AppText( + TranslationBase.of(context) + .verifyFingerprint2, + fontSize: + SizeConfig.textMultiplier * 2.5, + textAlign: TextAlign.start, + ), + ]), + model.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => { + // TODO check this logic it seem it will create bug to us + + authenticateUser( + AuthMethodTypes + .Fingerprint, + true) + }, + child: MethodCard( + authMethodType: model.user + .logInTypeID == + 4 + ? AuthMethodTypes.FaceID + : model.user.logInTypeID == 2 + ? AuthMethodTypes + .WhatsApp + : model.user.logInTypeID == + 3 + ? AuthMethodTypes + .Fingerprint + : AuthMethodTypes + .SMS, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + ), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.MoreOptions, + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + )) + ]), + ]) + : Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + onlySMSBox == false + ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( - child: InkWell( - onTap: () => { - // TODO check this logic it seem it will create bug to us - - authenticateUser(AuthMethodTypes.Fingerprint, - true) - }, - child: methodCard( - user.logInTypeID == 4 ?AuthMethodTypes.FaceID:user.logInTypeID == 2?AuthMethodTypes.WhatsApp:user.logInTypeID ==3? AuthMethodTypes.Fingerprint:AuthMethodTypes.SMS - ))), + child: MethodCard( + authMethodType: + AuthMethodTypes.Fingerprint, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), Expanded( - child: methodCard(AuthMethodTypes.MoreOptions)) - ]), - ]) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - onlySMSBox == false - ? Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: methodCard( - AuthMethodTypes.Fingerprint)), - Expanded( - child: methodCard( - AuthMethodTypes.FaceID)) - ], - ) - : SizedBox(), - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Expanded( - child: methodCard(AuthMethodTypes.SMS)), - Expanded( - child: methodCard(AuthMethodTypes.WhatsApp)) - ], - ), - ]), - - // ) - ], - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - user != null - ? Row( - children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context) - .useAnotherAccount, - color: Colors.red[700], - onPressed: () { - Navigator.of(context).pushNamed(LOGIN); - }, - )), - ], - ) - : SizedBox(), - ], - ), + child: MethodCard( + authMethodType: + AuthMethodTypes.FaceID, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )) + ], + ) + : SizedBox(), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: MethodCard( + authMethodType: AuthMethodTypes.SMS, + authenticateUser: + (AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )), + Expanded( + child: MethodCard( + authMethodType: + AuthMethodTypes.WhatsApp, + authenticateUser: + (AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )) + ], + ), + ]), + + // ) + ], + ), + ), + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + model.user != null + ? Row( + children: [ + Expanded( + child: AppButton( + title: TranslationBase.of(context) + .useAnotherAccount, + color: Colors.red[700], + onPressed: () { + Navigator.of(context).pushNamed(LOGIN); + }, + )), + ], + ) + : SizedBox(), ], ), - )); - } - } - }); + ], + ), + ), + ), + ), + ), + )); } - + sendActivationCodeByOtpNotificationType( AuthMethodTypes authMethodType) async { - if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { + if (authMethodType == AuthMethodTypes.SMS || + authMethodType == AuthMethodTypes.WhatsApp) { GifLoaderDialogUtils.showMyDialog(context); int projectID = await sharedPref.getInt(PROJECT_ID); - // TODO create model for _loggedUser; + // TODO create model for model.loggedUser; ActivationCodeModel activationCodeModel = ActivationCodeModel( facilityId: projectID, - memberID: _loggedUser['List_MemberInformation'][0]['MemberID'], - zipCode: _loggedUser['ZipCode'], - mobileNumber: _loggedUser['MobileNumber'], + memberID: model.loggedUser['List_MemberInformation'][0]['MemberID'], + zipCode: model.loggedUser['ZipCode'], + mobileNumber: model.loggedUser['MobileNumber'], otpSendType: authMethodType.getTypeIdService().toString(), password: widget.password); - await widget.model - .sendActivationCodeForDoctorApp(activationCodeModel); - if(widget.model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(widget.model.error); - GifLoaderDialogUtils.hideDialog(context); - }else{ - print("VerificationCode : " + widget.model.activationCodeForDoctorAppRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeForDoctorAppRes["LogInTokenID"]); - sharedPref.setString(PASSWORD, widget.password); - GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(authMethodType); - } + await model.sendActivationCodeForDoctorApp(activationCodeModel); + if (model.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(model.error); + GifLoaderDialogUtils.hideDialog(context); + } else { + print("VerificationCode : " + + model.activationCodeForDoctorAppRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + model.activationCodeForDoctorAppRes["VidaAuthTokenID"]); + sharedPref.setString(VIDA_REFRESH_TOKEN_ID, + model.activationCodeForDoctorAppRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, + model.activationCodeForDoctorAppRes["LogInTokenID"]); + sharedPref.setString(PASSWORD, widget.password); + 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) { Helpers.showErrorToast('Your device not support this feature'); - } else { - } + } else {} } } - sendActivationCodeVerificationScreen( - AuthMethodTypes authMethodType) async { + sendActivationCodeVerificationScreen(AuthMethodTypes authMethodType) async { GifLoaderDialogUtils.showMyDialog(context); - ActivationCodeForVerificationScreenModel activationCodeModel = ActivationCodeForVerificationScreenModel( - iMEI: user.iMEI, - facilityId: user.projectID, - memberID: user.doctorID, - zipCode: user.outSA == true ? '971' : '966', - mobileNumber: user.mobile, - oTPSendType: authMethodType ==AuthMethodTypes.FaceID?4:authMethodType ==AuthMethodTypes.Fingerprint?3:authMethodType ==AuthMethodTypes.WhatsApp?2:1, + ActivationCodeForVerificationScreenModel activationCodeModel = + ActivationCodeForVerificationScreenModel( + iMEI: model.user.iMEI, + facilityId: model.user.projectID, + memberID: model.user.doctorID, + zipCode: model.user.outSA == true ? '971' : '966', + mobileNumber: model.user.mobile, + oTPSendType: authMethodType.getTypeIdService(), isMobileFingerPrint: 1, - vidaAuthTokenID: user.vidaAuthTokenID, - vidaRefreshTokenID: user.vidaRefreshTokenID); + vidaAuthTokenID: model.user.vidaAuthTokenID, + vidaRefreshTokenID: model.user.vidaRefreshTokenID); - await widget.model + await model .sendActivationCodeVerificationScreen(activationCodeModel); - if(widget.model.state == ViewState.ErrorLocal) { + if (model.state == ViewState.ErrorLocal) { GifLoaderDialogUtils.hideDialog(context); - Helpers.showErrorToast(widget.model.error); + Helpers.showErrorToast(model.error); } else { - print("VerificationCode : " + widget.model.activationCodeVerificationScreenRes["VerificationCode"]); - sharedPref.setString(VIDA_AUTH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); - sharedPref.setString( - VIDA_REFRESH_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); - sharedPref.setString(LOGIN_TOKEN_ID, widget.model.activationCodeVerificationScreenRes["LogInTokenID"]); - if (authMethodType == AuthMethodTypes.SMS || authMethodType == AuthMethodTypes.WhatsApp) { - GifLoaderDialogUtils.hideDialog(context); - this.startSMSService(authMethodType); - } else { - checkActivationCode(); - } - } - } - - Widget methodCard(AuthMethodTypes authMethodType) { - switch (authMethodType) { - case AuthMethodTypes.WhatsApp: - return InkWell( - onTap: () => {authenticateUser(AuthMethodTypes.WhatsApp, true)}, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Image.asset( - 'assets/images/verify-whtsapp.png', - height: 60, - width: 60, - ), - ], - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyWhatsApp, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.SMS: - return InkWell( - onTap: () => {authenticateUser(AuthMethodTypes.SMS, true)}, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verify-sms.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifySMS, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.Fingerprint: - return InkWell( - onTap: () => { - if (checkIfBiometricAvailable(BiometricType.fingerprint)) - {authenticateUser(AuthMethodTypes.Fingerprint, true)} - }, - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verification_fingerprint_icon.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyFingerprint, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - case AuthMethodTypes.FaceID: - return InkWell( - onTap: () { - if (checkIfBiometricAvailable(BiometricType.face)) { - authenticateUser(AuthMethodTypes.FaceID, true); - } - }, - child: - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - margin: EdgeInsets.all(10), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/verification_faceid_icon.png', - height: 60, - width: 60, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).verifyFaceID, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - break; - - default: - return InkWell( - onTap: () => { - setState(() { - isMoreOption = true; - }) - }, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, - ), - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/login/more_icon.png', - height: 60, - width: 60, - ), - projectsProvider.isArabic - ? SizedBox( - height: 20, - ) - : SizedBox( - height: 10, - ), - AppText( - TranslationBase.of(context).moreVerification, - fontSize: 14, - fontWeight: FontWeight.w600, - ) - ], - ), - ))); - } - } - - getType(type, context) { - switch (type) { - case 1: - return TranslationBase.of(context).verifySMS; - break; - case 3: - return TranslationBase.of(context).verifyFingerprint; - break; - case 4: - return TranslationBase.of(context).verifyFaceID; - break; - case 2: - 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; + print("VerificationCode : " + + model.activationCodeVerificationScreenRes["VerificationCode"]); + sharedPref.setString(VIDA_AUTH_TOKEN_ID, + model.activationCodeVerificationScreenRes["VidaAuthTokenID"]); + sharedPref.setString( + VIDA_REFRESH_TOKEN_ID, + model.activationCodeVerificationScreenRes["VidaRefreshTokenID"]); + sharedPref.setString(LOGIN_TOKEN_ID, + model.activationCodeVerificationScreenRes["LogInTokenID"]); + if (authMethodType == AuthMethodTypes.SMS || + authMethodType == AuthMethodTypes.WhatsApp) { + GifLoaderDialogUtils.hideDialog(context); + this.startSMSService(authMethodType); + } else { + checkActivationCode(); } } - return isAvailable; } - - authenticateUser( AuthMethodTypes authMethodType, isActive) { - if (authMethodType == AuthMethodTypes.Fingerprint || authMethodType == AuthMethodTypes.FaceID) { - fingrePrintBefore = authMethodType; + authenticateUser(AuthMethodTypes authMethodType, isActive) { + if (authMethodType == AuthMethodTypes.Fingerprint || + authMethodType == AuthMethodTypes.FaceID) { + fingerPrintBefore = authMethodType; } - this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : authMethodType; + this.selectedOption = + fingerPrintBefore != null ? fingerPrintBefore : authMethodType; switch (authMethodType) { case AuthMethodTypes.SMS: @@ -632,7 +466,8 @@ class _VerificationMethodsState extends State { sendActivationCode(authMethodType); break; case AuthMethodTypes.Fingerprint: - this.loginWithFingerPrintOrFaceID(AuthMethodTypes.Fingerprint, isActive); + this.loginWithFingerPrintOrFaceID( + AuthMethodTypes.Fingerprint, isActive); break; case AuthMethodTypes.FaceID: this.loginWithFingerPrintOrFaceID(AuthMethodTypes.FaceID, isActive); @@ -643,23 +478,8 @@ class _VerificationMethodsState extends State { sharedPref.setInt(OTP_TYPE, selectedOption.getTypeIdService()); } - - Future _getAvailableBiometrics() async { - var availableBiometrics; - try { - availableBiometrics = await auth.getAvailableBiometrics(); - } on PlatformException catch (e) { - print(e); - } - if (!mounted) return; - - setState(() { - _availableBiometrics = availableBiometrics; - }); - } - sendActivationCode(AuthMethodTypes authMethodType) async { - if (user != null) { + if (model.user != null) { sendActivationCodeVerificationScreen(authMethodType); } else { sendActivationCodeByOtpNotificationType(authMethodType); @@ -667,10 +487,11 @@ class _VerificationMethodsState extends State { } startSMSService(AuthMethodTypes type) { + // TODO improve this logic new SMSOTP( context, type, - _loggedUser != null ? _loggedUser['MobileNumber'] : user.mobile, + model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, (value) { showDialog( context: context, @@ -682,14 +503,16 @@ class _VerificationMethodsState extends State { this.checkActivationCode(value: value); }, - () => { + () => + { widget.changeLoadingState(false), print('Faild..'), }, ).displayDialog(context); } - loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, isActive) async { + loginWithFingerPrintOrFaceID(AuthMethodTypes authMethodTypes, + isActive) async { if (isActive) { const iosStrings = const IOSAuthMessages( cancelButton: 'cancel', @@ -707,7 +530,7 @@ class _VerificationMethodsState extends State { DrAppToastMsg.showErrorToast(e.toString()); } if (!mounted) return; - if (user != null && (user.logInTypeID == 3 || user.logInTypeID == 4)) { + if (model.user != null && (model.user.logInTypeID == 3 || model.user.logInTypeID == 4)) { this.sendActivationCode(authMethodTypes); } else { setState(() { @@ -717,34 +540,44 @@ class _VerificationMethodsState extends State { } } - checkActivationCode( {value}) async { + checkActivationCode({value}) async { CheckActivationCodeRequestModel checkActivationCodeForDoctorApp = - new CheckActivationCodeRequestModel( - zipCode: - _loggedUser != null ? _loggedUser['ZipCode'] : user.zipCode, - mobileNumber: - _loggedUser != null ? _loggedUser['MobileNumber'] : user.mobile, - projectID: await sharedPref.getInt(PROJECT_ID) != null - ? await sharedPref.getInt(PROJECT_ID) - : user.projectID, - logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), - activationCode: value ?? '0000', - oTPSendType: await sharedPref.getInt(OTP_TYPE), - generalid: "Cs2020@2016\$2958"); - await widget.model.checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); - - if(widget.model.state == ViewState.ErrorLocal){ + new CheckActivationCodeRequestModel( + zipCode: + model.loggedUser != null ? model.loggedUser['ZipCode'] : model.user.zipCode, + mobileNumber: + model.loggedUser != null ? model.loggedUser['MobileNumber'] : model.user.mobile, + projectID: await sharedPref.getInt(PROJECT_ID) != null + ? await sharedPref.getInt(PROJECT_ID) + : model.user.projectID, + logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID), + activationCode: value ?? '0000', + oTPSendType: await sharedPref.getInt(OTP_TYPE), + generalid: "Cs2020@2016\$2958"); + await model + .checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp); + + if (model.state == ViewState.ErrorLocal) { Navigator.pop(context); - Helpers.showErrorToast(widget.model.error); + Helpers.showErrorToast(model.error); } else { - sharedPref.setString(TOKEN, widget.model.checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); - if (widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != null) { - loginProcessCompleted(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); - sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + sharedPref.setString( + TOKEN, + model + .checkActivationCodeForDoctorAppRes['AuthenticationTokenID']); + if (model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'] != + null) { + loginProcessCompleted(model.checkActivationCodeForDoctorAppRes['List_DoctorProfile'][0]); + sharedPref.setObj( + CLINIC_NAME, + model + .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); } else { - sharedPref.setObj(CLINIC_NAME, widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); - ClinicModel clinic = - ClinicModel.fromJson(widget.model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); + sharedPref.setObj( + CLINIC_NAME, + model + .checkActivationCodeForDoctorAppRes['List_DoctorsClinic']); + ClinicModel clinic = ClinicModel.fromJson(model.checkActivationCodeForDoctorAppRes['List_DoctorsClinic'][0]); getDocProfiles(clinic); } } @@ -783,16 +616,4 @@ class _VerificationMethodsState extends State { Helpers.showErrorToast(err); }); } - - getDate(DateTime date) { - final DateFormat formatter = DateFormat('dd MMM yyyy'); - - return formatter.format(date); - } - - getTime(DateTime date) { - final DateFormat formatter = DateFormat('HH:mm a'); - - return formatter.format(date); - } }