diff --git a/assets/images/svg/location_unavailable_filled.svg b/assets/images/svg/location_unavailable_filled.svg new file mode 100644 index 00000000..8bc315c1 --- /dev/null +++ b/assets/images/svg/location_unavailable_filled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/location_unavailable_filled_background.svg b/assets/images/svg/location_unavailable_filled_background.svg new file mode 100644 index 00000000..cb3fa768 --- /dev/null +++ b/assets/images/svg/location_unavailable_filled_background.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index c5a2f058..a8df3819 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1759,6 +1759,13 @@ "conformationCall": "ستتلقى مكالمة لتأكيد طلبك قريباً.", "radiologyLabResults": "نتائج الأشعة", "disclaimerRadiology": "تم تحليل نتائج الأشعة هذه بواسطة الذكاء الاصطناعي، وهي لا تُعدّ نصيحة طبية. استشر طبيبك المختص للتشخيص والعلاج.", + "enterIdentificationNumberWithNoStar": "أدخل رقم الهوية", + "enterReferralNumber": "أدخل رقم الإحالة", + "referralNumber": "رقم الإحالة", + "phoneHint": "5xxxxxxxx", + "selectSearchCriteria": "اختر معيار البحث", + "selectCriteria": "اختيار المعيار", + "locationServicesDisabled": "حالة الطقس غير متوفرة لتعطيل خدمات الموقع. يرجى تفعيل خدمات الموقع لتتمكن من رؤية معلومات الطقس.", "selectDateTimeKey": "اختيار", "medicalKey": "الطبية", "convertBloodcholesterolInfo":"حول قيمة كوليسترول الدم بين ملجم/ديسيلتر و مليمول/لتر" diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 6207d343..ee1c1d01 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1748,10 +1748,17 @@ "conformationCall": "You will receive a call from HMG for confirmation ", "radiologyLabResults": "Radiology Results", "disclaimerRadiology": "This radiology result was analyzed by AI, and it is not medical advice. Consult your healthcare provider for diagnosis and treatment.", + "enterIdentificationNumberWithNoStar": "Enter Identification Number", + "enterReferralNumber": "Enter Referral Number", + "referralNumber": "Referral Number", + "phoneHint": "5xxxxxxxx", + "selectSearchCriteria": "Select the Search Criteria", + "selectCriteria": "Select Criteria", + "locationServicesDisabled": "Weather is unavailable because location services are disabled. Please enable location services to see the weather information.", "selectDateTimeKey": "Select", - "medicalKey": "Medical", + "medicalKey": "Medical" +, "convertBloodcholesterolInfo": "Convert blood cholesterol values between mg/dL and mmol/L. " - } diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index aab9e25d..c3811a94 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -119,6 +119,8 @@ class AppAssets { static const String search_by_region_icon = '$svgBasePath/search_by_region_icon.svg'; static const String location_red = '$svgBasePath/location_red.svg'; static const String location_unavailable = '$svgBasePath/location_unavailable.svg'; + static const String location_unavailable_filled = '$svgBasePath/location_unavailable_filled.svg'; + static const String location_unavailable_filled_background = '$svgBasePath/location_unavailable_filled_background.svg'; static const String livecare_clinic_icon = '$svgBasePath/livecare_clinic_icon.svg'; static const String immediate_service_icon = '$svgBasePath/immediate_service_icon.svg'; static const String no_visit_icon = '$svgBasePath/no_visit_icon.svg'; diff --git a/lib/core/location_util.dart b/lib/core/location_util.dart index c56c63d4..52a2e93d 100644 --- a/lib/core/location_util.dart +++ b/lib/core/location_util.dart @@ -89,7 +89,7 @@ class LocationUtils { } } - LocationPermission permissionGranted = await Geolocator.checkPermission(); + LocationPermission permissionGranted = await Geolocator.checkPermission(); if (permissionGranted == LocationPermission.denied) { permissionGranted = await Geolocator.requestPermission(); if (permissionGranted != LocationPermission.whileInUse && permissionGranted != LocationPermission.always) { @@ -257,6 +257,30 @@ class LocationUtils { appState.userLong = locationData.longitude; } + Future isLocationPermissionEnabled() async { + if (Platform.isIOS || (await isGMSDevice ?? true)) { + return await _isGMSLocationPermissionEnabled(); + } else { + return await _isHMSLocationPermissionEnabled(); + } + } + + Future _isGMSLocationPermissionEnabled() async { + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) return false; + + LocationPermission permission = await Geolocator.checkPermission(); + return permission == LocationPermission.whileInUse || permission == LocationPermission.always; + } + + Future _isHMSLocationPermissionEnabled() async { + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) return false; + + LocationPermission permission = await Geolocator.checkPermission(); + return permission == LocationPermission.whileInUse || permission == LocationPermission.always; + } + void getHMSLocation({VoidCallback? onFailure, Function(LatLng p1)? onSuccess, VoidCallback? onLocationDeniedForever}) async { try { var location = Location(); diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart index 6c4e7bec..5aa48b07 100644 --- a/lib/core/utils/date_util.dart +++ b/lib/core/utils/date_util.dart @@ -599,6 +599,17 @@ class DateUtil { return '${hours} hr ${minutes} min'; } + + /// Parses an ISO 8601 date string that may have more than 6 fractional-second digits. + /// e.g. '2026-04-12T12:07:35.4226413' → truncates to 6 digits before parsing. + static DateTime? parseISODate(String? date) { + if (date == null || date.isEmpty) return null; + final truncated = date.replaceFirstMapped( + RegExp(r'(\.\d{6})\d+'), + (m) => m.group(1)!, + ); + return DateTime.tryParse(truncated); + } } extension OnlyDate on DateTime { diff --git a/lib/features/emergency_services/emergency_services_view_model.dart b/lib/features/emergency_services/emergency_services_view_model.dart index 55e355fa..83d2a564 100644 --- a/lib/features/emergency_services/emergency_services_view_model.dart +++ b/lib/features/emergency_services/emergency_services_view_model.dart @@ -54,6 +54,7 @@ import 'package:hmg_patient_app_new/widgets/map/map_utility_screen.dart'; import 'package:hmg_patient_app_new/widgets/order_tracking/order_tracking_state.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:huawei_map/huawei_map.dart' as HMSCameraServices; +import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import '../location/GeocodeResponse.dart'; @@ -792,7 +793,6 @@ class EmergencyServicesViewModel extends ChangeNotifier { allOrders.clear(); allOrders.addAll(ambulanceOrders ?? []); allOrders.addAll(ordersRRT?.completedOrders ?? []); - _sortOrdersByDate(allOrders); changeOrderDisplayItems(OrderDislpay.ALL); notifyListeners(); }, @@ -967,7 +967,6 @@ class EmergencyServicesViewModel extends ChangeNotifier { allOrders.clear(); allOrders.addAll(ambulanceOrders ?? []); allOrders.addAll(ordersRRT?.completedOrders ?? []); - _sortOrdersByDate(allOrders); changeOrderDisplayItems(OrderDislpay.ALL); notifyListeners(); }, @@ -996,32 +995,38 @@ class EmergencyServicesViewModel extends ChangeNotifier { this.currentlyDisplayedOrder = currentlyDisplayedOrder; switch (currentlyDisplayedOrder) { case OrderDislpay.ALL: - orderDisplayList = allOrders; + orderDisplayList = List.from(allOrders); break; case OrderDislpay.RRT: - orderDisplayList = ordersRRT?.completedOrders ?? []; + orderDisplayList = List.from(ordersRRT?.completedOrders ?? []); break; case OrderDislpay.AMBULANCE: - orderDisplayList = ambulanceOrders ?? []; + orderDisplayList = List.from(ambulanceOrders ?? []); break; } - _sortOrdersByDate(orderDisplayList); + + orderDisplayList = _sortOrdersByDate(orderDisplayList); notifyListeners(); } - void _sortOrdersByDate(List list) { + List _sortOrdersByDate(List list) { list.sort((a, b) { - final String? dateA = _getCreatedDate(a); - final String? dateB = _getCreatedDate(b); - final bool hasDateA = dateA != null && dateA.contains('/Date('); - final bool hasDateB = dateB != null && dateB.contains('/Date('); - if (!hasDateA && !hasDateB) return 0; - if (!hasDateA) return 1; - if (!hasDateB) return -1; - final parsedA = DateUtil.convertStringToDate(dateA); - final parsedB = DateUtil.convertStringToDate(dateB); - return parsedB.compareTo(parsedA); + final int? dateA = _parseCreatedDate(a)?.millisecondsSinceEpoch; + final int? dateB = _parseCreatedDate(b)?.millisecondsSinceEpoch; + print("the dateA is $dateA and dateB is $dateB"); + if (dateA == null && dateB == null) return 0; + if (dateA == null) return 1; + if (dateB == null) return -1; + return dateB.compareTo(dateA); }); + return list; + } + + DateTime? _parseCreatedDate(dynamic order) { + final String? raw = _getCreatedDate(order); + + + return DateTime.tryParse(raw??""); } String? _getCreatedDate(dynamic order) { @@ -1030,7 +1035,7 @@ class EmergencyServicesViewModel extends ChangeNotifier { return null; } - void openRRT() { + void openRRT(BuildContext context) { if (appState.isAuthenticated) { if (agreedToTermsAndCondition == false) { dialogService.showErrorBottomSheet( @@ -1064,6 +1069,7 @@ class EmergencyServicesViewModel extends ChangeNotifier { return; } placeValueInController(); + context.read().placeValueInController(); locationUtils!.getLocation( isShowConfirmDialog: true, onSuccess: (position) async { diff --git a/lib/features/location/location_view_model.dart b/lib/features/location/location_view_model.dart index 5b0eef6d..460eb0f1 100644 --- a/lib/features/location/location_view_model.dart +++ b/lib/features/location/location_view_model.dart @@ -18,7 +18,6 @@ class LocationViewModel extends ChangeNotifier { final ErrorHandlerService errorHandlerService; LocationViewModel({required this.locationRepo, required this.errorHandlerService}) { - placeValueInController(); } List predictions = []; @@ -31,7 +30,9 @@ class LocationViewModel extends ChangeNotifier { Completer? gmsController; Completer? hmsController; - + get isGMSAvailable { + return getIt.get().isGMSAvailable; + } HMSCameraServices.CameraPosition getHMSLocation() { return HMSCameraServices.CameraPosition(target: HMSCameraServices.LatLng(getIt().userLat, getIt().userLong), zoom: 18); } @@ -43,7 +44,7 @@ class LocationViewModel extends ChangeNotifier { } void placeValueInController() async { - if (await getIt().isGMSAvailable) { + if (isGMSAvailable) { gmsController = Completer(); } else { hmsController = Completer(); diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index b9c29072..0f09f1e9 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -20,6 +20,7 @@ import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/widgets/map/map_utility_screen.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; class PrescriptionsViewModel extends ChangeNotifier { bool isPrescriptionsOrdersLoading = false; @@ -255,7 +256,9 @@ class PrescriptionsViewModel extends ChangeNotifier { ); } - void initiatePrescriptionDelivery() async { + void initiatePrescriptionDelivery(BuildContext context) async { + context.read().placeValueInController(); + getIt.get().getLocation( isShowConfirmDialog: true, onSuccess: (position) async { diff --git a/lib/features/weather/weather_view_model.dart b/lib/features/weather/weather_view_model.dart index 0e3a3285..874630d2 100644 --- a/lib/features/weather/weather_view_model.dart +++ b/lib/features/weather/weather_view_model.dart @@ -1,13 +1,17 @@ import 'package:flutter/cupertino.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/location_util.dart'; import 'package:hmg_patient_app_new/features/weather/models/waether_cities_model.dart'; import 'package:hmg_patient_app_new/features/weather/weather_repo.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import '../../core/app_state.dart' show AppState; + class WeatherMonitorViewModel extends ChangeNotifier { WeatherRepo weatherRepo; ErrorHandlerService errorHandlerService; LocationUtils locationUtils; + bool isLocationAvailable = false; WeatherMonitorViewModel({required this.weatherRepo, required this.errorHandlerService, required this.locationUtils}); @@ -18,11 +22,12 @@ class WeatherMonitorViewModel extends ChangeNotifier { Future fetchCityInfoList({Function(dynamic)? onSuccess, Function(String)? onError}) async { isLoading = true; + notifyListeners(); _cityInfoList.clear(); - locationUtils.getLocation( isShowConfirmDialog: true, onSuccess: (position) async { + isLocationAvailable = true; final result = await weatherRepo.getCityInfo(); result.fold( (failure) async { @@ -52,4 +57,18 @@ class WeatherMonitorViewModel extends ChangeNotifier { ); }); } + + Future checkIfTheLocationIsEnabledOrNot() async { + bool value = await locationUtils.isLocationPermissionEnabled(); + isLocationAvailable = value; + notifyListeners(); + return value; + + } + + void initiateFetchWeather() async { + if(await checkIfTheLocationIsEnabledOrNot()){ + fetchCityInfoList(); + } + } } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 4770dbad..c7c924ef 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1750,6 +1750,13 @@ abstract class LocaleKeys { static const conformationCall = 'conformationCall'; static const radiologyLabResults = 'radiologyLabResults'; static const disclaimerRadiology = 'disclaimerRadiology'; + static const enterIdentificationNumberWithNoStar = 'enterIdentificationNumberWithNoStar'; + static const enterReferralNumber = 'enterReferralNumber'; + static const referralNumber = 'referralNumber'; + static const phoneHint = 'phoneHint'; + static const selectSearchCriteria = 'selectSearchCriteria'; + static const selectCriteria = 'selectCriteria'; + static const locationServicesDisabled = 'locationServicesDisabled'; static const selectDateTimeKey = 'selectDateTimeKey'; static const medicalKey = 'medicalKey'; diff --git a/lib/presentation/e_referral/new_e_referral.dart b/lib/presentation/e_referral/new_e_referral.dart index 8631fa62..b9d54942 100644 --- a/lib/presentation/e_referral/new_e_referral.dart +++ b/lib/presentation/e_referral/new_e_referral.dart @@ -193,7 +193,7 @@ class _NewReferralPageState extends State { children: List.generate(3, (index) { // Fill current step and all previous completed steps if (index <= _currentStep) { - return StepperWidget(widthOfOneState, AppColors.primaryRedColor, true, 4.h); + return StepperWidget(widthOfOneState, AppColors.primaryRedColor, index == _currentStep, 4.h); } else { return StepperWidget(widthOfOneState, AppColors.greyLightColor, false, 4.h); } diff --git a/lib/presentation/e_referral/widget/e_referral_other_details.dart b/lib/presentation/e_referral/widget/e_referral_other_details.dart index 579f281f..c30b67c3 100644 --- a/lib/presentation/e_referral/widget/e_referral_other_details.dart +++ b/lib/presentation/e_referral/widget/e_referral_other_details.dart @@ -142,8 +142,8 @@ class _OtherDetailsStepState extends State { Widget _buildBranchField(BuildContext context, ReferralFormManager formManager) { return DropdownWidget( - labelText: 'Branch', - hintText: formManager.formData.branch?.desciption ?? "Select Branch", + labelText: LocaleKeys.branch.tr(), + hintText: formManager.formData.branch?.desciption ?? LocaleKeys.selectBranch.tr(), isEnable: false, hasSelectionCustomIcon: true, labelColor: Colors.black, 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 efbac168..a30c0c3e 100644 --- a/lib/presentation/e_referral/widget/e_referral_patient_info.dart +++ b/lib/presentation/e_referral/widget/e_referral_patient_info.dart @@ -2,9 +2,11 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'dart:ui' as ui; import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/utils/validation_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/hmg_services/models/resq_models/get_all_cities_resp_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_form_manager.dart'; import 'package:provider/provider.dart'; @@ -14,6 +16,8 @@ import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import '../../../core/dependencies.dart' show getIt; + class PatientInformationStep extends StatefulWidget { const PatientInformationStep({super.key}); @@ -171,8 +175,8 @@ class PatientInformationStepState extends State { Widget _buildPatientCityField(BuildContext context, ReferralFormManager formManager) { return DropdownWidget( - labelText: 'City', - hintText: formManager.formData.patientCity?.description ?? LocaleKeys.selectCity.tr(context: context), + labelText: LocaleKeys.city.tr(), + hintText: getLocaleDescription(formManager.formData.patientCity) ?? LocaleKeys.selectCity.tr(context: context), isEnable: false, hasSelectionCustomIcon: true, labelColor: Colors.black, @@ -187,6 +191,10 @@ class PatientInformationStepState extends State { }); } + String? getLocaleDescription(GetAllCitiesResponseModel? patientCity){ + return getIt.get().isArabic() ? patientCity?.descriptionN: patientCity?.description; + } + void _showCityBottomSheet(BuildContext context, ReferralFormManager formManager) { @@ -217,7 +225,7 @@ class PatientInformationStepState extends State { itemBuilder: (context, index) { final city = cities[index]; return ListTile( - title: (city.description ?? 'Unknown').toText14(), + title: (getLocaleDescription(city) ?? 'Unknown').toText14(), onTap: () { formManager.updatePatientCity(city); Navigator.pop(context); diff --git a/lib/presentation/e_referral/widget/e_referral_requester_form.dart b/lib/presentation/e_referral/widget/e_referral_requester_form.dart index d57abe23..926aab4f 100644 --- a/lib/presentation/e_referral/widget/e_referral_requester_form.dart +++ b/lib/presentation/e_referral/widget/e_referral_requester_form.dart @@ -116,9 +116,9 @@ class RequesterFormStepState extends State { Widget _buildRelationshipField(BuildContext context, ReferralFormManager formManager) { return DropdownWidget( labelText: LocaleKeys.relationship.tr(context: context), - hintText: formManager.formData.relationship?.textEn ?? LocaleKeys.selectRelation.tr(context: context), + hintText: formManager.formData.relationship?.text ?? LocaleKeys.selectRelation.tr(context: context), isEnable: false, - selectedValue: formManager.formData.relationship?.textEn ?? LocaleKeys.selectRelation.tr(context: context), + selectedValue: formManager.formData.relationship?.text ?? LocaleKeys.selectRelation.tr(context: context), errorMessage: formManager.errors.relationship, hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.relationship), hasSelectionCustomIcon: false, @@ -182,7 +182,7 @@ class RequesterFormStepState extends State { itemBuilder: (context, index) { final relationship = hmgServicesVM.relationTypes[index]; return ListTile( - title:relationship.textEn?.toText14(), + title:relationship.text?.toText14(), onTap: () { formManager.updateRelationship(relationship); Navigator.pop(context); diff --git a/lib/presentation/e_referral/widget/search_e_referral_form.dart b/lib/presentation/e_referral/widget/search_e_referral_form.dart index 33697d5e..c19b8a40 100644 --- a/lib/presentation/e_referral/widget/search_e_referral_form.dart +++ b/lib/presentation/e_referral/widget/search_e_referral_form.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/utils/validation_utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_form_manager.dart'; import 'package:provider/provider.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -69,12 +72,13 @@ class SearchEReferralFormFormState extends State { autofocus: true, child: TextInputWidget( controller: _searchController, - padding: const EdgeInsets.symmetric(horizontal: 16.0), - hintText: formManager.searchCriteria == 0 ? "Enter Identification Number" : "Enter Referral Number", - labelText: formManager.searchCriteria == 0 ? "Identification Number" : "Referral Number", + hintText: formManager.searchCriteria == 0 ? LocaleKeys.enterIdentificationNumber.tr() : LocaleKeys.enterReferralNumber.tr(), + labelText: formManager.searchCriteria == 0 ? LocaleKeys.identificationNumber.tr() : LocaleKeys.referralNumber.tr(), keyboardType: TextInputType.number, fontFamily: "Poppins", errorMessage: formManager.errors.searchValue, + padding: EdgeInsets.symmetric(vertical: 14.h, horizontal: 16.h), + hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.searchValue), onChange: (value) { formManager.updateSearchValue(value ?? ''); @@ -90,10 +94,10 @@ class SearchEReferralFormFormState extends State { autofocus: false, child: TextInputWidget( autoFocus: false, - labelText: 'Phone Number', - hintText: "5xxxxxxxx", + labelText: LocaleKeys.phoneNumber.tr(), + hintText: LocaleKeys.phoneHint.tr(), controller: _phoneController, - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), keyboardType: TextInputType.number, fontFamily: "Poppins", onChange: (value) { @@ -122,8 +126,8 @@ class SearchEReferralFormFormState extends State { Widget _buildSelectionField(BuildContext context, ReferralFormManager formManager) { return DropdownWidget( - labelText: "Select the Search Criteria", - hintText: formManager.searchCriteria == 0 ? "Identification Number" : "Referral Number", + labelText: LocaleKeys.selectCriteria.tr(), + hintText: formManager.searchCriteria == 0 ? LocaleKeys.identificationNumber.tr() : LocaleKeys.referralNumber.tr(), isEnable: false, hasSelectionCustomIcon: false, labelColor: Colors.black, @@ -137,13 +141,13 @@ class SearchEReferralFormFormState extends State { void _showCriteriaBottomSheet(BuildContext context, ReferralFormManager formManager) { final criteriaList = [ - {0: 'Identification Number'}, - {1: 'Referral Number'}, + {0: LocaleKeys.identificationNumber.tr()}, + {1: LocaleKeys.referralNumber.tr()}, ]; showCommonBottomSheetWithoutHeight( context, - title: "Select Criteria", + title: LocaleKeys.selectCriteria.tr(), child: ListView.separated( shrinkWrap: true, physics: const BouncingScrollPhysics(), diff --git a/lib/presentation/emergency_services/RRT/rrt_map_screen.dart b/lib/presentation/emergency_services/RRT/rrt_map_screen.dart index bd5407b6..1a603dc3 100644 --- a/lib/presentation/emergency_services/RRT/rrt_map_screen.dart +++ b/lib/presentation/emergency_services/RRT/rrt_map_screen.dart @@ -559,7 +559,9 @@ class RrtMapScreen extends StatelessWidget { context, child: SizedBox( height: MediaQuery.sizeOf(context).height * .8, - child: LocationInputBottomSheet(), + child: LocationInputBottomSheet( + moveCameraController:(location) => context.read().moveController(location) , + ), ), isFullScreen: false, isCloseButtonVisible: true, 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 3b095ecf..79172db3 100644 --- a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart +++ b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart @@ -140,7 +140,7 @@ class RrtRequestTypeSelect extends StatelessWidget { ), CustomButton(text: LocaleKeys.next.tr(), onPressed: () { Navigator.pop(context); - emergencyServicesVM.openRRT(); + emergencyServicesVM.openRRT(context); }, isDisabled: !emergencyServicesVM.agreedToTermsAndCondition, ) diff --git a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart index 3ac19814..c891e565 100644 --- a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart +++ b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart @@ -577,7 +577,9 @@ class CallAmbulancePage extends StatelessWidget { context, child: SizedBox( height: MediaQuery.sizeOf(context).height * .8, - child: LocationInputBottomSheet(), + child: LocationInputBottomSheet( + moveCameraController:(location) => context.read().moveController(location) , + ), ), isFullScreen: false, isCloseButtonVisible: true, diff --git a/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart b/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart index 67bdcbd8..52d820a3 100644 --- a/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart +++ b/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart @@ -42,7 +42,7 @@ class AmbulanceHistoryItem extends StatelessWidget { Row( spacing: 4.w, children: [ - chip(Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor), + chip(Utils.getDayMonthYearDateFormatted(DateUtil.parseISODate(order.created)), AppAssets.calendar, AppColors.blackBgColor), chip(LocaleKeys.ambulancerequest.tr(context: context), AppAssets.ambulance, AppColors.blackBgColor), ], ), diff --git a/lib/presentation/emergency_services/history/widget/rrt_item.dart b/lib/presentation/emergency_services/history/widget/rrt_item.dart index c85f12a5..d3c0e340 100644 --- a/lib/presentation/emergency_services/history/widget/rrt_item.dart +++ b/lib/presentation/emergency_services/history/widget/rrt_item.dart @@ -42,7 +42,7 @@ class RRTItem extends StatelessWidget { Row( spacing: 4.w, children: [ - chip(Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor), + chip(Utils.getDayMonthYearDateFormatted(DateUtil.parseISODate(order.created)), AppAssets.calendar, AppColors.blackBgColor), chip(LocaleKeys.rapidResponseTeam.tr(context: context), AppAssets.ic_rrt_vehicle, AppColors.blackBgColor), ], ), diff --git a/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart b/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart index 4b66abd9..9b1209c8 100644 --- a/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart +++ b/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart @@ -23,8 +23,9 @@ import '../../../theme/colors.dart'; class LocationInputBottomSheet extends StatelessWidget { final Debouncer debouncer = Debouncer(milliseconds: 500); + final Function(Location)? moveCameraController; - LocationInputBottomSheet({super.key}); + LocationInputBottomSheet({super.key, this.moveCameraController}); @override Widget build(BuildContext context) { @@ -106,7 +107,7 @@ class LocationInputBottomSheet extends StatelessWidget { Navigator.of(context).pop(); var location = context.read().placeDetails; if(location != null) { - context.read().moveController( + moveCameraController?.call( Location(lat: location.lat, lng: location.lng)); } }); diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 56923038..734401fe 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -380,7 +380,7 @@ class _ServicesPageState extends State { // TODO: implement initState super.initState(); weatherVM = getIt(); - weatherVM.fetchCityInfoList(); + weatherVM.initiateFetchWeather(); } diff --git a/lib/presentation/hmg_services/widgets/weather_widget.dart b/lib/presentation/hmg_services/widgets/weather_widget.dart index 6c055e76..b54ab78e 100644 --- a/lib/presentation/hmg_services/widgets/weather_widget.dart +++ b/lib/presentation/hmg_services/widgets/weather_widget.dart @@ -1,10 +1,12 @@ 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_export.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/weather/weather_view_model.dart'; +import 'package:hmg_patient_app_new/features/weather/models/waether_cities_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/weather/weather_details_page.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -39,15 +41,20 @@ class WeatherWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( - builder: (context, weatherVM, child) { - final currentCity = weatherVM.cityInfoList.isNotEmpty - ? weatherVM.cityInfoList.first - : null; + return Selector cityInfoList})>( + selector: (_, vm) => (isLoading: vm.isLoading, isLocationAvailable: vm.isLocationAvailable, cityInfoList: vm.cityInfoList), + builder: (context, state, child) { + if (state.isLoading) { + return _buildLoadingState().paddingSymmetrical(24.w, 0.w); + } + if (!state.isLocationAvailable) { + return noWeatherWidget(context).paddingSymmetrical(24.w, 0.w); + } + final currentCity = state.cityInfoList.isNotEmpty ? state.cityInfoList.first : null; final now = DateTime.now(); final temperature = currentCity?.temperature; - final healthTip = LocaleKeys.healthTipsBasedOnCurrentWeather.tr(); + final healthTip = LocaleKeys.healthTipsBasedOnCurrentWeather.tr(); return Row( children: [ @@ -59,69 +66,66 @@ class WeatherWidget extends StatelessWidget { borderRadius: 24.r, hasShadow: false, ), - child: weatherVM.isLoading - ? _buildLoadingState() - : Column( - children: [ - Row( + child: Column( + children: [ + Row( + children: [ + Utils.buildSvgWithAssets( + icon: _getWeatherIcon(currentCity?.categoryValue), + width: 64.w, + height: 64.w, + ), + SizedBox(width: 12.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets( - icon: _getWeatherIcon(currentCity?.categoryValue), - width: 64.w, - height: 64.w, + _formatDateTime(now).toText12( + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, ), - SizedBox(width: 12.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _formatDateTime(now).toText12( - fontWeight: FontWeight.w500, - color: AppColors.greyTextColor, - ), - SizedBox(height: 4.w), - "$temperature°C" - .toText16( - isBold: true, - weight: FontWeight.w600, - ), - SizedBox(height: 4.w), - healthTip.toText12( - color: AppColors.greyTextColor, - fontWeight: FontWeight.w500, - maxLine: 2, - ), - ], - ), + SizedBox(height: 4.w), + "$temperature°C".toText16( + isBold: true, + weight: FontWeight.w600, + ), + SizedBox(height: 4.w), + healthTip.toText12( + color: AppColors.greyTextColor, + fontWeight: FontWeight.w500, + maxLine: 2, ), ], ), - if (showButton) ...[ - SizedBox(height: 16.w), - CustomButton( - text: LocaleKeys.viewDetails.tr(context: context), - onPressed: () { - Navigator.of(context).push( - CustomPageRoute( - page: ChangeNotifierProvider.value( - value: weatherVM, - child: const WeatherDetailsPage(), - ), - ), - ); - }, - padding: EdgeInsets.zero, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 10.r, - height: 40.h, + ), + ], + ), + if (showButton) ...[ + SizedBox(height: 16.w), + CustomButton( + text: LocaleKeys.viewDetails.tr(context: context), + onPressed: () { + Navigator.of(context).push( + CustomPageRoute( + page: ChangeNotifierProvider.value( + value: context.read(), + child: const WeatherDetailsPage(), + ), ), - ], - ], + ); + }, + padding: EdgeInsets.zero, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 10.r, + height: 40.h, ), + ], + ], + ), ), ), ], @@ -130,6 +134,70 @@ class WeatherWidget extends StatelessWidget { ); } + Widget noWeatherWidget(BuildContext context){ + return Container( + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, + ), + child:Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + + Container( + height: 48.h, + width: 48.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.greyColor, + borderRadius: 12.r, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(12.h), + child: Utils.buildSvgWithAssets( + icon: AppAssets.location_unavailable_filled, + fit: BoxFit.contain, + applyThemeColor: false + ), + ), + ), + + + + SizedBox(width: 12.w), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + _formatDateTime(DateTime.now()).toText12( + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + SizedBox(height: 4.w), + + "--".toText16( + isBold: true, + weight: FontWeight.w600, + ), + SizedBox(height: 4.w), + LocaleKeys.locationServicesDisabled.tr().toText12( + color: AppColors.greyTextColor, + fontWeight: FontWeight.w500, + maxLine: 2, + ), + ], + ), + ), + ], + )).onPress((){ + context.read().fetchCityInfoList(); + }); + } + Widget _buildLoadingState() { return Column( children: [ diff --git a/lib/presentation/home_health_care/hhc_procedures_page.dart b/lib/presentation/home_health_care/hhc_procedures_page.dart index 2ece0598..fca3f9c4 100644 --- a/lib/presentation/home_health_care/hhc_procedures_page.dart +++ b/lib/presentation/home_health_care/hhc_procedures_page.dart @@ -12,6 +12,7 @@ import 'package:hmg_patient_app_new/features/authentication/authentication_view_ import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart'; +import 'package:hmg_patient_app_new/features/location/location_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_order_detail_page.dart'; import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_selection_review_page.dart'; @@ -395,9 +396,11 @@ class _HhcProceduresPageState extends State { final navigationServices = getIt.get(); final appState = getIt.get(); final hmgServicesViewModel = context.read(); + if (hmgServicesViewModel.selectedHhcServices.isNotEmpty) { - hmgServicesViewModel.setSelectedServiceForHhcOrder(hmgServicesViewModel.selectedHhcServices.first); + context.read().placeValueInController(); + hmgServicesViewModel.setSelectedServiceForHhcOrder(hmgServicesViewModel.selectedHhcServices.first); bool result = await navigationServices.push( CustomPageRoute( page: MapUtilityScreen( diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index f2ac16c9..a13dbcdd 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -250,7 +250,7 @@ class _PrescriptionDetailPageState extends State { LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); await prescriptionsViewModel.getPrescriptionDetails(widget.prescriptionsResponseModel, onSuccess: (val) { LoaderBottomSheet.hideLoader(); - prescriptionsViewModel.initiatePrescriptionDelivery(); + prescriptionsViewModel.initiatePrescriptionDelivery(context); }, onError: (err) { LoaderBottomSheet.hideLoader(); print(err); diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart index 483b1ad0..1291c2da 100644 --- a/lib/presentation/prescriptions/prescriptions_list_page.dart +++ b/lib/presentation/prescriptions/prescriptions_list_page.dart @@ -195,7 +195,7 @@ class _PrescriptionsListPageState extends State { LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); await prescriptionsViewModel.getPrescriptionDetails(prescriptionsViewModel.patientPrescriptionOrders[index], onSuccess: (val) { LoaderBottomSheet.hideLoader(); - prescriptionsViewModel.initiatePrescriptionDelivery(); + prescriptionsViewModel.initiatePrescriptionDelivery(context); }); } }, diff --git a/lib/widgets/map/map_utility_screen.dart b/lib/widgets/map/map_utility_screen.dart index b7e3a326..300ad57d 100644 --- a/lib/widgets/map/map_utility_screen.dart +++ b/lib/widgets/map/map_utility_screen.dart @@ -211,7 +211,9 @@ class MapUtilityScreen extends StatelessWidget { context, child: SizedBox( height: MediaQuery.sizeOf(context).height * .8, - child: LocationInputBottomSheet(), + child: LocationInputBottomSheet( + moveCameraController:(location) => context.read().moveController(location) , + ), ), isFullScreen: false, isCloseButtonVisible: true,