diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index cd9d7c8e..31dba2d9 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1637,5 +1637,12 @@ "emergencyServiceHeader": "تسجيل الوصول إلى قسم الطوارئ، أسرع من أي وقت مضى. اتصل بالإسعاف / فريق الاستجابة السريعة على الفور", "emergencyServiceDescription": "هل تواجه حالة طبية طارئة؟ سيارات الإسعاف وفرق الاستجابة السريعة لدينا جاهزة على مدار الساعة. بالإضافة إلى ذلك، يمكنك تسجيل دخولك إلى قسم الطوارئ بسرعة لتلقي رعاية أسرع.", "homeHealthCareServiceHeader": "صحتك، في أبهى صورها. رعاية فائقة الجودة، تصلك إلى عتبة دارك.", - "homeHealthCareServiceDescription": "نقدم لكم رعاية صحية عالية الجودة تصلكم إلى عتبة منزلكم. ممرضات ذوات خبرة يقدمون رعاية حانية في راحة منزلكم." + "homeHealthCareServiceDescription": "نقدم لكم رعاية صحية عالية الجودة تصلكم إلى عتبة منزلكم. ممرضات ذوات خبرة يقدمون رعاية حانية في راحة منزلكم.", + "profileOnlyText": "الملف الشخصي", + "information": "معلومة", + "noFavouriteDoctors": "ليس لديك أي أطباء مفضلين حتى الآن", + "addDoctors": "إضافة الأطباء", + "favouriteList": "قائمة المفضلة", + "later": "لاحقاً" + } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 438dc0c5..64cb63a3 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1612,28 +1612,28 @@ "sortByNearestLocation": "Sort by nearest to your location", "giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations.", "communicationLanguage": "Communication Language", - "cmcServiceHeader": "Complete Health Checkup: Advanced diagnostics, Detailed Health insights", "cmcServiceDescription": "Get detailed insights into your health with our advanced diagnostics. Understand your body better for a healthier future.", "eReferralServiceHeader": "HMG Hospital E-Referral: Streamlined patient referrals", "eReferralServiceDescription": "Facilitate seamless patient transfers to HMG with our secure e-referral system. Ensure continuity of care for every patient.", "bloodDonationServiceHeader": "Give Blood, Save Lives. Your donation makes a difference.", "bloodDonationServiceDescription": "Donate blood, empower lives. Your contribution creates hope. Join our blood drive and be a lifeline for those in need. Every drop counts!", - "healthTrackersServiceHeader": "Track Your Vitals with Ease and effortlessly ", "healthTrackersServiceDescription": "Input your metrics for continuous heart rate monitoring, blood pressure and precise daily activity summaries. Stay informed and optimize your well-being with ease.", - "waterConsumptionServiceHeader": "Stay Hydrated, Stay Healthy. Track your daily water intake with ease.", "waterConsumptionServiceDescription": "Quench your thirst, track your health. Effortlessly monitor your daily water intake with our user-friendly app, ensuring optimal hydration and well-being.", - "smartWatchServiceHeader": "Sync Your Smartwatch with Health Apps", "smartWatchServiceDescription": "Seamlessly connect your smartwatch to our health app for effortless data tracking and personalized insights.", - "liveChatServiceHeader": "24/7 Expert\nAssistance", "liveChatServiceDescription": "Need help ? Our live chat connects you with expert support for any questions about features, settings, or troubleshooting.", - "emergencyServiceHeader": "ER Check-in, Faster Than Ever. Call ambulance / Rapid Response Team instantly", "emergencyServiceDescription": "In a medical emergency? Our ambulances and rapid response teams are on standby 24/7. Plus, quick ER check-in for faster care.", "homeHealthCareServiceHeader": "Your Health, Elevated. Premium care, delivered to your doorstep.", - "homeHealthCareServiceDescription": "We bring quality healthcare to your doorstep. Experienced nurses providing compassionate care in the comfort of your home." + "homeHealthCareServiceDescription": "We bring quality healthcare to your doorstep. Experienced nurses providing compassionate care in the comfort of your home.", + "profileOnlyText": "Profile", + "information": "Information", + "noFavouriteDoctors": "You don't have any favourite doctors yet", + "addDoctors": "Add Doctors", + "favouriteList": "Favourite List", + "later": "Later" } diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 58256f3f..374ac9d1 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -200,7 +200,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 3628599; + // body['PatientID'] = 1018977; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index f63b160b..1f09cdfd 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -768,6 +768,7 @@ class Utils { return Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, + spacing: 5.w, children: [ Image.asset(AppAssets.mada, width: 35.h, height: 35.h), Image.asset( diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index f1de3201..907fc35c 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -157,7 +157,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { LaserCategoryType(11, 'retouch'), ]; List maleLaserCategory = [ - LaserCategoryType(1, 'body'), + LaserCategoryType(1, 'bodyString'), LaserCategoryType(2, 'face'), LaserCategoryType(11, 'retouch'), ]; diff --git a/lib/features/book_appointments/models/resp_models/laser_body_parts.dart b/lib/features/book_appointments/models/resp_models/laser_body_parts.dart index d7d3fbd1..dcb8a70e 100644 --- a/lib/features/book_appointments/models/resp_models/laser_body_parts.dart +++ b/lib/features/book_appointments/models/resp_models/laser_body_parts.dart @@ -61,4 +61,14 @@ class LaserBodyPart { data['CategoryNameN'] = this.categoryNameN; return data; } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is LaserBodyPart && + runtimeType == other.runtimeType && + id == other.id; + + @override + int get hashCode => id.hashCode; } diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index 4934435f..de543970 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -4,6 +4,7 @@ import 'dart:core'; 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/common_models/data_points.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; @@ -87,6 +88,9 @@ class LabViewModel extends ChangeNotifier { LabOrderResponseByAi? labOrderResponseByAi; LabOrdersResponseByAi? labOrdersResponseByAi; + bool isLabAIAnalysisNeedsToBeShown = true; + bool isLabResultsHistoryShowMore = false; + LabViewModel({required this.labRepo, required this.errorHandlerService, required this.navigationService}); initLabProvider() { @@ -96,6 +100,8 @@ class LabViewModel extends ChangeNotifier { labOrderTests.clear(); isLabOrdersLoading = true; isLabResultsLoading = true; + isLabAIAnalysisNeedsToBeShown = true; + isLabResultsHistoryShowMore = false; patientLabOrdersByClinic.clear(); patientLabOrdersByHospital.clear(); patientLabOrdersViewList.clear(); @@ -114,6 +120,16 @@ class LabViewModel extends ChangeNotifier { notifyListeners(); } + setIsLabAIAnalysisNeedsToBeShown(bool isLabAIAnalysisNeedsToBeShown) { + this.isLabAIAnalysisNeedsToBeShown = isLabAIAnalysisNeedsToBeShown; + notifyListeners(); + } + + setIsLabResultsHistoryShowMore() { + isLabResultsHistoryShowMore = !isLabResultsHistoryShowMore; + notifyListeners(); + } + void setIsSortByClinic(bool value) { isSortByClinic = value; patientLabOrdersViewList = isSortByClinic ? patientLabOrdersByClinic : patientLabOrdersByHospital; @@ -806,7 +822,13 @@ class LabViewModel extends ChangeNotifier { Future getAiOverviewLabOrders({required PatientLabOrdersResponseModel labOrder, required String loadingText}) async { // LoadingUtils.showFullScreenLoader(loadingText: "Loading and analysing your data,\nPlease be patient and let the AI do the magic. \nPlease be patient, This might take some time."); - LoadingUtils.showFullScreenLoader(loadingText: loadingText); + // LoadingUtils.showFullScreenLoader(loadingText: loadingText); + LoaderBottomSheet.showLoader( + loadingText: loadingText, + showCloseButton: true, + onCloseTap: () { + setIsLabAIAnalysisNeedsToBeShown(false); + }); List> results = []; Map orderData = {"order_date": labOrder.orderDate ?? "", "clinic": labOrder.clinicDescription ?? "", "doctor": labOrder.doctorName ?? "", "results": []}; List> testResults = []; @@ -829,16 +851,20 @@ class LabViewModel extends ChangeNotifier { result.fold( (failure) async { LoadingUtils.hideFullScreenLoader(); - await errorHandlerService.handleError(failure: failure); + if (isLabAIAnalysisNeedsToBeShown) { + await errorHandlerService.handleError(failure: failure); + } }, (apiResponse) { LoadingUtils.hideFullScreenLoader(); if (apiResponse.messageStatus == 2) { } else if (apiResponse.messageStatus == 1) { - labOrdersResponseByAi = apiResponse.data; - navigationService.push( - MaterialPageRoute(builder: (_) => LabAiAnalysisDetailedPage()), - ); + if (isLabAIAnalysisNeedsToBeShown) { + labOrdersResponseByAi = apiResponse.data; + navigationService.push( + MaterialPageRoute(builder: (_) => LabAiAnalysisDetailedPage()), + ); + } } }, ); @@ -847,7 +873,12 @@ class LabViewModel extends ChangeNotifier { } Future getAiOverviewSingleLabResult({required String langId, required LabResult recentLabResult, required String loadingText}) async { - LoaderBottomSheet.showLoader(loadingText: loadingText); + LoaderBottomSheet.showLoader( + loadingText: loadingText, + showCloseButton: true, + onCloseTap: () { + setIsLabAIAnalysisNeedsToBeShown(false); + }); List> results = []; results.add({ "Description": recentLabResult.description ?? '', @@ -857,19 +888,24 @@ class LabViewModel extends ChangeNotifier { "ReferanceRange": recentLabResult.referanceRange ?? '', }); - var payload = {"patient_id": currentlySelectedPatientOrder!.patientID, "language_id": langId, "lab_results": results}; + // var payload = {"patient_id": currentlySelectedPatientOrder!.patientID, "language_id": langId, "lab_results": results}; + var payload = {"patient_id": getIt.get().getAuthenticatedUser()!.patientId, "language_id": langId, "lab_results": results}; final result = await labRepo.getPatientAiOverViewLabOrder(payload); result.fold( (failure) async { LoaderBottomSheet.hideLoader(); - await errorHandlerService.handleError(failure: failure); + if (isLabAIAnalysisNeedsToBeShown) { + await errorHandlerService.handleError(failure: failure); + } }, (apiResponse) { LoaderBottomSheet.hideLoader(); if (apiResponse.messageStatus == 2) { } else if (apiResponse.messageStatus == 1) { - labOrderResponseByAi = apiResponse.data; - notifyListeners(); + if (isLabAIAnalysisNeedsToBeShown) { + labOrderResponseByAi = apiResponse.data; + notifyListeners(); + } } }, ); diff --git a/lib/features/my_appointments/appointment_via_region_viewmodel.dart b/lib/features/my_appointments/appointment_via_region_viewmodel.dart index 10da4e3d..1144be82 100644 --- a/lib/features/my_appointments/appointment_via_region_viewmodel.dart +++ b/lib/features/my_appointments/appointment_via_region_viewmodel.dart @@ -87,6 +87,8 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier { hmcCount = registeredDoctorMap.hmcSize; hmgCount = registeredDoctorMap.hmgSize; + hospitalList!.sort((a, b) => num.parse(a.distanceInKMs!).compareTo(num.parse(b.distanceInKMs!))); + getDisplayList(); } diff --git a/lib/features/notifications/notifications_repo.dart b/lib/features/notifications/notifications_repo.dart index 853a9792..a4588042 100644 --- a/lib/features/notifications/notifications_repo.dart +++ b/lib/features/notifications/notifications_repo.dart @@ -12,6 +12,10 @@ abstract class NotificationsRepo { required int pagingSize, required int currentPage, }); + + Future>>> markAsRead({ + required int notificationID, + }); } class NotificationsRepoImp implements NotificationsRepo { @@ -75,4 +79,38 @@ class NotificationsRepoImp implements NotificationsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>>> markAsRead({required int notificationID}) async { + Map mapDevice = {"NotificationPoolID": notificationID}; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + PUSH_NOTIFICATION_SET_MESSAGES_FROM_POOL_AS_READ, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: [], + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/notifications/notifications_view_model.dart b/lib/features/notifications/notifications_view_model.dart index e15e267c..fa2a893d 100644 --- a/lib/features/notifications/notifications_view_model.dart +++ b/lib/features/notifications/notifications_view_model.dart @@ -89,6 +89,21 @@ class NotificationsViewModel extends ChangeNotifier { ); } + Future markAsRead({ + int notificationID = 0, + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + final result = await notificationsRepo.markAsRead(notificationID: notificationID); + + result.fold( + (failure) async {}, + (apiResponse) { + refreshNotifications(); + }, + ); + } + Future refreshNotifications({ Function(dynamic)? onSuccess, Function(String)? onError, diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 2ca58bc1..98265513 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1630,5 +1630,11 @@ abstract class LocaleKeys { static const emergencyServiceDescription = 'emergencyServiceDescription'; static const homeHealthCareServiceHeader = 'homeHealthCareServiceHeader'; static const homeHealthCareServiceDescription = 'homeHealthCareServiceDescription'; + static const profileOnlyText = 'profileOnlyText'; + static const information = 'information'; + static const noFavouriteDoctors = 'noFavouriteDoctors'; + static const addDoctors = 'addDoctors'; + static const favouriteList = 'favouriteList'; + static const later = 'later'; } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 176b3771..f01c4a59 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -73,10 +73,10 @@ class _AppointmentDetailsPageState extends State { void initState() { scheduleMicrotask(() async { if (!AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) { - CalenderUtilsNew calendarUtils = await CalenderUtilsNew.instance; - var doesExist = await calendarUtils.checkIfEventExist("${widget.patientAppointmentHistoryResponseModel.appointmentNo}"); - myAppointmentsViewModel.setAppointmentReminder(doesExist, widget.patientAppointmentHistoryResponseModel); - setState(() {}); + // CalenderUtilsNew calendarUtils = await CalenderUtilsNew.instance; + // var doesExist = await calendarUtils.checkIfEventExist("${widget.patientAppointmentHistoryResponseModel.appointmentNo}"); + // myAppointmentsViewModel.setAppointmentReminder(doesExist, widget.patientAppointmentHistoryResponseModel); + // setState(() {}); } }); diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index 96db5187..44bcc5ab 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -206,7 +206,7 @@ class _SavedLogin extends State { }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor, - textColor: AppColors.textColor, + textColor: Colors.white, icon: AppAssets.sms), ), Row( diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index be1d9aad..b7a2de01 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -276,7 +276,46 @@ class _BookAppointmentPageState extends State { // Show empty state or actual list return myAppointmentsVM.patientFavouriteDoctorsList.isEmpty - ? SizedBox() + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 16.h), + LocaleKeys.favouriteList.tr(context: context).toText18(isBold: true).paddingSymmetrical(24.w, 0.h), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + padding: EdgeInsets.all(16.h), + child: Column( + children: [ + Center( + child: LocaleKeys.noFavouriteDoctors.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + ), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.add.tr(context: context), + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: SearchDoctorByName())); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 14.f, + fontWeight: FontWeight.w500, + padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), + icon: AppAssets.add_icon, + iconColor: AppColors.primaryRedColor, + height: 40.h, + ), + ], + ), + ).paddingSymmetrical(24.w, 0.h), + SizedBox(height: 24.h), + ], + ) : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -671,7 +710,7 @@ class _BookAppointmentPageState extends State { return SizedBox.shrink(); } - void _handleSortByLocationToggle(bool value, AppointmentViaRegionViewmodel regionVM) { + void _handleSortByLocationToggle(bool value, AppointmentViaRegionViewmodel regionVM) { if (value) { final locationUtils = getIt.get(); locationUtils.getLocation( diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index fe09cade..095133de 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -33,7 +33,7 @@ class DoctorProfilePage extends StatelessWidget { children: [ Expanded( child: CollapsingListView( - title: LocaleKeys.doctorProfile.tr(), + title: LocaleKeys.profileOnlyText.tr(), trailing: appState.isAuthenticated ? Consumer( builder: (context, viewModel, child) { return SizedBox( @@ -178,7 +178,7 @@ class DoctorProfilePage extends StatelessWidget { SizedBox(height: 16.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), SizedBox(height: 16.h), - LocaleKeys.docInfo.tr(context: context).toText14(weight: FontWeight.w600, color: AppColors.textColor), + LocaleKeys.information.tr(context: context).toText14(weight: FontWeight.w600, color: AppColors.textColor), SizedBox(height: 6.h), bookAppointmentsViewModel.doctorsProfileResponseModel.doctorProfileInfo!.toText12(fontWeight: FontWeight.w600, color: AppColors.greyTextColor), SizedBox(height: 24.h), diff --git a/lib/presentation/book_appointment/laser/laser_appointment.dart b/lib/presentation/book_appointment/laser/laser_appointment.dart index 3b94b0ec..c6bb1bd0 100644 --- a/lib/presentation/book_appointment/laser/laser_appointment.dart +++ b/lib/presentation/book_appointment/laser/laser_appointment.dart @@ -84,7 +84,7 @@ class LaserAppointment extends StatelessWidget { activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.malE.tr()), - CustomTabBarModel(null, "Female"), + CustomTabBarModel(null, LocaleKeys.femaleGender.tr()), ], onTabChange: (index) { var viewmodel = context.read(); diff --git a/lib/presentation/book_appointment/select_clinic_page.dart b/lib/presentation/book_appointment/select_clinic_page.dart index aaa52217..86d57ad2 100644 --- a/lib/presentation/book_appointment/select_clinic_page.dart +++ b/lib/presentation/book_appointment/select_clinic_page.dart @@ -1132,6 +1132,7 @@ class _SelectClinicPageState extends State { id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first.projectID?.toString() ?? ""; } if (bookAppointmentsViewModel.selectedClinic.clinicID == 17) { + bookAppointmentsViewModel.setProjectID(id); if (appState.isAuthenticated) { initDentalAppointment(); return SizedBox.shrink(); diff --git a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart index c17f3560..12996bd6 100644 --- a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart +++ b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart @@ -21,6 +21,7 @@ class RrtRequestTypeSelect extends StatelessWidget { return Column( children: [ Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.rapidResponseTeam.tr(context: context).toText20(color: AppColors.textColor, isBold: true), SizedBox( @@ -32,10 +33,9 @@ class RrtRequestTypeSelect extends StatelessWidget { borderRadius: 20.r, ), child: OptionSelection(context)), - SizedBox( - height: 24.h, - ), + SizedBox(height: 16.h), termsAndCondition(context, emergencyServicesVM), + SizedBox(height: 16.h), ], ).paddingSymmetrical(24.w, 0.h), bottomPriceContent(context, emergencyServicesVM) @@ -122,15 +122,7 @@ class RrtRequestTypeSelect extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - spacing: 6.w, - children: [ - Image.asset(AppAssets.mada, width: 24.h, height: 24.h), - Image.asset(AppAssets.visa, width: 24.h, height: 24.h), - Image.asset(AppAssets.mastercard, width: 24.h, height: 24.h), - Image.asset(AppAssets.applePay, width: 24.h, height: 24.h), - ], - ), + Utils.getPaymentMethods(), Column( children: [ Divider( @@ -149,7 +141,9 @@ class RrtRequestTypeSelect extends StatelessWidget { CustomButton(text: LocaleKeys.next.tr(), onPressed: () { Navigator.pop(context); emergencyServicesVM.openRRT(); - }) + }, + isDisabled: !emergencyServicesVM.agreedToTermsAndCondition, + ) ], ).paddingAll(24.h), ), @@ -236,7 +230,6 @@ class RrtRequestTypeSelect extends StatelessWidget { value: emergencyServicesVM.agreedToTermsAndCondition, checkColor: AppColors.whiteColor, fillColor: MaterialStateProperty.resolveWith((Set states) { - print("the state is ${states}"); if (states.contains(WidgetState.selected)) { return AppColors.errorColor; } diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 3109443f..dfb86a27 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -133,22 +133,22 @@ class _LandingPageState extends State { // Commented as per new requirement to remove rating popup from the app - // if(!appState.isRatedVisible) { - // appointmentRatingViewModel.getLastRatingAppointment(onSuccess: (response) { - // if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) { - // appointmentRatingViewModel.getAppointmentDetails(appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!, appointmentRatingViewModel.appointmentRatedList.last.projectID!, - // onSuccess: ((response) { - // appointmentRatingViewModel.setClinicOrDoctor(false); - // appointmentRatingViewModel.setTitle("Rate Doctor".needTranslation); - // appointmentRatingViewModel.setSubTitle("How was your last visit with doctor?".needTranslation); - // openLastRating(); - // appState.setRatedVisible(true); - // }), - // ); - // } - // }, - // ); - // } + if(!appState.isRatedVisible) { + appointmentRatingViewModel.getLastRatingAppointment(onSuccess: (response) { + if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) { + appointmentRatingViewModel.getAppointmentDetails(appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!, appointmentRatingViewModel.appointmentRatedList.last.projectID!, + onSuccess: ((response) { + appointmentRatingViewModel.setClinicOrDoctor(false); + appointmentRatingViewModel.setTitle(LocaleKeys.rateDoctor.tr(context: context)); + appointmentRatingViewModel.setSubTitle(LocaleKeys.howWasYourLastVisitWithDoctor.tr(context: context)); + openLastRating(); + appState.setRatedVisible(true); + }), + ); + } + }, + ); + } } }); super.initState(); @@ -173,7 +173,7 @@ class _LandingPageState extends State { children: [ SingleChildScrollView( padding: EdgeInsets.only( - top: (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) + top: (appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) ? (MediaQuery.paddingOf(context).top + 70.h) : kToolbarHeight + 0.h, bottom: 24), @@ -727,7 +727,7 @@ class _LandingPageState extends State { ], ), ), - (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) + (appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) ? Container( height: MediaQuery.paddingOf(context).top + 50.h, decoration: ShapeDecoration( diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart index 35e3acb8..1ac176e1 100644 --- a/lib/presentation/insurance/insurance_home_page.dart +++ b/lib/presentation/insurance/insurance_home_page.dart @@ -74,6 +74,7 @@ class _InsuranceHomePageState extends State { return Column( children: [ PatientInsuranceCard( + isShowButtons: index == 0, insuranceCardDetailsModel: insuranceVM.patientInsuranceList[index], isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))), SizedBox( diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index ab70eb6f..d0f1b4db 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -20,10 +20,11 @@ import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class PatientInsuranceCard extends StatelessWidget { - PatientInsuranceCard({super.key, required this.insuranceCardDetailsModel, required this.isInsuranceExpired}); + PatientInsuranceCard({super.key, required this.insuranceCardDetailsModel, required this.isInsuranceExpired, this.isShowButtons = true}); PatientInsuranceDetailsResponseModel insuranceCardDetailsModel; bool isInsuranceExpired = false; + bool isShowButtons = true; late InsuranceViewModel insuranceViewModel; late AppState appState; @@ -60,7 +61,7 @@ class PatientInsuranceCard extends StatelessWidget { ), ], ), - AppCustomChipWidget( + isShowButtons ? AppCustomChipWidget( icon: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!) ? AppAssets.cancel_circle_icon : insuranceViewModel.isInsuranceActive @@ -120,7 +121,7 @@ class PatientInsuranceCard extends StatelessWidget { ? AppColors.successColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceViewModel.isInsuranceActive ? 6.w : 0.w), - ).toShimmer2(isShow: insuranceViewModel.isInsuranceLoading), + ).toShimmer2(isShow: insuranceViewModel.isInsuranceLoading) : SizedBox.shrink(), // AppCustomChipWidget( // icon: isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon, // labelText: isInsuranceExpired ? LocaleKeys.insuranceExpired.tr(context: context) : LocaleKeys.insuranceActive.tr(context: context), @@ -168,7 +169,7 @@ class PatientInsuranceCard extends StatelessWidget { ), SizedBox(height: 10.h), isInsuranceExpired - ? CustomButton( + ? isShowButtons ? CustomButton( icon: AppAssets.update_insurance_card_icon, iconColor: AppColors.warningColorYellow, iconSize: 15.h, @@ -194,7 +195,7 @@ class PatientInsuranceCard extends StatelessWidget { borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, - ) + ) : SizedBox.shrink() : Container(), ], ), diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index ebdb3da3..aeef4240 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -23,6 +23,7 @@ import 'package:hmg_patient_app_new/widgets/graph/custom_graph.dart'; import 'package:provider/provider.dart' show Consumer, Provider, ReadContext, Selector; import '../../../widgets/common_bottom_sheet.dart' show showCommonBottomSheetWithoutHeight; +import 'dart:ui' as ui; class LabResultDetails extends StatelessWidget { final LabResult recentLabResult; @@ -73,14 +74,14 @@ class LabResultDetails extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - LocaleKeys.history.tr(context: context), - style: TextStyle( - fontSize: 16.f, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.history.tr(context: context).toText16(isBold: true, color: AppColors.textColor), + (labVM.isLabResultsHistoryShowMore ? "Show Less" : "Show More").toText14(weight: FontWeight.w500, color: AppColors.primaryRedColor, isUnderLine: true).onPress(() { + labVM.setIsLabResultsHistoryShowMore(); + }), + ], ), SizedBox(height: 24.h,), labHistoryList(labVM), @@ -194,7 +195,7 @@ class LabResultDetails extends StatelessWidget { ], ), SizedBox(height: 4.h), - ("${LocaleKeys.resultOf.tr(context: context)} ${recentLabResult.verifiedOn ?? ""}").toText11(weight: FontWeight.w500, color: AppColors.greyTextColor), + ("${LocaleKeys.resultOf.tr(context: context)} ${recentLabResult.verifiedOn ?? ""}").toText11(weight: FontWeight.w500, color: AppColors.greyTextColor, isEnglishOnly: true), ], ), Row( @@ -256,15 +257,16 @@ class LabResultDetails extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - labmodel.isGraphVisible ? LocaleKeys.historyFlowchart.tr(context: context) : LocaleKeys.history.tr(context: context), - style: TextStyle( - fontSize: 16.f, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ), - ), + (labmodel.isGraphVisible ? LocaleKeys.historyFlowchart.tr(context: context) : LocaleKeys.history.tr(context: context)).toText16(isBold: true, color: AppColors.textColor), + // Text( + // labmodel.isGraphVisible ? LocaleKeys.historyFlowchart.tr(context: context) : LocaleKeys.history.tr(context: context), + // style: TextStyle( + // fontSize: 16.f, + // fontFamily: 'Poppins', + // fontWeight: FontWeight.w600, + // color: AppColors.textColor, + // ), + // ), Row( spacing: 16.h, children: [ @@ -335,6 +337,7 @@ class LabResultDetails extends StatelessWidget { minY: labmodel.minY, maxX: labmodel.filteredGraphValues.length.toDouble() - .75, horizontalInterval: .1, + isRTL: getIt.get().isArabic(), getDrawingHorizontalLine: (value) { value = double.parse(value.toStringAsFixed(1)); if (value == labmodel.highRefrenceValue || value == labmodel.lowRefenceValue) { @@ -416,10 +419,11 @@ class LabResultDetails extends StatelessWidget { Widget labHistoryList(LabViewModel labmodel) { return SizedBox( - height: labmodel.filteredGraphValues.length < 3 ? labmodel.filteredGraphValues.length * 64 : 180.h, + height: labmodel.filteredGraphValues.length < 3 ? labmodel.filteredGraphValues.length * 64 : (!labmodel.isLabResultsHistoryShowMore ? 180.h : 220.h), child: ListView.separated( padding: EdgeInsets.zero, - itemCount: labmodel.filteredGraphValues.length, + // itemCount: labmodel.isLabResultsHistoryShowMore ? (labmodel.filteredGraphValues.length < 3 ? labmodel.filteredGraphValues : 3) : labmodel.filteredGraphValues.length, + itemCount: !labmodel.isLabResultsHistoryShowMore ? (labmodel.filteredGraphValues.length < 3 ? labmodel.filteredGraphValues.length : 3) : labmodel.filteredGraphValues.length, itemBuilder: (context, index) { var data = labmodel.filteredGraphValues.reversed.toList()[index]; return LabHistoryItem( diff --git a/lib/presentation/lab/search_lab_report.dart b/lib/presentation/lab/search_lab_report.dart index d366f38f..abd5ea0a 100644 --- a/lib/presentation/lab/search_lab_report.dart +++ b/lib/presentation/lab/search_lab_report.dart @@ -93,7 +93,7 @@ class _SearchLabResultsContentState extends State { ), SizedBox(height: ResponsiveExtension(20).h), if (filteredSuggestions.isNotEmpty) ...[ - "Suggestions".toText16(isBold: true), + "Suggestions".toText16(isBold: true, isEnglishOnly: true), ], ], ), @@ -147,6 +147,7 @@ class SuggestionChip extends StatelessWidget { // color: isSelected ? AppColors.textColor : Colors.black87, color: AppColors.textColor, fontWeight: FontWeight.w500, + isEnglishOnly: true ), ), ); diff --git a/lib/presentation/notifications/notifications_list_page.dart b/lib/presentation/notifications/notifications_list_page.dart index 6c344b2e..ec1b34c2 100644 --- a/lib/presentation/notifications/notifications_list_page.dart +++ b/lib/presentation/notifications/notifications_list_page.dart @@ -54,6 +54,7 @@ class NotificationsListPage extends StatelessWidget { child: FadeInAnimation( child: GestureDetector( onTap: () { + notificationsVM.markAsRead(notificationID: notificationsVM.notificationsList[index].id ?? 0); Navigator.push( context, MaterialPageRoute( diff --git a/lib/presentation/rate_appointment/rate_appointment_doctor.dart b/lib/presentation/rate_appointment/rate_appointment_doctor.dart index b9a6c587..8940f0fc 100644 --- a/lib/presentation/rate_appointment/rate_appointment_doctor.dart +++ b/lib/presentation/rate_appointment/rate_appointment_doctor.dart @@ -10,6 +10,7 @@ import 'package:hmg_patient_app_new/presentation/rate_appointment/rate_appointme import 'package:hmg_patient_app_new/presentation/rate_appointment/widget/doctor_row.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/loader/bottomsheet_loader.dart'; import 'package:provider/provider.dart'; class RateAppointmentDoctor extends StatefulWidget { @@ -48,16 +49,16 @@ class _RateAppointmentDoctorState extends State { return Selector( selector: (_, vm) => vm.isRateClinic, - builder: (context, isRateClinic, child) => isRateClinic - ? RateAppointmentClinic(doctorNote: note, doctorRate: rating,) - : SizedBox( - height: sheetHeight, + builder: (context, isRateClinic, child) => + // isRateClinic ? RateAppointmentClinic(doctorNote: note, doctorRate: rating,) + // : + SizedBox( + height: sheetHeight, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Scrollable main content Expanded( - child: Padding( padding: const EdgeInsets.only(top: 0.0, left: 0, right: 0), child: Column( @@ -162,7 +163,6 @@ class _RateAppointmentDoctorState extends State { ), ), - // Bottom action buttons pinned to bottom SafeArea( top: false, @@ -172,7 +172,7 @@ class _RateAppointmentDoctorState extends State { children: [ Expanded( child: CustomButton( - text: "Later", + text: LocaleKeys.later.tr(context: context), backgroundColor: Color(0xffFEE9EA), borderColor: Color(0xffFEE9EA), textColor: Color(0xffED1C2B), @@ -184,12 +184,18 @@ class _RateAppointmentDoctorState extends State { SizedBox(width: 10), Expanded( child: CustomButton( - text: LocaleKeys.next.tr(context: context), - onPressed: () { + text: LocaleKeys.submit.tr(context: context), + onPressed: () async { // Set up clinic rating and show clinic rating view - appointmentRatingViewModel!.setTitle(LocaleKeys.rateDoctor.tr(context: context),); - appointmentRatingViewModel!.setSubTitle(LocaleKeys.howWasYourLastVisitWithDoctor.tr(context: context),); - appointmentRatingViewModel!.setClinicOrDoctor(true); + // appointmentRatingViewModel!.setTitle(LocaleKeys.rateDoctor.tr(context: context),); + // appointmentRatingViewModel!.setSubTitle(LocaleKeys.howWasYourLastVisitWithDoctor.tr(context: context),); + // appointmentRatingViewModel!.setClinicOrDoctor(true); + + LoaderBottomSheet.showLoader(); + await appointmentRatingViewModel!.submitDoctorRating(docRate: rating, docNote: note); + // await appointmentRatingViewModel!.submitClinicRating(clinicRate: rating, clinicNote: note); + LoaderBottomSheet.hideLoader(); + Navigator.pop(context); setState(() {}); }, diff --git a/lib/widgets/graph/custom_graph.dart b/lib/widgets/graph/custom_graph.dart index 3b0629f0..c655ec0d 100644 --- a/lib/widgets/graph/custom_graph.dart +++ b/lib/widgets/graph/custom_graph.dart @@ -31,6 +31,7 @@ import 'package:hmg_patient_app_new/theme/colors.dart'; /// - [showBottomTitleDates]: Whether to show bottom axis labels. /// - [isFullScreeGraph]: Whether the graph is fullscreen. /// - [makeGraphBasedOnActualValue]: Use `actualValue` for plotting. +/// - [isRTL]: Whether the graph should render in right-to-left direction. /// /// Example usage: /// ```dart @@ -70,6 +71,7 @@ class CustomGraph extends StatelessWidget { final bool showLinePoints; final double? cutOffY; final RangeAnnotations? rangeAnnotations; + final bool isRTL; ///creates the left label and provide it to the chart as it will be used by other part of the application so the label will be different for every chart final Widget Function(double) leftLabelFormatter; @@ -113,7 +115,8 @@ class CustomGraph extends StatelessWidget { this.showShadow = false, this.showLinePoints = false, this.cutOffY = 0, - this.rangeAnnotations}); + this.rangeAnnotations, + this.isRTL = false}); @override Widget build(BuildContext context) { @@ -122,6 +125,12 @@ class CustomGraph extends StatelessWidget { final resolvedGraphShadowColor = graphShadowColor ?? AppColors.graphGridColor; final resolvedGraphGridColor = graphGridColor ?? AppColors.graphGridColor; + // For RTL, reverse the data points so the graph reads right-to-left + final displayDataPoints = isRTL ? dataPoints.reversed.toList() : dataPoints; + final displaySecondaryDataPoints = (isRTL && secondaryDataPoints != null) + ? secondaryDataPoints!.reversed.toList() + : secondaryDataPoints; + return Material( color: AppColors.whiteColor, child: SizedBox( @@ -176,10 +185,10 @@ class CustomGraph extends StatelessWidget { // Show tooltip for each touched line return touchedSpots.map((spot) { // Determine which dataset this spot belongs to - final isSecondary = secondaryDataPoints != null && spot.barIndex == 1; + final isSecondary = displaySecondaryDataPoints != null && spot.barIndex == 1; final dataPoint = isSecondary - ? secondaryDataPoints![spot.x.toInt()] - : dataPoints[spot.x.toInt()]; + ? displaySecondaryDataPoints[spot.x.toInt()] + : displayDataPoints[spot.x.toInt()]; return LineTooltipItem( '${dataPoint.actualValue} ${dataPoint.unitOfMeasurement ?? ""} - ${dataPoint.displayTime}', @@ -192,9 +201,19 @@ class CustomGraph extends StatelessWidget { titlesData: FlTitlesData( leftTitles: AxisTitles( sideTitles: SideTitles( - showTitles: true, + showTitles: !isRTL, + reservedSize: leftLabelReservedSize ?? 80, + interval: leftLabelInterval ?? .1, + getTitlesWidget: (value, _) { + return leftLabelFormatter(value); + }, + ), + ), + rightTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: isRTL, reservedSize: leftLabelReservedSize ?? 80, - interval: leftLabelInterval ?? .1, // Let fl_chart handle it + interval: leftLabelInterval ?? .1, getTitlesWidget: (value, _) { return leftLabelFormatter(value); }, @@ -206,30 +225,28 @@ class CustomGraph extends StatelessWidget { showTitles: showBottomTitleDates, reservedSize: bottomLabelReservedSize ?? 20, getTitlesWidget: (value, _) { - return bottomLabelFormatter(value, dataPoints); + return bottomLabelFormatter(value, displayDataPoints); }, interval: 1, // ensures 1:1 mapping with spots ), ), topTitles: AxisTitles(), - rightTitles: AxisTitles(), ), borderData: FlBorderData( show: true, - border: const Border( + border: Border( bottom: BorderSide.none, - left: BorderSide(color: Colors.grey, width: .5), - right: BorderSide.none, + left: isRTL ? BorderSide.none : const BorderSide(color: Colors.grey, width: .5), + right: isRTL ? const BorderSide(color: Colors.grey, width: .5) : BorderSide.none, top: BorderSide.none, ), ), - lineBarsData: _buildColoredLineSegments(dataPoints, showLinePoints, resolvedGraphColor, resolvedGraphShadowColor), + lineBarsData: _buildColoredLineSegments(displayDataPoints, showLinePoints, resolvedGraphColor, resolvedGraphShadowColor, + secondaryPoints: displaySecondaryDataPoints), gridData: FlGridData( show: showGridLines ?? true, drawVerticalLine: false, horizontalInterval: horizontalInterval, - // checkToShowHorizontalLine: (value) => - // value >= 0 && value <= 100, getDrawingHorizontalLine: getDrawingHorizontalLine ?? (value) { return FlLine( @@ -245,7 +262,8 @@ class CustomGraph extends StatelessWidget { ); } - List _buildColoredLineSegments(List dataPoints, bool showLinePoints, Color resolvedGraphColor, Color resolvedGraphShadowColor) { + List _buildColoredLineSegments(List dataPoints, bool showLinePoints, Color resolvedGraphColor, Color resolvedGraphShadowColor, + {List? secondaryPoints}) { final List allSpots = dataPoints.asMap().entries.map((entry) { double value = (makeGraphBasedOnActualValue) ? double.tryParse(entry.value.actualValue) ?? 0.0 : entry.value.value; return FlSpot(entry.key.toDouble(), value); @@ -281,8 +299,8 @@ class CustomGraph extends StatelessWidget { ]; // Add secondary line if provided (for dual-line graphs like blood pressure) - if (secondaryDataPoints != null && secondaryDataPoints!.isNotEmpty) { - final List secondarySpots = secondaryDataPoints!.asMap().entries.map((entry) { + if (secondaryPoints != null && secondaryPoints.isNotEmpty) { + final List secondarySpots = secondaryPoints.asMap().entries.map((entry) { double value = (makeGraphBasedOnActualValue) ? double.tryParse(entry.value.actualValue) ?? 0.0 : entry.value.value; return FlSpot(entry.key.toDouble(), value); }).toList(); diff --git a/lib/widgets/loader/bottomsheet_loader.dart b/lib/widgets/loader/bottomsheet_loader.dart index bff293d0..306d7ce4 100644 --- a/lib/widgets/loader/bottomsheet_loader.dart +++ b/lib/widgets/loader/bottomsheet_loader.dart @@ -5,6 +5,8 @@ import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/enums.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/route_extensions.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/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -13,7 +15,7 @@ class LoaderBottomSheet { static final NavigationService _navService = GetIt.I(); static bool _isVisible = false; - static void showLoader({String? loadingText}) { + static void showLoader({String? loadingText, bool showCloseButton = false, Function? onCloseTap}) { if (_isVisible) return; _isVisible = true; @@ -32,7 +34,31 @@ class LoaderBottomSheet { color: AppColors.whiteColor, borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), - child: Center( + child: (showCloseButton) ? Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "".toText20(), + if (showCloseButton) + IconButton( + icon: Icon(Icons.close, color: AppColors.textColor), + onPressed: () { + context.pop(); + if(onCloseTap != null) { + onCloseTap(); + } + }, + ) + else + SizedBox(width: 48), // Placeholder for alignment + ], + ), + Center( + child: Utils.getLoadingWidget(loadingText: loadingText), + ).paddingSymmetrical(24.w, 0), + ], + ) : Center( child: Utils.getLoadingWidget(loadingText: loadingText), ).paddingSymmetrical(24.w, 0), );