From 8881e9c0c7fede620aaa2574f7d53bb6034fc192 Mon Sep 17 00:00:00 2001 From: Sultan khan Date: Wed, 13 Aug 2025 17:15:35 +0300 Subject: [PATCH] login fixes --- lib/config/localized_values.dart | 4 +- .../otp/otp_validation_bootmsheet_widget.dart | 15 +- lib/pages/landing/landing_page.dart | 4 + lib/pages/login/register_new.dart | 42 +- lib/pages/login/register_new_step_2.dart | 14 +- lib/pages/login/saved_login.dart | 7 +- lib/pages/login/welcome.dart | 10 +- lib/uitl/translations_delegate_base.dart | 4 + lib/uitl/utils.dart | 405 ++++++++++++++---- 9 files changed, 388 insertions(+), 117 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index eb14cadc..4bdf0696 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2365,7 +2365,9 @@ const Map localizedValues = { "notice": {"en": "Notice", "ar":"إشعار"}, "receiveOtpToast": {"en": "Where would you like to receive OTP?", "ar":"أين تود تلقي رمز التحقق OTP؟"}, "pleaseChooseOption": {"en": "Please select from the below options to receive OTP.", "ar":"الرجاء اختيار من الخيارات أدناه لتلقي رمز التحقق OTP."}, - + "pleaseEnterMobile": {"en": "Please enter phone number", "ar":"الرجاء إدخال رقم الهاتف"}, + "pleaseEnterValidMobile": {"en": "Please enter valid phone number", "ar":"الرجاء إدخال رقم هاتف صالح"}, + "pleaseEnterNationalIdOrFileNo": {"en": "Please enter National id or File no", "ar":"الرجاء إدخال رقم الهوية الوطنية أو رقم الملف"}, diff --git a/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart b/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart index 11ab1260..9fc6d8ae 100644 --- a/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart +++ b/lib/new_ui/otp/otp_validation_bootmsheet_widget.dart @@ -20,7 +20,7 @@ class GenericBottomSheet extends StatefulWidget { final bool isEnableCountryDropdown; final bool isFromSavedLogin; Function(String?)? onChange; - + FocusNode myFocusNode; GenericBottomSheet( {this.countryCode = "", this.initialPhoneNumber = "", @@ -30,7 +30,9 @@ class GenericBottomSheet extends StatefulWidget { this.onCountryChange, this.isEnableCountryDropdown = false, this.isFromSavedLogin = false, - this.onChange}); + this.onChange, + required this.myFocusNode + }); @override _GenericBottomSheetState createState() => _GenericBottomSheetState(); @@ -138,7 +140,7 @@ class _GenericBottomSheetState extends State { } }, isEnable: true, - autoFocus: true, + focusNode: widget.myFocusNode, isReadOnly: widget.isFromSavedLogin, prefix: widget.isForEmail ? null : widget.countryCode, hasSelection: false, @@ -182,7 +184,7 @@ class CustomButton extends StatelessWidget { final String? fontFamily; final FontWeight fontWeight; final bool isDisabled; - + final Color iconColor; CustomButton({ Key? key, required this.text, @@ -198,6 +200,7 @@ class CustomButton extends StatelessWidget { this.fontWeight = FontWeight.w500, this.isDisabled = false, this.icon, + this.iconColor = Colors.white, }) : super(key: key); @override @@ -222,6 +225,10 @@ class CustomButton extends StatelessWidget { padding: const EdgeInsets.only(right: 8.0), child: SvgPicture.asset( icon!, + colorFilter: ColorFilter.mode( + isDisabled ? iconColor.withOpacity(0.5) : iconColor, + BlendMode.srcIn, + ), width: 24, height: 24, ), diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 33bfad18..0f5c695e 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -809,6 +809,10 @@ class _LandingPageState extends State with WidgetsBindingObserver { await sharedPref.setInt(LAST_LOGIN, lastLogin); showQuickLoginBottomSheet(context, user, deviceToken, true); + + Future.delayed(Duration(seconds: 3), () { + Navigator.of(context).pop(); + }); insertIMEI(lastLogin, deviceToken); } } diff --git a/lib/pages/login/register_new.dart b/lib/pages/login/register_new.dart index d6aea8c5..34b753d8 100644 --- a/lib/pages/login/register_new.dart +++ b/lib/pages/login/register_new.dart @@ -66,7 +66,7 @@ class _RegisterNew extends State { final nationalIDorFile = TextEditingController(); final phoneController = TextEditingController(); AppointmentRateViewModel appointmentRateViewModel = locator(); - + final FocusNode myFocusNode = FocusNode(); Country selectedCountry = Country.saudiArabia; OTPType? otpType; bool isTermsAccepted = false; @@ -324,7 +324,8 @@ class _RegisterNew extends State { // Utils.showErrorToast(TranslationBase.of(context).pleaseEnterNationalId); return; } - if (nationalIDorFile != null && !Utils.validateIqama(nationalIDorFile.text)) { + if ((!Utils.validateIqama(nationalIDorFile.text) && selectedCountry.countryCode == '966') || + (!Utils.validateUaeNationalId(nationalIDorFile.text) && selectedCountry.countryCode == '971')) { context.showBottomSheet( child: ExceptionBottomSheet( message: "Please enter correct national id", @@ -401,7 +402,18 @@ class _RegisterNew extends State { if (mobileNo.isEmpty) { context.showBottomSheet( child: ExceptionBottomSheet( - message: "Please enter mobile number", + message: TranslationBase.of(context).pleaseEnterMobile, + showCancel: false, + onOkPressed: () { + Navigator.of(context).pop(); + }, + ), + ); + } + else if (!Utils.validateMobileNumber(mobileNo)) { + context.showBottomSheet( + child: ExceptionBottomSheet( + message: TranslationBase.of(context).pleaseEnterValidMobile, showCancel: false, onOkPressed: () { Navigator.of(context).pop(); @@ -409,19 +421,6 @@ class _RegisterNew extends State { ), ); } - // - // else if (mobileNo.length < 8) { - // context.showBottomSheet( - // child: ExceptionBottomSheet( - // message: "Please enter correct mobile number", - // showCancel: false, - // onOkPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // } - else { registerUser(1); } @@ -456,17 +455,17 @@ class _RegisterNew extends State { if (mobileNo.isEmpty) { context.showBottomSheet( child: ExceptionBottomSheet( - message: "Please enter mobile number", + message: TranslationBase.of(context).pleaseEnterMobile, showCancel: false, onOkPressed: () { Navigator.of(context).pop(); }, ), ); - } else if (mobileNo.length < 9) { + } else if (!Utils.validateMobileNumber(mobileNo)) { context.showBottomSheet( child: ExceptionBottomSheet( - message: "Please enter correct mobile number", + message: TranslationBase.of(context).pleaseEnterValidMobile, showCancel: false, onOkPressed: () { Navigator.of(context).pop(); @@ -485,11 +484,14 @@ class _RegisterNew extends State { icon: "assets/images/svg/whatsapp.svg", ), ), - ], + ], myFocusNode:myFocusNode, ), ), ), ); + Future.delayed(Duration(milliseconds: 500), () { + myFocusNode.requestFocus(); + }); }, fontFamily: context.fontFamily, ), diff --git a/lib/pages/login/register_new_step_2.dart b/lib/pages/login/register_new_step_2.dart index 7efbbef1..b5323803 100644 --- a/lib/pages/login/register_new_step_2.dart +++ b/lib/pages/login/register_new_step_2.dart @@ -57,7 +57,7 @@ class _RegisterNew extends State { late ProjectViewModel projectViewModel; bool isFromDubai = false; List countriesList = []; - + final FocusNode myFocusNode = FocusNode(); // TextEditingController nationality = TextEditingController(); String? name, nationalId; @@ -336,6 +336,7 @@ class _RegisterNew extends State { backgroundColor: Color(0xFFFEE9EA), borderColor: Color(0xFFFEE9EA), textColor: Color(0xFFED1C2B), + iconColor: Color(0xFFED1C2B), ), ), SizedBox( @@ -343,10 +344,12 @@ class _RegisterNew extends State { ), Expanded( child: CustomButton( - backgroundColor: Color(0xFF18C273), - borderColor: Color(0xFF18C273), + backgroundColor: Color(0xFFccedde), + borderColor: Color(0xFFccedde), + textColor: Color(0xFF18C273), text: TranslationBase.of(context).confirm, icon: "assets/images/svg/confirm.svg", + iconColor: Color(0xFF18C273), onPressed: () { if (isFromDubai) { if (name == null) { @@ -396,11 +399,14 @@ class _RegisterNew extends State { borderColor: Color(0xFF18C273), textColor: Colors.white), ), - ], + ], myFocusNode: myFocusNode, ), ), ), ); + Future.delayed(Duration(milliseconds: 500), () { + myFocusNode.requestFocus(); + }); }, fontFamily: context.fontFamily, ), diff --git a/lib/pages/login/saved_login.dart b/lib/pages/login/saved_login.dart index f59d5571..3ba48cf5 100644 --- a/lib/pages/login/saved_login.dart +++ b/lib/pages/login/saved_login.dart @@ -54,7 +54,7 @@ class _SavedLogin extends State { TextEditingController? phoneController; final authService = AuthProvider(); late ProjectViewModel projectViewModel; - + final FocusNode myFocusNode = FocusNode(); late ToDoCountProviderModel toDoProvider; Country selectedCountry = Country.saudiArabia; @@ -295,12 +295,15 @@ class _SavedLogin extends State { icon: "assets/images/svg/whatsapp.svg", ), ), - ], + ], myFocusNode: myFocusNode, ), ), ); }), ); + Future.delayed(Duration(milliseconds: 500), () { + myFocusNode.requestFocus(); + }); }, backgroundColor: Colors.white, borderColor: Color(0xFF2E3039), diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 57cb5f6a..0b1b9550 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -77,6 +77,7 @@ class _WelcomeLogin extends State { AuthenticatedUserObject authenticatedUserObject = locator(); AppointmentRateViewModel appointmentRateViewModel = locator(); late ProjectViewModel projectViewModel; + final FocusNode myFocusNode = FocusNode(); late ToDoCountProviderModel toDoProvider; @@ -189,6 +190,7 @@ class _WelcomeLogin extends State { text: TranslationBase.of(context).login, icon: "assets/images/svg/login1.svg", onPressed: () { + if (nationIdController.text.isNotEmpty) { showModalBottomSheet( context: context, @@ -199,6 +201,7 @@ class _WelcomeLogin extends State { enableDrag: false, // Prevent dragging to avoid focus conflicts builder: (bottomSheetContext) => StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) { + return Padding( padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom), child: SingleChildScrollView( @@ -258,16 +261,19 @@ class _WelcomeLogin extends State { icon: "assets/images/svg/whatsapp.svg", ), ), - ], + ], myFocusNode: myFocusNode, ), ), ); }), ); + Future.delayed(Duration(milliseconds: 500), () { + myFocusNode.requestFocus(); + }); } else { context.showBottomSheet( child: ExceptionBottomSheet( - message: "Please enter National id or File no", + message: TranslationBase.of(context).pleaseEnterNationalIdOrFileNo, showCancel: false, onOkPressed: () { Navigator.of(context).pop(); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 2bd0a54d..e66f30bc 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -3512,6 +3512,10 @@ class TranslationBase { String get notice => localizedValues["notice"][locale.languageCode]; String get receiveOtpToast => localizedValues["receiveOtpToast"][locale.languageCode]; String get pleaseChooseOption => localizedValues["pleaseChooseOption"][locale.languageCode]; + String get pleaseEnterMobile => localizedValues["pleaseEnterMobile"][locale.languageCode]; + String get pleaseEnterValidMobile => localizedValues["pleaseEnterValidMobile"][locale.languageCode]; + String get pleaseEnterNationalIdOrFileNo => localizedValues["pleaseEnterNationalIdOrFileNo"][locale.languageCode]; + } diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 1782be1d..d4a1bc01 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -81,16 +81,28 @@ enum GenderType { male, female } enum MaritalStatusType { single, married, divorced, widowed } class Utils { - static int? onOtpBtnPressed(OTPType type, String? phoneNumber, BuildContext context) { - if (phoneNumber == null || phoneNumber.isEmpty || phoneNumber.length < 9) { + static int? onOtpBtnPressed( + OTPType type, String? phoneNumber, BuildContext context) { + if (phoneNumber == null || phoneNumber.isEmpty) { context.showBottomSheet( child: ExceptionBottomSheet( - message: "Please enter your phone number.", + message: TranslationBase.of(context).pleaseEnterMobile, onOkPressed: () { Navigator.of(context).pop(); }, )); return null; + } else if (!Utils.validateMobileNumber(phoneNumber)) { + context.showBottomSheet( + child: ExceptionBottomSheet( + message: TranslationBase.of(context).pleaseEnterValidMobile, + showCancel: false, + onOkPressed: () { + Navigator.of(context).pop(); + }, + ), + ); + return null; } return type == OTPType.sms ? 1 : 4; } @@ -114,15 +126,30 @@ class Utils { return sum % 10 == 0; } + static bool validateUaeNationalId(String id) { + // Must be exactly 15 digits + final regex = RegExp(r'^784\d{4}\d{7}\d{1}$'); + return regex.hasMatch(id); + } + + static bool validateMobileNumber(String number) { + final regex = RegExp(r'^(05\d{8}|5\d{8})$'); + return regex.hasMatch(number); + } + static void changeAppLanguage({required BuildContext context}) { sharedPref.setBool(IS_ROBOT_INIT, false); sharedPref.remove(CLINICS_LIST); if (context.read().isArabic) { context.read().changeLanguage('en'); - locator().hamburgerMenu.logMenuItemClick('change language to english'); + locator() + .hamburgerMenu + .logMenuItemClick('change language to english'); } else { context.read().changeLanguage('ar'); - locator().hamburgerMenu.logMenuItemClick('change language to arabic'); + locator() + .hamburgerMenu + .logMenuItemClick('change language to arabic'); } } @@ -133,7 +160,20 @@ class Utils { final year = dateTime.year.toString(); // Map month number to short month name - const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + const monthNames = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec' + ]; final month = monthNames[dateTime.month - 1]; return '$day $month, $year'; @@ -155,7 +195,20 @@ class Utils { final year = parts[0]; // Map month number to short month name (Hijri months) - const hijriMonthNames = ['Muharram', 'Safar', 'Rabi I', 'Rabi II', 'Jumada I', 'Jumada II', 'Rajab', 'Sha\'ban', 'Ramadan', 'Shawwal', 'Dhu al-Qi\'dah', 'Dhu al-Hijjah']; + const hijriMonthNames = [ + 'Muharram', + 'Safar', + 'Rabi I', + 'Rabi II', + 'Jumada I', + 'Jumada II', + 'Rajab', + 'Sha\'ban', + 'Ramadan', + 'Shawwal', + 'Dhu al-Qi\'dah', + 'Dhu al-Hijjah' + ]; final monthIndex = int.tryParse(parts[1]) ?? 1; final month = hijriMonthNames[monthIndex - 1]; @@ -247,10 +300,13 @@ class Utils { // } // } - static Future checkConnection({bool bypassConnectionCheck = false}) async { + static Future checkConnection( + {bool bypassConnectionCheck = false}) async { if (bypassConnectionCheck) return true; - List connectivityResult = await (Connectivity().checkConnectivity()); - if (connectivityResult.contains(ConnectivityResult.mobile) || connectivityResult.contains(ConnectivityResult.wifi)) { + List connectivityResult = + await (Connectivity().checkConnectivity()); + if (connectivityResult.contains(ConnectivityResult.mobile) || + connectivityResult.contains(ConnectivityResult.wifi)) { return true; } else { return false; @@ -271,7 +327,8 @@ class Utils { FocusScope.of(context).unfocus(); } - static showPermissionConsentDialog(BuildContext context, String message, VoidCallback? onTap) { + static showPermissionConsentDialog( + BuildContext context, String message, VoidCallback? onTap) { showDialog( context: context, builder: (cxt) => CovidConsentDialog( @@ -324,13 +381,27 @@ class Utils { } } - static String getAppointmentTransID(int projectID, int clinicID, int appoNo, {bool isAddMilliseconds = true}) { + static String getAppointmentTransID(int projectID, int clinicID, int appoNo, + {bool isAddMilliseconds = true}) { String currentMillis = DateTime.now().millisecondsSinceEpoch.toString(); - return projectID.toString() + '-' + clinicID.toString() + '-' + appoNo.toString() + (isAddMilliseconds ? '-' + currentMillis.substring(currentMillis.length - 5, currentMillis.length) : ""); + return projectID.toString() + + '-' + + clinicID.toString() + + '-' + + appoNo.toString() + + (isAddMilliseconds + ? '-' + + currentMillis.substring( + currentMillis.length - 5, currentMillis.length) + : ""); } static String getAdvancePaymentTransID(int projectID, int fileNumber) { - return projectID.toString() + '-' + fileNumber.toString() + '-' + DateTime.now().millisecondsSinceEpoch.toString(); + return projectID.toString() + + '-' + + fileNumber.toString() + + '-' + + DateTime.now().millisecondsSinceEpoch.toString(); } bool validateIDBox(String value, int type) { @@ -389,14 +460,23 @@ class Utils { } static validEmail(email) { - return RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email); + return RegExp( + r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") + .hasMatch(email); } - static List myMedicalList({ProjectViewModel? projectViewModel, BuildContext? context, bool? isLogin, count, Function? onWeCareClick}) { + static List myMedicalList( + {ProjectViewModel? projectViewModel, + BuildContext? context, + bool? isLogin, + count, + Function? onWeCareClick}) { List medical = []; medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(5) ? Navigator.push(context, FadePage(page: MyAppointments())) : null, + onTap: () => projectViewModel.havePrivilege(5) + ? Navigator.push(context, FadePage(page: MyAppointments())) + : null, child: isLogin! ? Stack(children: [ Container( @@ -415,7 +495,8 @@ class Utils { left: 8, top: 4, child: badge_import.Badge( - badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeAnimation: badge_import.BadgeAnimation.fade( + toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, @@ -425,7 +506,11 @@ class Utils { position: badge_import.BadgePosition.topEnd(), badgeContent: Container( padding: EdgeInsets.all(2.0), - child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + child: Text(count.toString(), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12.0)), ), ), ) @@ -436,7 +521,8 @@ class Utils { top: 4, child: badge_import.Badge( position: badge_import.BadgePosition.topEnd(), - badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeAnimation: badge_import.BadgeAnimation.fade( + toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, @@ -445,7 +531,11 @@ class Utils { ), badgeContent: Container( padding: EdgeInsets.all(2.0), - child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + child: Text(count.toString(), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12.0)), ), ), ) @@ -472,7 +562,9 @@ class Utils { } medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(7) ? Navigator.push(context, FadePage(page: RadiologyHomePage())) : null, + onTap: () => projectViewModel.havePrivilege(7) + ? Navigator.push(context, FadePage(page: RadiologyHomePage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).radiology, imagePath: 'radiology.svg', @@ -482,7 +574,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(12) ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) : null, + onTap: () => projectViewModel.havePrivilege(12) + ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).medicines, imagePath: 'medicine_prescription.svg', @@ -508,7 +602,8 @@ class Utils { medical.add(InkWell( onTap: () { - if (projectViewModel.havePrivilege(48)) Navigator.push(context, FadePage(page: ActiveMedicationsPage())); + if (projectViewModel.havePrivilege(48)) + Navigator.push(context, FadePage(page: ActiveMedicationsPage())); }, child: MedicalProfileItem( title: TranslationBase.of(context).myMedical, @@ -527,12 +622,17 @@ class Utils { ), ) : null, - child: - MedicalProfileItem(title: TranslationBase.of(context).myDoctor, imagePath: 'my_doc.svg', subTitle: TranslationBase.of(context).myDoctorSubtitle, isEnable: projectViewModel.havePrivilege(6)), + child: MedicalProfileItem( + title: TranslationBase.of(context).myDoctor, + imagePath: 'my_doc.svg', + subTitle: TranslationBase.of(context).myDoctorSubtitle, + isEnable: projectViewModel.havePrivilege(6)), )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: MyInvoices())) : null, + onTap: () => projectViewModel.havePrivilege(14) + ? Navigator.push(context, FadePage(page: MyInvoices())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).invoicesList, imagePath: 'invoice_list.svg', @@ -542,7 +642,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(85) ? Navigator.push(context, FadePage(page: AnicllaryOrders())) : null, + onTap: () => projectViewModel.havePrivilege(85) + ? Navigator.push(context, FadePage(page: AnicllaryOrders())) + : null, // onTap: () => Navigator.push(context, FadePage(page: AnicllaryOrders())), child: MedicalProfileItem( title: TranslationBase.of(context).anicllaryOrders, @@ -578,7 +680,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: EyeMeasurementsPage())) : null, + onTap: () => projectViewModel.havePrivilege(14) + ? Navigator.push(context, FadePage(page: EyeMeasurementsPage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).eye, imagePath: 'eye_measurement.svg', @@ -633,7 +737,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(23) ? Navigator.push(context, FadePage(page: AllergiesPage())) : null, + onTap: () => projectViewModel.havePrivilege(23) + ? Navigator.push(context, FadePage(page: AllergiesPage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).allergies, imagePath: 'allergies_diagnosed.svg', @@ -643,7 +749,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(26) ? Navigator.push(context, FadePage(page: MyVaccines())) : null, + onTap: () => projectViewModel.havePrivilege(26) + ? Navigator.push(context, FadePage(page: MyVaccines())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).myVaccines, imagePath: 'vaccine_list.svg', @@ -653,7 +761,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(20) ? Navigator.push(context, FadePage(page: HomeReportPage())) : null, + onTap: () => projectViewModel.havePrivilege(20) + ? Navigator.push(context, FadePage(page: HomeReportPage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).medical, imagePath: 'medical_report.svg', @@ -663,7 +773,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(19) ? Navigator.push(context, FadePage(page: MonthlyReportsPage())) : null, + onTap: () => projectViewModel.havePrivilege(19) + ? Navigator.push(context, FadePage(page: MonthlyReportsPage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).monthly, imagePath: 'monthly_report.svg', @@ -673,7 +785,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(16) ? Navigator.push(context, FadePage(page: PatientSickLeavePage())) : null, + onTap: () => projectViewModel.havePrivilege(16) + ? Navigator.push(context, FadePage(page: PatientSickLeavePage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).sick, imagePath: 'sick_leave.svg', @@ -683,7 +797,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(47) ? Navigator.push(context, FadePage(page: MyBalancePage())) : null, + onTap: () => projectViewModel.havePrivilege(47) + ? Navigator.push(context, FadePage(page: MyBalancePage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).myBalance, imagePath: 'balance_credit.svg', @@ -700,7 +816,9 @@ class Utils { // )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(24) ? Navigator.push(context, FadePage(page: MyTrackers())) : null, + onTap: () => projectViewModel.havePrivilege(24) + ? Navigator.push(context, FadePage(page: MyTrackers())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).myTrackers, imagePath: 'tracker.svg', @@ -710,7 +828,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(30) ? Navigator.push(context, FadePage(page: SmartWatchInstructions())) : null, + onTap: () => projectViewModel.havePrivilege(30) + ? Navigator.push(context, FadePage(page: SmartWatchInstructions())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).smartWatchesSubtitle, imagePath: 'smart_watch.svg', @@ -720,16 +840,22 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(28) ? Navigator.push(context, FadePage(page: AskDoctorHomPage())) : null, + onTap: () => projectViewModel.havePrivilege(28) + ? Navigator.push(context, FadePage(page: AskDoctorHomPage())) + : null, child: MedicalProfileItem( - title: TranslationBase.of(context).askYourSubtitle, imagePath: 'ask_doctor.svg', subTitle: TranslationBase.of(context).askYour, isEnable: projectViewModel.havePrivilege(28)), + title: TranslationBase.of(context).askYourSubtitle, + imagePath: 'ask_doctor.svg', + subTitle: TranslationBase.of(context).askYour, + isEnable: projectViewModel.havePrivilege(28)), )); if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( onTap: () { if (Platform.isAndroid) { - showPermissionConsentDialog(context, TranslationBase.of(context).wifiPermission, () { + showPermissionConsentDialog( + context, TranslationBase.of(context).wifiPermission, () { connectWifi(projectViewModel, context); }); } else { @@ -745,7 +871,9 @@ class Utils { } medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(40) ? launch('whatsapp://send?phone=18885521858&text=') : null, + onTap: () => projectViewModel.havePrivilege(40) + ? launch('whatsapp://send?phone=18885521858&text=') + : null, child: MedicalProfileItem( title: TranslationBase.of(context).chatbot, imagePath: 'chatbot.svg', @@ -757,15 +885,20 @@ class Utils { return medical; } - static getPatientWifiCredentials(String patientID, Function(String username, String password) successCallback) { + static getPatientWifiCredentials(String patientID, + Function(String username, String password) successCallback) { final body = {"PatientID": patientID}; - locator().post(WIFI_CREDENTIALS, body: body, onSuccess: (dynamic response, int statusCode) { + locator().post(WIFI_CREDENTIALS, body: body, + onSuccess: (dynamic response, int statusCode) { print(response); var data = response["Hmg_SMS_Get_By_ProjectID_And_PatientIDList"]; if (data is List && data.first != null) { final username = data.first['UserName']; final password = data.first['Password']; - if (username != null && password != null && username.isNotEmpty && password.isNotEmpty) { + if (username != null && + password != null && + username.isNotEmpty && + password.isNotEmpty) { successCallback(username, password); } } @@ -784,12 +917,18 @@ class Utils { // projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}).catchError((err) { // print(err.toString()); // }); - projectViewModel.platformBridge().connectHMGGuestWifi(GUEST_SSID).then((value) async { + projectViewModel + .platformBridge() + .connectHMGGuestWifi(GUEST_SSID) + .then((value) async { if (value == 0) { GifLoaderDialogUtils.hideDialog(context); } else { getPatientWifiCredentials(patientID, (username, password) async { - final result = await projectViewModel.platformBridge().connectHMGInternetWifi(PATIENT_SSID, username, password).catchError((err) => print(err.toString())); + final result = await projectViewModel + .platformBridge() + .connectHMGInternetWifi(PATIENT_SSID, username, password) + .catchError((err) => print(err.toString())); GifLoaderDialogUtils.hideDialog(context); if (result == 1) { // Success @@ -802,7 +941,8 @@ class Utils { } else { AlertDialogBox( context: context, - confirmMessage: "Please login with your account first to use this feature", + confirmMessage: + "Please login with your account first to use this feature", okText: "OK", okFunction: () { AlertDialogBox.closeAlertDialog(context); @@ -811,11 +951,17 @@ class Utils { }); } - static List myMedicalListHomePage({ProjectViewModel? projectViewModel, BuildContext? context, bool? isLogin, count}) { + static List myMedicalListHomePage( + {ProjectViewModel? projectViewModel, + BuildContext? context, + bool? isLogin, + count}) { List medical = []; medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(5) ? Navigator.push(context!, FadePage(page: MyAppointments())) : null, + onTap: () => projectViewModel.havePrivilege(5) + ? Navigator.push(context!, FadePage(page: MyAppointments())) + : null, child: isLogin! ? Stack(children: [ MedicalProfileItem( @@ -831,7 +977,8 @@ class Utils { top: 4, child: badge_import.Badge( position: badge_import.BadgePosition.topEnd(), - badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeAnimation: badge_import.BadgeAnimation.fade( + toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, @@ -840,7 +987,11 @@ class Utils { ), badgeContent: Container( padding: EdgeInsets.all(2.0), - child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + child: Text(count.toString(), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12.0)), ), ), ) @@ -850,7 +1001,8 @@ class Utils { right: 8, top: 4, child: badge_import.Badge( - badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), + badgeAnimation: badge_import.BadgeAnimation.fade( + toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, @@ -860,7 +1012,11 @@ class Utils { position: badge_import.BadgePosition.topEnd(), badgeContent: Container( padding: EdgeInsets.all(2.0), - child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), + child: Text(count.toString(), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12.0)), ), ), ) @@ -876,7 +1032,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(10) ? Navigator.push(context, FadePage(page: LabsHomePage())) : null, + onTap: () => projectViewModel.havePrivilege(10) + ? Navigator.push(context, FadePage(page: LabsHomePage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).lab, imagePath: 'lab_result.svg', @@ -886,7 +1044,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(7) ? Navigator.push(context, FadePage(page: RadiologyHomePage())) : null, + onTap: () => projectViewModel.havePrivilege(7) + ? Navigator.push(context, FadePage(page: RadiologyHomePage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).radiology, imagePath: 'radiology.svg', @@ -896,7 +1056,9 @@ class Utils { )); medical.add(InkWell( - onTap: () => projectViewModel.havePrivilege(12) ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) : null, + onTap: () => projectViewModel.havePrivilege(12) + ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) + : null, child: MedicalProfileItem( title: TranslationBase.of(context).medicines, imagePath: 'medicine_prescription.svg', @@ -914,19 +1076,24 @@ class Utils { ), ) : null, - child: - MedicalProfileItem(title: TranslationBase.of(context).myDoctor, imagePath: 'my_doc.svg', subTitle: TranslationBase.of(context).myDoctorSubtitle, isEnable: projectViewModel.havePrivilege(6)), + child: MedicalProfileItem( + title: TranslationBase.of(context).myDoctor, + imagePath: 'my_doc.svg', + subTitle: TranslationBase.of(context).myDoctorSubtitle, + isEnable: projectViewModel.havePrivilege(6)), )); return medical; } - static Widget loadNetworkImage({required String url, BoxFit fitting = BoxFit.cover}) { + static Widget loadNetworkImage( + {required String url, BoxFit fitting = BoxFit.cover}) { return CachedNetworkImage( placeholderFadeInDuration: Duration(milliseconds: 250), fit: fitting, imageUrl: url, - placeholder: (context, url) => Container(child: Center(child: CircularProgressIndicator())), + placeholder: (context, url) => + Container(child: Center(child: CircularProgressIndicator())), errorWidget: (context, url, error) { return Icon( Icons.error, @@ -944,7 +1111,11 @@ class Utils { } static navigateToCartPage() { - Navigator.pushAndRemoveUntil(locator()!.navigatorKey!.currentContext!, MaterialPageRoute(builder: (context) => LandingPagePharmacy(currentTab: 3)), (Route r) => false); + Navigator.pushAndRemoveUntil( + locator()!.navigatorKey!.currentContext!, + MaterialPageRoute( + builder: (context) => LandingPagePharmacy(currentTab: 3)), + (Route r) => false); } static Widget tableColumnTitle(String text, {bool showDivider = true}) { @@ -956,7 +1127,12 @@ class Utils { Text( text, maxLines: 1, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff2E303A), + letterSpacing: -0.48, + height: 18 / 12), ), SizedBox(height: 5), if (showDivider) @@ -969,8 +1145,14 @@ class Utils { ); } - static Widget tableColumnValue(String text, {bool isLast = false, bool isCapitable = true, bool isHighLow = false, bool isCurrency = false, required ProjectViewModel mProjectViewModel}) { - ProjectViewModel projectViewModel = mProjectViewModel ?? Provider.of(AppGlobal.context); + static Widget tableColumnValue(String text, + {bool isLast = false, + bool isCapitable = true, + bool isHighLow = false, + bool isCurrency = false, + required ProjectViewModel mProjectViewModel}) { + ProjectViewModel projectViewModel = + mProjectViewModel ?? Provider.of(AppGlobal.context); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -980,10 +1162,19 @@ class Utils { children: [ Expanded( child: Text( - isCapitable && !projectViewModel.isArabic ? text.toLowerCase().capitalizeFirstofEach : text, + isCapitable && !projectViewModel.isArabic + ? text.toLowerCase().capitalizeFirstofEach + : text, maxLines: 2, overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: isHighLow ? CustomColors.accentColor : Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: isHighLow + ? CustomColors.accentColor + : Color(0xff575757), + letterSpacing: -0.4, + height: 16 / 10), ), ), isCurrency ? getSaudiRiyalSymbol() : Container(), @@ -1000,7 +1191,10 @@ class Utils { ); } - static Widget tableColumnValueWithFlowChart(String text, String flowChartText, {bool isLast = false, bool isCapitable = true, ProjectViewModel? mProjectViewModel}) { + static Widget tableColumnValueWithFlowChart(String text, String flowChartText, + {bool isLast = false, + bool isCapitable = true, + ProjectViewModel? mProjectViewModel}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -1010,14 +1204,25 @@ class Utils { text, maxLines: 2, overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xff575757), + letterSpacing: -0.4, + height: 16 / 10), ), SizedBox(height: 8), AutoSizeText( flowChartText, maxLines: 1, minFontSize: 6, - style: TextStyle(decoration: TextDecoration.underline, fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffD02127), letterSpacing: -0.48, height: 18 / 12), + style: TextStyle( + decoration: TextDecoration.underline, + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xffD02127), + letterSpacing: -0.48, + height: 18 / 12), ), SizedBox(height: 12), if (!isLast) @@ -1031,7 +1236,9 @@ class Utils { } static Future isGoogleServicesAvailable() async { - GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability(); + GooglePlayServicesAvailability availability = await GoogleApiAvailability + .instance + .checkGooglePlayServicesAvailability(); String status = availability.toString().split('.').last; if (status == "success") { return true; @@ -1047,7 +1254,8 @@ class Utils { final lat1Radians = _toRadians(lat1); final lat2Radians = _toRadians(lat2); - final a = _haversin(dLat) + cos(lat1Radians) * cos(lat2Radians) * _haversin(dLon); + final a = + _haversin(dLat) + cos(lat1Radians) * cos(lat2Radians) * _haversin(dLon); final c = 2 * asin(sqrt(a)); return r * c; @@ -1057,7 +1265,8 @@ class Utils { static num _haversin(double radians) => pow(sin(radians / 2), 2); - static Widget tableColumnValueWithUnderLine(String text, {bool isLast = false, bool isCapitable = true}) { + static Widget tableColumnValueWithUnderLine(String text, + {bool isLast = false, bool isCapitable = true}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, @@ -1068,7 +1277,13 @@ class Utils { isCapitable ? text.toLowerCase().capitalizeFirstofEach : text, maxLines: 1, minFontSize: 6, - style: TextStyle(decoration: TextDecoration.underline, fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xffD02127), letterSpacing: -0.48, height: 18 / 12), + style: TextStyle( + decoration: TextDecoration.underline, + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xffD02127), + letterSpacing: -0.48, + height: 18 / 12), ), SizedBox(height: 10), if (!isLast) @@ -1085,7 +1300,8 @@ class Utils { return crypto.md5.convert(utf8.encode(input)).toString(); } - static bool isVidaPlusProject(ProjectViewModel projectViewModel, int projectID) { + static bool isVidaPlusProject( + ProjectViewModel projectViewModel, int projectID) { bool isVidaPlus = false; projectViewModel.vidaPlusProjectList.forEach((element) { if (element.projectID == projectID) { @@ -1105,7 +1321,8 @@ class Utils { return isHMCProject; } - static ProjectDetailListModel getProjectDetailObj(ProjectViewModel projectViewModel, int projectID) { + static ProjectDetailListModel getProjectDetailObj( + ProjectViewModel projectViewModel, int projectID) { ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); projectViewModel.projectDetailListModel.forEach((element) { if (element.projectID == projectID) { @@ -1116,13 +1333,20 @@ class Utils { } static Widget getSaudiRiyalSymbol({double fontSize = 16}) { - return Text(" SAR ", style: TextStyle(fontFamily: "SaudiRiyal", fontSize: fontSize)); + return Text(" SAR ", + style: TextStyle(fontFamily: "SaudiRiyal", fontSize: fontSize)); } //static String generateSignature() {} } -Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), required Widget child}) { +Widget applyShadow( + {Color color = Colors.grey, + double shadowOpacity = 0.5, + double spreadRadius = 2, + double blurRadius = 7, + Offset offset = const Offset(2, 2), + required Widget child}) { return Container( decoration: BoxDecoration( boxShadow: [ @@ -1139,7 +1363,8 @@ Widget applyShadow({Color color = Colors.grey, double shadowOpacity = 0.5, doubl } Future userData() async { - var userData = AuthenticatedUser.fromJson(await AppSharedPreferences().getObject(MAIN_USER)); + var userData = AuthenticatedUser.fromJson( + await AppSharedPreferences().getObject(MAIN_USER)); return userData; } @@ -1151,9 +1376,13 @@ extension IndexedIterable on Iterable { } } -openAppStore({String? androidPackageName, String? iOSAppID, bool isHuawei = false}) async { +openAppStore( + {String? androidPackageName, + String? iOSAppID, + bool isHuawei = false}) async { if (Platform.isAndroid) { - assert(!(androidPackageName == null), "Should have valid value in androidPackageName parameter"); + assert(!(androidPackageName == null), + "Should have valid value in androidPackageName parameter"); if (isHuawei) { launchUrl(Uri.parse("appmarket://details?id=com.ejada.hmg")); } else { @@ -1161,7 +1390,8 @@ openAppStore({String? androidPackageName, String? iOSAppID, bool isHuawei = fals } } else if (Platform.isIOS) { assert((iOSAppID == null), "Should have valid value in iOSAppID parameter"); - launchUrl(Uri.parse("https://itunes.apple.com/kr/app/apple-store/$iOSAppID)")); + launchUrl( + Uri.parse("https://itunes.apple.com/kr/app/apple-store/$iOSAppID)")); } } @@ -1184,7 +1414,11 @@ String labelFrom({required String className}) { extension StringExtension on String { String capitalize() { - return this.splitMapJoin(RegExp(r'\w+'), onMatch: (m) => '${m.group(0)}'.substring(0, 1).toUpperCase() + '${m.group(0)}'.substring(1).toLowerCase(), onNonMatch: (n) => ' '); + return this.splitMapJoin(RegExp(r'\w+'), + onMatch: (m) => + '${m.group(0)}'.substring(0, 1).toUpperCase() + + '${m.group(0)}'.substring(1).toLowerCase(), + onNonMatch: (n) => ' '); } } @@ -1288,9 +1522,12 @@ extension SelectedLanguageExtension on BuildContext { return language; } - double getLottieScaledWidth(double value) => MediaQuery.of(this).size.width * (value / MediaQuery.of(this).size.width); + double getLottieScaledWidth(double value) => + MediaQuery.of(this).size.width * (value / MediaQuery.of(this).size.width); - double getLottieScaledHeight(double value) => MediaQuery.of(this).size.height * (value / MediaQuery.of(this).size.height); + double getLottieScaledHeight(double value) => + MediaQuery.of(this).size.height * + (value / MediaQuery.of(this).size.height); } extension GenderTypeExtension on GenderType {