diff --git a/assets/images/png/lakum_logo.png b/assets/images/png/lakum_logo.png new file mode 100644 index 00000000..b0318712 Binary files /dev/null and b/assets/images/png/lakum_logo.png differ diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index e77df4c6..dab50baa 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -286,7 +286,7 @@ "gate": "البوابة:", "building": "المبنى:", "branch": "الفرع:", - "emergencyServices": "خدمات الطوارئ", + "emergencyServices": "خدمات \n الطوارئ", "nearester": "أقرب طوارئ", "locationa": "الموقع", "callNow": "الاتصال المباشر", @@ -1236,9 +1236,9 @@ "monitorBloodPressureLevels": "راقب مستويات ضغط الدم لديك، وتتبع القراءات الانقباضية والانبساطية، وحافظ على صحة قلبك.", "trackWeightProgress": "تتبع تقدم وزنك، وضع الأهداف، وحافظ على كتلة جسم صحية من أجل العافية الشاملة.", "bookAppointment": "حجز\nموعد", - "completeCheckup": "الفحص الشامل", + "completeCheckup": "الفحص \n الشامل", "indoorNavigation": "الملاحة الداخلية", - "eReferralServices": "الإحالة الإلكترونية", + "eReferralServices": "الإحالة \n الإلكترونية", "bloodDonation": "التبرع بالدم", "dailyWaterMonitor": "مراقب الماء اليومي", "fetchingYourWaterIntakeDetails": "يرجى الانتظار…", @@ -1845,5 +1845,5 @@ "maxOneFileAllowed": "يمكن رفع ملف واحد فقط", "fileSizeExceedsLimit": "يجب ألا يتجاوز حجم الملف 1 ميغابايت", "completedPrescriptionOrder": "تمت الخدمة", - "submitReferral": "تقديم الطلب" + "submitEReferral": "تقديم الطلب" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 12d9659a..b4dd35f7 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1801,7 +1801,7 @@ "watchUsOnYoutube": "Watch us on youtube", "connectOnLinkedin": "Connect on LinkedIn", "riskFactorPageTitle": "What do you feel?", - "bloodDonationService": "Blood Donation", + "bloodDonationService": "Blood \nDonation", "bookAppointmentService": "Book\nAppointment", "pinchToZoom": "Pinch to zoom", "gotIt": "Got it", @@ -1835,7 +1835,7 @@ "maxOneFileAllowed": "Only 1 file can be uploaded", "fileSizeExceedsLimit": "File size must not exceed 1 MB", "completedPrescriptionOrder": "Completed", - "submitReferral": "Submit" + "submitEReferral": "Submit" } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index c394d3f9..74fa0ee7 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -4,7 +4,7 @@ import 'package:hmg_patient_app_new/core/enums.dart'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT @@ -58,8 +58,6 @@ class ApiConsts { symptomsCheckerApi = symptomsCheckerApiLive; symptomsCheckerUsername = 'mobile_user'; symptomsCheckerPassword = '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'; - - CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId="; break; case AppEnvironmentTypeEnum.dev: baseUrl = "https://uat.hmgwebservices.com/"; @@ -283,7 +281,7 @@ class ApiConsts { static String googleCloudStorageENTranslationFileBaseURL = "https://storage.googleapis.com/hmg-patientapp-translations"; // ************ static values for Api **************** - static final double appVersionID = 21.0; + static final double appVersionID = 21.1; // static final double appVersionID = 50.7; static final int appChannelId = 3; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index e3f180c1..2612bde9 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -417,6 +417,7 @@ class AppAssets { static const String comprehensiveCheckupAr = '$pngBasePath/cc_ar.png'; static const String maleIcon = '$pngBasePath/male_icon.png'; static const String femaleIcon = '$pngBasePath/female_icon.png'; + static const String lakumLogo = '$pngBasePath/lakum_logo.png'; static const String fullBodyFrontMale = '$pngBasePath/full_body_front_male.png'; static const String fullBodyBackMale = '$pngBasePath/full_body_back_male.png'; diff --git a/lib/core/utils/push_notification_handler.dart b/lib/core/utils/push_notification_handler.dart index 9bf34660..4b7250ba 100644 --- a/lib/core/utils/push_notification_handler.dart +++ b/lib/core/utils/push_notification_handler.dart @@ -442,7 +442,7 @@ class PushNotificationHandler { badge: true, sound: true, ); - if (permission.authorizationStatus == AuthorizationStatus.denied) return; + // if (permission.authorizationStatus == AuthorizationStatus.denied) return; } else { final permission = await FirebaseMessaging.instance.requestPermission(); } @@ -494,7 +494,7 @@ class PushNotificationHandler { log("Push Notification getToken: ${token!}"); onToken(token!); }).catchError((err) { - log(err); + log(err.toString()); }); FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 066464b9..385d3e76 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -284,10 +284,14 @@ class AuthenticationViewModel extends ChangeNotifier { // Validate based on selected country if (selectedCountrySignup == CountryEnum.saudiArabia) { - if (!ValidationUtils.validateIqama(nationalIdController.text)) { - _nationalIdError = LocaleKeys.pleaseEnterAValidIqamaID.tr(); - notifyListeners(); - return false; + if (cleanedId.length == 10) { + if (!ValidationUtils.validateIqama(nationalIdController.text)) { + _nationalIdError = LocaleKeys.pleaseEnterAValidIqamaID.tr(); + notifyListeners(); + return false; + } + } else { + return true; } } else if (selectedCountrySignup == CountryEnum.unitedArabEmirates) { if (!ValidationUtils.validateUaeNationalId(nationalIdController.text)) { diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index 1d15fdd2..7ac09686 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -1106,7 +1106,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { docID: selectedDoctor.doctorID!, clinicID: selectedDoctor.clinicID!, projectID: selectedDoctor.projectID!, - serviceID: selectedLiveCareClinic.serviceID!, + serviceID: selectedLiveCareClinic.serviceID ?? 0, selectedDate: selectedAppointmentDate, selectedTime: selectedAppointmentTime, initialSlotDuration: initialSlotDuration, diff --git a/lib/features/contact_us/contact_us_view_model.dart b/lib/features/contact_us/contact_us_view_model.dart index b9fe55f0..00ef8dbc 100644 --- a/lib/features/contact_us/contact_us_view_model.dart +++ b/lib/features/contact_us/contact_us_view_model.dart @@ -290,9 +290,9 @@ class ContactUsViewModel extends ChangeNotifier { requestInsertCOCItem.isUserLoggedIn = true; requestInsertCOCItem.projectID = 0; requestInsertCOCItem.patientName = "${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}"; - requestInsertCOCItem.fileName = ""; + requestInsertCOCItem.fileName = "Image 1"; requestInsertCOCItem.appVersion = ApiConsts.appVersionID; - requestInsertCOCItem.uILanguage = appState.isArabic() ? "ar" : "en"; //TODO Change it to be dynamic + requestInsertCOCItem.uILanguage = appState.isArabic() ? "ar" : "en"; requestInsertCOCItem.browserInfo = Platform.localHostname; requestInsertCOCItem.deviceInfo = Platform.localHostname; requestInsertCOCItem.resolution = "400x847"; diff --git a/lib/features/habib_wallet/habib_wallet_view_model.dart b/lib/features/habib_wallet/habib_wallet_view_model.dart index 44fd640a..01dc2357 100644 --- a/lib/features/habib_wallet/habib_wallet_view_model.dart +++ b/lib/features/habib_wallet/habib_wallet_view_model.dart @@ -42,6 +42,8 @@ class HabibWalletViewModel extends ChangeNotifier { String? get amountError => _amountError; String? get hospitalError => _hospitalError; + String yahalaAccountNumber = ''; + // Clear amount error void clearAmountError() { _amountError = null; diff --git a/lib/features/hmg_services/hmg_services_repo.dart b/lib/features/hmg_services/hmg_services_repo.dart index 1484c91f..8f439d2c 100644 --- a/lib/features/hmg_services/hmg_services_repo.dart +++ b/lib/features/hmg_services/hmg_services_repo.dart @@ -959,9 +959,9 @@ class HmgServicesRepoImp implements HmgServicesRepo { final hasValidRespiration = _isValidValue(vitalSign.respirationBeatPerMinute); final hasValidBloodPressure = _isValidValue(vitalSign.bloodPressureHigher) || _isValidValue(vitalSign.bloodPressureLower); - print('hasValidBloodPressure: $hasValidBloodPressure'); - print('Will add to list: ${hasValidWeight || hasValidHeight || hasValidBMI || hasValidTemperature || hasValidHeartRate || hasValidRespiration || hasValidBloodPressure}'); - print('====================================='); + // print('hasValidBloodPressure: $hasValidBloodPressure'); + // print('Will add to list: ${hasValidWeight || hasValidHeight || hasValidBMI || hasValidTemperature || hasValidHeartRate || hasValidRespiration || hasValidBloodPressure}'); + // print('====================================='); // Add if ANY vital sign has valid data if (hasValidWeight || hasValidHeight || hasValidBMI || hasValidTemperature || diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 7104e42d..ae8c6817 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1837,6 +1837,6 @@ abstract class LocaleKeys { static const maxOneFileAllowed = 'maxOneFileAllowed'; static const fileSizeExceedsLimit = 'fileSizeExceedsLimit'; static const completedPrescriptionOrder = 'completedPrescriptionOrder'; - static const submitReferral = 'submitReferral'; + static const submitEReferral = 'submitEReferral'; } diff --git a/lib/main.dart b/lib/main.dart index 5999a04e..ffe2043e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -96,7 +96,13 @@ Future callAppStateInitializations() async { // Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics PlatformDispatcher.instance.onError = (error, stack) { - if (!kDebugMode) FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); + if (!kDebugMode) { + FirebaseCrashlytics.instance.recordError(error, stack, + fatal: true, + printDetails: true, + reason: + "${appState.isAuthenticated ? "Authenticated User ID: ${appState.getAuthenticatedUser()!.patientId} - ${appState.getAuthenticatedUser()!.mobileNumber}" : "Unauthenticated User"} - Uncaught asynchronous error"); + } return true; }; } diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index 7cf8155a..0c574a4c 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -219,14 +219,7 @@ class _MyDoctorsPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget( - richText: Row( - children: [ - "${group.length} ".toText10(isEnglishOnly: true), - "${LocaleKeys.doctors2.tr(context: context)} ".toText10() - ], - ), - // labelText: "${group.length} ${'doctors'}", - isEnglishOnly: true, + labelText: "${group.length} ${LocaleKeys.doctors.tr(context: context)}", ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], @@ -360,8 +353,8 @@ class _MyDoctorsPageState extends State { ), ); }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ), + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 0.h), + ), SizedBox(height: 60.h), ], ); diff --git a/lib/presentation/ask_doctor/doctor_response_page.dart b/lib/presentation/ask_doctor/doctor_response_page.dart index 9cd19ef6..1aed8cfb 100644 --- a/lib/presentation/ask_doctor/doctor_response_page.dart +++ b/lib/presentation/ask_doctor/doctor_response_page.dart @@ -78,7 +78,7 @@ class _DoctorResponsePageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - askDoctorVM.doctorResponsesList[index].requestTypeDescription!.toText18(isBold: true), + (askDoctorVM.doctorResponsesList[index].requestTypeDescription ?? "").toText18(isBold: true), SizedBox(height: 24.h), Row( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index 7d4d32aa..64afff0b 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -150,7 +150,7 @@ class _SavedLogin extends State { fontSize: 12.f, fontWeight: FontWeight.w600, borderRadius: 12.r, - height: 40.h, + height: 44.h, padding: EdgeInsets.symmetric(vertical: 10.h), icon: (isOther == true && loginType == LoginTypeEnum.sms) ? AppAssets.whatsapp : getTypeIcons(loginType.toInt), iconColor: diff --git a/lib/presentation/contact_us/feedback_page.dart b/lib/presentation/contact_us/feedback_page.dart index 730fcddf..00576e9d 100644 --- a/lib/presentation/contact_us/feedback_page.dart +++ b/lib/presentation/contact_us/feedback_page.dart @@ -356,7 +356,7 @@ class FeedbackPage extends StatelessWidget { (String image, file) { print(image); print(file); - Navigator.pop(context); + // Navigator.pop(context); contactUsViewModel.addFeedbackAttachment(image); }, ); diff --git a/lib/presentation/e_referral/new_e_referral.dart b/lib/presentation/e_referral/new_e_referral.dart index c426b5c9..4135f15f 100644 --- a/lib/presentation/e_referral/new_e_referral.dart +++ b/lib/presentation/e_referral/new_e_referral.dart @@ -185,7 +185,7 @@ class _NewReferralPageState extends State { color: AppColors.whiteColor, padding: EdgeInsets.all(ResponsiveExtension(20).h), child: CustomButton( - text: _currentStep <= 1 ? LocaleKeys.next.tr() : LocaleKeys.submitReferral.tr(), + text: _currentStep <= 1 ? LocaleKeys.next.tr() : LocaleKeys.submitEReferral.tr(), // icon: AppAssets.search_icon, iconColor: Colors.white, onPressed: () => {_handleNextStep()}, diff --git a/lib/presentation/e_referral/widget/e_referral_patient_info.dart b/lib/presentation/e_referral/widget/e_referral_patient_info.dart index a30c0c3e..ce70b9b9 100644 --- a/lib/presentation/e_referral/widget/e_referral_patient_info.dart +++ b/lib/presentation/e_referral/widget/e_referral_patient_info.dart @@ -89,87 +89,75 @@ class PatientInformationStepState extends State { } Widget _buildSectionTitle(String title) { - return Text( - title, - style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 16) - ).paddingSymmetrical(4, 0); + return Text(title, style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 16)).paddingSymmetrical(4, 0); } Widget _buildIdentificationField(ReferralFormManager formManager) { - return Focus( + return TextInputWidget( + controller: _identificationController, focusNode: _identificationFocusNode, - child: TextInputWidget( - controller: _identificationController, - padding: EdgeInsets.symmetric( - vertical: ResponsiveExtension(12).h, - horizontal: ResponsiveExtension(16).h, - ), - hintText: LocaleKeys.enterIdentificationNumber.tr(context: context), - labelText: LocaleKeys.identificationNumber.tr(context: context), - errorMessage: formManager.errors.patientIdentification, - hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientIdentification), - onChange: (value) { - formManager.updatePatientIdentification(value ?? ''); - }, - onSubmitted: (value) { - _nameFocusNode.requestFocus(); - }, - ).paddingSymmetrical(0, 4), - ); + padding: EdgeInsets.symmetric( + vertical: ResponsiveExtension(12).h, + horizontal: ResponsiveExtension(16).h, + ), + hintText: LocaleKeys.enterIdentificationNumber.tr(context: context), + labelText: LocaleKeys.identificationNumber.tr(context: context), + errorMessage: formManager.errors.patientIdentification, + hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientIdentification), + onChange: (value) { + formManager.updatePatientIdentification(value ?? ''); + }, + onSubmitted: (value) { + _nameFocusNode.requestFocus(); + }, + ).paddingSymmetrical(0, 4); } Widget _buildPatientNameField(ReferralFormManager formManager) { - return Focus( + return TextInputWidget( + controller: _nameController, focusNode: _nameFocusNode, - child: TextInputWidget( - controller: _nameController, - padding: EdgeInsets.symmetric( - vertical: ResponsiveExtension(12).h, - horizontal: ResponsiveExtension(16).h, - ), - hintText: LocaleKeys.patientName.tr(context: context), - labelText: LocaleKeys.name.tr(context: context), - keyboardType: TextInputType.text, - errorMessage: formManager.errors.patientName, - hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientName), - onChange: (value) { - formManager.updatePatientName(value ?? ''); - }, - onSubmitted: (value) { - // Optionally move to next field or keep focus - }, - ).paddingSymmetrical(0, 4), - ); + padding: EdgeInsets.symmetric(vertical: ResponsiveExtension(12).h, horizontal: ResponsiveExtension(16).h), + hintText: LocaleKeys.patientName.tr(context: context), + labelText: LocaleKeys.name.tr(context: context), + keyboardType: TextInputType.text, + errorMessage: formManager.errors.patientName, + hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientName), + onChange: (value) { + formManager.updatePatientName(value ?? ''); + }, + onSubmitted: (value) { + _phoneFocusNode.requestFocus(); + }, + ).paddingSymmetrical(0, 4); } Widget _buildPatientPhoneField(ReferralFormManager formManager) { return Directionality( textDirection: ui.TextDirection.ltr, - child: Focus( + child: TextInputWidget( + labelText: LocaleKeys.phoneNumber.tr(context: context), + hintText: "5xxxxxxxx", + controller: _phoneController, focusNode: _phoneFocusNode, - child: TextInputWidget( - labelText: LocaleKeys.phoneNumber.tr(context: context), - hintText: "5xxxxxxxx", - controller: _phoneController, - padding: const EdgeInsets.all(8), - keyboardType: TextInputType.number, - fontFamily: "Poppins", - onChange: (value) { - formManager.updatePatientPhone(value ?? ''); - }, - onCountryChange: (value) { - formManager.updatePatientCountryEnum(value); - }, - prefix: '966', - isBorderAllowed: false, - isAllowLeadingIcon: true, - fontSize: 13, - isCountryDropDown: true, - leadingIcon: AppAssets.smart_phone, - errorMessage: formManager.errors.patientPhone, - hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientPhone) - ).paddingSymmetrical(0, 8), - ), + padding: const EdgeInsets.all(8), + keyboardType: TextInputType.number, + fontFamily: "Poppins", + onChange: (value) { + formManager.updatePatientPhone(value ?? ''); + }, + onCountryChange: (value) { + formManager.updatePatientCountryEnum(value); + }, + prefix: '966', + isBorderAllowed: false, + isAllowLeadingIcon: true, + fontSize: 13, + isCountryDropDown: true, + leadingIcon: AppAssets.smart_phone, + errorMessage: formManager.errors.patientPhone, + hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientPhone), + ).paddingSymmetrical(0, 8), ); } @@ -185,19 +173,17 @@ class PatientInformationStepState extends State { leadingIcon: AppAssets.globe, dropdownItems: [], errorMessage: formManager.errors.patientCity, - hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientCity), + hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientCity), ).paddingSymmetrical(0, 4).onPress(() { _showCityBottomSheet(context, formManager); }); } - String? getLocaleDescription(GetAllCitiesResponseModel? patientCity){ - return getIt.get().isArabic() ? patientCity?.descriptionN: patientCity?.description; + String? getLocaleDescription(GetAllCitiesResponseModel? patientCity) { + return getIt.get().isArabic() ? patientCity?.descriptionN : patientCity?.description; } - void _showCityBottomSheet(BuildContext context, ReferralFormManager formManager) { - showCommonBottomSheetWithoutHeight( context, title: LocaleKeys.selectCity.tr(context: context), @@ -216,25 +202,25 @@ class PatientInformationStepState extends State { return DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: Colors.white, - customBorder: BorderRadius.all(Radius.circular(24.h)) , - - ), child: ListView.builder( - shrinkWrap: true, - padding: EdgeInsets.all(16.h), - physics: const BouncingScrollPhysics(), - itemBuilder: (context, index) { - final city = cities[index]; - return ListTile( - title: (getLocaleDescription(city) ?? 'Unknown').toText14(), - onTap: () { - formManager.updatePatientCity(city); - Navigator.pop(context); + customBorder: BorderRadius.all(Radius.circular(24.h)), + ), + child: ListView.builder( + shrinkWrap: true, + padding: EdgeInsets.all(16.h), + physics: const BouncingScrollPhysics(), + itemBuilder: (context, index) { + final city = cities[index]; + return ListTile( + title: (getLocaleDescription(city) ?? 'Unknown').toText14(), + onTap: () { + formManager.updatePatientCity(city); + Navigator.pop(context); + }, + ); }, - ); - }, - // separatorBuilder: (context, index) => const Divider(), - itemCount: cities.length, - )); + // separatorBuilder: (context, index) => const Divider(), + itemCount: cities.length, + )); }, ), useSafeArea: true, @@ -253,4 +239,4 @@ class PatientInformationStepState extends State { _phoneFocusNode.dispose(); super.dispose(); } -} \ No newline at end of file +} diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 4346d8b5..5ea5b96b 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -41,6 +41,7 @@ import 'package:hmg_patient_app_new/presentation/contact_us/contact_us.dart'; import 'package:hmg_patient_app_new/presentation/hmg_services/services_page.dart'; import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card.dart'; +import 'package:hmg_patient_app_new/presentation/home/widgets/lakum_wallet_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart'; @@ -451,12 +452,12 @@ class _LandingPageState extends State { height: isTablet ? 290.h : 255.h, child: ListView.separated( scrollDirection: Axis.horizontal, - itemCount: 3, + itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length < 3 ? myAppointmentsVM.patientAppointmentsHistoryList.length : 3, shrinkWrap: true, padding: EdgeInsets.only(left: 16.h, right: 16.h), itemBuilder: (context, index) { return SizedBox( - height: isTablet ? 290.h : 255.h, + height: isTablet ? 290.h : 255.h, width: 250.w, child: getIndexSwiperCard(index), ); @@ -833,7 +834,26 @@ class _LandingPageState extends State { separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), ), ), - appState.isAuthenticated ? HabibWalletCard() : SizedBox(), + appState.isAuthenticated + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.myBalanceSubtitle.tr(context: context).toText16(isBold: true).paddingSymmetrical(24.h, 0.h), + SizedBox( + height: 170.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: 2, + padding: EdgeInsetsDirectional.only(start: 24.h, end: 24.h), + itemBuilder: (BuildContext context, int index) { + return index == 0 ? HabibWalletCard() : LakumWalletCard(); + }, + separatorBuilder: (BuildContext context, int index) => SizedBox(width: 12.h), + ), + ), + ], + ) + : SizedBox(), ], ), ), @@ -980,9 +1000,14 @@ class _LandingPageState extends State { // ); // } - return _buildAppointmentCardWrapper( - myAppointmentsViewModel.patientAppointmentsHistoryList[1], - ); + // Safety check: ensure list has at least 2 items + if (myAppointmentsViewModel.patientAppointmentsHistoryList.length > 1) { + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList[1], + ); + } + + return Container(); // Return empty container if not enough items } // Third slot: Shows ancillary orders or appointment @@ -996,9 +1021,14 @@ class _LandingPageState extends State { // ); } - return _buildAppointmentCardWrapper( - myAppointmentsViewModel.patientAppointmentsHistoryList[2], - ); + // Safety check: ensure list has at least 3 items + if (myAppointmentsViewModel.patientAppointmentsHistoryList.length > 2) { + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList[2], + ); + } + + return Container(); // Return empty container if not enough items } // Queue Card Widget diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index 5e4b4dfe..15aed11a 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -23,23 +23,23 @@ class HabibWalletCard extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.myBalanceSubtitle.tr(context: context).toText16(isBold: true), - // Row( - // children: [ - // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), - // SizedBox(width: 2.h), - // Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), - // ], - // ), - ], - ).paddingSymmetrical(24.h, 0.h), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // LocaleKeys.myBalanceSubtitle.tr(context: context).toText16(isBold: true), + // // Row( + // // children: [ + // // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), + // // SizedBox(width: 2.h), + // // Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + // // ], + // // ), + // ], + // ).paddingSymmetrical(24.h, 0.h), SizedBox(height: 16.h), Container( // height: 150.h, - width: double.infinity, + width: 355.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 24, @@ -104,7 +104,7 @@ class HabibWalletCard extends StatelessWidget { .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h), ], ), - Spacer(), + // Spacer(), Utils.getPaymentMethods(), ], ); @@ -171,7 +171,7 @@ class HabibWalletCard extends StatelessWidget { ), ), ]), - ).paddingSymmetrical(24.h, 0.h).onPress(() { + ).paddingSymmetrical(0.h, 0.h).onPress(() { Navigator.of(context).push( CustomPageRoute( page: HabibWalletPage(), diff --git a/lib/presentation/home/widgets/lakum_wallet_card.dart b/lib/presentation/home/widgets/lakum_wallet_card.dart new file mode 100644 index 00000000..e693667c --- /dev/null +++ b/lib/presentation/home/widgets/lakum_wallet_card.dart @@ -0,0 +1,189 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart'; +import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; + +class LakumWalletCard extends StatelessWidget { + const LakumWalletCard({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // LocaleKeys.myBalanceSubtitle.tr(context: context).toText16(isBold: true), + // // Row( + // // children: [ + // // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), + // // SizedBox(width: 2.h), + // // Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + // // ], + // // ), + // ], + // ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 16.h), + Container( + // height: 150.h, + width: 355.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24, + ), + child: Stack(children: [ + Positioned( + right: 0, + child: ClipRRect( + borderRadius: BorderRadius.circular(24.0), + child: Utils.buildImgWithAssets( + icon: AppAssets.lakumLogo, + width: 150.h, + height: 150.h, + )), + ), + Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // LocaleKeys.habibWallet.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), + "Lakum Wallet".toText16(isBold: true, letterSpacing: -0.2), + // Container( + // height: 40.h, + // width: 40.h, + // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + // color: AppColors.textColor, + // borderRadius: 8.h, + // ), + // child: Padding( + // padding: EdgeInsets.all(8.h), + // child: Utils.buildSvgWithAssets( + // icon: AppAssets.show_icon, + // width: 12.h, + // height: 12.h, + // fit: BoxFit.contain, + // ), + // ), + // ), + // ], + // ), + SizedBox(height: 4.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Consumer(builder: (context, habibWalletVM, child) { + return Row( + mainAxisSize: MainAxisSize.max, + children: [ + Row( + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.saudi_riyal_icon, + iconColor: AppColors.inputLabelTextColor, + width: 24.h, + height: 24.h, + fit: BoxFit.contain, + ), + SizedBox(width: 8.h), + NumberFormat.decimalPattern() + .format(habibWalletVM.habibWalletAmount) + .toString() + .toText32(isBold: true, isEnglishOnly: true) + .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h), + ], + ), + // Spacer(), + Utils.getPaymentMethods(), + ], + ); + }), + ], + ), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + flex: 6, + child: CustomButton( + height: 40.h, + icon: AppAssets.recharge_icon, + iconColor: AppColors.infoColor, + iconSize: 24.h, + backgroundColor: AppColors.infoColor.withAlpha(15), + textColor: AppColors.infoColor, + text: LocaleKeys.recharge.tr(context: context), + borderWidth: 0.w, + fontWeight: FontWeight.w600, + borderColor: AppColors.infoColor.withAlpha(15), + padding: EdgeInsets.fromLTRB(4, 0, 12, 0), + fontSize: 14.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, + ), + ), + SizedBox(width: 8.h), + Expanded( + flex: 1, + child: Container( + height: (isFoldable || isTablet) ? 50.h : 40.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.textColor, + borderRadius: 10.h, + side: BorderSide( + color: AppColors.textColor, + width: 1.2, + ), + ), + child: Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.whiteColor, + width: 24.w, + height: 24.h, + fit: BoxFit.contain, + ), + ), + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: HabibWalletPage(), + ), + ); + }), + ), + ], + ), + ], + ), + ), + ]), + ).paddingSymmetrical(0.h, 0.h).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: HabibWalletPage(), + ), + ); + }), + ], + ); + } +} diff --git a/lib/presentation/insurance/insurance_approval_details_page.dart b/lib/presentation/insurance/insurance_approval_details_page.dart index 29663938..c80767eb 100644 --- a/lib/presentation/insurance/insurance_approval_details_page.dart +++ b/lib/presentation/insurance/insurance_approval_details_page.dart @@ -186,7 +186,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ "${LocaleKeys.status.tr(context: context)}: ".toText14(isBold: true), - insuranceApprovalResponseModel.apporvalDetails![index]!.status!.toText12(isBold: true, color: AppColors.greyTextColor), + (insuranceApprovalResponseModel.apporvalDetails![index].status ?? "").toText12(isBold: true, color: AppColors.greyTextColor), ], ), SizedBox(height: 8.h), @@ -194,7 +194,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ "${LocaleKeys.usageStatus.tr(context: context)}: ".toText14(isBold: true), - (insuranceApprovalResponseModel.apporvalDetails![index]!.isInvoicedDesc ?? "").toText12(isBold: true, color: AppColors.greyTextColor), + (insuranceApprovalResponseModel.apporvalDetails![index].isInvoicedDesc ?? "").toText12(isBold: true, color: AppColors.greyTextColor), ], ), ], diff --git a/lib/presentation/insurance/widgets/insurance_approval_card.dart b/lib/presentation/insurance/widgets/insurance_approval_card.dart index a12a26b6..8357a2d9 100644 --- a/lib/presentation/insurance/widgets/insurance_approval_card.dart +++ b/lib/presentation/insurance/widgets/insurance_approval_card.dart @@ -117,7 +117,7 @@ class InsuranceApprovalCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (isLoading ? "John Smith" : insuranceApprovalResponseModel.doctorName!).toText16(isBold: true).toShimmer2(isShow: isLoading), + (isLoading ? "John Smith" : insuranceApprovalResponseModel.doctorName ?? "").toText16(isBold: true).toShimmer2(isShow: isLoading), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, @@ -128,7 +128,7 @@ class InsuranceApprovalCard extends StatelessWidget { // backgroundColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor.withValues(alpha: 0.1) : AppColors.primaryRedColor.withValues(alpha: 0.1), // textColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor : AppColors.primaryRedColor, // ).toShimmer2(isShow: isLoading), - AppCustomChipWidget(labelText: isLoading ? "Cardiology" : insuranceApprovalResponseModel.clinicName!).toShimmer2(isShow: isLoading), + AppCustomChipWidget(labelText: isLoading ? "Cardiology" : insuranceApprovalResponseModel.clinicName ?? "").toShimmer2(isShow: isLoading), Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index a403dbb1..b60cd8bc 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -241,8 +241,7 @@ class _MedicalFilePageState extends State { children: [ AppCustomChipWidget( icon: AppAssets.file_icon, - richText: "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}" - .toText10(isEnglishOnly: true), + labelText: "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}", labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), ), AppCustomChipWidget( diff --git a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart index a8edeae3..667e1a30 100644 --- a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart +++ b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart @@ -123,9 +123,9 @@ class PatientSickLeaveCard extends StatelessWidget { backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, - fontSize: 14, + fontSize: 14.f, isBold: true, - borderRadius: 12, + borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, icon: AppAssets.download, diff --git a/lib/widgets/attachment_options.dart b/lib/widgets/attachment_options.dart index 4d52d1e2..bbc0bc6d 100644 --- a/lib/widgets/attachment_options.dart +++ b/lib/widgets/attachment_options.dart @@ -48,11 +48,11 @@ class AttachmentOptions extends StatelessWidget { ).onPress(() async { await onGalleryTap(); }), - if (showFilesOption) SizedBox(height: 16.h), + if (!showFilesOption) SizedBox(height: 16.h), if (showFilesOption) checkInOptionCard( appState, - AppAssets.files, + AppAssets.file_icon, LocaleKeys.openFiles.tr(context: context), LocaleKeys.selectDocumentFiles.tr(context: context), ).onPress(() async { diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 8270966f..7b485e75 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -265,7 +265,7 @@ void showCommonBottomSheetWithoutHeight( builder: (BuildContext context) { if (isAutoDismiss) { Future.delayed(Duration(seconds: 2), () { - Navigator.of(context).pop(); + Navigator.of(GetIt.instance().navigatorKey.currentContext!).pop(); if (callBackFunc != null) { callBackFunc(); } diff --git a/pubspec.yaml b/pubspec.yaml index 5db6c526..99310e51 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,8 +2,8 @@ name: hmg_patient_app_new description: "New HMG Patient App" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.25+24 -#version: 0.0.1+23 +#version: 0.0.30+29 +version: 0.0.4+1 environment: sdk: ">=3.6.0 <4.0.0"