diff --git a/assets/images/lock-icon.png b/assets/images/lock-icon.png new file mode 100644 index 00000000..39645887 Binary files /dev/null and b/assets/images/lock-icon.png differ diff --git a/assets/images/svg/Check Mark.lottie b/assets/images/svg/Check Mark.lottie new file mode 100644 index 00000000..28630fbd Binary files /dev/null and b/assets/images/svg/Check Mark.lottie differ diff --git a/assets/images/svg/qlogin.svg b/assets/images/svg/qlogin.svg deleted file mode 100644 index 3fcf2ffd..00000000 --- a/assets/images/svg/qlogin.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 8c2ccb4e..31b2f39f 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2328,5 +2328,7 @@ const Map localizedValues = { "liveCareTermsConditions48": {"en": "If you have any complaints or concerns about the Application and or the Website, Our Services, or how we handle your personal information please contact us on: EServices.HMG@drsulaimanalhabib.com or call 011 525 9553", "ar": "إذا كانت لديك أي شكاوى أو مخاوف بشأن التطبيق و/أو موقع الويب أو خدماتنا أو كيفية تعاملنا مع معلوماتك الشخصية، فيرجى التواصل معنا على: EServices.HMG@drsulaimanalhabib.com أو الاتصال على الرقم: 9553 525 011"}, "clickPrivacyPolicy": {"en": "Please click here to view the privacy policy", "ar": "الرجاء الضغط هنا لعرض سياسة الخصوصية"}, "welcomeToDrSulaiman": {"en": "Welcome to Dr. Sulaiman Al Habib Medical Group", "ar": "مرحباً بكم في مجموعة الدكتور سليمان الحبيب الطبية"}, - "dontHaveAccount": {"en": "Don’t have an account?", "ar": "ليس لديك حساب؟"} + "dontHaveAccount": {"en": "Don’t have an account?", "ar": "ليس لديك حساب؟"}, + "loginByOTP": {"en": "Login By OTP", "ar":"تسجيل الدخول باستخدام OTP"}, + "loginBy": {"en": "Login By", "ar":"تسجيل الدخول بواسطة"} }; diff --git a/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart b/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart index 3262dd20..5223209c 100644 --- a/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart +++ b/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart @@ -108,6 +108,7 @@ class CustomButton extends StatelessWidget { this.fontFamily = 'poppins', this.fontWeight = FontWeight.w500, this.isDisabled = false, + this.icon, }) : super(key: key); diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 2d686531..0ce516bc 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -17,6 +17,8 @@ import 'package:hmg_patient_app/pages/BookAppointment/Search.dart'; import 'package:hmg_patient_app/pages/DrawerPages/family/my-family.dart'; import 'package:hmg_patient_app/pages/ToDoList/ToDo.dart'; import 'package:hmg_patient_app/pages/landing/home_page_2.dart'; +import 'package:hmg_patient_app/pages/login/saved_login.dart'; +import 'package:hmg_patient_app/pages/login/welcome.dart'; import 'package:hmg_patient_app/pages/medical/medical_profile_page_new.dart'; import 'package:hmg_patient_app/services/authentication/auth_provider.dart'; import 'package:hmg_patient_app/services/clinic_services/get_clinic_service.dart'; @@ -84,7 +86,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { DateTime? currentBackPressTime; bool authenticated = false; // SignalRUtil signalRUtil; - + // bool isDoneQuickLogin =false; late ToDoCountProviderModel toDoProvider; bool _showBottomNavigationBar = true; @@ -105,26 +107,26 @@ class _LandingPageState extends State with WidgetsBindingObserver { bool isTalking = false; var sharedPref = new AppSharedPreferences(); - - var data = { - "AppointmentNo": "2016059247", - "ProjectID": "15", - "NotificationType": "10", - "background": "0", - "doctorname": "Call from postman", - "clinicname": "LIVECARE FAMILY MEDICINE AND GP", - "speciality": "General Practioner", - "appointmentdate": "2022-01-19", - "appointmenttime": "12:10", - "PatientName": "Testing", - "session_id": "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg", - "token": - "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", - "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", - "callerID": "9920", - "PatientID": "1231755", - "is_call": "true" - }; + // + // var data = { + // "AppointmentNo": "2016059247", + // "ProjectID": "15", + // "NotificationType": "10", + // "background": "0", + // "doctorname": "Call from postman", + // "clinicname": "LIVECARE FAMILY MEDICINE AND GP", + // "speciality": "General Practioner", + // "appointmentdate": "2022-01-19", + // "appointmenttime": "12:10", + // "PatientName": "Testing", + // "session_id": "1_MX40NjIwOTk2Mn5-MTY0NzI1NjYxNDI2OX5ySXhlVjZjam13RFdMVmdleWVsSDhzQkx-fg", + // "token": + // "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9OGMyY2IyYWFiZmZmMzI4ZmEwMjgxNDdmMGFhZGI0N2JiZjdmZWY4MjpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTBOekkxTmpZeE5ESTJPWDV5U1hobFZqWmphbTEzUkZkTVZtZGxlV1ZzU0RoelFreC1mZyZjcmVhdGVfdGltZT0xNjQ3MjU2NjE0Jm5vbmNlPTAuMjgzNDgyNjM1NDczNjQ2OCZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjQ3MjU4NDE0JmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", + // "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", + // "callerID": "9920", + // "PatientID": "1231755", + // "is_call": "true" + // }; void _requestIOSPermissions() { flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation()?.requestPermissions( @@ -373,25 +375,42 @@ class _LandingPageState extends State with WidgetsBindingObserver { var data = await sharedPref.getObject(IMEI_USER_DATA); sharedPref.remove(REGISTER_DATA_FOR_LOGIIN); if (data != null) { - Navigator.of(context).pushNamed(CONFIRM_LOGIN); + SelectDeviceIMEIRES savedData = SelectDeviceIMEIRES.fromJson(data); + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => SavedLogin(savedData), + ), + ); + + } else { - // AppGlobal.context = context; GifLoaderDialogUtils.showMyDialog(context); authService.selectDeviceImei(DEVICE_TOKEN).then((value) async { GifLoaderDialogUtils.hideDialog(context); var data = await sharedPref.getObject(IMEI_USER_DATA); if (value != null) { + SelectDeviceIMEIRES savedData = SelectDeviceIMEIRES.fromJson(data); setUserValues(value); - Navigator.of(context).pushNamed(CONFIRM_LOGIN); + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => SavedLogin(savedData), + ), + ); } else { GifLoaderDialogUtils.hideDialog(context); - Navigator.of(context).pushNamed( - WELCOME_LOGIN, + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => WelcomeLogin(), + ), ); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - Navigator.of(context).pushNamed(WELCOME_LOGIN); + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => WelcomeLogin(), + ), + ); }); } } @@ -455,10 +474,12 @@ class _LandingPageState extends State with WidgetsBindingObserver { getNotificationCount(token) async { if (await sharedPref.getObject(USER_PROFILE) != null) { var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + if (data != null) { authService.getDashboard().then((value) => { if (value != null) { + setState(() { notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); @@ -656,7 +677,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { if (authenticatedUserObject.isLogin) { var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); if (data != null) { - // authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {}); + authService.registeredAuthenticatedUser(data, token, 0, 0).then((res) => {}); + checkLastLoginStatus(data, token); authService.getDashboard().then((value) async { setState(() { if (value != null) { @@ -664,7 +686,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99 ? '99+' : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); model.setState(model.count, model.ancillaryCount, true, notificationCount); sharedPref.setString(NOTIFICATION_COUNT, notificationCount); - checkLastLoginStatus(data, token); + } }); // if (await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN) == null || !await AppSharedPreferences().getBool(IS_LAST_APPOINTMENT_RATE_SHOWN)) { @@ -715,17 +737,19 @@ class _LandingPageState extends State with WidgetsBindingObserver { int lastLoginStatus = await sharedPref.getInt(LAST_LOGIN) != null ? await sharedPref.getInt(LAST_LOGIN) : 1; if(lastLoginStatus == 1 || lastLoginStatus == 2){ - showQuickLoginBottomSheet(context, user, deviceToken); + showQuickLoginBottomSheet(context, user, deviceToken,false); } } - void showQuickLoginBottomSheet(BuildContext context, AuthenticatedUser user, String deviceToken) { + void showQuickLoginBottomSheet(BuildContext context, AuthenticatedUser user, String deviceToken, bool isDone) { showModalBottomSheet( context: context, backgroundColor: Colors.transparent, isScrollControlled: true, - builder: (context) => QuickLoginBottomSheet(onPressed: (){ + builder: (context) => QuickLoginBottomSheet( + isDone:isDone, + onPressed: (){ loginWithFingerPrintFace(3, 1, user, deviceToken); },), ); @@ -751,18 +775,26 @@ class _LandingPageState extends State with WidgetsBindingObserver { AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); } if (authenticated == true) { + Navigator.of(context).pop(); int lastLogin = 1; - List availableBiometrics = []; - if (availableBiometrics.contains(BiometricType.face)) { - lastLogin = 3; - } else if (availableBiometrics.contains(BiometricType.fingerprint)) { - lastLogin = 2; - } else { - lastLogin = 1; + var availableBiometrics = await auth.getAvailableBiometrics(); + + if (availableBiometrics.contains(BiometricType.strong)) { + lastLogin = 3; // Assume Face or secure fingerprint + } else if (availableBiometrics.contains(BiometricType.weak)) { + lastLogin = 2; // Likely weak fingerprint } + await sharedPref.setInt(LAST_LOGIN, lastLogin); - authService.registeredAuthenticatedUser(user, deviceToken, 0, 0).then(( - res) => {}); + showQuickLoginBottomSheet(context, user, deviceToken, true); + insertIMEI(lastLogin); } } + + insertIMEI(lastLogin) { + authService.insertDeviceImei(lastLogin).then((value) => {}).catchError((err) { + print(err); + }); } + } + diff --git a/lib/pages/login/saved_login.dart b/lib/pages/login/saved_login.dart new file mode 100644 index 00000000..50ebe25e --- /dev/null +++ b/lib/pages/login/saved_login.dart @@ -0,0 +1,441 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:hmg_patient_app/config/config.dart'; +import 'package:hmg_patient_app/config/shared_pref_kay.dart'; +import 'package:hmg_patient_app/core/service/client/base_app_client.dart'; +import 'package:hmg_patient_app/core/viewModels/project_view_model.dart'; +import 'package:hmg_patient_app/extensions/string_extensions.dart'; +import 'package:hmg_patient_app/models/Authentication/authenticated_user.dart'; +import 'package:hmg_patient_app/models/Authentication/check_activation_code_response.dart'; +import 'package:hmg_patient_app/models/Authentication/select_device_imei_res.dart'; +import 'package:hmg_patient_app/new_ui/otp/otp_validation_bootmsheet_widget.dart'; +import 'package:hmg_patient_app/pages/landing/landing_page.dart'; +import 'package:hmg_patient_app/pages/login/welcome.dart'; +import 'package:hmg_patient_app/services/authentication/auth_provider.dart' hide sharedPref; +import 'package:hmg_patient_app/uitl/app_toast.dart'; +import 'package:hmg_patient_app/uitl/date_uitl.dart'; +import 'package:hmg_patient_app/uitl/gif_loader_dialog_utils.dart'; +import 'package:hmg_patient_app/uitl/translations_delegate_base.dart'; +import 'package:hmg_patient_app/uitl/utils.dart' hide sharedPref; +import 'package:hmg_patient_app/widgets/text/app_texts_widget.dart'; +import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; + + +class SavedLogin extends StatefulWidget { + final SelectDeviceIMEIRES savedLoginData; + const SavedLogin(this.savedLoginData, {Key? key}) : super(key: key); + + @override + _SavedLogin createState() => _SavedLogin(); +} + +class _SavedLogin extends State { + TextEditingController get phoneController => + TextEditingController( + text: widget.savedLoginData.mobile!.startsWith('0') + ? widget.savedLoginData.mobile!.substring(1) + : widget.savedLoginData.mobile, + ); + + final authService = new AuthProvider(); + late ProjectViewModel projectViewModel; + + + @override + Widget build(BuildContext context) { + + projectViewModel = Provider.of(context); + + return Scaffold( + backgroundColor: const Color(0xFFF8F8FA), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(flex: 2), + // Welcome back text + const Text( + 'Welcome back', + style: TextStyle( + fontSize: 22, + color: Color(0xFF6C757D), + fontWeight: FontWeight.w400, + ), + ), + const SizedBox(height: 16), + // Names + Column( + children: [ + Text( + widget.savedLoginData.name!.toLowerCase().capitalizeFirstofEach, + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Colors.grey[800], + ), + ), + // Text( + // 'Abdul Ghaffar', + // style: TextStyle( + // fontSize: 28, + // fontWeight: FontWeight.bold, + // color: Colors.grey[800], + // ), + // ), + ], + ), + const SizedBox(height: 24), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.white), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column(children: [ + + // Last login info + Text( + 'Last Login by ${getType(widget.savedLoginData!.logInType!, context)}', + style: const TextStyle( + fontSize: 14, + color: Color(0xFF6C757D), + ), + ), + Text( + widget.savedLoginData.createdOn != null ? DateUtil.getFormattedDate(DateUtil.convertStringToDate( widget.savedLoginData!.createdOn!), "d MMMM, y 'at' HH:mm") : '--', + style: const TextStyle( + fontSize: 16, + ), + ), + Container( + margin: EdgeInsets.all(16), + child: SvgPicture.asset("assets/images/svg/apple-finder.svg", color: Colors.red, height: 54, width: 54,),), + // Face ID login button + CustomButton( + text: "${TranslationBase.of(context).loginBy} ${getType(widget.savedLoginData!.logInType!, context)}", + onPressed: (){ + loginWithFingerPrintFace(widget.savedLoginData!.logInType!, widget.savedLoginData!.iMEI!); + + }, + backgroundColor:Color(0xffFEE9EA), + borderColor:Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 12, + padding : EdgeInsets.fromLTRB(0, 10, 0, 10), + // icon: "assets/images/svg/apple-finder.svg", + ), + ],),), + const SizedBox(height: 24), + Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0), + + child: Text( + 'OR', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500 + ), + ), + ), + const SizedBox(height: 24), + // OTP login button + CustomButton( + text:TranslationBase.of(context).loginByOTP, + onPressed: (){ + + showModalBottomSheet( + context: context, + isScrollControlled: true, + isDismissible: false, + backgroundColor: Colors.transparent, + builder: (bottomSheetContext) => Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), + child: SingleChildScrollView( + child: GenericBottomSheet( + countryCode: "966", + initialPhoneNumber: "", + textController: phoneController!, // Assumed to be a TextEditingController + buttons: [ + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: CustomButton( + text: "Send me OTP on SMS", + onPressed: () { + int? val = Utils.onOtpBtnPressed(OTPType.sms, phoneController); + if (val != null) { + //checkUserAuthentication(val); + } + }, + backgroundColor: Colors.red, + borderColor: Colors.red, + textColor: Colors.white, + icon: "assets/images/svg/message.svg", + ), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: AppText( + "OR", + fontSize: 16, + fontFamily: 'poppins', + color: Color(0xFF2E3039), + fontWeight: FontWeight.w500, + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: CustomButton( + text: "Send me OTP on WhatsApp", + onPressed: () { + int? val = Utils.onOtpBtnPressed(OTPType.whatsapp, phoneController); + if (val != null) { + //checkUserAuthentication(val); + } + }, + backgroundColor: Colors.white, + borderColor: Color(0xFF2E3039), + textColor: Color(0xFF2E3039), + icon: "assets/images/svg/whatsapp.svg", + ), + ), + ], + ), + ), + ));}, + backgroundColor:Colors.white, + borderColor:Colors.black, + textColor: Colors.black, + padding : EdgeInsets.fromLTRB(0, 14, 0, 14), + // icon: "assets/images/svg/apple-finder.svg", + ), + const Spacer(flex: 2), + // OR divider + + const SizedBox(height: 24), + // Guest and Switch account + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: () { Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => LandingPage(), + + ), + );}, + child: const Text( + 'Guest', + style: TextStyle( + color: Color(0xFFED1C2B), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ), + const SizedBox(width: 24), + TextButton( + onPressed: () { + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => WelcomeLogin(), + + ), + ); + + }, + child: const Text( + 'Switch account', + style: TextStyle( + color: Color(0xFFED1C2B), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + const SizedBox(height: 20), + ], + ), + ), + ), + + ); + } + + String getType(int type, BuildContext context) { + final t = TranslationBase.of(context); + final types = { + 1: t.verifySMS, + 2: t.verifyFingerprint, + 3: t.verifyFaceID, + 4: t.verifyWhatsApp, + }; + return types[type] ?? t.verifySMS; + } + + //need to move this function on provider to avoid multiple repeat + + loginWithFingerPrintFace(type, String deviceToken ) async { + bool authenticated = false; + final LocalAuthentication auth = LocalAuthentication(); + + try { + authenticated = await auth.authenticate( + localizedReason: 'Scan your fingerprint to authenticate', + options: const AuthenticationOptions( + useErrorDialogs: true, + stickyAuth: true, + ), + authMessages: [ + // Optional: uncomment for iOS custom messages + // IOSAuthMessages( + // cancelButton: 'Cancel', + // goToSettingsButton: 'Settings', + // goToSettingsDescription: 'Please set up your Touch ID.', + // lockOut: 'Please re-enable your Touch ID.', + // ), + ], + ); + } on PlatformException catch (e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); + return; + } + + + if (authenticated) { + int lastLogin = 1; + var availableBiometrics = await auth.getAvailableBiometrics(); + + if (availableBiometrics.contains(BiometricType.strong)) { + lastLogin = 3; // Assume Face or secure fingerprint + } else if (availableBiometrics.contains(BiometricType.weak)) { + lastLogin = 2; // Likely weak fingerprint + } + + var request = authService.getCommonRequest( + type: type, + registerd_data: null, + deviceToken: widget.savedLoginData.iMEI, + mobileNumber: int.parse(widget.savedLoginData.mobile!), + zipCode: widget.savedLoginData.outSA == 1 ? '971' : '966', + patientOutSA: widget.savedLoginData.outSA, + loginTokenID: null, + selectedOption: lastLogin, + user: widget.savedLoginData, + ); + + getMobileInfo(request, lastLogin); + } +} + + + getMobileInfo(request,int lastLogin) { + // GifLoaderDialogUtils.showMyDialog(context); + this.authService.getLoginInfo(request).then((result) { + GifLoaderDialogUtils.hideDialog(context); + if (result['SMSLoginRequired'] == false) { + // this.loginTokenID = result['LogInTokenID']; + // this.patientOutSA = result['PatientOutSA']; + // setDefault(); + checkActivationCode(lastLogin,result['LogInTokenID']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + + checkActivationCode(int loginType, String loginToken) async { + + AppGlobal.context = context; + GifLoaderDialogUtils.showMyDialog(context); + var request = authService.getCommonRequest( + type: loginType, + registerd_data: null, + deviceToken: widget.savedLoginData.iMEI, + mobileNumber: int.parse(widget.savedLoginData.mobile!), + zipCode: widget.savedLoginData.outSA == 1 ? '971' : '966', + patientOutSA: widget.savedLoginData.outSA, + loginTokenID: loginToken, + selectedOption: loginType, + user: widget.savedLoginData, + ).toJson(); + dynamic res; + + authService + .checkActivationCode(request, null) + .then((result) async => { + res = result, + if (result is Map) + { + result = CheckActivationCode.fromJson(result as Map), + // if (result.errorCode == '699') + // { + // //699 block run here + // GifLoaderDialogUtils.hideDialog(context), + // Future.delayed(Duration(seconds: 2), () { + // AppToast.showErrorToast(message: result.errorEndUserMessage); + // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: Login)); + // }) + // } + // else if (this.registerd_data != null && this.registerd_data.isRegister == true) + // { + // widget.changePageViewIndex!(1), + // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), + // } + // else + { + sharedPref.remove(FAMILY_FILE), + result.list.isFamily = false, + // userData = result.list, + sharedPref.setString(BLOOD_TYPE, result.patientBloodType ?? ""), + //Remove o+ from here Added by Aamir + authenticatedUserObject.user = result.list, + projectViewModel.setPrivilege(privilegeList: res), + await sharedPref.setObject(MAIN_USER, result.list), + await sharedPref.setObject(USER_PROFILE, result.list), + // loginTokenID = result.logInTokenID, + await sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), + await sharedPref.setString(TOKEN, result.authenticationTokenID), + // checkIfUserAgreedBefore(result), + projectViewModel.analytics.loginRegistration.login_successful(), + } + } + // else + // { + // // Navigator.of(context).pop(), + // GifLoaderDialogUtils.hideDialog(context), + // Future.delayed(Duration(seconds: 1), () { + // Navigator.of(context).pop(); + // AppToast.showErrorToast(message: result, localContext: context); + // startSMSService(tempType); + // }), + // + // projectViewModel.analytics.loginRegistration.login_fail(error: result), + // projectViewModel.analytics.errorTracking.log('otp_verification_at_confirm_login', error: result) + // } + }); + } + + + insertIMEI(lastLogin) { + + authService.insertDeviceImei(lastLogin).then((value) => {}).catchError((err) { + print(err); + }); + } +} \ No newline at end of file diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 7d12657d..3e023c79 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -102,6 +102,7 @@ class _WelcomeLogin extends State { @override Widget build(BuildContext context) { projectViewModel = context.read(); + toDoProvider = context.read(); return AppScaffold( appBarTitle: TranslationBase.of(context).welcome, isShowDecPage: false, diff --git a/lib/routes.dart b/lib/routes.dart index ec391bd3..b48cd5d7 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -15,6 +15,7 @@ import 'package:hmg_patient_app/pages/login/login-type.dart'; import 'package:hmg_patient_app/pages/login/login.dart'; import 'package:hmg_patient_app/pages/login/register-info.dart'; import 'package:hmg_patient_app/pages/login/register.dart'; +import 'package:hmg_patient_app/pages/login/saved_login.dart'; import 'package:hmg_patient_app/pages/login/welcome.dart'; import 'package:hmg_patient_app/pages/packages_offers/OfferAndPackagesCartPage.dart'; import 'package:hmg_patient_app/pages/packages_offers/PackageOrderCompletedPage.dart'; @@ -58,7 +59,6 @@ const String OPENTOK_CALL_PAGE = 'OPENTOK_CALL_PAGE'; const String CART_ORDER_PAGE = 'cart-order-page'; const String CALL_PAGE = 'CALL_PAGE'; const String INCOMING_CALL_PAGE = 'INCOMING_CALL_PAGE'; - const String HEALTH_WEATHER = 'health-weather'; const APP_UPDATE = 'app-update'; diff --git a/lib/splashPage.dart b/lib/splashPage.dart index ebff30a2..ac51a490 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -51,7 +51,7 @@ class _SplashScreenState extends State { if (!_privilegeService.hasError) { Navigator.of(context).pushReplacement( MaterialPageRoute( - builder: (BuildContext context) => WelcomeLogin(), + builder: (BuildContext context) => LandingPage(), // builder: (BuildContext context) => LandingPage(), ), ); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index b19943a2..bb6ebc7c 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -3476,8 +3476,8 @@ class TranslationBase { String get clickPrivacyPolicy => localizedValues["clickPrivacyPolicy"][locale.languageCode]; String get welcomeToDrSulaiman => localizedValues["welcomeToDrSulaiman"][locale.languageCode]; String get dontHaveAccount => localizedValues["dontHaveAccount"][locale.languageCode]; - - + String get loginByOTP => localizedValues['loginByOTP'][locale.languageCode]; + String get loginBy => localizedValues['loginBy'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/quick_login.dart b/lib/widgets/quick_login.dart index ad73642d..ae57f2af 100644 --- a/lib/widgets/quick_login.dart +++ b/lib/widgets/quick_login.dart @@ -1,13 +1,22 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:hmg_patient_app/new_ui/otp/otp_validation_bootmsheet_widget.dart'; import 'package:hmg_patient_app/uitl/translations_delegate_base.dart'; +import 'package:hmg_patient_app/uitl/utils.dart'; import 'package:hmg_patient_app/widgets/buttons/defaultButton.dart'; -class QuickLoginBottomSheet extends StatelessWidget { +class QuickLoginBottomSheet extends StatefulWidget { final VoidCallback onPressed; - const QuickLoginBottomSheet({required this.onPressed}); + final bool isDone; + + const QuickLoginBottomSheet({required this.onPressed, this.isDone = false}); + + @override + _QuickLoginBottomSheet createState() => _QuickLoginBottomSheet(); +} +class _QuickLoginBottomSheet extends State { @override Widget build(BuildContext context) { @@ -20,21 +29,50 @@ class QuickLoginBottomSheet extends StatelessWidget { ), ), padding: const EdgeInsets.all(24), - child: Column( + child: Column( mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center,children: [ + + + widget.isDone ? Column(children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: SvgPicture.asset("assets/images/svg/cross-circle.svg", width: 24, height: 24)),],), + Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/checkmark.json', width: 120, height: 120, repeat: true), + + + const Text( + 'All Set! Now you can login with Face ID or Biometric', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + fontFamily: 'Poppins', + + ), + ), + + ],) : Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Header + + Image.asset("assets/images/lock-icon.png", height: 101,), + const SizedBox(height: 10), const Text( 'Enable Quick Login', style: TextStyle( - fontSize: 20, + fontSize: 26, fontWeight: FontWeight.bold, color: Colors.black, ), ), - const SizedBox(height: 16), + const SizedBox(height: 5), // Description const Text( @@ -46,10 +84,7 @@ class QuickLoginBottomSheet extends StatelessWidget { ), ), - const SizedBox(height: 24), - // Divider - const Divider(height: 1, thickness: 1), const SizedBox(height: 24), @@ -61,16 +96,34 @@ class QuickLoginBottomSheet extends StatelessWidget { CustomButton( text: "Enable Quick Login", - onPressed: onPressed, - backgroundColor: Colors.red, - borderColor: Colors.red, + onPressed:widget.onPressed, + backgroundColor:Color(0xffED1C2B), + borderColor:Color(0xffED1C2B), textColor: Colors.white, - icon: "assets/images/svg/apple_finder.svg", + icon: "assets/images/svg/apple-finder.svg", )), ], ), + SizedBox(height: 16,), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded(child: + + CustomButton( + text: "Not Now", + onPressed: (){ Navigator.pop(context);}, + backgroundColor:Color(0xffFEE9EA), + borderColor:Color(0xffFEE9EA), + textColor: Colors.red, + // icon: "assets/images/svg/apple-finder.svg", + )), + ], + ), ], - ), + )],), ); } + + } \ No newline at end of file