import 'dart:convert'; import 'dart:core'; import 'dart:io'; import 'dart:typed_data'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:badges/badges.dart' as badge_import; import 'package:cached_network_image/cached_network_image.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:crypto/crypto.dart' as crypto; import 'package:hmg_patient_app/analytics/google-analytics.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/model/privilege/ProjectDetailListModel.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/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart'; import 'package:hmg_patient_app/pages/MyAppointments/MyAppointments.dart'; import 'package:hmg_patient_app/pages/insurance/insurance_approval_screen.dart'; import 'package:hmg_patient_app/pages/insurance/insurance_card_screen.dart'; import 'package:hmg_patient_app/pages/insurance/insurance_update_screen.dart'; import 'package:hmg_patient_app/pages/landing/landing_page_pharmcy.dart'; import 'package:hmg_patient_app/pages/medical/active_medications/ActiveMedicationsPage.dart'; import 'package:hmg_patient_app/pages/medical/allergies_page.dart'; import 'package:hmg_patient_app/pages/medical/ask_doctor/ask_doctor_home_page.dart'; import 'package:hmg_patient_app/pages/medical/balance/my_balance_page.dart'; import 'package:hmg_patient_app/pages/medical/dental_instructions_page.dart'; import 'package:hmg_patient_app/pages/medical/doctor/doctor_home_page.dart'; import 'package:hmg_patient_app/pages/medical/eye/EyeMeasurementsPage.dart'; import 'package:hmg_patient_app/pages/medical/labs/labs_home_page.dart'; import 'package:hmg_patient_app/pages/medical/my_invoices/my_invoice_page.dart'; import 'package:hmg_patient_app/pages/medical/my_trackers/my_trackers.dart'; import 'package:hmg_patient_app/pages/medical/patient_sick_leave_page.dart'; import 'package:hmg_patient_app/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:hmg_patient_app/pages/medical/radiology/radiology_home_page.dart'; import 'package:hmg_patient_app/pages/medical/reports/monthly_reports.dart'; import 'package:hmg_patient_app/pages/medical/reports/report_home_page.dart'; import 'package:hmg_patient_app/pages/medical/smart_watch_health_data/smart_watch_instructions.dart'; import 'package:hmg_patient_app/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:hmg_patient_app/pages/vaccine/my_vaccines_screen.dart'; import 'package:hmg_patient_app/theme/colors.dart'; import 'package:hmg_patient_app/uitl/translations_delegate_base.dart'; import 'package:hmg_patient_app/uitl/utils_new.dart'; import 'package:hmg_patient_app/widgets/data_display/medical/medical_profile_item.dart'; import 'package:hmg_patient_app/widgets/dialogs/alert_dialog.dart'; import 'package:hmg_patient_app/widgets/dialogs/covid_consent_dialog.dart'; import 'package:hmg_patient_app/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_api_availability/google_api_availability.dart'; import 'package:lottie/lottie.dart'; import 'dart:math' show asin, cos, pi, pow, sin, sqrt; // import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import '../Constants.dart'; import '../locator.dart'; import 'app_shared_preferences.dart'; import 'app_toast.dart'; import 'gif_loader_dialog_utils.dart'; import 'navigation_service.dart'; AppSharedPreferences sharedPref = new AppSharedPreferences(); enum OTPType { sms, whatsapp } enum Country { saudiArabia, unitedArabEmirates } enum SelectionType { dropdown, calendar } enum GenderType { male, female } enum MaritalStatusType { single, married, divorced, widowed } class Utils { static int? onOtpBtnPressed(OTPType type, String? phoneNumber) { if (phoneNumber == null || phoneNumber.isEmpty) { Utils.showErrorToast("Please enter your phone number."); return null; } print("Requesting OTP for ${phoneNumber} via ${type == OTPType.whatsapp ? "WhatsApp" : "SMS"} and "); return type == OTPType.sms ? 1 : 4; } static bool validateIqama(String iqamaNumber) { String cleanedIqama = iqamaNumber.replaceAll(RegExp(r'[^0-9]'), ''); if (cleanedIqama.length != 10) { return false; } int firstDigit = int.parse(cleanedIqama[0]); if (firstDigit != 2 && firstDigit != 1) { return false; } int sum = 0; for (int i = 0; i < 10; i++) { int digit = int.parse(cleanedIqama[i]); int weight = (i % 2 == 0) ? 2 : 1; // Alternate weights: 2, 1, 2, 1... int product = digit * weight; sum += (product > 9) ? product - 9 : product; // Sum digits if product > 9 } return sum % 10 == 0; } 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'); } else { context.read().changeLanguage('ar'); locator().hamburgerMenu.logMenuItemClick('change language to arabic'); } } static String formatDateToDisplay(String isoDateString) { try { final dateTime = DateTime.parse(isoDateString); final day = dateTime.day.toString().padLeft(2, '0'); 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']; final month = monthNames[dateTime.month - 1]; return '$day $month, $year'; return '$day $month, $year'; } catch (e) { print("Error formatting date: $e"); return ""; } } static String formatDateToUsage(String isoDateString) { try { final dateTime = DateTime.parse(isoDateString); final day = dateTime.day.toString().padLeft(2, '0'); final month = dateTime.month.toString().padLeft(2, '0'); final year = dateTime.year.toString(); return '$day-$month-$year'; } catch (e) { print("Error formatting date: $e"); return ""; } } static Widget showLottie({ required BuildContext context, String assetPath = 'assets/icons/no_property.json', double? height, double? width, BoxFit fit = BoxFit.cover, Alignment alignment = Alignment.center, bool repeat = false, bool animate = true, void Function(LottieComposition)? onLoaded, }) { return Lottie.asset(assetPath, height: height ?? MediaQuery.of(context).size.height * 0.26, width: width ?? MediaQuery.of(context).size.width, fit: fit, alignment: alignment, repeat: repeat, animate: animate, onLoaded: onLoaded); } static var navigationProjectsList = [ { "Desciption": "Sahafa Hospital", "DesciptionN": "مستشفى الصحافة", "ID": 130, "LegalName": "Sahafa Hospital", "LegalNameN": "مستشفى الصحافة", "Name": "Sahafa Hospital", "NameN": "مستشفى الصحافة", "PhoneNumber": "+966115222222", "SetupID": "013311", "DistanceInKilometers": 0, "HasVida3": false, "IsActive": true, "IsHmg": true, "IsVidaPlus": false, "Latitude": "24.8113774", "Longitude": "46.6239813", "MainProjectID": 130, "ProjectOutSA": false, "UsingInDoctorApp": false } ]; ///show custom Error Toast /// [message] to show for user static showErrorToast([String? message, BuildContext? context]) { String localMsg = generateContactAdminMessage(); if (message != null) { localMsg = message.toString(); } AppToast.showErrorToast(message: localMsg, localContext: context); } /// Check The Internet Connection // static Future checkConnection({bool bypassConnectionCheck = false}) async { // if (bypassConnectionCheck) return true; // //return true; // ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity()); // if ((connectivityResult == ConnectivityResult.mobile) || (connectivityResult == ConnectivityResult.wifi)) { // return true; // } else { // return false; // } // } 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)) { return true; } else { return false; } } /// generate Contact Admin Message static generateContactAdminMessage([err]) { String localMsg = 'Something wrong happened, please contact the admin'; if (err != null) { localMsg = localMsg + '\n \n' + err.toString(); } return localMsg; } /// hides the keyboard if its already open static hideKeyboard(BuildContext context) { FocusScope.of(context).unfocus(); } static showPermissionConsentDialog(BuildContext context, String message, VoidCallback? onTap) { showDialog( context: context, builder: (cxt) => CovidConsentDialog( okTitle: TranslationBase.of(context).acceptLbl, title: TranslationBase.of(context).covidConsentHeader, message: message, onTap: onTap!, )); } bool isSAUDIIDValid(String id, type) { if (type == 1) { if (id == null) { return false; } try { id = id.toString(); id = id.trim(); var returnValue = int.parse(id); var sum = 0; if (returnValue > 0) { var type = int.parse(id[0]); if (id.length != 10) { return false; } if (type != 2 && type != 1) { return false; } for (var i = 0; i < 10; i++) { if (i % 2 == 0) { var a = id[i]; var x = int.parse(a) * 2; var b = x.toString(); if (b.length == 1) { b = "0" + b; } sum += int.parse(b[0]) + int.parse(b[1]); } else { sum += int.parse(id[i]); } } return sum % 10 == 0; } } catch (err) {} return false; } else { return 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) : ""); } static String getAdvancePaymentTransID(int projectID, int fileNumber) { return projectID.toString() + '-' + fileNumber.toString() + '-' + DateTime.now().millisecondsSinceEpoch.toString(); } bool validateIDBox(String value, int type) { String pattern = loginIDPattern(type); // Get the pattern based on type RegExp regex = RegExp(pattern); return regex.hasMatch(value); } String loginIDPattern(int loginType) { var length = loginType == 1 ? 10 : 1; return "([0-9]{" + length.toString() + "}\$)"; } static showProgressDialog(context, [String message = "Loading..."]) async { // pr = ProgressDialog(context, // type: ProgressDialogType.Normal, isDismissible: false, showLogs: false); // pr.style( // message: message, // borderRadius: 10.0, // backgroundColor: Colors.white, // elevation: 10.0, // insetAnimCurve: Curves.easeInOut, // progress: 0.0, // maxProgress: 100.0, // progressTextStyle: TextStyle( // color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.w400), // messageTextStyle: TextStyle( // color: Colors.black, fontSize: 19.0, fontWeight: FontWeight.w600)); // if (!pr.isShowing()) { // await pr.show(); // } else { // await pr.hide(); // await pr.show(); // } } static hideProgressDialog() async { // if (pr.isShowing()) { // await pr.hide(); // } } static getPhoneNumberWithoutZero(String number) { String newNumber = ""; if (number.startsWith('0')) { newNumber = number.substring(1); } else { newNumber = number; } return newNumber; } static Uint8List dataFromBase64String(String base64String) { return base64Decode(base64String); } static validEmail(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}) { List medical = []; medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(5) ? Navigator.push(context, FadePage(page: MyAppointments())) : null, child: isLogin! ? Stack(children: [ Container( width: double.infinity, height: double.infinity, child: MedicalProfileItem( title: TranslationBase.of(context!).myAppointments, imagePath: 'appointment_list.svg', subTitle: TranslationBase.of(context).myAppointmentsList, hasBadge: true, isEnable: projectViewModel!.havePrivilege(5)), ), projectViewModel.isArabic ? !projectViewModel.user.isFamily ? Positioned( left: 8, top: 4, child: badge_import.Badge( badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, badgeColor: secondaryColor!.withOpacity(1.0), borderRadius: BorderRadius.circular(8), ), 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)), ), ), ) : Container() : !projectViewModel.user!.isFamily ? Positioned( right: 8, top: 4, child: badge_import.Badge( position: badge_import.BadgePosition.topEnd(), badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, badgeColor: secondaryColor!.withOpacity(1.0), borderRadius: BorderRadius.circular(8), ), badgeContent: Container( padding: EdgeInsets.all(2.0), child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), ), ), ) : Container(), ]) : MedicalProfileItem( title: TranslationBase.of(context!).myAppointments, imagePath: 'appointment_list.svg', subTitle: TranslationBase.of(context!).myAppointmentsList, hasBadge: true, isEnable: projectViewModel!.havePrivilege(5), ), )); if (projectViewModel.havePrivilege(10)) { medical.add(InkWell( onTap: () => Navigator.push(context, FadePage(page: LabsHomePage())), child: MedicalProfileItem( title: TranslationBase.of(context).lab, imagePath: 'lab_result.svg', subTitle: TranslationBase.of(context).labSubtitle, ), )); } medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(7) ? Navigator.push(context, FadePage(page: RadiologyHomePage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).radiology, imagePath: 'radiology.svg', subTitle: TranslationBase.of(context).radiologySubtitle, isEnable: projectViewModel.havePrivilege(7), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(12) ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).medicines, imagePath: 'medicine_prescription.svg', subTitle: TranslationBase.of(context).medicinesSubtitle, isEnable: projectViewModel.havePrivilege(12), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(25) ? Navigator.push( context, FadePage(page: VitalSignDetailsScreen()), ) : null, child: MedicalProfileItem( title: TranslationBase.of(context).vitalSigns, imagePath: 'vital_signs.svg', subTitle: TranslationBase.of(context).vitalSignsSubtitle, isEnable: projectViewModel.havePrivilege(25), ), )); medical.add(InkWell( onTap: () { if (projectViewModel.havePrivilege(48)) Navigator.push(context, FadePage(page: ActiveMedicationsPage())); }, child: MedicalProfileItem( title: TranslationBase.of(context).myMedical, imagePath: 'active_medication.svg', subTitle: TranslationBase.of(context).myMedicalSubtitle, isEnable: projectViewModel.havePrivilege(48), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(6) ? Navigator.push( context, FadePage( page: DoctorHomePage(), ), ) : null, 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, child: MedicalProfileItem( title: TranslationBase.of(context).invoicesList, imagePath: 'invoice_list.svg', subTitle: TranslationBase.of(context).myInvoice, isEnable: projectViewModel.havePrivilege(14), ), )); medical.add(InkWell( 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, imagePath: 'ancillary.svg', isPngImage: false, subTitle: TranslationBase.of(context).myInvoice, isEnable: projectViewModel.havePrivilege(85), ), )); medical.add(InkWell( onTap: () => onWeCareClick!(), child: MedicalProfileItem( title: TranslationBase.of(context).wecare, imagePath: 'assets/images/new-design/virtual_tour_icon.png', isPngImage: true, subTitle: TranslationBase.of(context).service, isEnable: projectViewModel.havePrivilege(105), ), )); medical.add(InkWell( onTap: () { Navigator.push(context, FadePage(page: DentalInstructionsPage())); }, child: MedicalProfileItem( title: TranslationBase.of(context).myinstructions, imagePath: 'medical_instructions.svg', isPngImage: false, subTitle: TranslationBase.of(context).service, isEnable: projectViewModel.havePrivilege(106), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: EyeMeasurementsPage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).eye, imagePath: 'eye_measurement.svg', subTitle: TranslationBase.of(context).eyeSubtitle, isEnable: projectViewModel.havePrivilege(14), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(22) ? Navigator.push( context, FadePage( page: InsuranceCard( appointmentNo: 0, ))) : null, child: MedicalProfileItem( title: TranslationBase.of(context).insurance, imagePath: 'insurance_card.svg', subTitle: TranslationBase.of(context).insuranceSubtitle, isEnable: projectViewModel.havePrivilege(22), ), )); medical.add(InkWell( onTap: () { Navigator.push(context, FadePage(page: InsuranceUpdate())); }, child: MedicalProfileItem( title: TranslationBase.of(context).updateInsurance, imagePath: 'insurance_card.svg', subTitle: TranslationBase.of(context).updateInsuranceSubtitle, ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(18) ? Navigator.push( context, FadePage( page: InsuranceApproval( appointmentNo: 0, ))) : null, child: MedicalProfileItem( title: TranslationBase.of(context).insuranceApproval, imagePath: 'insurance_approval.svg', subTitle: TranslationBase.of(context).insuranceApprovalSubtitle, isEnable: projectViewModel.havePrivilege(18), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(23) ? Navigator.push(context, FadePage(page: AllergiesPage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).allergies, imagePath: 'allergies_diagnosed.svg', subTitle: TranslationBase.of(context).allergiesSubtitle, isEnable: projectViewModel.havePrivilege(23), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(26) ? Navigator.push(context, FadePage(page: MyVaccines())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).myVaccines, imagePath: 'vaccine_list.svg', subTitle: TranslationBase.of(context).myVaccinesSubtitle, isEnable: projectViewModel.havePrivilege(26), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(20) ? Navigator.push(context, FadePage(page: HomeReportPage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).medical, imagePath: 'medical_report.svg', subTitle: TranslationBase.of(context).medicalSubtitle, isEnable: projectViewModel.havePrivilege(20), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(19) ? Navigator.push(context, FadePage(page: MonthlyReportsPage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).monthly, imagePath: 'monthly_report.svg', subTitle: TranslationBase.of(context).monthlySubtitle, isEnable: projectViewModel.havePrivilege(19), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(16) ? Navigator.push(context, FadePage(page: PatientSickLeavePage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).sick, imagePath: 'sick_leave.svg', subTitle: TranslationBase.of(context).sickSubtitle, isEnable: projectViewModel.havePrivilege(16), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(47) ? Navigator.push(context, FadePage(page: MyBalancePage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).myBalance, imagePath: 'balance_credit.svg', subTitle: TranslationBase.of(context).myBalanceSubtitle, isEnable: projectViewModel.havePrivilege(47), ), )); // medical.add(MedicalProfileItem( // title: TranslationBase.of(context).patientCall, // imagePath: 'medical_history_icon.png', // subTitle: TranslationBase.of(context).patientCallSubtitle, // isEnable: projectViewModel.havePrivilege(61), // )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(24) ? Navigator.push(context, FadePage(page: MyTrackers())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).myTrackers, imagePath: 'tracker.svg', subTitle: TranslationBase.of(context).myTrackersSubtitle, isEnable: projectViewModel.havePrivilege(24), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(30) ? Navigator.push(context, FadePage(page: SmartWatchInstructions())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).smartWatchesSubtitle, imagePath: 'smart_watch.svg', subTitle: TranslationBase.of(context).smartWatches, isEnable: projectViewModel.havePrivilege(30), ), )); medical.add(InkWell( 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)), )); if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( onTap: () { if (Platform.isAndroid) { showPermissionConsentDialog(context, TranslationBase.of(context).wifiPermission, () { connectWifi(projectViewModel, context); }); } else { connectWifi(projectViewModel, context); } }, child: MedicalProfileItem( title: TranslationBase.of(context).internet, imagePath: 'internet_connection.svg', subTitle: TranslationBase.of(context).internetSubtitle, ), )); } medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(40) ? launch('whatsapp://send?phone=18885521858&text=') : null, child: MedicalProfileItem( title: TranslationBase.of(context).chatbot, imagePath: 'chatbot.svg', subTitle: TranslationBase.of(context).chatbotSubtitle, isEnable: projectViewModel.havePrivilege(40), ), )); return medical; } 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) { 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) { successCallback(username, password); } } }, onFailure: (String error, int statusCode) { print(error); }, bypassConnectionCheck: true); } static connectWifi(ProjectViewModel projectViewModel, BuildContext context) { final String GUEST_SSID = "HMG-MobileApp"; final String PATIENT_SSID = "GUEST-POC"; userData().then((userData_) { if (projectViewModel.isLogin && userData_ != null || true) { String patientID = userData_.patientID.toString(); GifLoaderDialogUtils.showMyDialog(context); // projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}).catchError((err) { // print(err.toString()); // }); 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())); GifLoaderDialogUtils.hideDialog(context); if (result == 1) { // Success } }); } }).catchError((e) { GifLoaderDialogUtils.hideDialog(context); }); } else { AlertDialogBox( context: context, confirmMessage: "Please login with your account first to use this feature", okText: "OK", okFunction: () { AlertDialogBox.closeAlertDialog(context); }).showAlertDialog(context); } }); } 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, child: isLogin! ? Stack(children: [ MedicalProfileItem( title: TranslationBase.of(context!).myAppointments, imagePath: 'appointment_list.svg', subTitle: TranslationBase.of(context!).myAppointmentsList, hasBadge: true, isEnable: projectViewModel!.havePrivilege(5)), projectViewModel.isArabic! ? !projectViewModel.isLoginChild ? Positioned( left: 8, top: 4, child: badge_import.Badge( position: badge_import.BadgePosition.topEnd(), badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, badgeColor: secondaryColor!.withOpacity(1.0), borderRadius: BorderRadius.circular(8), ), badgeContent: Container( padding: EdgeInsets.all(2.0), child: Text(count.toString(), style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12.0)), ), ), ) : Container() : !projectViewModel.isLoginChild ? Positioned( right: 8, top: 4, child: badge_import.Badge( badgeAnimation: badge_import.BadgeAnimation.fade(toAnimate: false), badgeStyle: badge_import.BadgeStyle( elevation: 0, shape: badge_import.BadgeShape.circle, badgeColor: secondaryColor!.withOpacity(1.0), borderRadius: BorderRadius.circular(8), ), 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)), ), ), ) : Container(), ]) : MedicalProfileItem( title: TranslationBase.of(context!).myAppointments, imagePath: 'appointment_list.svg', subTitle: TranslationBase.of(context!).myAppointmentsList, hasBadge: true, isEnable: projectViewModel!.havePrivilege(5), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(10) ? Navigator.push(context, FadePage(page: LabsHomePage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).lab, imagePath: 'lab_result.svg', subTitle: TranslationBase.of(context).labSubtitle, isEnable: projectViewModel.havePrivilege(10), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(7) ? Navigator.push(context, FadePage(page: RadiologyHomePage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).radiology, imagePath: 'radiology.svg', subTitle: TranslationBase.of(context).radiologySubtitle, isEnable: projectViewModel.havePrivilege(7), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(12) ? Navigator.push(context, FadePage(page: HomePrescriptionsPage())) : null, child: MedicalProfileItem( title: TranslationBase.of(context).medicines, imagePath: 'medicine_prescription.svg', subTitle: TranslationBase.of(context).medicinesSubtitle, isEnable: projectViewModel.havePrivilege(12), ), )); medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(6) ? Navigator.push( context, FadePage( page: DoctorHomePage(), ), ) : null, 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}) { return CachedNetworkImage( placeholderFadeInDuration: Duration(milliseconds: 250), fit: fitting, imageUrl: url, placeholder: (context, url) => Container(child: Center(child: CircularProgressIndicator())), errorWidget: (context, url, error) { return Icon( Icons.error, color: Colors.red, size: 50, ); }); } static bool route(Route route, {required Type equalsTo}) { if ((route is FadePage)) { return route.page.runtimeType == equalsTo; } return route.runtimeType == equalsTo; } static navigateToCartPage() { Navigator.pushAndRemoveUntil(locator()!.navigatorKey!.currentContext!, MaterialPageRoute(builder: (context) => LandingPagePharmacy(currentTab: 3)), (Route r) => false); } static Widget tableColumnTitle(String text, {bool showDivider = true}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 6), Text( text, maxLines: 1, style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.48, height: 18 / 12), ), SizedBox(height: 5), if (showDivider) Divider( height: 1, color: Color(0xff2E303A), thickness: 1, ) ], ); } 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, children: [ SizedBox(height: 12), Row( children: [ Expanded( child: 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), ), ), isCurrency ? getSaudiRiyalSymbol() : Container(), ], ), SizedBox(height: 12), if (!isLast) Divider( height: 1, color: Color(0xffEFEFEF), thickness: 1, ) ], ); } static Widget tableColumnValueWithFlowChart(String text, String flowChartText, {bool isLast = false, bool isCapitable = true, ProjectViewModel? mProjectViewModel}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 12), Text( text, maxLines: 2, overflow: TextOverflow.ellipsis, 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), ), SizedBox(height: 12), if (!isLast) Divider( height: 1, color: Color(0xffEFEFEF), thickness: 1, ) ], ); } static Future isGoogleServicesAvailable() async { GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability(); String status = availability.toString().split('.').last; if (status == "success") { return true; } return false; } static double distance(double lat1, double lon1, double lat2, double lon2) { const r = 6372.8; // Earth radius in kilometers final dLat = _toRadians(lat2 - lat1); final dLon = _toRadians(lon2 - lon1); final lat1Radians = _toRadians(lat1); final lat2Radians = _toRadians(lat2); final a = _haversin(dLat) + cos(lat1Radians) * cos(lat2Radians) * _haversin(dLon); final c = 2 * asin(sqrt(a)); return r * c; } static double _toRadians(double degrees) => degrees * pi / 180; static num _haversin(double radians) => pow(sin(radians / 2), 2); static Widget tableColumnValueWithUnderLine(String text, {bool isLast = false, bool isCapitable = true}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 14), AutoSizeText( 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), ), SizedBox(height: 10), if (!isLast) Divider( height: 1, color: Color(0xffEFEFEF), thickness: 1, ) ], ); } static String generateMd5Hash(String input) { return crypto.md5.convert(utf8.encode(input)).toString(); } static bool isVidaPlusProject(ProjectViewModel projectViewModel, int projectID) { bool isVidaPlus = false; projectViewModel.vidaPlusProjectList.forEach((element) { if (element.projectID == projectID) { isVidaPlus = true; } }); return isVidaPlus; } static bool isHMCProject(ProjectViewModel projectViewModel, int projectID) { bool isHMCProject = false; projectViewModel.hMCProjectListModel.forEach((element) { if (element.projectID == projectID) { isHMCProject = true; } }); return isHMCProject; } static ProjectDetailListModel getProjectDetailObj(ProjectViewModel projectViewModel, int projectID) { ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); projectViewModel.projectDetailListModel.forEach((element) { if (element.projectID == projectID) { projectDetailListModel = element; } }); return projectDetailListModel; } static Widget getSaudiRiyalSymbol({double fontSize = 16}) { 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}) { return Container( decoration: BoxDecoration( boxShadow: [ BoxShadow( color: color.withOpacity(shadowOpacity), spreadRadius: spreadRadius, blurRadius: blurRadius, offset: offset, // changes position of shadow ), ], ), child: child, ); } Future userData() async { var userData = AuthenticatedUser.fromJson(await AppSharedPreferences().getObject(MAIN_USER)); return userData; } // extension function that use in iterations(list.. etc) to iterate items and get index and item it self extension IndexedIterable on Iterable { Iterable mapIndexed(T Function(E e, int i) f) { var i = 0; return map((e) => f(e, i++)); } } openAppStore({String? androidPackageName, String? iOSAppID, bool isHuawei = false}) async { if (Platform.isAndroid) { assert(!(androidPackageName == null), "Should have valid value in androidPackageName parameter"); if (isHuawei) { launchUrl(Uri.parse("appmarket://details?id=com.ejada.hmg")); } else { launchUrl(Uri.parse("market://details?id=com.ejada.hmg")); } } 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)")); } } String labelFrom({required String className}) { RegExp exp = RegExp(r'(?<=[a-z])[A-Z]'); String result = className.replaceAllMapped(exp, (m) { var str = m.group(0); if (str != null) { return ('_' + str); } return ""; }); if (result.isEmpty) return className; result = result.replaceAll("_", " "); return result; } 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) => ' '); } } extension TextToRichTextWithIcon on Text { RichText toRichTextWithIcon() { // Create the base TextSpan with the text data and style from the Text widget return RichText( text: TextSpan( style: this.style, // Inherit the text style children: [ WidgetSpan( child: Text(" SAR ", style: TextStyle(fontFamily: "SaudiRiyal")), ), TextSpan( text: this.data, // Add the original text style: this.style, // Inherit the text style ), ], ), ); } } extension WidgetPaddingExtensions on Widget { Widget withHorizontalPadding([double padding = 16.0]) { return Padding( padding: EdgeInsets.symmetric(horizontal: padding), child: this, ); } Widget withVerticalPadding([double padding = 16.0]) { return Padding( padding: EdgeInsets.symmetric(vertical: padding), child: this, ); } } extension CountryExtension on Country { String get displayName { switch (this) { case Country.saudiArabia: return "Kingdom Of Saudi Arabia"; case Country.unitedArabEmirates: return "United Arab Emirates"; } } String get nameArabic { switch (this) { case Country.saudiArabia: return "المملكة العربية السعودية"; case Country.unitedArabEmirates: return "الإمارات العربية المتحدة"; } } String get iconPath { switch (this) { case Country.saudiArabia: return "assets/images/svg/ksa.svg"; case Country.unitedArabEmirates: return "assets/images/svg/uae.svg"; } } String get countryCode { switch (this) { case Country.saudiArabia: return "966"; case Country.unitedArabEmirates: return "971"; } } static Country fromDisplayName(String name) { switch (name) { case "Kingdom Of Saudi Arabia": case "المملكة العربية السعودية": return Country.saudiArabia; case "United Arab Emirates": case "الإمارات العربية المتحدة": return Country.unitedArabEmirates; default: throw Exception("Invalid country name"); } } } extension FontFamilyExtension on BuildContext { String get fontFamily { final language = read().currentLanguage; return language == 'ar' ? 'Cairo' : 'Poppins'; } } extension SelectedLanguageExtension on BuildContext { String get selectedLanguage { final language = read().currentLanguage; return language; } 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); } extension GenderTypeExtension on GenderType { String get value => this == GenderType.male ? "M" : "F"; String get type => this == GenderType.male ? "Male" : "Female"; String get typeAr => this == GenderType.male ? "ذكر" : "أنثى"; static GenderType? fromValue(String? value) { switch (value) { case "M": return GenderType.male; case "F": return GenderType.female; default: return null; } } static GenderType? fromType(String? type) { switch (type) { case "Male": return GenderType.male; case "Female": return GenderType.female; default: return null; } } } extension MaritalStatusTypeExtension on MaritalStatusType { String get value { switch (this) { case MaritalStatusType.single: return "U"; case MaritalStatusType.married: return "M"; case MaritalStatusType.divorced: return "D"; case MaritalStatusType.widowed: return "W"; } } String get type { switch (this) { case MaritalStatusType.single: return "Single"; case MaritalStatusType.married: return "Married"; case MaritalStatusType.divorced: return "Divorced"; case MaritalStatusType.widowed: return "Widowed"; } } String get typeAr { switch (this) { case MaritalStatusType.single: return "أعزب"; case MaritalStatusType.married: return "متزوج"; case MaritalStatusType.divorced: return "مطلق"; case MaritalStatusType.widowed: return "أرمل"; } } static MaritalStatusType? fromValue(String? value) { switch (value) { case "U": return MaritalStatusType.single; case "M": return MaritalStatusType.married; case "D": return MaritalStatusType.divorced; case "W": return MaritalStatusType.widowed; default: return null; } } static MaritalStatusType? fromType(String? type) { switch (type) { case "Single": return MaritalStatusType.single; case "Married": return MaritalStatusType.married; case "Divorced": return MaritalStatusType.divorced; case "Widowed": return MaritalStatusType.widowed; default: return null; } } } /* userBoard.asMap().map((i, element) => MapEntry(i, Stack( GestureDetector(onTap: () { setState(() { // print("element=${element.toString()}"); // print("element=${userBoard[i].toString()}"); }); }), ))).values.toList(); */