diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart index d04ad70d..c7f3fa06 100644 --- a/lib/core/utils/size_utils.dart +++ b/lib/core/utils/size_utils.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'dart:math' as math; import 'package:flutter/material.dart'; // These are the Viewport values of your Figma Design. @@ -26,8 +25,14 @@ extension ResponsiveExtension on num { /// Check if device is likely a foldable bool get _isFoldable { double aspectRatio = _screenWidth / _screenHeight; - // Foldable devices typically have aspect ratios close to 1:1 when unfolded - return (aspectRatio > 0.9 && aspectRatio < 1.1) && (_screenWidth > 700 || _screenHeight > 700); + double shorterSide = _screenWidth < _screenHeight ? _screenWidth : _screenHeight; + + // Foldable devices (unfolded) typically have: + // - Shorter side > 600 logical pixels (to exclude regular phones) + // - Aspect ratio between 0.80 and 0.92 (almost square, like Galaxy Z Fold) + // Galaxy Z Fold 5: 1812x2176 physical, ~690x796 logical = 0.866 aspect ratio + // Regular phones: typically 375-430 width, aspect ratio 0.45-0.55 + return (shorterSide > 600) && (aspectRatio > 0.80 && aspectRatio < 0.92); } /// Scale text size - enhanced for foldable devices @@ -53,7 +58,7 @@ extension ResponsiveExtension on num { double get w { double baseScale = (this * _screenWidth) / figmaDesignWidth; - if (_isFoldable|| isTablet ) { + if (_isFoldable || isTablet) { // For foldables, use more conservative width scaling double scale = _screenWidth / figmaDesignWidthTF; scale = scale.clamp(0.8, 1.4); @@ -67,7 +72,7 @@ extension ResponsiveExtension on num { double get h { double baseScale = (this * _screenHeight) / figmaDesignHeight; - if (_isFoldable || isTablet ) { + if (_isFoldable || isTablet) { // For foldables, use height-based scaling but with constraints double scale = (_screenHeight / figmaDesignHeightTF).clamp(0.8, 1.4); return this * scale; @@ -225,10 +230,16 @@ class SizeUtils { deviceType = DeviceType.mobile; } - log("longerSide: $longerSide"); - log("shorterSide: $shorterSide"); - log("isTablet: $isTablet"); - log("isFoldable: $isFoldable"); + debugPrint("============ Device Detection ============"); + debugPrint("longerSide: $longerSide"); + debugPrint("shorterSide: $shorterSide"); + debugPrint("width: $width"); + debugPrint("height: $height"); + debugPrint("deviceType: $deviceType"); + debugPrint("isTablet: $isTablet"); + debugPrint("isFoldable: $isFoldable"); + debugPrint("aspectRatio: ${width / height}"); + debugPrint("=========================================="); } } @@ -241,6 +252,12 @@ bool get isDesktop => SizeUtils.deviceType == DeviceType.desktop; bool get isFoldable { double aspectRatio = SizeUtils.width / SizeUtils.height; - // Foldable devices typically have aspect ratios close to 1:1 when unfolded - return (aspectRatio > 0.9 && aspectRatio < 1.1) && (SizeUtils.width > 700 || SizeUtils.height > 700); + double shorterSide = SizeUtils.width < SizeUtils.height ? SizeUtils.width : SizeUtils.height; + + // Foldable devices (unfolded) typically have: + // - Shorter side > 600 logical pixels (to exclude regular phones) + // - Aspect ratio between 0.80 and 0.92 (almost square, like Galaxy Z Fold) + // Galaxy Z Fold 5: 1812x2176 physical, ~690x796 logical = 0.866 aspect ratio + // Regular phones: typically 375-430 width, aspect ratio 0.45-0.55 + return (shorterSide > 600) && (aspectRatio > 0.80 && aspectRatio < 0.92); } diff --git a/lib/features/smartwatch_health_data/HealthDataTransformation.dart b/lib/features/smartwatch_health_data/health_data_transformations.dart similarity index 99% rename from lib/features/smartwatch_health_data/HealthDataTransformation.dart rename to lib/features/smartwatch_health_data/health_data_transformations.dart index ffda4f4f..6f777353 100644 --- a/lib/features/smartwatch_health_data/HealthDataTransformation.dart +++ b/lib/features/smartwatch_health_data/health_data_transformations.dart @@ -3,7 +3,7 @@ import 'dart:math'; import 'package:hmg_patient_app_new/core/common_models/data_points.dart'; import 'package:intl/intl.dart'; -import 'model/Vitals.dart'; +import 'model/vitals_data_model.dart'; enum Durations { daily("daily"), diff --git a/lib/features/smartwatch_health_data/health_provider.dart b/lib/features/smartwatch_health_data/health_provider.dart index 963c0352..c296f717 100644 --- a/lib/features/smartwatch_health_data/health_provider.dart +++ b/lib/features/smartwatch_health_data/health_provider.dart @@ -1,18 +1,17 @@ import 'package:flutter/foundation.dart'; import 'package:health/health.dart'; +import 'package:hmg_patient_app_new/core/common_models/data_points.dart'; import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; -import 'package:hmg_patient_app_new/core/utils/loading_utils.dart'; import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_service.dart'; +import 'package:hmg_patient_app_new/presentation/smartwatches/activity_detail.dart'; +import 'package:hmg_patient_app_new/presentation/smartwatches/smart_watches_health_data_screen.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; -import '../../core/common_models/data_points.dart'; -import '../../core/dependencies.dart'; -import '../../presentation/smartwatches/activity_detail.dart' show ActivityDetails; -import '../../presentation/smartwatches/smart_watch_activity.dart' show SmartWatchActivity; -import '../../services/navigation_service.dart' show NavigationService; -import 'HealthDataTransformation.dart'; -import 'model/Vitals.dart'; +import 'health_data_transformations.dart'; +import 'model/vitals_data_model.dart'; class HealthProvider with ChangeNotifier { final HealthService _healthService = HealthService(); @@ -22,7 +21,8 @@ class HealthProvider with ChangeNotifier { String selectedTimeRange = '7D'; int selectedTabIndex = 0; - SmartWatchTypes? selectedWatchType ; + SmartWatchTypes? selectedWatchType; + String selectedWatchURL = 'assets/images/png/smartwatches/apple-watch-5.jpg'; HealthDataTransformation healthDataTransformation = HealthDataTransformation(); @@ -90,7 +90,7 @@ class HealthProvider with ChangeNotifier { healthData[type] = data; notifyListeners(); } catch (e) { - print('Error refreshing metric $type: $e'); + debugPrint('Error refreshing metric $type: $e'); } } @@ -129,14 +129,12 @@ class HealthProvider with ChangeNotifier { await getVitals(); // LoaderBottomSheet.hideLoader(); // await Future.delayed(Duration(seconds: 5)); - getIt.get().pushPage(page: SmartWatchActivity()); - print('Device initialized successfully'); + getIt.get().pushPage(page: SmartWatchesHealthDataScreen()); } notifyListeners(); } Future getVitals() async { - final result = await _healthService.getVitals(); vitals = result; LoaderBottomSheet.hideLoader(); @@ -186,15 +184,17 @@ class HealthProvider with ChangeNotifier { } selectedData = yearly = healthDataTransformation.transformVitalsToDataPoints(vitals!, Durations.yearly.value, selectedSection); break; - default: - {} - ; } notifyListeners(); } void navigateToDetails(String value, {required String sectionName, required String uom}) { - getIt.get().pushPage(page: ActivityDetails(selectedActivity: value, sectionName:sectionName, uom: uom,)); + getIt.get().pushPage( + page: ActivityDetails( + selectedActivity: value, + sectionName: sectionName, + uom: uom, + )); } void saveSelectedSection(String value) { @@ -243,7 +243,6 @@ class HealthProvider with ChangeNotifier { count++; } }); - print("total count is $count and total is $total"); averageValue = count > 0 ? total / count : null; notifyListeners(); } @@ -261,7 +260,7 @@ class HealthProvider with ChangeNotifier { String firstNonEmptyValue(List dataPoints) { try { - return dataPoints.firstWhere((dp) => dp.value != null && dp.value!.trim().isNotEmpty).value; + return dataPoints.firstWhere((dp) => dp.value.trim().isNotEmpty).value; } catch (e) { return "0"; // no non-empty value found } diff --git a/lib/features/smartwatch_health_data/health_service.dart b/lib/features/smartwatch_health_data/health_service.dart index 7d42092d..78411bfb 100644 --- a/lib/features/smartwatch_health_data/health_service.dart +++ b/lib/features/smartwatch_health_data/health_service.dart @@ -5,7 +5,7 @@ import 'dart:io'; import 'package:health/health.dart'; import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart'; -import 'package:hmg_patient_app_new/features/smartwatch_health_data/model/Vitals.dart'; +import 'package:hmg_patient_app_new/features/smartwatch_health_data/model/vitals_data_model.dart'; import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/create_watch_helper.dart'; import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart'; import 'package:permission_handler/permission_handler.dart'; diff --git a/lib/features/smartwatch_health_data/model/Vitals.dart b/lib/features/smartwatch_health_data/model/vitals_data_model.dart similarity index 69% rename from lib/features/smartwatch_health_data/model/Vitals.dart rename to lib/features/smartwatch_health_data/model/vitals_data_model.dart index 96386f2d..ba1ac9f1 100644 --- a/lib/features/smartwatch_health_data/model/Vitals.dart +++ b/lib/features/smartwatch_health_data/model/vitals_data_model.dart @@ -1,5 +1,5 @@ class Vitals { - String value; + String value; final String timestamp; final String unitOfMeasure; @@ -16,11 +16,6 @@ class Vitals { unitOfMeasure: map['uom'] ?? "", ); } - - - toString(){ - return "{\"value\": \"$value\", \"timeStamp\": \"$timestamp\", \"uom\": \"$unitOfMeasure\"}"; - } } class VitalsWRTType { @@ -31,15 +26,21 @@ class VitalsWRTType { final List activity; final List bodyOxygen; final List bodyTemperature; - double maxHeartRate = double.negativeInfinity; - double maxSleep = double.negativeInfinity; - double maxStep= double.negativeInfinity; - double maxActivity = double.negativeInfinity; - double maxBloodOxygen = double.negativeInfinity; - double maxBodyTemperature = double.negativeInfinity; - + double maxHeartRate = double.negativeInfinity; + double maxSleep = double.negativeInfinity; + double maxStep = double.negativeInfinity; + double maxActivity = double.negativeInfinity; + double maxBloodOxygen = double.negativeInfinity; + double maxBodyTemperature = double.negativeInfinity; - VitalsWRTType({required this.distance, required this.bodyOxygen, required this.bodyTemperature, required this.heartRate, required this.sleep, required this.step, required this.activity}); + VitalsWRTType( + {required this.distance, + required this.bodyOxygen, + required this.bodyTemperature, + required this.heartRate, + required this.sleep, + required this.step, + required this.activity}); factory VitalsWRTType.fromMap(Map map) { List activity = []; @@ -82,16 +83,23 @@ class VitalsWRTType { map["distance"].forEach((element) { element["uom"] = "km"; var data = Vitals.fromMap(element); - data.value = (double.parse(data.value)/1000).toStringAsFixed(2); + data.value = (double.parse(data.value) / 1000).toStringAsFixed(2); distance.add(data); }); - return VitalsWRTType(bodyTemperature: bodyTemperature, bodyOxygen: bodyOxygen, heartRate: heartRate, sleep: sleeps, step: steps, activity: activity, distance: distance); + return VitalsWRTType( + bodyTemperature: bodyTemperature, + bodyOxygen: bodyOxygen, + heartRate: heartRate, + sleep: sleeps, + step: steps, + activity: activity, + distance: distance); } Map> getVitals() { return { - "heartRate": heartRate , + "heartRate": heartRate, "sleep": sleep, "steps": step, "activity": activity, diff --git a/lib/features/smartwatch_health_data/watch_connectors/health_connect_helper.dart b/lib/features/smartwatch_health_data/watch_connectors/health_connect_helper.dart index 87e1cf3a..b77b5430 100644 --- a/lib/features/smartwatch_health_data/watch_connectors/health_connect_helper.dart +++ b/lib/features/smartwatch_health_data/watch_connectors/health_connect_helper.dart @@ -6,7 +6,7 @@ import 'package:health/health.dart'; import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart' show WatchHelper; import 'package:permission_handler/permission_handler.dart'; -import '../model/Vitals.dart'; +import '../model/vitals_data_model.dart'; class HealthConnectHelper extends WatchHelper { final Health health = Health(); diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 83fd4342..1c0347e1 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -364,10 +364,6 @@ class _AppointmentDetailsPageState extends State { isFullScreen: false, isCloseButtonVisible: true, ); - // var isEventAddedOrRemoved = await CalenderUtilsNew.instance.checkAndRemove( id:"${widget.patientAppointmentHistoryResponseModel.appointmentNo}", ); - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // }); }, onRescheduleTap: () async { openDoctorScheduleCalendar(); @@ -507,67 +503,11 @@ class _AppointmentDetailsPageState extends State { } }, ) - - // Switch( - // activeThumbColor: AppColors.successColor, - // // activeTrackColor: AppColors.successColor.withValues(alpha: .15), - // value: widget.patientAppointmentHistoryResponseModel.hasReminder!, - // onChanged: (newValue) async { - // CalenderUtilsNew calender = CalenderUtilsNew.instance; - // bool isEventAddedOrRemoved = false; - // if(newValue == true){ - // DateTime startDate = DateTime.now(); - // DateTime endDate = DateUtil.convertStringToDate(widget - // .patientAppointmentHistoryResponseModel.appointmentDate); - // BottomSheetUtils().showReminderBottomSheet( - // context, - // endDate, - // widget.patientAppointmentHistoryResponseModel.doctorNameObj??"", - // "${widget.patientAppointmentHistoryResponseModel.appointmentNo}"??"", - // "", - // "", - // title: "Appointment with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}", - // description: - // "${widget.patientAppointmentHistoryResponseModel.doctorNameObj} will be having an appointment on ${widget.patientAppointmentHistoryResponseModel.appointmentDate}", - // onSuccess: () { - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - // }); - // }, - // isMultiAllowed: true, - // onMultiDateSuccess: (int selectedIndex) async { - // isEventAddedOrRemoved = await calender.createOrUpdateEvent( - // title: - // "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} on ${DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)}, Appointment #${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // description: - // "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} in ${widget.patientAppointmentHistoryResponseModel.projectName}", - // scheduleDateTime: DateUtil.convertStringToDate(widget - // .patientAppointmentHistoryResponseModel.appointmentDate), - // eventId: "${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // location: '', - // reminderMinutes: selectedIndex - // ); - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // }); - // }, - // ); - // }else { - // isEventAddedOrRemoved = await calender.checkAndRemove( id:"${widget.patientAppointmentHistoryResponseModel.appointmentNo}", ); - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(!isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // }); - // } - // - // - // }, - // ), ], ).paddingSymmetrical(16.w, 0) ], ), ), - SizedBox(height: 16.h), !AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? Column( @@ -602,48 +542,6 @@ class _AppointmentDetailsPageState extends State { SizedBox(height: 16.h), ], ), - // ((!AppointmentType.isConfirmed(widget.patientAppointmentHistoryResponseModel) && widget.patientAppointmentHistoryResponseModel.nextAction != 10) - // ? CustomButton( - // text: LocaleKeys.confirm.tr(), - // onPressed: () async { - // LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingAppointmentPleaseWait.tr(context: context)); - // await myAppointmentsViewModel.confirmAppointment( - // patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, - // onSuccess: (apiResponse) { - // LoaderBottomSheet.hideLoader(); - // myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); - // myAppointmentsViewModel.initAppointmentsViewModel(); - // // myAppointmentsViewModel.getPatientAppointments(true, false); - // showCommonBottomSheetWithoutHeight( - // title: "", - // context, - // child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentConfirmedSuccessfully.tr(context: context)), - // callBackFunc: () { - // Navigator.pushAndRemoveUntil( - // context, - // CustomPageRoute( - // page: LandingNavigation(), - // ), - // (r) => false); - // }, - // isFullScreen: false, - // isCloseButtonVisible: false, - // isAutoDismiss: true - // ); - // }); - // }, - // backgroundColor: AppColors.successColor, - // borderColor: AppColors.successColor, - // textColor: Colors.white, - // fontSize: 14.f, - // isBold: true, - // borderRadius: 12.r, - // height: 40.h, - // icon: AppAssets.confirm_appointment_icon, - // iconColor: Colors.white, - // iconSize: 16.h, - // ) - // : SizedBox.shrink()) ], ), //TODO Add countdown timer in case of LiveCare Appointment @@ -748,148 +646,6 @@ class _AppointmentDetailsPageState extends State { ); }), SizedBox(height: 16.h), - // Container( - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // color: AppColors.whiteColor, - // borderRadius: 20.r, - // hasShadow: false, - // ), - // child: Row( - // mainAxisSize: MainAxisSize.max, - // children: [ - // Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h, applyThemeColor: false), - // SizedBox(width: 8.h), - // Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), - // LocaleKeys.notifyMeBeforeAppointment.tr(context: context).toText11(color: AppColors.textColorLight, isBold: true), - // ], - // ), - // const Spacer(), - // BellAnimatedSwitch( - // key: _bellSwitchKey, - // initialValue: widget.patientAppointmentHistoryResponseModel.hasReminder ?? false, - // activeColor: AppColors.successColor.withOpacity(0.2), - // inactiveColor: AppColors.lightGrayBGColor, - // activeCircleColor: AppColors.successColor, - // inactiveCircleColor: AppColors.greyTextColor, - // activeIconColor: AppColors.bgGreenColor, - // inactiveIconColor: AppColors.greyTextColor, - // activeIcon: Utils.buildSvgWithAssets(icon: AppAssets.bell, iconColor: AppColors.whiteColor, width: 15.w, height: 15.h), - // inactiveIcon: Utils.buildSvgWithAssets(icon: AppAssets.bell, iconColor: AppColors.whiteColor, width: 15.w, height: 15.h), - // onChanged: (newValue) async { - // CalenderUtilsNew calender = CalenderUtilsNew.instance; - // bool isEventAddedOrRemoved = false; - // if (newValue == true) { - // DateTime startDate = DateTime.now(); - // DateTime endDate = DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate); - // - // // Show reminder bottom sheet and check if permission was granted - // bool permissionGranted = await BottomSheetUtils().showReminderBottomSheet( - // context, - // endDate, - // widget.patientAppointmentHistoryResponseModel.doctorNameObj ?? "", - // "${widget.patientAppointmentHistoryResponseModel.appointmentNo}" ?? "", - // "", - // "", - // title: "Appointment with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}", - // description: - // "${widget.patientAppointmentHistoryResponseModel.doctorNameObj} will be having an appointment on ${widget.patientAppointmentHistoryResponseModel.appointmentDate}", - // onSuccess: () { - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - // }); - // }, - // isMultiAllowed: true, - // onMultiDateSuccess: (int selectedIndex) async { - // isEventAddedOrRemoved = await calender.createOrUpdateEvent( - // title: - // "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} on ${DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)}, Appointment #${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // description: - // "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} in ${widget.patientAppointmentHistoryResponseModel.projectName}", - // scheduleDateTime: DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), - // eventId: "${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // location: '', - // reminderMinutes: selectedIndex); - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // }); - // }, - // ); - // - // // If permission was not granted, revert the switch back to OFF - // if (!permissionGranted) { - // _bellSwitchKey.currentState?.setSwitchValue(false); - // } - // } else { - // isEventAddedOrRemoved = await calender.checkAndRemove( - // id: "${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // ); - // setState(() { - // myAppointmentsViewModel.setAppointmentReminder(!isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // }); - // } - // }, - // ) - // - // // Switch( - // // activeThumbColor: AppColors.successColor, - // // // activeTrackColor: AppColors.successColor.withValues(alpha: .15), - // // value: widget.patientAppointmentHistoryResponseModel.hasReminder!, - // // onChanged: (newValue) async { - // // CalenderUtilsNew calender = CalenderUtilsNew.instance; - // // bool isEventAddedOrRemoved = false; - // // if(newValue == true){ - // // DateTime startDate = DateTime.now(); - // // DateTime endDate = DateUtil.convertStringToDate(widget - // // .patientAppointmentHistoryResponseModel.appointmentDate); - // // BottomSheetUtils().showReminderBottomSheet( - // // context, - // // endDate, - // // widget.patientAppointmentHistoryResponseModel.doctorNameObj??"", - // // "${widget.patientAppointmentHistoryResponseModel.appointmentNo}"??"", - // // "", - // // "", - // // title: "Appointment with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}", - // // description: - // // "${widget.patientAppointmentHistoryResponseModel.doctorNameObj} will be having an appointment on ${widget.patientAppointmentHistoryResponseModel.appointmentDate}", - // // onSuccess: () { - // // setState(() { - // // myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - // // }); - // // }, - // // isMultiAllowed: true, - // // onMultiDateSuccess: (int selectedIndex) async { - // // isEventAddedOrRemoved = await calender.createOrUpdateEvent( - // // title: - // // "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} on ${DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)}, Appointment #${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // // description: - // // "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} in ${widget.patientAppointmentHistoryResponseModel.projectName}", - // // scheduleDateTime: DateUtil.convertStringToDate(widget - // // .patientAppointmentHistoryResponseModel.appointmentDate), - // // eventId: "${widget.patientAppointmentHistoryResponseModel.appointmentNo}", - // // location: '', - // // reminderMinutes: selectedIndex - // // ); - // // setState(() { - // // myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // // }); - // // }, - // // ); - // // }else { - // // isEventAddedOrRemoved = await calender.checkAndRemove( id:"${widget.patientAppointmentHistoryResponseModel.appointmentNo}", ); - // // setState(() { - // // myAppointmentsViewModel.setAppointmentReminder(!isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); - // // }); - // // } - // // - // // - // // }, - // // ), - // ], - // ).paddingSymmetrical(16.h, 16.h), - // ), SizedBox(height: 16.h), ], ) @@ -900,7 +656,7 @@ class _AppointmentDetailsPageState extends State { crossAxisCount: 3, crossAxisSpacing: 16.h, mainAxisSpacing: 16.w, - mainAxisExtent: 115.h, + childAspectRatio: isFoldable ? 1.2 : (isTablet ? 1.1 : 0.78), ), physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, @@ -1093,213 +849,6 @@ class _AppointmentDetailsPageState extends State { ], ); }), - - // Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // "Lab & Radiology".needTranslation.toText18(isBold: true), - // SizedBox(height: 16.h), - // Row( - // children: [ - // Expanded( - // child: LabRadCard( - // icon: AppAssets.lab_result_icon, - // labelText: LocaleKeys.labResults.tr(context: context), - // // labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar"], - // // labOrderTests: labViewModel.isLabOrdersLoading ? [] : labViewModel.labOrderTests, - // labOrderTests: [], - // // isLoading: labViewModel.isLabOrdersLoading, - // isLoading: false, - // ).onPress(() { - // Navigator.of(context).push( - // CustomPageRoute( - // page: LabOrdersPage(), - // ), - // ); - // }), - // ), - // SizedBox(width: 16.h), - // Expanded( - // child: LabRadCard( - // icon: AppAssets.radiology_icon, - // labelText: LocaleKeys.radiology.tr(context: context), - // // labOrderTests: ["Chest X-ray", "Abdominal Ultrasound", "Dental X-ray"], - // labOrderTests: [], - // isLoading: false, - // ).onPress(() { - // Navigator.of(context).push( - // CustomPageRoute( - // page: RadiologyOrdersPage(), - // ), - // ); - // }), - // ), - // ], - // ), - // SizedBox(height: 16.h), - // LocaleKeys.prescriptions.tr(context: context).toText18(isBold: true), - // SizedBox(height: 16.h), - // Consumer(builder: (context, prescriptionVM, child) { - // return prescriptionVM.isPrescriptionsDetailsLoading - // ? const MoviesShimmerWidget() - // : Container( - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // color: Colors.white, - // borderRadius: 20.r, - // ), - // padding: EdgeInsets.all(16.w), - // child: Column( - // children: [ - // // ListView.separated( - // // itemCount: prescriptionVM.prescriptionDetailsList.length, - // // shrinkWrap: true, - // // padding: EdgeInsets.only(right: 8.w), - // // physics: NeverScrollableScrollPhysics(), - // // itemBuilder: (context, index) { - // // return AnimationConfiguration.staggeredList( - // // position: index, - // // duration: const Duration(milliseconds: 500), - // // child: SlideAnimation( - // // verticalOffset: 100.0, - // // child: FadeInAnimation( - // // child: Row( - // // children: [ - // // Utils.buildSvgWithAssets( - // // icon: AppAssets.prescription_item_icon, - // // width: 40.h, - // // height: 40.h, - // // ), - // // SizedBox(width: 8.h), - // // Row( - // // mainAxisSize: MainAxisSize.max, - // // children: [ - // // Column( - // // children: [ - // // prescriptionVM.prescriptionDetailsList[index].itemDescription! - // // .toText12(isBold: true, maxLine: 1), - // // "Prescribed By: ${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}" - // // .needTranslation - // // .toText10( - // // weight: FontWeight.w600, - // // color: AppColors.greyTextColor, - // // letterSpacing: -0.4), - // // ], - // // ), - // // SizedBox(width: 68.w), - // // Transform.flip( - // // flipX: appState.isArabic(), - // // child: Utils.buildSvgWithAssets( - // // icon: AppAssets.forward_arrow_icon, - // // iconColor: AppColors.blackColor, - // // width: 18.w, - // // height: 13.h, - // // fit: BoxFit.contain, - // // ), - // // ), - // // ], - // // ), - // // ], - // // ), - // // ), - // // ), - // // ); - // // }, - // // separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - // // ).onPress(() { - // // prescriptionVM.setPrescriptionsDetailsLoading(); - // // Navigator.of(context).push( - // // CustomPageRoute( - // // page: PrescriptionDetailPage(prescriptionsResponseModel: getPrescriptionRequestModel()), - // // ), - // // ); - // // }), - // SizedBox(height: 16.h), - // const Divider(color: AppColors.dividerColor), - // SizedBox(height: 16.h), - // // Wrap( - // // runSpacing: 6.w, - // // children: [ - // // // Expanded( - // // // child: CustomButton( - // // // text: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? LocaleKeys.resendOrder.tr(context: context) : LocaleKeys.prescriptionDeliveryError.tr(context: context), - // // // onPressed: () {}, - // // // backgroundColor: AppColors.secondaryLightRedColor, - // // // borderColor: AppColors.secondaryLightRedColor, - // // // textColor: AppColors.primaryRedColor, - // // // fontSize: 14, - // // // isBold: true, - // // // borderRadius: 12.h, - // // // height: 40.h, - // // // icon: AppAssets.appointment_calendar_icon, - // // // iconColor: AppColors.primaryRedColor, - // // // iconSize: 16.h, - // // // ), - // // // ), - // // // SizedBox(width: 16.h), - // // Expanded( - // // child: CustomButton( - // // text: "Refill & Delivery".needTranslation, - // // onPressed: () { - // // Navigator.of(context) - // // .push( - // // CustomPageRoute( - // // page: PrescriptionsListPage(), - // // ), - // // ) - // // .then((val) { - // // prescriptionsViewModel.setPrescriptionsDetailsLoading(); - // // prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel()); - // // }); - // // }, - // // backgroundColor: AppColors.secondaryLightRedColor, - // // borderColor: AppColors.secondaryLightRedColor, - // // textColor: AppColors.primaryRedColor, - // // fontSize: 14.f, - // // isBold: true, - // // borderRadius: 12.r, - // // height: 40.h, - // // icon: AppAssets.requests, - // // iconColor: AppColors.primaryRedColor, - // // iconSize: 16.h, - // // ), - // // ), - // // - // // SizedBox(width: 16.w), - // // Expanded( - // // child: CustomButton( - // // text: "All Prescriptions".needTranslation, - // // onPressed: () { - // // Navigator.of(context) - // // .push( - // // CustomPageRoute( - // // page: PrescriptionsListPage(), - // // ), - // // ) - // // .then((val) { - // // prescriptionsViewModel.setPrescriptionsDetailsLoading(); - // // prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel()); - // // }); - // // }, - // // backgroundColor: AppColors.secondaryLightRedColor, - // // borderColor: AppColors.secondaryLightRedColor, - // // textColor: AppColors.primaryRedColor, - // // fontSize: 14.f, - // // isBold: true, - // // borderRadius: 12.r, - // // height: 40.h, - // // icon: AppAssets.requests, - // // iconColor: AppColors.primaryRedColor, - // // iconSize: 16.h, - // // ), - // // ), - // // ], - // // ), - // ], - // ), - // ); - // }), - // ], - // ), ], ).paddingAll(24.w), ), diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 05358243..951583d6 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -1,3 +1,5 @@ +import 'dart:ui' as ui; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -17,8 +19,6 @@ 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/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; -import 'dart:ui' as ui; - import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; @@ -67,8 +67,8 @@ class AppointmentDoctorCard extends StatelessWidget { Transform.translate( offset: Offset(0.0, -20.h), child: Container( - width: 40.w, - height: 40.h, + width: 50.h, + height: 50.h, decoration: BoxDecoration( color: AppColors.whiteColor, shape: BoxShape.circle, // Makes the container circular @@ -80,9 +80,10 @@ class AppointmentDoctorCard extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, iconColor: AppColors.ratingColorYellow), + Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.h, height: 15.h, iconColor: AppColors.ratingColorYellow), SizedBox(height: 2.h), - "${patientAppointmentHistoryResponseModel.decimalDoctorRate ?? 0.0}".toText11(isBold: true, color: AppColors.textColor, isEnglishOnly: true), + "${patientAppointmentHistoryResponseModel.decimalDoctorRate ?? 0.0}" + .toText11(isBold: true, color: AppColors.textColor, isEnglishOnly: true), ], ), ).circle(100), @@ -97,9 +98,14 @@ class AppointmentDoctorCard extends StatelessWidget { children: [ Row( children: [ - patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "")), + patientAppointmentHistoryResponseModel.doctorNameObj!.toText16( + isBold: true, + isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? ""), + textOverflow: TextOverflow.ellipsis, + ), SizedBox(width: 12.w), - (patientAppointmentHistoryResponseModel.doctorNationalityFlagURL != null && patientAppointmentHistoryResponseModel.doctorNationalityFlagURL!.isNotEmpty) + (patientAppointmentHistoryResponseModel.doctorNationalityFlagURL != null && + patientAppointmentHistoryResponseModel.doctorNationalityFlagURL!.isNotEmpty) ? Image.network( patientAppointmentHistoryResponseModel.doctorNationalityFlagURL ?? "https://hmgwebservices.com/Images/flag/SAU.png", width: 20.h, @@ -130,19 +136,25 @@ class AppointmentDoctorCard extends StatelessWidget { child: AppCustomChipWidget( labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), icon: AppAssets.doctor_calendar_icon, - richText: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang( + richText: + "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang( DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false, )}" - .toText10(isBold: true), + .toText10(isBold: true), ), ), AppCustomChipWidget( labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), - icon: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppAssets.walkin_appointment_icon : AppAssets.small_livecare_icon, + icon: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! + ? AppAssets.walkin_appointment_icon + : AppAssets.small_livecare_icon, iconColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white, - labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? LocaleKeys.livecare.tr(context: context) : LocaleKeys.walkin.tr(context: context), - backgroundColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor, + labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! + ? LocaleKeys.livecare.tr(context: context) + : LocaleKeys.walkin.tr(context: context), + backgroundColor: + !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor, textColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white, ), ], @@ -150,10 +162,12 @@ class AppointmentDoctorCard extends StatelessWidget { ], ), ), - - patientAppointmentHistoryResponseModel.isLiveCareAppointment! || patientAppointmentHistoryResponseModel.isClinicReBookingAllowed! ==false || patientAppointmentHistoryResponseModel.isActiveDoctor! == false + patientAppointmentHistoryResponseModel.isLiveCareAppointment! || + patientAppointmentHistoryResponseModel.isClinicReBookingAllowed! == false || + patientAppointmentHistoryResponseModel.isActiveDoctor! == false ? SizedBox.shrink() - : Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown).onPress(() async { + : Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown) + .onPress(() async { DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel(); selectedDoctor.doctorID = patientAppointmentHistoryResponseModel.doctorID; selectedDoctor.doctorImageURL = patientAppointmentHistoryResponseModel.doctorImageURL; @@ -197,8 +211,7 @@ class AppointmentDoctorCard extends StatelessWidget { AppointmentType.isArrived(patientAppointmentHistoryResponseModel), ), ), - if (timerWidget != null) - timerWidget ?? SizedBox() + if (timerWidget != null) timerWidget ?? SizedBox() ], ), ), diff --git a/lib/presentation/book_appointment/widgets/appointment_calendar.dart b/lib/presentation/book_appointment/widgets/appointment_calendar.dart index 9e83a70d..0b9d9029 100644 --- a/lib/presentation/book_appointment/widgets/appointment_calendar.dart +++ b/lib/presentation/book_appointment/widgets/appointment_calendar.dart @@ -92,7 +92,7 @@ class _AppointmentCalendarState extends State { // ], // ), SizedBox( - height: 350.h, + height: MediaQuery.of(context).size.height * 0.45, child: Directionality( textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr, child: Localizations.override( @@ -102,7 +102,7 @@ class _AppointmentCalendarState extends State { controller: _calendarController, minDate: DateTime.now(), showNavigationArrow: true, - headerHeight: 60.h, + // headerHeight: 60.h, headerStyle: CalendarHeaderStyle( backgroundColor: AppColors.transparent, textAlign: isArabic ? TextAlign.end : TextAlign.start, @@ -157,8 +157,11 @@ class _AppointmentCalendarState extends State { ), //TODO: Add Next Day Span here dayEvents.isNotEmpty - ? SizedBox( - height: 100.h, + ? ConstrainedBox( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.15, + minHeight: 0, + ), child: Directionality( textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr, child: SingleChildScrollView( @@ -169,7 +172,7 @@ class _AppointmentCalendarState extends State { spacing: 6.h, runSpacing: 6.h, children: List.generate( - dayEvents.length, // Generate a large number of items to ensure scrolling + dayEvents.length, (index) => TimeSlotChip( label: dayEvents[index].isoTime!, isSelected: index == selectedButtonIndex, @@ -204,7 +207,8 @@ class _AppointmentCalendarState extends State { ), ); } else { - bookAppointmentsViewModel.getAppointmentNearestGate(projectID: bookAppointmentsViewModel.selectedDoctor.projectID!, clinicID: bookAppointmentsViewModel.selectedDoctor.clinicID!); + bookAppointmentsViewModel.getAppointmentNearestGate( + projectID: bookAppointmentsViewModel.selectedDoctor.projectID!, clinicID: bookAppointmentsViewModel.selectedDoctor.clinicID!); bookAppointmentsViewModel.setSelectedAppointmentDateTime(selectedDate, selectedTime, selectedDateDisplay); Navigator.of(context).pop(); Navigator.of(context).push( @@ -221,7 +225,8 @@ class _AppointmentCalendarState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), + Lottie.asset(AppAnimations.errorAnimation, + repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), SizedBox(height: 8.h), (LocaleKeys.loginToUseService.tr(context: context)).toText16(color: AppColors.blackColor), SizedBox(height: 16.h), @@ -320,7 +325,12 @@ class _AppointmentCalendarState extends State { selectedButtonIndex = 0; List> timeList = []; for (var i = 0; i < dayEvents.length; i++) { - Map timeSlot = {"isoTime": dayEvents[i].isoTime, "start": dayEvents[i].start.toString(), "end": dayEvents[i].end.toString(), "vidaDate": dayEvents[i].vidaDate}; + Map timeSlot = { + "isoTime": dayEvents[i].isoTime, + "start": dayEvents[i].start.toString(), + "end": dayEvents[i].end.toString(), + "vidaDate": dayEvents[i].vidaDate + }; timeList.add(timeSlot); } if (dayEvents.isNotEmpty) { @@ -333,9 +343,7 @@ class _AppointmentCalendarState extends State { final DateFormat formatter = DateFormat('yyyy-MM-dd', "en-US"); final isArabic = appState.isArabic(); setState(() { - selectedDateDisplay = isArabic - ? DateUtil.getMonthDayYearDateFormattedAr(day) - : DateUtil.getMonthDayYearDateFormatted(day); + selectedDateDisplay = isArabic ? DateUtil.getMonthDayYearDateFormattedAr(day) : DateUtil.getMonthDayYearDateFormatted(day); selectedNextDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day.add(Duration(days: 1)), isArabic ? "ar" : "en"); _calendarController.selectedDate = day; openTimeSlotsPickerForDate(day, bookAppointmentsViewModel.docFreeSlots); diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 4ea290b0..d75c83e7 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -1,12 +1,10 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; -import 'package:get_it/get_it.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/app_state.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; -import 'package:hmg_patient_app_new/core/location_util.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'; @@ -14,10 +12,8 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; -import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_view_model.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/hmg_services_component_model.dart'; -import 'package:hmg_patient_app_new/features/hospital/hospital_selection_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_view_model.dart'; import 'package:hmg_patient_app_new/features/weather/weather_view_model.dart'; @@ -29,13 +25,11 @@ import 'package:hmg_patient_app_new/presentation/emergency_services/emergency_se 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/presentation/hmg_services/services_view.dart'; +import 'package:hmg_patient_app_new/presentation/hmg_services/widgets/weather_widget.dart'; import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; import 'package:hmg_patient_app_new/presentation/home/service_info_page.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; -import 'package:hmg_patient_app_new/presentation/hmg_services/widgets/weather_widget.dart'; -import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart'; -import 'package:hmg_patient_app_new/presentation/parking/paking_page.dart'; import 'package:hmg_patient_app_new/presentation/servicesPriceList/services_price_list_page.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; @@ -49,8 +43,6 @@ import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../core/dependencies.dart' show getIt; -import '../../features/qr_parking/qr_parking_view_model.dart'; -import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; class ServicesPage extends StatefulWidget { bool showBackIcon; @@ -69,7 +61,14 @@ class _ServicesPageState extends State { late WeatherMonitorViewModel weatherVM; late final List hmgServices = [ - HmgServicesComponentModel(11, LocaleKeys.emergencyServices.tr(), "", AppAssets.emergency_services_icon, bgColor: AppColors.primaryRedColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 11, + LocaleKeys.emergencyServices.tr(), + "", + AppAssets.emergency_services_icon, + bgColor: AppColors.primaryRedColor, + true, + route: null, onTap: () async { // if (getIt.get().isAuthenticated) { // getIt.get().flushData(); // getIt.get().getTransportationOrders( @@ -88,11 +87,19 @@ class _ServicesPageState extends State { // await getIt.get().onLoginPressed(); // } }), - HmgServicesComponentModel(11, LocaleKeys.bookAppointmentService.tr(), "", AppAssets.appointment_calendar_icon, bgColor: AppColors.bookAppointment, true, route: null, onTap: () { + HmgServicesComponentModel( + 11, + LocaleKeys.bookAppointmentService.tr(), + "", + AppAssets.appointment_calendar_icon, + bgColor: AppColors.bookAppointment, + true, + route: null, onTap: () { getIt.get().onTabChanged(0); Navigator.of(getIt().navigatorKey.currentContext!).push(CustomPageRoute(page: BookAppointmentPage())); }), - HmgServicesComponentModel(5, LocaleKeys.completeCheckup.tr(), "", AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 5, LocaleKeys.completeCheckup.tr(), "", AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.comprehensiveCheckupPage); } else { @@ -152,7 +159,8 @@ class _ServicesPageState extends State { // ); // }, // ), - HmgServicesComponentModel(11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.eReferralPage); } else { @@ -403,14 +411,13 @@ class _ServicesPageState extends State { }, ), HmgServicesComponentModel( - 103, - LocaleKeys.watchUsOnYoutube.tr(), - "", - AppAssets.youtube, - bgColor: AppColors.whiteColor, - true, - onTap:()=> launchUrl(Uri.parse("https://www.youtube.com/c/DrsulaimanAlhabibHospitals")) - ), + 103, + LocaleKeys.watchUsOnYoutube.tr(), + "", + AppAssets.youtube, + bgColor: AppColors.whiteColor, + true, + onTap: () => launchUrl(Uri.parse("https://www.youtube.com/c/DrsulaimanAlhabibHospitals"))), HmgServicesComponentModel( 104, LocaleKeys.connectOnLinkedin.tr(), @@ -418,9 +425,8 @@ class _ServicesPageState extends State { AppAssets.linkedin, bgColor: AppColors.whiteColor, true, - onTap:()=> launchUrl(Uri.parse("https://www.linkedin.com/company/drsulaiman-alhabib-medical-group")), + onTap: () => launchUrl(Uri.parse("https://www.linkedin.com/company/drsulaiman-alhabib-medical-group")), ), - ]; @override @@ -431,8 +437,6 @@ class _ServicesPageState extends State { weatherVM.initiateFetchWeather(); } - - @override Widget build(BuildContext context) { bloodDonationViewModel = Provider.of(context); @@ -451,456 +455,393 @@ class _ServicesPageState extends State { children: [ const WeatherWidget(), SizedBox(height: 16.h), - LocaleKeys.medicalAndCareServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), - SizedBox(height: 16.h), - GridView.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row - crossAxisSpacing: 21.w, - mainAxisSpacing: 18.h, - childAspectRatio: 80 / 94), - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: hmgServices.length, - padding: EdgeInsets.zero, - itemBuilder: (BuildContext context, int index) { - return ServiceGridViewItem(hmgServices[index], index, false, isHealthToolIcon: false); - }, - ).paddingSymmetrical(24.w, 0), - SizedBox(height: 24.h), - LocaleKeys.hmgServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), - SizedBox(height: 16.h), - SizedBox( - height: 350.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getServiceCardsList.length, + LocaleKeys.medicalAndCareServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + SizedBox(height: 16.h), + GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: (isFoldable || isTablet) ? 5 : 4, // 4 icons per row + ), + physics: NeverScrollableScrollPhysics(), shrinkWrap: true, - padding: EdgeInsets.symmetric(horizontal: 24.w), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: LargeServiceCard( - serviceCardData: LandingPageData.getServiceCardsList[index], - image: LandingPageData.getServiceCardsList[index].icon, - title: LandingPageData.getServiceCardsList[index].title, - subtitle: LandingPageData.getServiceCardsList[index].subtitle, - icon: LandingPageData.getServiceCardsList[index].largeCardIcon, - isPNG: LandingPageData.getServiceCardsList[index].isPNG, + itemCount: hmgServices.length, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int index) { + return ServiceGridViewItem(hmgServices[index], index, false, isHealthToolIcon: false); + }, + ).paddingSymmetrical(24.w, 0), + SizedBox(height: 24.h), + LocaleKeys.hmgServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + SizedBox(height: 16.h), + ConstrainedBox( + constraints: BoxConstraints( + minHeight: 320.h, + maxHeight: isFoldable ? 400.h : (isTablet ? 360.h : 340.h), + ), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getServiceCardsList.length, + shrinkWrap: true, + padding: EdgeInsets.symmetric(horizontal: 24.w), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: LargeServiceCard( + serviceCardData: LandingPageData.getServiceCardsList[index], + image: LandingPageData.getServiceCardsList[index].icon, + title: LandingPageData.getServiceCardsList[index].title, + subtitle: LandingPageData.getServiceCardsList[index].subtitle, + icon: LandingPageData.getServiceCardsList[index].largeCardIcon, + isPNG: LandingPageData.getServiceCardsList[index].isPNG, + ), ), ), - ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), + ), + ), + SizedBox(height: 24.h), + getIt.get().isAuthenticated + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.personalServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: Container( + height: 183.h, + width: 183.h, + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: false, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + spacing: 8.w, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), + LocaleKeys.habibWallet.tr().toText14(isBold: true, maxlines: 2).expanded, + Utils.buildSvgWithAssets( + icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + ], + ), + Spacer(), + getIt.get().isAuthenticated + ? Consumer(builder: (context, habibWalletVM, child) { + return Utils.getPaymentAmountWithSymbol2( + num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)), + isExpanded: false, + letterSpacing: -1) + .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); + }) + : LocaleKeys.loginToViewWalletBalance.tr().toText12(isBold: true, maxLine: 2), + Spacer(), + getIt.get().isAuthenticated + ? CustomButton( + height: 40.h, + icon: AppAssets.recharge_icon, + iconSize: 24.w, + iconColor: AppColors.infoColor, + textColor: AppColors.infoColor, + text: LocaleKeys.recharge.tr(), + borderWidth: 0.w, + isBold: true, + borderColor: Colors.transparent, + backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 14.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, + ) + : SizedBox.shrink(), + ], + ).onPress(() async { + if (getIt.get().isAuthenticated) { + Navigator.of(context).push(CustomPageRoute(page: HabibWalletPage())); + } else { + await getIt.get().onLoginPressed(); + } + }), + ), + ), + SizedBox(width: 16.w), + Expanded( + child: Container( + height: 183.h, + width: 183.h, + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: false, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + spacing: 8.w, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h, applyThemeColor: false), + LocaleKeys.familyTitle.tr().toText16(isBold: true, maxlines: 2).expanded, + Utils.buildSvgWithAssets( + icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + ], + ), + Spacer(), + getIt.get().isAuthenticated + ? Wrap( + spacing: -12.h, + // runSpacing: 0.h, + children: [ + Utils.buildImgWithAssets( + icon: AppAssets.babyGirlImg, + height: 32.h, + width: 32.w, + border: 1, + fit: BoxFit.contain, + borderRadius: 50.r, + ), + Utils.buildImgWithAssets( + icon: AppAssets.femaleImg, + height: 32.h, + width: 32.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + Utils.buildImgWithAssets( + icon: AppAssets.maleImg, + height: 32.h, + width: 32.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + ], + ) + : LocaleKeys.loginToViewMedicalFile.tr().toText12(isBold: true, maxLine: 2), + Spacer(), + getIt.get().isAuthenticated + ? CustomButton( + height: 40.h, + icon: AppAssets.add_icon, + iconSize: 24.h, + iconColor: AppColors.primaryRedColor, + textColor: AppColors.primaryRedColor, + text: getIt.get().isArabic() ? LocaleKeys.add.tr() : LocaleKeys.addMember.tr(), + borderWidth: 0.w, + isBold: true, + borderColor: Colors.transparent, + backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 14.f, + onPressed: () { + DialogService dialogService = getIt.get(); + medicalFileViewModel.clearAuthValues(); + dialogService.showAddFamilyFileSheet( + label: LocaleKeys.addFamilyMember.tr(), + message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), + onVerificationPress: () { + medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + }); + }, + ) + : SizedBox.shrink(), + ], + ).onPress(() async { + if (getIt.get().isAuthenticated) { + // Navigator.of(context).push( + // CustomPageRoute( + // page: MedicalFilePage(), + // ), + // ); + Navigator.of(context).push( + CustomPageRoute( + direction: AxisDirection.down, + page: FamilyMedicalScreen(), + ), + ); + } else { + await getIt.get().onLoginPressed(); + } + }), + ), + ), + ], + ).paddingSymmetrical(24.w, 0), + ], + ) + : SizedBox(), + SizedBox(height: 24.h), + LocaleKeys.healthTools.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + SizedBox(height: 16.h), + GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: (isFoldable || isTablet) ? 5 : 4, // 4 icons per row + mainAxisSpacing: 18.h, + ), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: hmgHealthToolServices.length, + padding: EdgeInsets.zero, + itemBuilder: (BuildContext context, int index) { + return ServiceGridViewItem( + hmgHealthToolServices[index], + index, + false, + isHealthToolIcon: true, ); }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), - ), - ), - SizedBox(height: 24.h), - getIt.get().isAuthenticated - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, + ).paddingSymmetrical(24.w, 0), + SizedBox(height: 24.h), + LocaleKeys.supportServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + SizedBox(height: 16.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 16.h), + Row( children: [ - LocaleKeys.personalServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: Container( - height: 183.h, - width: 183.h, - padding: EdgeInsets.all(16.w), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: false, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - spacing: 8.w, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), - LocaleKeys.habibWallet.tr().toText14(isBold: true, maxlines: 2).expanded, - Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), - ], - ), - Spacer(), - getIt.get().isAuthenticated - ? Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)), - isExpanded: false, letterSpacing: -1) - .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); - }) - : LocaleKeys.loginToViewWalletBalance.tr().toText12(isBold: true, maxLine: 2), - Spacer(), - getIt.get().isAuthenticated - ? CustomButton( - height: 40.h, - icon: AppAssets.recharge_icon, - iconSize: 24.w, - iconColor: AppColors.infoColor, - textColor: AppColors.infoColor, - text: LocaleKeys.recharge.tr(), - borderWidth: 0.w, - isBold: true, - borderColor: Colors.transparent, - backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 14.f, - onPressed: () { - Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); - }, - ) - : SizedBox.shrink(), - ], - ).onPress(() async { - if (getIt.get().isAuthenticated) { - Navigator.of(context).push(CustomPageRoute(page: HabibWalletPage())); - } else { - await getIt.get().onLoginPressed(); - } - }), + Expanded( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.h, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.latest_news_icon, + width: 32.h, + height: 32.h, + fit: BoxFit.contain, + ), + SizedBox(width: 8.w), + LocaleKeys.latestNews.tr().toText14(isBold: true) + ], ), ), - SizedBox(width: 16.w), - Expanded( - child: Container( - height: 183.h, - width: 183.h, - padding: EdgeInsets.all(16.w), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: false, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - spacing: 8.w, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h, applyThemeColor: false), - LocaleKeys.familyTitle.tr().toText16(isBold: true, maxlines: 2).expanded, - Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), - ], - ), - Spacer(), - getIt.get().isAuthenticated - ? Wrap( - spacing: -12.h, - // runSpacing: 0.h, - children: [ - Utils.buildImgWithAssets( - icon: AppAssets.babyGirlImg, - height: 32.h, - width: 32.w, - border: 1, - fit: BoxFit.contain, - borderRadius: 50.r, - ), - Utils.buildImgWithAssets( - icon: AppAssets.femaleImg, - height: 32.h, - width: 32.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - Utils.buildImgWithAssets( - icon: AppAssets.maleImg, - height: 32.h, - width: 32.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - ], - ) - : LocaleKeys.loginToViewMedicalFile.tr().toText12(isBold: true, maxLine: 2), - Spacer(), - getIt.get().isAuthenticated - ? CustomButton( - height: 40.h, - icon: AppAssets.add_icon, - iconSize: 24.h, - iconColor: AppColors.primaryRedColor, - textColor: AppColors.primaryRedColor, - text: getIt.get().isArabic() ? LocaleKeys.add.tr() :LocaleKeys.addMember.tr(), - borderWidth: 0.w, - isBold: true, - borderColor: Colors.transparent, - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 14.f, - onPressed: () { - DialogService dialogService = getIt.get(); - medicalFileViewModel.clearAuthValues(); - dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), - onVerificationPress: () { - medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, - ) - : SizedBox.shrink(), - ], - ).onPress(() async { - if (getIt.get().isAuthenticated) { - // Navigator.of(context).push( - // CustomPageRoute( - // page: MedicalFilePage(), - // ), - // ); - Navigator.of(context).push( - CustomPageRoute( - direction: AxisDirection.down, - page: FamilyMedicalScreen(), - ), - ); - } else { - await getIt.get().onLoginPressed(); - } - }), + ).onPress(() { + Utils.openWebView( + url: 'https://x.com/HMG', + ); + }), + ), + SizedBox(width: 16.w), + Expanded( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.h, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.hmg_contact_icon, + width: 32.h, + height: 32.h, + fit: BoxFit.contain, + ), + SizedBox(width: 8.w), + Expanded(child: LocaleKeys.hmgContact.tr().toText14(isBold: true)) + ], ), ), - ], - ).paddingSymmetrical(24.w, 0), + ).onPress(() { + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.contactUs.tr(), + child: ContactUs(), + callBackFunc: () {}, + isFullScreen: false, + ); + }), + ) ], - ) - : SizedBox(), - SizedBox(height: 24.h), - LocaleKeys.healthTools.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), - SizedBox(height: 16.h), - GridView.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row - crossAxisSpacing: 21.w, - mainAxisSpacing: 18.h, - childAspectRatio: 80.w / 94.h, - ), - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: hmgHealthToolServices.length, - padding: EdgeInsets.zero, - itemBuilder: (BuildContext context, int index) { - return ServiceGridViewItem( - hmgHealthToolServices[index], - index, - false, - isHealthToolIcon: true, - ); - }, - ).paddingSymmetrical(24.w, 0), - SizedBox(height: 24.h), - LocaleKeys.supportServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), - SizedBox(height: 16.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Row( - // children: [ - // // Expanded( - // // child: Container( - // // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // // color: AppColors.whiteColor, - // // borderRadius: 12.h, - // // hasShadow: false, - // // ), - // // child: Padding( - // // padding: EdgeInsets.all(16.h), - // // child: Row( - // // children: [ - // // Utils.buildSvgWithAssets( - // // icon: AppAssets.virtual_tour_icon, - // // width: 32.w, - // // height: 32.h, - // // fit: BoxFit.contain, - // // ), - // // SizedBox(width: 8.w), - // // LocaleKeys.virtualTour.tr().toText14(isBold: true) - // // ], - // // ), - // // ), - // // ).onPress(() { - // // Utils.openWebView( - // // url: 'https://hmgwebservices.com/vt_mobile/html/index.html', - // // ); - // // }), - // // ), - // SizedBox(width: 16.w), - // Expanded( - // child: Container( - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // color: AppColors.whiteColor, - // borderRadius: 12.h, - // hasShadow: false, - // ), - // child: Padding( - // padding: EdgeInsets.all(16.h), - // child: Row( - // children: [ - // Utils.buildSvgWithAssets( - // icon: AppAssets.car_parking_icon, - // width: 32.w, - // height: 32.h, - // fit: BoxFit.contain, - // ), - // SizedBox(width: 8.w), - // LocaleKeys.carParking.tr().toText14(isBold: true) - // ], - // ).onPress(() { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (_) => ChangeNotifierProvider( - // create: (_) => getIt(), - // child: const ParkingPage(), - // ), - // ), - // ); - // }), - // ), - // ), - // ), - // ], - // ), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.h, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Utils.buildSvgWithAssets( - icon: AppAssets.latest_news_icon, - width: 32.w, - height: 32.h, - fit: BoxFit.contain, - ), - SizedBox(width: 8.w), - LocaleKeys.latestNews.tr().toText14(isBold: true) - ], + ), + SizedBox(height: 24.h), + LocaleKeys.hmgPolicies.tr().toText18(weight: FontWeight.bold), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.h, + hasShadow: false, ), - ), - ).onPress(() { - Utils.openWebView( - url: 'https://x.com/HMG', - ); - }), - ), - SizedBox(width: 16.w), - Expanded( - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.h, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Utils.buildSvgWithAssets( - icon: AppAssets.hmg_contact_icon, - width: 32.w, - height: 32.h, - fit: BoxFit.contain, - ), - SizedBox(width: 8.w), - Expanded(child: LocaleKeys.hmgContact.tr().toText14(isBold: true)) - ], + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor), + SizedBox(width: 8.w), + Expanded(child: LocaleKeys.termsConditoins.tr().toText14(isBold: true)) + ], + ), ), - ), - ).onPress(() { - showCommonBottomSheetWithoutHeight( - context, - title: LocaleKeys.contactUs.tr(), - child: ContactUs(), - callBackFunc: () {}, - isFullScreen: false, - ); - }), - ) - ], - ), - SizedBox(height: 24.h), - LocaleKeys.hmgPolicies.tr().toText18(weight: FontWeight.bold), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.h, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor), - SizedBox(width: 8.w), - Expanded(child: LocaleKeys.termsConditoins.tr().toText14(isBold: true)) - ], + ).onPress(() { + Utils.openWebView( + url: 'https://hmg.com/en/Pages/Terms.aspx', + ); + }), + ), + SizedBox(width: 16.w), + Expanded( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.h, + hasShadow: false, ), - ), - ).onPress(() { - Utils.openWebView( - url: 'https://hmg.com/en/Pages/Terms.aspx', - ); - }), - ), - SizedBox(width: 16.w), - Expanded( - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.h, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor), - SizedBox(width: 8.w), - Expanded(child: LocaleKeys.privacyPolicy.tr().toText14(isBold: true)) - ], + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor), + SizedBox(width: 8.w), + Expanded(child: LocaleKeys.privacyPolicy.tr().toText14(isBold: true)) + ], + ), ), - ), - ).onPress(() { - Utils.openWebView( - url: 'https://hmg.com/en/Pages/Privacy.aspx', - ); - }), - ) - ], - ) - ], - ).paddingSymmetrical(24.w, 0), + ).onPress(() { + Utils.openWebView( + url: 'https://hmg.com/en/Pages/Privacy.aspx', + ); + }), + ) + ], + ) + ], + ).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row - crossAxisSpacing: 21.w, + crossAxisCount: (isFoldable || isTablet) ? 5 : 4, // 4 icons per row mainAxisSpacing: 18.h, - childAspectRatio: 80.w / 94.h, ), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -915,11 +856,11 @@ class _ServicesPageState extends State { ); }, ).paddingSymmetrical(24.w, 0), - SizedBox(height: 24.h), - ], + SizedBox(height: 24.h), + ], + ), ), ), - ), ); } } diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 706041ec..b8313323 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:developer'; +import 'dart:ui' as ui; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -10,7 +11,6 @@ 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/cache_consts.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; -import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -25,8 +25,6 @@ import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_mode import 'package:hmg_patient_app_new/features/hospital/hospital_selection_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; -import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; -import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_rating_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; @@ -40,44 +38,35 @@ import 'package:hmg_patient_app_new/presentation/authentication/quick_login.dart import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/immediate_livecare_pending_request_page.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/contact_us.dart'; -import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_home.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/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'; -import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; -import 'package:hmg_patient_app_new/widgets/user_avatar_widget.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart'; import 'package:hmg_patient_app_new/presentation/notifications/notifications_list_page.dart'; -import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart'; import 'package:hmg_patient_app_new/presentation/rate_appointment/rate_appointment_doctor.dart'; import 'package:hmg_patient_app_new/presentation/todo_section/ancillary_procedures_details_page.dart'; import 'package:hmg_patient_app_new/presentation/todo_section/todo_page.dart'; import 'package:hmg_patient_app_new/presentation/todo_section/widgets/ancillary_orders_list.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; -import 'package:hmg_patient_app_new/services/dialog_service.dart'; -import 'package:hmg_patient_app_new/services/zoom_service.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/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/countdown_timer.dart'; -import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/routes/spring_page_route_builder.dart'; +import 'package:hmg_patient_app_new/widgets/user_avatar_widget.dart'; import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; import 'package:smooth_corner/smooth_corner.dart'; import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; -import 'dart:ui' as ui; - class LandingPage extends StatefulWidget { const LandingPage({super.key}); @@ -159,11 +148,14 @@ 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) { + 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)); @@ -222,15 +214,16 @@ class _LandingPageState extends State { controller: _scrollController, physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only( - top: (appState.isAuthenticated && !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), child: Column( spacing: 16.h, children: [ - - Row( spacing: 8.h, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -241,42 +234,40 @@ class _LandingPageState extends State { // ...existing navigation code... Navigator.of(context).push( - CustomPageRoute( - direction: AxisDirection.down, - page: FamilyMedicalScreen(), - ), - ); - }, - name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), - imageWidget: UserAvatarWidget( - width: 42.w, - height: 42.h, - fit: BoxFit.cover, - isCircular: true, - ), - ).expanded + CustomPageRoute( + direction: AxisDirection.down, + page: FamilyMedicalScreen(), + ), + ); + }, + name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), + imageWidget: UserAvatarWidget( + width: 42.w, + height: 42.h, + fit: BoxFit.cover, + isCircular: true, + ), + ).expanded : CustomButton( - text: LocaleKeys.loginOrRegister.tr(context: context), - onPressed: () async { - await authVM.onLoginPressed(); - // ...existing commented code... - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14.f, + text: LocaleKeys.loginOrRegister.tr(context: context), + onPressed: () async { + await authVM.onLoginPressed(); + // ...existing commented code... + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14.f, fontWeight: FontWeight.w700, borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0), - height: 40.h, - ), + padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0), + height: 40.h, + ), Consumer(builder: (context, todoSectionVM, child) { return Row( mainAxisSize: MainAxisSize.min, // spacing: 18.h, children: [ - - Stack(clipBehavior: Clip.none, children: [ if (appState.isAuthenticated) Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async { @@ -295,33 +286,35 @@ class _LandingPageState extends State { }), (appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0)) ? Positioned( - // right: appState.isArabic() ? 8.w : -8.w, - top: -8.h, - // left: 4.h, - // bottom: 4.h, - child: Container( - width: 18.w, - height: 18.h, - padding: EdgeInsets.all(2), - decoration: BoxDecoration( - color: AppColors.primaryRedColor, - borderRadius: BorderRadius.circular(20.r), - ), - child: Text( - todoSectionVM.notificationsCount.toString(), - style: TextStyle( - color: Colors.white, - fontFamily: "Poppins", - fontSize: 10.f, - fontWeight: FontWeight.w600, - ), - textAlign: TextAlign.center, - ), - ), - ) + // right: appState.isArabic() ? 8.w : -8.w, + top: -8.h, + // left: 4.h, + // bottom: 4.h, + child: Container( + width: 18.w, + height: 18.h, + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: AppColors.primaryRedColor, + borderRadius: BorderRadius.circular(20.r), + ), + child: Text( + todoSectionVM.notificationsCount.toString(), + style: TextStyle( + color: Colors.white, + fontFamily: "Poppins", + fontSize: 10.f, + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.center, + ), + ), + ) : SizedBox.shrink(), ]), - SizedBox(width: 24.w,), + SizedBox( + width: 24.w, + ), Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() { // openIndoorNavigationBottomSheet(context); showCommonBottomSheetWithoutHeight( @@ -343,9 +336,16 @@ class _LandingPageState extends State { // ); // }), !appState.isAuthenticated - ?Row(children: [ SizedBox(width: 24.w,), Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { - context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); - })]) + ? Row(children: [ + SizedBox( + width: 24.w, + ), + Utils.buildSvgWithAssets( + icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h) + .onPress(() { + context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); + }) + ]) : SizedBox() ], ); @@ -354,140 +354,141 @@ class _LandingPageState extends State { ).paddingSymmetrical(24.h, 0.h), !appState.isAuthenticated ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Utils.buildSvgWithAssets( - width: 50.w, - height: 60.h, - icon: AppAssets.symptomCheckerIcon, - fit: BoxFit.contain, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, ), - SizedBox(width: 12.w), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(isBold: true), - LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(isBold: true), - SizedBox(height: 14.h), - CustomButton( - text: LocaleKeys.checkYourSymptoms.tr(context: context), - onPressed: () async { - context.navigateWithName(AppRoutes.userInfoSelection); - }, - padding: EdgeInsetsGeometry.zero, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: Colors.white, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - height: 40.h, - ), - ], - ).expanded - ], - ), - ), - ).paddingSymmetrical(24.w, 0.h) + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + width: 50.w, + height: 60.h, + icon: AppAssets.symptomCheckerIcon, + fit: BoxFit.contain, + ), + SizedBox(width: 12.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(isBold: true), + LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(isBold: true), + SizedBox(height: 14.h), + CustomButton( + text: LocaleKeys.checkYourSymptoms.tr(context: context), + onPressed: () async { + context.navigateWithName(AppRoutes.userInfoSelection); + }, + padding: EdgeInsetsGeometry.zero, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: Colors.white, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + height: 40.h, + ), + ], + ).expanded + ], + ), + ), + ).paddingSymmetrical(24.w, 0.h) : SizedBox.shrink(), appState.isAuthenticated ? Column( - children: [ - SizedBox(height: 12.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true), - Row( - children: [ - LocaleKeys.viewAll.tr(context: context).toText14(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).onPress(() { - myAppointmentsViewModel.onTabChange(0); - myAppointmentsViewModel.updateListWRTTab(0); - Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); - }), - Consumer3( - builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { - return myAppointmentsVM.isMyAppointmentsLoading - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: true, - isFromHomePage: true, - ), - ).paddingSymmetrical(24.h, 16.h) - : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty - ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first, - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ).paddingSymmetrical(24.h, 0.h) - : isTablet - ? SizedBox( - height: isFoldable ? 290.h : 255.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: 3, - shrinkWrap: true, - padding: EdgeInsets.only(left: 16.h, right: 16.h), - itemBuilder: (context, index) { - return SizedBox( - height: 255.h, - width: 250.w, - child: getIndexSwiperCard(index), - ); - // return AnimationConfiguration.staggeredList( - // position: index, - // duration: const Duration(milliseconds: 1000), - // child: SlideAnimation( - // horizontalOffset: 100.0, - // child: FadeInAnimation( - // child: SizedBox( - // height: 255.h, - // width: 250.w, - // child: getIndexSwiperCard(index), - // ), - // ), - // ), - // ); - }, - separatorBuilder: (BuildContext cxt, int index) => - SizedBox( - width: 10.w, - ), - ), - ) - : SizedBox( - height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space + children: [ + SizedBox(height: 12.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true), + Row( + children: [ + LocaleKeys.viewAll.tr(context: context).toText14(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).onPress(() { + myAppointmentsViewModel.onTabChange(0); + myAppointmentsViewModel.updateListWRTTab(0); + Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); + }), + Consumer3( + builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { + return myAppointmentsVM.isMyAppointmentsLoading + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: true, + isFromHomePage: true, + ), + ).paddingSymmetrical(24.h, 16.h) + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty + ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first, + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: false, + isFromHomePage: true, + ), + ).paddingSymmetrical(24.h, 0.h) + : isTablet + ? SizedBox( + height: isFoldable ? 290.h : 255.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: 3, + shrinkWrap: true, + padding: EdgeInsets.only(left: 16.h, right: 16.h), + itemBuilder: (context, index) { + return SizedBox( + height: 255.h, + width: 250.w, + child: getIndexSwiperCard(index), + ); + // return AnimationConfiguration.staggeredList( + // position: index, + // duration: const Duration(milliseconds: 1000), + // child: SlideAnimation( + // horizontalOffset: 100.0, + // child: FadeInAnimation( + // child: SizedBox( + // height: 255.h, + // width: 250.w, + // child: getIndexSwiperCard(index), + // ), + // ), + // ), + // ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox( + width: 10.w, + ), + ), + ) + : SizedBox( + height: 255.h + + 20 + + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space child: Builder( builder: (context) { final int swiperItemCount = myAppointmentsVM.isMyAppointmentsLoading @@ -532,159 +533,217 @@ class _LandingPageState extends State { ? _buildLiveCareRequestCard().paddingSymmetrical(24.h, 16.h) : Container( width: double.infinity, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + decoration: RoundedRectangleBorder() + .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Padding( padding: EdgeInsets.all(16.h), - child: Column( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), - SizedBox(height: 12.h), - LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), - SizedBox(height: 12.h), - CustomButton( - text: LocaleKeys.bookAppo.tr(context: context), - onPressed: () { - getIt.get().onTabChanged(0); - Navigator.of(context).push(CustomPageRoute(page: BookAppointmentPage())); - }, - backgroundColor: Color(0xffFEE9EA), - borderColor: Color(0xffFEE9EA), - textColor: Color(0xffED1C2B), - fontSize: 14.f, - fontWeight: FontWeight.w600, - padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), - icon: AppAssets.add_icon, - iconColor: AppColors.primaryRedColor, - height: 40.h, + child: Column( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), + SizedBox(height: 12.h), + LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.bookAppo.tr(context: context), + onPressed: () { + getIt.get().onTabChanged(0); + Navigator.of(context).push(CustomPageRoute(page: BookAppointmentPage())); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 14.f, + fontWeight: FontWeight.w600, + padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), + icon: AppAssets.add_icon, + iconColor: AppColors.primaryRedColor, + height: 40.h, + ), + ], ), - ], - ), - ), - ).paddingSymmetrical(24.h, 16.h); + ), + ).paddingSymmetrical(24.h, 16.h); }, ), // Consumer for ER Online Check-In pending request - // Consumer( - // builder: (context, emergencyServicesVM, child) { - // return emergencyServicesVM.patientHasAdvanceERBalance - // ? Column( - // children: [ - // SizedBox(height: 16.h), - // Container( - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // color: AppColors.whiteColor, - // borderRadius: 20.r, - // hasShadow: false, - // side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), - // ), - // width: double.infinity, - // child: Padding( - // padding: EdgeInsets.all(16.h), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // // Row( - // // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // // children: [ - // // AppCustomChipWidget( - // // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), - // // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), - // // textColor: AppColors.primaryRedColor, - // // ), - // // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), - // // ], - // // ), - // SizedBox(height: 8.h), - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), - // Transform.flip( - // flipX: getIt.get().isArabic(), - // child: Utils.buildSvgWithAssets( - // icon: AppAssets.forward_arrow_icon_small, - // iconColor: AppColors.blackColor, - // width: 20.h, - // height: 15.h, - // fit: BoxFit.contain, - // ), - // ), - // ], - // ), - // ], - // ), - // ), - // ).paddingSymmetrical(24.h, 0.h).onPress(() { - // Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); - // // context.read().navigateToEROnlineCheckIn(); - // }), - // SizedBox(height: 12.h), - // ], - // ) - // : SizedBox(height: 0.h); - // }, - // ), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true), - Row( - children: [ - LocaleKeys.viewMedicalFileLandingPage.tr(context: context).toText14(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).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); - }), - SizedBox(height: 16.h), - Consumer(builder: (BuildContext context, TodoSectionViewModel todoSectionVM, Widget? child) { - return Container( - // height: 121.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( - children: [ - todoSectionVM.patientAncillaryOrdersList.isNotEmpty - ? Container( - height: 50.h, - decoration: ShapeDecoration( - color: AppColors.eReferralCardColor.withAlpha(50), - shape: SmoothRectangleBorder( - borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), - smoothness: 1, - ), + // Consumer( + // builder: (context, emergencyServicesVM, child) { + // return emergencyServicesVM.patientHasAdvanceERBalance + // ? Column( + // children: [ + // SizedBox(height: 16.h), + // Container( + // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + // color: AppColors.whiteColor, + // borderRadius: 20.r, + // hasShadow: false, + // side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), + // ), + // width: double.infinity, + // child: Padding( + // padding: EdgeInsets.all(16.h), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // // Row( + // // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // // children: [ + // // AppCustomChipWidget( + // // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), + // // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), + // // textColor: AppColors.primaryRedColor, + // // ), + // // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), + // // ], + // // ), + // SizedBox(height: 8.h), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), + // Transform.flip( + // flipX: getIt.get().isArabic(), + // child: Utils.buildSvgWithAssets( + // icon: AppAssets.forward_arrow_icon_small, + // iconColor: AppColors.blackColor, + // width: 20.h, + // height: 15.h, + // fit: BoxFit.contain, + // ), + // ), + // ], + // ), + // ], + // ), + // ), + // ).paddingSymmetrical(24.h, 0.h).onPress(() { + // Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); + // // context.read().navigateToEROnlineCheckIn(); + // }), + // SizedBox(height: 12.h), + // ], + // ) + // : SizedBox(height: 0.h); + // }, + // ), + SizedBox(height: 16.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true), + Row( + children: [ + LocaleKeys.viewMedicalFileLandingPage + .tr(context: context) + .toText14(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + ], ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + ], + ).paddingSymmetrical(24.h, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); + }), + SizedBox(height: 16.h), + Consumer(builder: (BuildContext context, TodoSectionViewModel todoSectionVM, Widget? child) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( children: [ - LocaleKeys.pendingAncillaryOrders.tr(context: context).toText14(color: AppColors.eReferralCardColor, isBold: true).paddingSymmetrical(24.h, 0.h), - CustomButton( - text: LocaleKeys.view.tr(context: context), - onPressed: () { - todoSectionVM.setIsAncillaryOrdersNeedReloading(true); - Navigator.of(context).push( - CustomPageRoute( - page: ToDoPage(), - ), - ); - }, - backgroundColor: AppColors.eReferralCardColor, - borderColor: AppColors.eReferralCardColor, - textColor: AppColors.whiteColor, - fontSize: 10.f, - fontWeight: FontWeight.w600, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(15, 0, 15, 0), - height: 30.h, - ).paddingSymmetrical(24.h, 0.h), + todoSectionVM.patientAncillaryOrdersList.isNotEmpty + ? Container( + height: 50.h, + decoration: ShapeDecoration( + color: AppColors.eReferralCardColor.withAlpha(50), + shape: SmoothRectangleBorder( + borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), + smoothness: 1, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.pendingAncillaryOrders + .tr(context: context) + .toText14(color: AppColors.eReferralCardColor, isBold: true) + .paddingSymmetrical(24.h, 0.h), + CustomButton( + text: LocaleKeys.view.tr(context: context), + onPressed: () { + todoSectionVM.setIsAncillaryOrdersNeedReloading(true); + Navigator.of(context).push(CustomPageRoute(page: ToDoPage())); + }, + backgroundColor: AppColors.eReferralCardColor, + borderColor: AppColors.eReferralCardColor, + textColor: AppColors.whiteColor, + fontSize: 10.f, + fontWeight: FontWeight.w600, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(15, 0, 15, 0), + height: 30.h, + ).paddingSymmetrical(24.h, 0.h), + ], + ), + ) + : SizedBox.shrink(), + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only( + top: 92.h + 32.h, + left: MediaQuery.sizeOf(context).width / 2.5 - 10, + right: MediaQuery.sizeOf(context).width / 2.5 - 10), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData().getLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 200), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + icon: LandingPageData().getLoggedInServiceCardsList[index].icon, + title: LandingPageData().getLoggedInServiceCardsList[index].title, + subtitle: LandingPageData().getLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData().getLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData().getLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData().getLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData().getLoggedInServiceCardsList[index].isBold, + serviceName: LandingPageData().getLoggedInServiceCardsList[index].serviceName, + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 10.width, + ).paddingSymmetrical(16.h, 0.h), + ), + ), + SizedBox(height: 16.h), ], ), - ) - : SizedBox.shrink(), + ).paddingSymmetrical(24.h, 0.h); + }), + ], + ) + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( + children: [ SizedBox( height: 92.h + 32.h - 4.h, child: RawScrollbar( @@ -696,104 +755,45 @@ class _LandingPageState extends State { trackColor: Color(0xffD9D9D9), trackBorderColor: Colors.transparent, trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery - .sizeOf(context) - .width / 2.5 - 10, right: MediaQuery - .sizeOf(context) - .width / 2.5 - 10), + padding: EdgeInsets.only( + top: 92.h + 32.h, + left: MediaQuery.sizeOf(context).width / 2.5 - 10, + right: MediaQuery.sizeOf(context).width / 2.5 - 10), child: ListView.separated( scrollDirection: Axis.horizontal, - itemCount: LandingPageData().getLoggedInServiceCardsList.length, + itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, shrinkWrap: true, controller: _horizontalScrollController, padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( position: index, - duration: const Duration(milliseconds: 200), - child: SlideAnimation( + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( horizontalOffset: 100.0, child: FadeInAnimation( child: SmallServiceCard( - icon: LandingPageData().getLoggedInServiceCardsList[index].icon, - title: LandingPageData().getLoggedInServiceCardsList[index].title, - subtitle: LandingPageData().getLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData().getLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData().getLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData().getLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData().getLoggedInServiceCardsList[index].isBold, - serviceName: LandingPageData().getLoggedInServiceCardsList[index].serviceName, + serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, + icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, + title: LandingPageData.getNotLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, ), ), ), ); }, - separatorBuilder: (BuildContext cxt, int index) => 10.width, + separatorBuilder: (BuildContext cxt, int index) => 0.width, ).paddingSymmetrical(16.h, 0.h), ), ), SizedBox(height: 16.h), ], ), - ).paddingSymmetrical(24.h, 0.h); - }), - ], - ) - : Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( - children: [ - SizedBox( - height: 92.h + 32.h - 4.h, - child: RawScrollbar( - controller: _horizontalScrollController, - thumbVisibility: true, - radius: Radius.circular(10.0), - thumbColor: AppColors.primaryRedColor, - trackVisibility: true, - trackColor: Color(0xffD9D9D9), - trackBorderColor: Colors.transparent, - trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery - .sizeOf(context) - .width / 2.5 - 10, right: MediaQuery - .sizeOf(context) - .width / 2.5 - 10), - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, - shrinkWrap: true, - controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, - icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, - title: LandingPageData.getNotLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, - ), - ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 0.width, - ).paddingSymmetrical(16.h, 0.h), - ), - ), - SizedBox(height: 16.h), - ], - ), - ).paddingSymmetrical(24.h, 0.h), + ).paddingSymmetrical(24.h, 0.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -809,8 +809,8 @@ class _LandingPageState extends State { }), ], ).paddingSymmetrical(24.w, 0.h), - SizedBox( - height: 431.h, + ConstrainedBox( + constraints: BoxConstraints(maxHeight: isFoldable ? 450.h : (isTablet ? 440.h : 431.h), minHeight: 411.h), child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: LandingPageData.getServiceCardsList.length, @@ -862,7 +862,10 @@ class _LandingPageState extends State { ), ), ), - (appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) + (appState.isAuthenticated && + !insuranceVM.isInsuranceLoading && + insuranceVM.isInsuranceExpired && + insuranceVM.isInsuranceExpiryBannerShown) ? Container( height: MediaQuery.paddingOf(context).top + 50.h, decoration: ShapeDecoration( @@ -879,17 +882,24 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.insuranceExpiredOrInactive.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true).paddingSymmetrical(0.h, 0.h), + LocaleKeys.insuranceExpiredOrInactive + .tr(context: context) + .toText14(color: AppColors.primaryRedColor, isBold: true) + .paddingSymmetrical(0.h, 0.h), Row( children: [ CustomButton( text: LocaleKeys.updateInsurance.tr(context: context), onPressed: () { insuranceVM.setIsInsuranceUpdateDetailsLoading(true); - insuranceVM.getPatientInsuranceDetailsForUpdate( - appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + insuranceVM.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(), + appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); showCommonBottomSheetWithoutHeight(context, - child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + child: PatientInsuranceCardUpdateCard(), + callBackFunc: () {}, + title: "", + isCloseButtonVisible: false, + isFullScreen: false); }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.secondaryLightRedBorderColor, @@ -1029,7 +1039,8 @@ class _LandingPageState extends State { SizedBox(height: 6.h), _buildServingNowSection(), SizedBox(height: 5.h), - _buildQueueActionButton(currentStatus, currentQueue.roomNo ?? "").toShimmer2(isShow: myAppointmentsViewModel.patientQueueDetailsList.isEmpty), + _buildQueueActionButton(currentStatus, currentQueue.roomNo ?? "") + .toShimmer2(isShow: myAppointmentsViewModel.patientQueueDetailsList.isEmpty), ], ), ), @@ -1058,7 +1069,8 @@ class _LandingPageState extends State { hasShadow: false, ), padding: EdgeInsets.all(6.h), - child: Lottie.asset(AppAnimations.hourGlass, repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)), + child: Lottie.asset(AppAnimations.hourGlass, + repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)), ], ); } @@ -1171,7 +1183,6 @@ class _LandingPageState extends State { height: 40.h, iconColor: AppColors.whiteColor, iconSize: 18.h, - ), // _buildLiveCareWaitingTime(), ], @@ -1238,7 +1249,8 @@ class _LandingPageState extends State { hasShadow: false, ), padding: EdgeInsets.all(6.h), - child: Lottie.asset(AppAnimations.hourGlass, repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)), + child: Lottie.asset(AppAnimations.hourGlass, + repeat: true, reverse: false, frameRate: FrameRate(60), width: 40.h, height: 40.h, fit: BoxFit.fill)), // Utils.buildSvgWithAssets( // icon: AppAssets.waiting_icon, // width: 24.h, @@ -1286,12 +1298,8 @@ class _LandingPageState extends State { // Appointment Card Wrapper (reusable) Widget _buildAppointmentCardWrapper(appointment) { return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - hasDenseShadow: true - ), + decoration: + RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true, hasDenseShadow: true), child: AppointmentCard( patientAppointmentHistoryResponseModel: appointment, myAppointmentsViewModel: myAppointmentsViewModel, @@ -1447,9 +1455,7 @@ class _DirectionalDotPaginationBuilder extends SwiperPlugin { @override Widget build(BuildContext context, SwiperPluginConfig config) { - final int activeIndex = isRTL - ? (totalCount - 1 - config.activeIndex) - : config.activeIndex; + final int activeIndex = isRTL ? (totalCount - 1 - config.activeIndex) : config.activeIndex; print("the index is $activeIndex"); print("the config.activeIndex is ${config.activeIndex}"); @@ -1471,4 +1477,3 @@ class _DirectionalDotPaginationBuilder extends SwiperPlugin { ); } } - diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index c36f7a90..72b11ef3 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -43,83 +43,87 @@ class LargeServiceCard extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - height: 350.h, width: 230.w, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.transparent, borderRadius: 24.r), - child: Stack( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: Column( + mainAxisSize: MainAxisSize.min, children: [ ClipRRect( - borderRadius: BorderRadius.circular(24.r), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(24.r), + topRight: Radius.circular(24.r), + ), child: Image.asset( serviceCardData.largeCardIcon, fit: BoxFit.cover, + width: double.infinity, + height: isFoldable ? 190.h : (isTablet ? 200.h : 180.h), ), ), - Positioned( - bottom: 0.0, // Positions the child 0 logical pixels from the bottom - left: 0.0, - right: 0.0, - child: Container( - height: 180.h, - padding: EdgeInsets.only(bottom: 16.h, top: 16.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - customBorder: BorderRadius.only( - bottomLeft: Radius.circular(24.r), - bottomRight: Radius.circular(24.r), - ), - ), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - isPNG ? Image.asset(serviceCardData.icon, width: 35.h, height: 35.h) : Container( - height: 48.h, - width: 48.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: serviceCardData.backgroundColor!, - borderRadius: 12.r, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(12.h), - child: Utils.buildSvgWithAssets( - icon: serviceCardData.icon, - iconColor: serviceCardData.iconColor, - fit: BoxFit.contain, - applyThemeColor: false, + Container( + padding: EdgeInsets.all(16.w), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + isPNG + ? Image.asset(serviceCardData.icon, width: 35.h, height: 35.h) + : Container( + height: 48.h, + width: 48.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: serviceCardData.backgroundColor!, + borderRadius: 12.r, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(12.h), + child: Utils.buildSvgWithAssets( + icon: serviceCardData.icon, + iconColor: serviceCardData.iconColor, + fit: BoxFit.contain, + applyThemeColor: false, + ), + ), ), - ), + SizedBox(width: 12.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + serviceCardData.title.tr(context: context).toText14( + isBold: true, + color: AppColors.textColor, + maxlines: 1, + textOverflow: TextOverflow.ellipsis, + ), + serviceCardData.subtitle.tr(context: context).toText12(isBold: true, color: AppColors.textColorLight, maxLine: 2), + ], ), - SizedBox(width: 12.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - serviceCardData.title.tr(context: context).toText14(isBold: true, color: AppColors.textColor), - serviceCardData.subtitle.tr(context: context).toText12(isBold: true, color: AppColors.textColorLight, maxLine: 2), - ], - ), - ), - ], - ).paddingSymmetrical(8.w, 0.h).expanded, - CustomButton( - text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context), - onPressed: () { - handleOnTap(); - }, - padding: EdgeInsets.zero, - backgroundColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.2) : AppColors.bgRedLightColor, - borderColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.01) : AppColors.bgRedLightColor, - textColor: serviceCardData.isBold ? AppColors.successColor : AppColors.primaryRedColor, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 10.r, - height: 40.h, - ).paddingSymmetrical(16.w, 0.h), - ], - ), + ), + ], + ), + SizedBox(height: 24.h), + CustomButton( + text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context), + onPressed: () { + handleOnTap(); + }, + padding: EdgeInsets.zero, + backgroundColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.2) : AppColors.bgRedLightColor, + borderColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.01) : AppColors.bgRedLightColor, + textColor: serviceCardData.isBold ? AppColors.successColor : AppColors.primaryRedColor, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 10.r, + height: 40.h, + ), + ], ), ), ], @@ -229,27 +233,25 @@ class FadedLargeServiceCard extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - isPNG ? Image.asset(serviceCardData.icon, width: 32.h, height: 32.h).circle(100.h) : Container( - height: 32.h, - width: 32.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: serviceCardData.backgroundColor!, - borderRadius: 30.r, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(8.h), - child: Transform.flip( - flipX: getIt.get().isArabic(), - child: Utils.buildSvgWithAssets( - icon: serviceCardData.icon, - iconColor: serviceCardData.iconColor, - fit: BoxFit.contain, - applyThemeColor: false + isPNG + ? Image.asset(serviceCardData.icon, width: 32.h, height: 32.h).circle(100.h) + : Container( + height: 32.h, + width: 32.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: serviceCardData.backgroundColor!, + borderRadius: 30.r, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(8.h), + child: Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: serviceCardData.icon, iconColor: serviceCardData.iconColor, fit: BoxFit.contain, applyThemeColor: false), + ), + ), ), - ), - ), - ), SizedBox(width: 12.w), serviceCardData.title.tr(context: context).toText18(isBold: true, color: AppColors.textColor).expanded, ], diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 86807150..008a3849 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:ui' as ui; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -7,17 +8,13 @@ import 'package:get_it/get_it.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/app_state.dart'; -import 'package:hmg_patient_app_new/core/cache_consts.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; -import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_config.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/features/active_prescriptions/models/active_prescriptions_response_model.dart'; -import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; @@ -26,7 +23,6 @@ import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/vital import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; -import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; import 'package:hmg_patient_app_new/features/monthly_report/monthly_report_view_model.dart'; @@ -37,16 +33,13 @@ import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_mo import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart'; import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/active_medication/active_medication_page.dart'; import 'package:hmg_patient_app_new/presentation/allergies/allergies_list_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; -import 'package:hmg_patient_app_new/presentation/ask_doctor/ask_doctor_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; -import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_approvals_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; @@ -56,14 +49,11 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/eye_measurements_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/patient_sickleaves_list_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/vaccine_list_page.dart'; -import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart'; -import 'package:hmg_patient_app_new/presentation/medical_file/widgets/health_tracker_menu_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/health_tools_card.dart'; +import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_report_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.dart'; -import 'package:hmg_patient_app_new/presentation/medical_report/medical_reports_page.dart'; -import 'package:hmg_patient_app_new/presentation/monthly_report/monthly_report.dart'; import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart'; import 'package:hmg_patient_app_new/presentation/my_invoices/my_invoices_list.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart'; @@ -71,7 +61,6 @@ import 'package:hmg_patient_app_new/presentation/radiology/radiology_orders_page import 'package:hmg_patient_app_new/presentation/todo_section/todo_page.dart'; import 'package:hmg_patient_app_new/presentation/vital_sign/vital_sign_page.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; -import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; @@ -79,20 +68,16 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/expandable_list_widget.dart'; -import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart'; import 'package:hmg_patient_app_new/widgets/user_avatar_widget.dart'; import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; import '../../features/active_prescriptions/active_prescriptions_view_model.dart'; import '../prescriptions/prescription_detail_page.dart'; import 'widgets/medical_file_appointment_card.dart'; -import 'dart:ui' as ui; - class MedicalFilePage extends StatefulWidget { bool showBackIcon; @@ -119,10 +104,6 @@ class _MedicalFilePageState extends State { int currentIndex = 0; - // Used to make the PageView height follow the card's intrinsic height - final GlobalKey _vitalSignMeasureKey = GlobalKey(); - double? _vitalSignMeasuredHeight; - @override void initState() { appState = getIt.get(); @@ -143,22 +124,6 @@ class _MedicalFilePageState extends State { super.initState(); } - void _scheduleVitalSignMeasure() { - WidgetsBinding.instance.addPostFrameCallback((_) { - final ctx = _vitalSignMeasureKey.currentContext; - if (ctx == null) return; - final box = ctx.findRenderObject(); - if (box is RenderBox) { - final h = box.size.height; - if (h > 0 && h != _vitalSignMeasuredHeight) { - setState(() { - _vitalSignMeasuredHeight = h; - }); - } - } - }); - } - @override Widget build(BuildContext context) { labViewModel = Provider.of(context, listen: false); @@ -251,7 +216,7 @@ class _MedicalFilePageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ UserAvatarWidget( - width: 56.w, + width: 56.h, height: 56.h, fit: BoxFit.cover, isCircular: true, @@ -273,7 +238,8 @@ class _MedicalFilePageState extends State { children: [ AppCustomChipWidget( icon: AppAssets.file_icon, - richText: "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}".toText10(isEnglishOnly: true), + richText: "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}" + .toText10(isEnglishOnly: true), labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), ), AppCustomChipWidget( @@ -297,7 +263,9 @@ class _MedicalFilePageState extends State { runSpacing: 4.h, children: [ AppCustomChipWidget( - labelText: LocaleKeys.ageYearsOld.tr(namedArgs: {'age': '${appState.getAuthenticatedUser()!.age}', 'yearsOld': LocaleKeys.yearsOld.tr(context: context)}, context: context), + labelText: LocaleKeys.ageYearsOld.tr( + namedArgs: {'age': '${appState.getAuthenticatedUser()!.age}', 'yearsOld': LocaleKeys.yearsOld.tr(context: context)}, + context: context), labelPadding: EdgeInsetsDirectional.only(start: 8.w, end: 8.w), ), AppCustomChipWidget( @@ -340,9 +308,14 @@ class _MedicalFilePageState extends State { onChipTap: () { if (!insuranceVM.isInsuranceActive) { insuranceVM.setIsInsuranceUpdateDetailsLoading(true); - insuranceVM.getPatientInsuranceDetailsForUpdate( - appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); - showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + insuranceVM.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(), + appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, + child: PatientInsuranceCardUpdateCard(), + callBackFunc: () {}, + title: "", + isCloseButtonVisible: false, + isFullScreen: false); // showCommonBottomSheetWithoutHeight( // title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!), // navigationService.navigatorKey.currentContext!, @@ -438,17 +411,16 @@ class _MedicalFilePageState extends State { ); } - // The cards define their own height; measure the first rendered page once - _scheduleVitalSignMeasure(); - final double hostHeight = _vitalSignMeasuredHeight ?? (135.h); - - return SizedBox( - height: hostHeight, + // Responsive PageView with dynamic height constraint + return ConstrainedBox( + constraints: BoxConstraints( + minHeight: 135.h, + maxHeight: isFoldable ? 160.h : (isTablet ? 165.h : 135.h), + ), child: PageView( controller: hmgServicesVM.vitalSignPageController, onPageChanged: (index) { hmgServicesVM.setVitalSignCurrentPage(index); - _scheduleVitalSignMeasure(); }, children: _buildVitalSignPages( vitalSign: hmgServicesVM.vitalSignList.first, @@ -459,7 +431,6 @@ class _MedicalFilePageState extends State { ), ); }, - measureKey: _vitalSignMeasureKey, currentPageIndex: hmgServicesVM.vitalSignCurrentPage, ), ), @@ -517,7 +488,9 @@ class _MedicalFilePageState extends State { getSelectedTabData(0), ], ), - ExpandableListItem(title: LocaleKeys.medicalReports.tr(context: context).toText18(isBold: true), expandedBackgroundColor: Colors.transparent, + ExpandableListItem( + title: LocaleKeys.medicalReports.tr(context: context).toText18(isBold: true), + expandedBackgroundColor: Colors.transparent, children: [ SizedBox(height: 10.h), getSelectedTabData(2), @@ -588,871 +561,848 @@ class _MedicalFilePageState extends State { }); } - Widget getSelectedTabData(int index) { - switch (index) { - case 0: - //General Tab Data - return Column( - crossAxisAlignment: CrossAxisAlignment.start, + Widget buildInsuranceTab(int index) { + return Column( + children: [ + Consumer(builder: (context, insuranceVM, child) { + return insuranceVM.isInsuranceLoading + ? LabResultItemView( + onTap: () {}, + labOrder: null, + index: index, + isLoading: true, + ).paddingSymmetrical(0.w, 0.0) + : insuranceVM.patientInsuranceList.isNotEmpty + ? PatientInsuranceCard( + insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, + isInsuranceExpired: DateTime.now().isAfter( + DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo), + ), + ) + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.bgRedLightColor, + borderRadius: 12.r, + hasShadow: false, + ), + child: Utils.getNoDataWidget( + context, + noDataText: LocaleKeys.noInsuranceWithHMG.tr(context: context), + isSmallWidget: true, + width: 62.w, + height: 62.h, + callToActionButton: CustomButton( + icon: AppAssets.update_insurance_card_icon, + iconColor: AppColors.successColor, + iconSize: 15.h, + text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", + onPressed: () { + insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); + insuranceViewModel.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(), + appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, + child: PatientInsuranceCardUpdateCard(), + callBackFunc: () {}, + title: "", + isCloseButtonVisible: false, + isFullScreen: false); + }, + backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), + borderColor: AppColors.bgGreenColor.withOpacity(0.0), + textColor: AppColors.bgGreenColor, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), + height: isFoldable ? 50.h : 40.h, + ).paddingOnly(left: 12.w, right: 12.w, bottom: 12.h), + ), + ).paddingSymmetrical(0.w, 0.h); + }), + SizedBox(height: 10.h), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 10.h, + mainAxisSpacing: 16.w, + // mainAxisExtent: 120.h, + ), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 12.h), + shrinkWrap: true, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), - Row( - children: [ - LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), - ], - ), - ], - ).paddingSymmetrical(0.w, 0.h).onPress(() { + MedicalFileCard( + label: LocaleKeys.updateInsuranceInfo.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.update_insurance_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: InsuranceHomePage())); + }), + MedicalFileCard( + label: "${LocaleKeys.approvals1.tr(context: context)} ${LocaleKeys.insurance.tr(context: context)}", + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.insurance_approval_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { Navigator.of(context).push( CustomPageRoute( - page: MyAppointmentsPage(), + page: InsuranceApprovalsPage(), ), ); }), - SizedBox(height: 16.h), - Consumer(builder: (context, myAppointmentsVM, child) { - // Provide an explicit height so the horizontal ListView has a bounded height - return SizedBox( - height: 192.h, - child: myAppointmentsVM.isMyAppointmentsLoading - ? MedicalFileAppointmentCard( - patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), - myAppointmentsViewModel: myAppointmentsVM, - onRescheduleTap: () {}, - onAskDoctorTap: () {}, - ) - : myAppointmentsVM.patientAppointmentsHistoryList.isEmpty - ? Container( - padding: EdgeInsets.all(12.w), - width: MediaQuery.of(context).size.width, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: false), - child: Column( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), - SizedBox(height: 12.h), - LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), - SizedBox(height: 12.h), - CustomButton( - text: LocaleKeys.bookAppo.tr(context: context), - onPressed: () { - getIt.get().onTabChanged(0); - Navigator.of(context).push( - CustomPageRoute( - page: BookAppointmentPage(), - ), - ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.symmetric(horizontal: 10.w), - height: isFoldable || isTablet ? 50.h : 40.h, - icon: AppAssets.add_icon, - iconColor: AppColors.primaryRedColor, - ), - ], - ), - ) - : ListView.separated( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length, - padding: EdgeInsets.zero, - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 500), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOut, - child: MedicalFileAppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - onRescheduleTap: () { - openDoctorScheduleCalendar(myAppointmentsVM.patientAppointmentsHistoryList[index]); - }, - onAskDoctorTap: () async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context)); - await myAppointmentsViewModel.isDoctorAvailable( - projectID: myAppointmentsVM.patientAppointmentsHistoryList[index].projectID, - doctorId: myAppointmentsVM.patientAppointmentsHistoryList[index].doctorID, - clinicId: myAppointmentsVM.patientAppointmentsHistoryList[index].clinicID, - onSuccess: (value) async { - if (value) { - await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - title: LocaleKeys.askDoctor.tr(context: context), - child: AskDoctorRequestTypeSelect( - askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList, - myAppointmentsViewModel: myAppointmentsViewModel, - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], - ), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - } else { - LoaderBottomSheet.hideLoader(); - } - }, - onError: (_) { - LoaderBottomSheet.hideLoader(); - }, - ); - }, - ), - ), - ), - )); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.w), - ), + MedicalFileCard( + label: LocaleKeys.myInvoicesList.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.invoices_list_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: MyInvoicesList(), + ), ); }), - SizedBox(height: 10.h), - LocaleKeys.labAndRadiology.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: LabRadCard( - icon: AppAssets.lab_result_icon, - labelText: LocaleKeys.labResults.tr(context: context), - // labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar"], - labOrderTests: labViewModel.isLabOrdersLoading ? [] : labViewModel.labOrderTests, - isLoading: labViewModel.isLabOrdersLoading, - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: LabOrdersPage(), - ), - ); - }), - ), - SizedBox(width: 8.w), - Expanded( - child: LabRadCard( - icon: AppAssets.radiology_icon, - labelText: LocaleKeys.radiologyLabResults.tr(context: context), - // labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar", - // labOrderTests: ["Chest X-ray", "Abdominal Ultrasound", "Dental X-ray"], - labOrderTests: [], - isLoading: false, - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: RadiologyOrdersPage(), - ), - ); - }), + MedicalFileCard( + label: LocaleKeys.ancillaryOrdersListNew.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.ancillary_orders_list_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { + getIt.get().setIsAncillaryOrdersNeedReloading(true); + Navigator.of(context).push( + CustomPageRoute( + page: ToDoPage(), ), - ], - ).paddingSymmetrical(0.w, 0.h), - SizedBox(height: 24.h), + ); + }), + ], + ).paddingSymmetrical(0.w, 0.0), + SizedBox(height: 16.h), + ], + ); + } + + Widget buildMedicalServicesTab() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), - Row( - children: [ - LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), - SizedBox(width: 2.w), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), - ], - ).onPress(() { - // myAppointmentsViewModel.getPatientMyDoctors(); - Navigator.of(context).push( - CustomPageRoute( - page: PrescriptionsListPage(), - ), - ); - }), + LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], ), - SizedBox(height: 16.h), - Consumer(builder: (context, prescriptionVM, child) { - return prescriptionVM.isPrescriptionsOrdersLoading - ? const CommonShimmerWidget().paddingSymmetrical(0.w, 0.h) - : prescriptionVM.patientPrescriptionOrders.isNotEmpty - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.r, hasShadow: false), - child: Padding( - padding: EdgeInsets.all(16.w), - child: Column( - children: [ - ListView.separated( - itemCount: prescriptionVM.patientPrescriptionOrders.length <= 2 ? prescriptionVM.patientPrescriptionOrders.length : 2, - shrinkWrap: true, - padding: EdgeInsets.only(left: 0, right: 8.w), - physics: NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 500), - child: SlideAnimation( - verticalOffset: 100.0, - child: FadeInAnimation( - child: Row( - children: [ - Image.network( - prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!, - width: 40.w, - height: 40.h, - fit: BoxFit.cover, - ).circle(100.r), - SizedBox(width: 16.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - prescriptionVM.patientPrescriptionOrders[index].doctorName!.toText16(isBold: true), - SizedBox(height: 4.h), - Wrap( - direction: Axis.horizontal, - spacing: 3.w, - runSpacing: 4.w, - children: [ - AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), - Directionality( - textDirection: ui.TextDirection.ltr, - child: AppCustomChipWidget( - icon: AppAssets.doctor_calendar_icon, - labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), - false, - ), - isEnglishOnly: true, - ), - ), - ], - ), - ], + ], + ).paddingSymmetrical(0.w, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); + }), + SizedBox(height: 16.h), + Consumer(builder: (context, myAppointmentsVM, child) { + // Dynamic height that adapts to device and content + return ConstrainedBox( + constraints: BoxConstraints( + minHeight: 150.h, + maxHeight: isFoldable ? 230.h : (isTablet ? 240.h : 180.h), + ), + child: myAppointmentsVM.isMyAppointmentsLoading + ? MedicalFileAppointmentCard( + patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), + myAppointmentsViewModel: myAppointmentsVM, + onRescheduleTap: () {}, + onAskDoctorTap: () {}, + ) + : myAppointmentsVM.patientAppointmentsHistoryList.isEmpty + ? Container( + padding: EdgeInsets.all(12.w), + width: MediaQuery.of(context).size.width, + decoration: + RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: false), + child: Column( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), + SizedBox(height: 12.h), + LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.bookAppo.tr(context: context), + onPressed: () { + getIt.get().onTabChanged(0); + Navigator.of(context).push( + CustomPageRoute( + page: BookAppointmentPage(), + ), + ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: isFoldable || isTablet ? 50.h : 40.h, + icon: AppAssets.add_icon, + iconColor: AppColors.primaryRedColor, + ), + ], + ), + ) + : ListView.separated( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length, + padding: EdgeInsets.zero, + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + child: MedicalFileAppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + onRescheduleTap: () { + openDoctorScheduleCalendar(myAppointmentsVM.patientAppointmentsHistoryList[index]); + }, + onAskDoctorTap: () async { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context)); + await myAppointmentsViewModel.isDoctorAvailable( + projectID: myAppointmentsVM.patientAppointmentsHistoryList[index].projectID, + doctorId: myAppointmentsVM.patientAppointmentsHistoryList[index].doctorID, + clinicId: myAppointmentsVM.patientAppointmentsHistoryList[index].clinicID, + onSuccess: (value) async { + if (value) { + await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.askDoctor.tr(context: context), + child: AskDoctorRequestTypeSelect( + askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList, + myAppointmentsViewModel: myAppointmentsViewModel, + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], ), - ), - // SizedBox(width: 40.h), - Transform.flip( - flipX: appState.isArabic(), - child: Utils.buildSvgWithAssets( - icon: AppAssets.forward_arrow_icon_small, width: 15.w, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), - ], - ).onPress(() { - prescriptionVM.setPrescriptionsDetailsLoading(); - Navigator.of(context).push( - CustomPageRoute( - page: PrescriptionDetailPage(isFromAppointments: false, prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), - ), - ); - }), - ), - )); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + } else { + LoaderBottomSheet.hideLoader(); + } + }, + onError: (_) { + LoaderBottomSheet.hideLoader(); + }, + ); + }, + ), + ), ), - SizedBox(height: 16.h), - // Divider(color: AppColors.dividerColor), - // SizedBox(height: 16.h), - // Row( - // children: [ - // Expanded( - // child: CustomButton( - // text: LocaleKeys.allPrescriptions.tr(context: context), - // onPressed: () { - // Navigator.of(context).push( - // CustomPageRoute( - // page: PrescriptionsListPage(), - // ), - // ); - // }, - // backgroundColor: AppColors.secondaryLightRedColor, - // borderColor: AppColors.secondaryLightRedColor, - // textColor: AppColors.primaryRedColor, - // fontSize: 12.f, - // isBold: true, - // borderRadius: 12.r, - // height: 40.h, - // icon: AppAssets.requests, - // iconColor: AppColors.primaryRedColor, - // iconSize: 16.w, - // ), - // ), - // SizedBox(width: 6.w), - // Expanded( - // child: CustomButton( - // text: LocaleKeys.allMedications.tr(context: context), - // onPressed: () { Navigator.of(context).push( - // CustomPageRoute( - // page: ActiveMedicationPage(), - // ), - // );}, - // backgroundColor: AppColors.secondaryLightRedColor, - // borderColor: AppColors.secondaryLightRedColor, - // textColor: AppColors.primaryRedColor, - // fontSize: 12.f, - // isBold: true, - // borderRadius: 12.h, - // height: 40.h, - // icon: AppAssets.all_medications_icon, - // iconColor: AppColors.primaryRedColor, - // iconSize: 16.h, - // ), - // ), - // ], - // ), - ], - ), - ), - ).paddingSymmetrical(0.w, 0.h) - : Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.r, - hasShadow: false, - ), - child: Utils.getNoDataWidget( - context, - noDataText: LocaleKeys.youDontHaveAnyPrescriptionsYet.tr(context: context), - isSmallWidget: true, - width: 62.w, - height: 62.h, - ), - ).paddingSymmetrical(0.w, 0.h); - }), - SizedBox(height: 24.h), - //My Doctor Section + )); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.w), + ), + ); + }), + SizedBox(height: 10.h), + LocaleKeys.labAndRadiology.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: LabRadCard( + icon: AppAssets.lab_result_icon, + labelText: LocaleKeys.labResults.tr(context: context), + // labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar"], + labOrderTests: labViewModel.isLabOrdersLoading ? [] : labViewModel.labOrderTests, + isLoading: labViewModel.isLabOrdersLoading, + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: LabOrdersPage(), + ), + ); + }), + ), + SizedBox(width: 8.w), + Expanded( + child: LabRadCard( + icon: AppAssets.radiology_icon, + labelText: LocaleKeys.radiologyLabResults.tr(context: context), + // labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar", + // labOrderTests: ["Chest X-ray", "Abdominal Ultrasound", "Dental X-ray"], + labOrderTests: [], + isLoading: false, + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: RadiologyOrdersPage(), + ), + ); + }), + ), + ], + ).paddingSymmetrical(0.w, 0.h), + SizedBox(height: 24.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.myDoctor.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), - Row( - children: [ - LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), - SizedBox(width: 2.w), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), - ], - ).onPress(() { - // myAppointmentsViewModel.getPatientMyDoctors(); - Navigator.of(context).push( - CustomPageRoute( - page: MyDoctorsPage(), - ), - ); - }), + LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.w), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], - ).paddingSymmetrical(0.w, 0.h), - SizedBox(height: 16.h), - Consumer(builder: (context, myAppointmentsVM, child) { - return myAppointmentsVM.isPatientMyDoctorsLoading - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.network( - "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", - width: 64.w, - height: 64.h, - fit: BoxFit.cover, - ).circle(100).toShimmer2(isShow: true, radius: 50.r), - SizedBox(height: 8.h), - ("Dr. John Smith Smith Smith").toString().toText12(isBold: true, isCenter: true, maxLine: 2).toShimmer2(isShow: true), - ], - ) - : myAppointmentsVM.patientMyDoctorsList.isEmpty - ? Container( - width: SizeConfig.screenWidth, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.r, - hasShadow: false, - ), - child: Utils.getNoDataWidget( - context, - noDataText: LocaleKeys.youDontHaveAnyCompletedVisitsYet.tr(context: context), - isSmallWidget: true, - width: 62.w, - height: 62.h, - ), - ).paddingSymmetrical(0.w, 0.h) - : SizedBox( - height: 110.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: myAppointmentsVM.patientMyDoctorsList.length, - shrinkWrap: true, - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SizedBox( - // width: 80.w, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, + ).onPress(() { + // myAppointmentsViewModel.getPatientMyDoctors(); + Navigator.of(context).push( + CustomPageRoute( + page: PrescriptionsListPage(), + ), + ); + }), + ], + ), + SizedBox(height: 16.h), + Consumer(builder: (context, prescriptionVM, child) { + return prescriptionVM.isPrescriptionsOrdersLoading + ? const CommonShimmerWidget().paddingSymmetrical(0.w, 0.h) + : prescriptionVM.patientPrescriptionOrders.isNotEmpty + ? Container( + decoration: + RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.r, hasShadow: false), + child: Padding( + padding: EdgeInsets.all(16.w), + child: Column( + children: [ + ListView.separated( + itemCount: prescriptionVM.patientPrescriptionOrders.length <= 2 ? prescriptionVM.patientPrescriptionOrders.length : 2, + shrinkWrap: true, + padding: EdgeInsets.only(left: 0, right: 8.w), + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: Row( children: [ Image.network( - myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, - width: 64.w, - height: 64.h, + prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!, + width: 40.h, + height: 40.h, fit: BoxFit.cover, - ).circle(100).toShimmer2(isShow: false, radius: 50.r), - SizedBox(height: 8.h), - SizedBox( - width: 80.w, - child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName) - .toString().toText12(isBold: true, isCenter: true, maxLine: 2).toShimmer2(isShow: false), + ).circle(100.r), + SizedBox(width: 16.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + prescriptionVM.patientPrescriptionOrders[index].doctorName!.toText16(isBold: true), + SizedBox(height: 4.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.w, + runSpacing: 4.w, + children: [ + AppCustomChipWidget( + labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: DateUtil.formatDateToDate( + DateUtil.convertStringToDate( + prescriptionVM.patientPrescriptionOrders[index].appointmentDate), + false, + ), + isEnglishOnly: true, + ), + ), + ], + ), + ], + ), ), + // SizedBox(width: 40.h), + Transform.flip( + flipX: appState.isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon_small, + width: 15.w, + height: 15.h, + fit: BoxFit.contain, + iconColor: AppColors.textColor)), ], - ), - ).onPress(() async { - bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( - clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, - projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, - doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, - )); - LoaderBottomSheet.showLoader(); - await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { - LoaderBottomSheet.hideLoader(); + ).onPress(() { + prescriptionVM.setPrescriptionsDetailsLoading(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(isDoctorAllowedToBook: !(myAppointmentsVM.patientMyDoctorsList[index].isLiveCareClinic ?? false)), + page: PrescriptionDetailPage( + isFromAppointments: false, + prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), ), ); - }, onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - }), - ), - )); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h), - ), - ).paddingSymmetrical(0.w, 0); - }), - SizedBox(height: 24.h), - LocaleKeys.others.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), - SizedBox(height: 16.h), - GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - crossAxisSpacing: 10.h, - mainAxisSpacing: 16.w, - mainAxisExtent: 115.h, - ), - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.zero, - shrinkWrap: true, - children: [ - MedicalFileCard( - label: LocaleKeys.eyeMeasurements.tr(context: context), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.eye_result_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - myAppointmentsViewModel.setIsEyeMeasurementsAppointmentsLoading(true); - myAppointmentsViewModel.onEyeMeasurementsTabChanged(0); - myAppointmentsViewModel.getPatientEyeMeasurementAppointments(); - Navigator.of(context).push( - CustomPageRoute( - page: EyeMeasurementsAppointmentsPage(), - ), - ); - }), - MedicalFileCard( - label: LocaleKeys.illurgyInfomation.tr(), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.allergy_info_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - medicalFileViewModel.getPatientAllergiesList(); - Navigator.of(context).push( - CustomPageRoute( - page: AllergiesListPage(), - ), - ); - }), - MedicalFileCard( - label: LocaleKeys.vaccineInfomation.tr(), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.vaccine_info_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: VaccineListPage(), - ), - ); - }), - ], - ).paddingSymmetrical(0.w, 0.0), - SizedBox(height: 24.h), - ], - ); - case 1: - //Insurance Tab Data - return Column( - children: [ - Consumer(builder: (context, insuranceVM, child) { - return insuranceVM.isInsuranceLoading - ? LabResultItemView( - onTap: () {}, - labOrder: null, - index: index, - isLoading: true, - ).paddingSymmetrical(0.w, 0.0) - : insuranceVM.patientInsuranceList.isNotEmpty - ? PatientInsuranceCard( - insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, - isInsuranceExpired: DateTime.now().isAfter( - DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo), - ), - ) - : Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.r, - hasShadow: false, - ), - child: Utils.getNoDataWidget( - context, - noDataText: LocaleKeys.noInsuranceWithHMG.tr(context: context), - isSmallWidget: true, - width: 62.w, - height: 62.h, - callToActionButton: CustomButton( - icon: AppAssets.update_insurance_card_icon, - iconColor: AppColors.successColor, - iconSize: 15.h, - text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", - onPressed: () { - insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); - insuranceViewModel.getPatientInsuranceDetailsForUpdate( - appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); - showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + }), + ), + )); }, - backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - borderColor: AppColors.bgGreenColor.withOpacity(0.0), - textColor: AppColors.bgGreenColor, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), - height: isFoldable ? 50.h : 40.h, - ).paddingOnly(left: 12.w, right: 12.w, bottom: 12.h), - ), - ).paddingSymmetrical(0.w, 0.h); - }), - SizedBox(height: 10.h), - GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - crossAxisSpacing: 10.h, - mainAxisSpacing: 16.w, - mainAxisExtent: 120.h, - ), - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(top: 12.h), - shrinkWrap: true, - children: [ - MedicalFileCard( - label: LocaleKeys.updateInsuranceInfo.tr(context: context), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.update_insurance_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: InsuranceHomePage())); - }), - MedicalFileCard( - label: "${LocaleKeys.approvals1.tr(context: context)} ${LocaleKeys.insurance.tr(context: context)}", - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.insurance_approval_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: InsuranceApprovalsPage(), - ), - ); - }), - MedicalFileCard( - label: LocaleKeys.myInvoicesList.tr(context: context), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.invoices_list_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: MyInvoicesList(), - ), - ); - }), - MedicalFileCard( - label: LocaleKeys.ancillaryOrdersListNew.tr(context: context), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.ancillary_orders_list_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - getIt.get().setIsAncillaryOrdersNeedReloading(true); - Navigator.of(context).push( - CustomPageRoute( - page: ToDoPage(), - ), - ); - }), - ], - ).paddingSymmetrical(0.w, 0.0), - SizedBox(height: 16.h), - ], - ); - case 2: - // Requests Tab Data - return Column( + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ), + SizedBox(height: 16.h), + // Divider(color: AppColors.dividerColor), + // SizedBox(height: 16.h), + // Row( + // children: [ + // Expanded( + // child: CustomButton( + // text: LocaleKeys.allPrescriptions.tr(context: context), + // onPressed: () { + // Navigator.of(context).push( + // CustomPageRoute( + // page: PrescriptionsListPage(), + // ), + // ); + // }, + // backgroundColor: AppColors.secondaryLightRedColor, + // borderColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.primaryRedColor, + // fontSize: 12.f, + // isBold: true, + // borderRadius: 12.r, + // height: 40.h, + // icon: AppAssets.requests, + // iconColor: AppColors.primaryRedColor, + // iconSize: 16.w, + // ), + // ), + // SizedBox(width: 6.w), + // Expanded( + // child: CustomButton( + // text: LocaleKeys.allMedications.tr(context: context), + // onPressed: () { Navigator.of(context).push( + // CustomPageRoute( + // page: ActiveMedicationPage(), + // ), + // );}, + // backgroundColor: AppColors.secondaryLightRedColor, + // borderColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.primaryRedColor, + // fontSize: 12.f, + // isBold: true, + // borderRadius: 12.h, + // height: 40.h, + // icon: AppAssets.all_medications_icon, + // iconColor: AppColors.primaryRedColor, + // iconSize: 16.h, + // ), + // ), + // ], + // ), + ], + ), + ), + ).paddingSymmetrical(0.w, 0.h) + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.r, + hasShadow: false, + ), + child: Utils.getNoDataWidget( + context, + noDataText: LocaleKeys.youDontHaveAnyPrescriptionsYet.tr(context: context), + isSmallWidget: true, + width: 62.w, + height: 62.h, + ), + ).paddingSymmetrical(0.w, 0.h); + }), + SizedBox(height: 24.h), + //My Doctor Section + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + LocaleKeys.myDoctor.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "${LocaleKeys.sickSubtitle.tr(context: context)} ${LocaleKeys.sick2.tr(context: context)}".toText16(isBold: true), - Row( + LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.w), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + ], + ).onPress(() { + // myAppointmentsViewModel.getPatientMyDoctors(); + Navigator.of(context).push( + CustomPageRoute( + page: MyDoctorsPage(), + ), + ); + }), + ], + ).paddingSymmetrical(0.w, 0.h), + SizedBox(height: 16.h), + Consumer(builder: (context, myAppointmentsVM, child) { + return myAppointmentsVM.isPatientMyDoctorsLoading + ? Column( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + Image.network( + "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + width: 64.h, + height: 64.h, + fit: BoxFit.cover, + ).circle(100).toShimmer2(isShow: true, radius: 50.r), + SizedBox(height: 8.h), + ("Dr. John Smith Smith Smith").toString().toText12(isBold: true, isCenter: true, maxLine: 2).toShimmer2(isShow: true), ], + ) + : myAppointmentsVM.patientMyDoctorsList.isEmpty + ? Container( + width: SizeConfig.screenWidth, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.r, + hasShadow: false, + ), + child: Utils.getNoDataWidget( + context, + noDataText: LocaleKeys.youDontHaveAnyCompletedVisitsYet.tr(context: context), + isSmallWidget: true, + width: 62.w, + height: 62.h, + ), + ).paddingSymmetrical(0.w, 0.h) + : ConstrainedBox( + constraints: BoxConstraints( + minHeight: 100.h, + maxHeight: isFoldable ? 130.h : (isTablet ? 140.h : 115.h), + ), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: myAppointmentsVM.patientMyDoctorsList.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SizedBox( + // width: 80.w, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.network( + myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, + width: 64.h, + height: 64.h, + fit: BoxFit.cover, + ).circle(100).toShimmer2(isShow: false, radius: 50.r), + SizedBox(height: 8.h), + SizedBox( + width: 80.w, + child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName) + .toString() + .toText12(isBold: true, isCenter: true, maxLine: 2) + .toShimmer2(isShow: false), + ), + ], + ), + ).onPress(() async { + bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( + clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, + projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, + doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, + )); + LoaderBottomSheet.showLoader(); + await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage( + isDoctorAllowedToBook: !(myAppointmentsVM.patientMyDoctorsList[index].isLiveCareClinic ?? false)), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }), + ), + )); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h), + ), + ).paddingSymmetrical(0.w, 0); + }), + SizedBox(height: 24.h), + LocaleKeys.others.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), + SizedBox(height: 16.h), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1, + crossAxisSpacing: 10.h, + ), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + shrinkWrap: true, + children: [ + MedicalFileCard( + label: LocaleKeys.eyeMeasurements.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.eye_result_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { + myAppointmentsViewModel.setIsEyeMeasurementsAppointmentsLoading(true); + myAppointmentsViewModel.onEyeMeasurementsTabChanged(0); + myAppointmentsViewModel.getPatientEyeMeasurementAppointments(); + Navigator.of(context).push( + CustomPageRoute( + page: EyeMeasurementsAppointmentsPage(), ), - ], + ); + }), + MedicalFileCard( + label: LocaleKeys.illurgyInfomation.tr(), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.allergy_info_icon, + isLargeText: true, + iconSize: 36.w, ).onPress(() { + medicalFileViewModel.getPatientAllergiesList(); Navigator.of(context).push( CustomPageRoute( - page: PatientSickleavesListPage(), + page: AllergiesListPage(), ), ); }), - SizedBox(height: 16.h), - Consumer(builder: (context, medicalFileVM, child) { - return medicalFileVM.isPatientSickLeaveListLoading + MedicalFileCard( + label: LocaleKeys.vaccineInfomation.tr(), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.vaccine_info_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: VaccineListPage(), + ), + ); + }), + ], + ).paddingSymmetrical(0.w, 0.0), + SizedBox(height: 24.h), + ], + ); + } + + Widget buildRequestsTab() { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "${LocaleKeys.sickSubtitle.tr(context: context)} ${LocaleKeys.sick2.tr(context: context)}".toText16(isBold: true), + Row( + children: [ + LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + ], + ), + ], + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: PatientSickleavesListPage(), + ), + ); + }), + SizedBox(height: 16.h), + Consumer(builder: (context, medicalFileVM, child) { + return medicalFileVM.isPatientSickLeaveListLoading + ? PatientSickLeaveCard( + patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), + isLoading: true, + ).paddingSymmetrical(0.w, 0.0) + : medicalFileVM.patientSickLeaveList.isNotEmpty ? PatientSickLeaveCard( - patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), - isLoading: true, + patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first, + isLoading: false, ).paddingSymmetrical(0.w, 0.0) - : medicalFileVM.patientSickLeaveList.isNotEmpty - ? PatientSickLeaveCard( - patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first, - isLoading: false, - ).paddingSymmetrical(0.w, 0.0) - : Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 12.r, - hasShadow: false, - ), - child: Utils.getNoDataWidget( - context, - noDataText: LocaleKeys.youDontHaveAnySickLeavesYet.tr(context: context), - isSmallWidget: true, - width: 62.w, - height: 62.h, - ), - ).paddingSymmetrical(0.w, 0.h); + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.r, + hasShadow: false, + ), + child: Utils.getNoDataWidget( + context, + noDataText: LocaleKeys.youDontHaveAnySickLeavesYet.tr(context: context), + isSmallWidget: true, + width: 62.w, + height: 62.h, + ), + ).paddingSymmetrical(0.w, 0.h); + }), + SizedBox(height: 16.h), + Selector listRequest, List listReady})>( + selector: (context, vm) => ( + isLoading: vm.isPatientMedicalReportsListLoading, + listRequest: vm.patientMedicalReportRequestedList, + listReady: vm.patientMedicalReportReadyList + ), + builder: (context, data, _) { + return MedicalReportCard(isLoading: data.isLoading, listRequest: data.listRequest, listReady: data.listReady); + }, + ), + SizedBox(height: 24.h), + ], + ); + } + + Widget buildHealthToolsTab() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 10.h, + mainAxisSpacing: 16.w, + ), + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 12.h), + shrinkWrap: true, + children: [ + // Health Trackers + HealthToolsCard( + label: LocaleKeys.healthTrackers.tr(context: context), + textColor: AppColors.blackColor, + svgIcon: AppAssets.general_health, + iconColor: null, + iconSize: 24.w, + ).onPress(() { + if (getIt.get().isAuthenticated) { + context.navigateWithName(AppRoutes.healthTrackersPage); + } }), - SizedBox(height: 16.h), - Selector listRequest, List listReady})>( - selector: (context, vm) => (isLoading: vm.isPatientMedicalReportsListLoading, listRequest: vm.patientMedicalReportRequestedList, listReady: vm.patientMedicalReportReadyList), - builder: (context, data, _){ - return MedicalReportCard( - isLoading: data.isLoading, listRequest: data.listRequest, listReady: data.listReady + // Daily Water Monitor + HealthToolsCard( + label: LocaleKeys.dailyWaterMonitor.tr(context: context), + textColor: AppColors.blackColor, + svgIcon: AppAssets.daily_water_monitor_icon, + iconColor: AppColors.infoColor, + iconSize: 24.w, + ).onPress(() async { + if (getIt.get().isAuthenticated) { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingYourWaterIntakeDetails.tr()); + final waterMonitorVM = getIt.get(); + await waterMonitorVM.fetchUserDetailsForMonitoring( + onSuccess: (userDetail) { + LoaderBottomSheet.hideLoader(); + if (userDetail == null) { + waterMonitorVM.populateFromAuthenticatedUser(); + context.navigateWithName(AppRoutes.waterMonitorSettingsPage); + } else { + context.navigateWithName(AppRoutes.waterConsumptionPage); + } + }, + onError: (error) { + LoaderBottomSheet.hideLoader(); + context.navigateWithName(AppRoutes.waterConsumptionPage); + }, ); - }, - ) - // GridView( - // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - // crossAxisCount: 3, - // crossAxisSpacing: 10.h, - // mainAxisSpacing: 16.w, - // mainAxisExtent: 110.h, - // ), - // physics: NeverScrollableScrollPhysics(), - // padding: EdgeInsets.zero, - // shrinkWrap: true, - // children: [ - // // MedicalFileCard( - // // label: LocaleKeys.monthlyReports.tr(context: context), - // // textColor: AppColors.blackColor, - // // backgroundColor: AppColors.whiteColor, - // // svgIcon: AppAssets.monthly_reports_icon, - // // isLargeText: true, - // // iconSize: 36.h, - // // ).onPress(() { - // // monthlyReportViewModel.setHealthSummaryEnabled(cacheService.getBool(key: CacheConst.isMonthlyReportEnabled) ?? false); - // // Navigator.of(context).push( - // // CustomPageRoute( - // // page: MonthlyReport(), - // // ), - // // ); - // // }), - // ///todo te changes of the medical report should be displayed here. - // /// - // - // // MedicalFileCard( - // // label: LocaleKeys.medicalReports.tr(context: context), - // // textColor: AppColors.blackColor, - // // backgroundColor: AppColors.whiteColor, - // // svgIcon: AppAssets.medical_reports_icon, - // // isLargeText: true, - // // iconSize: 36.w, - // // ).onPress(() { - // // - // // Navigator.of(context).push( - // // CustomPageRoute( - // // page: MedicalReportsPage(), - // // ), - // // ); - // // }), - // // MedicalFileCard( - // // label: LocaleKeys.sickLeaveReport.tr(context: context), - // // textColor: AppColors.blackColor, - // // backgroundColor: AppColors.whiteColor, - // // svgIcon: AppAssets.sick_leave_report_icon, - // // isLargeText: true, - // // iconSize: 36.h, - // // ).onPress(() { - // // Navigator.of(context).push( - // // CustomPageRoute( - // // page: PatientSickleavesListPage(), - // // ), - // // ); - // // }), - // ], - // ).paddingSymmetrical(0.w, 0.0), - ,SizedBox(height: 24.h), + } + }), + // Health Calculators + HealthToolsCard( + label: LocaleKeys.healthCalculatorsServices.tr(context: context), + textColor: AppColors.blackColor, + svgIcon: AppAssets.health_calculators_services_icon, + iconColor: AppColors.successColor, + iconSize: 24.w, + ).onPress(() { + context.navigateWithName(AppRoutes.healthCalculatorsPage); + }), + // Health Converters + HealthToolsCard( + label: LocaleKeys.healthConvertersServices.tr(context: context), + textColor: AppColors.blackColor, + svgIcon: AppAssets.health_converters_icon, + iconColor: AppColors.primaryRedColor, + iconSize: 24.w, + ).onPress(() { + context.navigateWithName(AppRoutes.healthConvertersPage); + }), + // Smart Watches + HealthToolsCard( + label: LocaleKeys.smartWatchesServices.tr(context: context), + textColor: AppColors.blackColor, + svgIcon: AppAssets.smartwatch_icon, + iconColor: AppColors.warningColorYellow, + iconSize: 24.w, + ).onPress(() { + if (getIt.get().isAuthenticated) { + context.navigateWithName(AppRoutes.smartWatches); + } + }), ], - ); + ).paddingSymmetrical(0.w, 0.0), + SizedBox(height: 24.h), + ], + ); + } + + Widget getSelectedTabData(int index) { + switch (index) { + case 0: + //General Tab Data + return buildMedicalServicesTab(); + case 1: + //Insurance Tab Data + return buildInsuranceTab(index); + case 2: + // Requests Tab Data + return buildRequestsTab(); case 3: // Health Tools Tab Data - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - crossAxisSpacing: 10.h, - mainAxisSpacing: 16.w, - mainAxisExtent: 120.h, - ), - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(top: 12.h), - shrinkWrap: true, - children: [ - // Health Trackers - HealthToolsCard( - label: LocaleKeys.healthTrackers.tr(context: context), - textColor: AppColors.blackColor, - svgIcon: AppAssets.general_health, - iconColor:null, - iconSize: 24.w, - ).onPress(() { - if (getIt.get().isAuthenticated) { - context.navigateWithName(AppRoutes.healthTrackersPage); - } - }), - // Daily Water Monitor - HealthToolsCard( - label: LocaleKeys.dailyWaterMonitor.tr(context: context), - textColor: AppColors.blackColor, - svgIcon: AppAssets.daily_water_monitor_icon, - iconColor: AppColors.infoColor, - iconSize: 24.w, - ).onPress(() async { - if (getIt.get().isAuthenticated) { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingYourWaterIntakeDetails.tr()); - final waterMonitorVM = getIt.get(); - await waterMonitorVM.fetchUserDetailsForMonitoring( - onSuccess: (userDetail) { - LoaderBottomSheet.hideLoader(); - if (userDetail == null) { - waterMonitorVM.populateFromAuthenticatedUser(); - context.navigateWithName(AppRoutes.waterMonitorSettingsPage); - } else { - context.navigateWithName(AppRoutes.waterConsumptionPage); - } - }, - onError: (error) { - LoaderBottomSheet.hideLoader(); - context.navigateWithName(AppRoutes.waterConsumptionPage); - }, - ); - } - }), - // Health Calculators - HealthToolsCard( - label: LocaleKeys.healthCalculatorsServices.tr(context: context), - textColor: AppColors.blackColor, - svgIcon: AppAssets.health_calculators_services_icon, - iconColor: AppColors.successColor, - iconSize: 24.w, - ).onPress(() { - context.navigateWithName(AppRoutes.healthCalculatorsPage); - }), - // Health Converters - HealthToolsCard( - label: LocaleKeys.healthConvertersServices.tr(context: context), - textColor: AppColors.blackColor, - svgIcon: AppAssets.health_converters_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 24.w, - ).onPress(() { - context.navigateWithName(AppRoutes.healthConvertersPage); - }), - // Smart Watches - HealthToolsCard( - label: LocaleKeys.smartWatchesServices.tr(context: context), - textColor: AppColors.blackColor, - svgIcon: AppAssets.smartwatch_icon, - iconColor: AppColors.warningColorYellow, - iconSize: 24.w, - ).onPress(() { - if (getIt.get().isAuthenticated) { - context.navigateWithName(AppRoutes.smartWatches); - } - }), - ], - ).paddingSymmetrical(0.w, 0.0), - SizedBox(height: 24.h), - ], - ); + return buildHealthToolsTab(); default: return Container(); } @@ -1538,13 +1488,12 @@ class _MedicalFilePageState extends State { List _buildVitalSignPages({ required VitalSignResModel vitalSign, required VoidCallback onTap, - required GlobalKey measureKey, required int currentPageIndex, }) { return [ // Page 1: BMI + Height Padding( - padding: EdgeInsets.only(left: 24.w), + padding: EdgeInsets.symmetric(horizontal: 24.w), child: Row( children: [ Expanded( @@ -1574,7 +1523,7 @@ class _MedicalFilePageState extends State { ), // Page 2: Weight + Blood Pressure Padding( - padding: EdgeInsets.symmetric(horizontal: 12.w), + padding: EdgeInsets.symmetric(horizontal: 24.w), child: Row( children: [ Expanded( @@ -1592,13 +1541,17 @@ class _MedicalFilePageState extends State { child: _buildVitalSignCard( icon: AppAssets.bloodPressure, label: LocaleKeys.bloodPressure.tr(context: context), - value: (vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null && - vitalSign.bloodPressureLower != 0 && vitalSign.bloodPressureHigher != 0) + value: (vitalSign.bloodPressureLower != null && + vitalSign.bloodPressureHigher != null && + vitalSign.bloodPressureLower != 0 && + vitalSign.bloodPressureHigher != 0) ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" : '--', unit: '', - status: (vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null && - vitalSign.bloodPressureLower != 0 && vitalSign.bloodPressureHigher != 0) + status: (vitalSign.bloodPressureLower != null && + vitalSign.bloodPressureHigher != null && + vitalSign.bloodPressureLower != 0 && + vitalSign.bloodPressureHigher != 0) ? _getBloodPressureStatus( systolic: vitalSign.bloodPressureHigher, diastolic: vitalSign.bloodPressureLower, @@ -1682,7 +1635,8 @@ class _MedicalFilePageState extends State { weight: FontWeight.w600, ), ), - Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward, width: 18.w, height: 18.h), + Utils.buildSvgWithAssets( + icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward, width: 18.w, height: 18.h), ], ), SizedBox(height: 14.h), @@ -1702,11 +1656,7 @@ class _MedicalFilePageState extends State { mainAxisSize: MainAxisSize.min, children: [ Flexible( - child: value.toText17( - isBold: true, - color: AppColors.textColor, - isEnglishOnly: true - ), + child: value.toText17(isBold: true, color: AppColors.textColor, isEnglishOnly: true), ), if (unit.isNotEmpty && value != '--' && value != '0') ...[ SizedBox(width: 3.w), diff --git a/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart b/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart index 9c64884a..5a9ae8b6 100644 --- a/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart +++ b/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart @@ -152,7 +152,7 @@ class _MedicalFileAppointmentCardState extends State backgroundColor: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? AppColors.greyColor : AppColors.secondaryLightRedColor, textColor: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor, - padding: EdgeInsets.only(top: 12.h, bottom: 12.h, left: 8.w, right: 8.w), + padding: EdgeInsets.only(top: 12.h, left: 8.w, right: 8.w, bottom: 8.h), ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), SizedBox(height: 16.h), IntrinsicWidth( @@ -166,10 +166,10 @@ class _MedicalFileAppointmentCardState extends State Image.network( widget.patientAppointmentHistoryResponseModel.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", - width: 25.w, - height: 27.h, + width: 30.h, + height: 30.h, fit: BoxFit.fill, - ).circle(100).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), + ).circle(100.r).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), SizedBox(width: 8.w), Expanded( child: Column( @@ -190,138 +190,7 @@ class _MedicalFileAppointmentCardState extends State ], ), SizedBox(height: 8.h), - // Check if doctor is active - if not, show only View Details button - (widget.patientAppointmentHistoryResponseModel.isActiveDoctor ?? true) - ? // Doctor is active - check rebooking logic - (AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) && - widget.patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false) - ? // Show only the button without arrow when rebooking not allowed - widget.myAppointmentsViewModel.isMyAppointmentsLoading - ? Container().toShimmer2(isShow: true, height: 40.h, width: 100.w, radius: 12.r) - : AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) - ? getArrivedAppointmentButton(context).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading) - : CustomButton( - text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), - onPressed: () { - handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction, context); - }, - backgroundColor: - AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction) - .withValues(alpha: 0.15), - borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction) - .withValues(alpha: 0.01), - textColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.symmetric(horizontal: 10.w), - height: 40.h, - icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), - iconColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), - iconSize: 14.h, - ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading) - : // Normal flow - show button with arrow - Row( - children: [ - widget.myAppointmentsViewModel.isMyAppointmentsLoading - ? Container().toShimmer2(isShow: true, height: 40.h, width: 100.w, radius: 12.r) - : Expanded( - flex: 7, - child: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) - ? getArrivedAppointmentButton(context) - .toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading) - : CustomButton( - text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), - onPressed: () { - handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction, context); - }, - backgroundColor: - AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction) - .withValues(alpha: 0.15), - borderColor: - AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction) - .withValues(alpha: 0.01), - textColor: - AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.symmetric(horizontal: 10.w), - height: 40.h, - icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), - iconColor: - AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), - iconSize: 14.h, - ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), - ), - SizedBox(width: 8.w), - ((((widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) || - (widget.patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) || - !Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID ?? 0))) && - AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) - ? SizedBox.shrink() - : Expanded( - flex: 2, - child: Container( - height: 40.h, - width: 40.w, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.textColor, - borderRadius: 10.r, - ), - child: Padding( - padding: EdgeInsets.all(10.w), - child: Transform.flip( - flipX: appState.isArabic(), - child: Utils.buildSvgWithAssets( - iconColor: AppColors.whiteColor, - icon: AppAssets.forward_arrow_icon_small, - width: 40.w, - height: 40.h, - fit: BoxFit.contain, - ), - ), - ), - ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading).onPress(() { - Navigator.of(context) - .push( - CustomPageRoute( - page: AppointmentDetailsPage( - patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), - ), - ) - .then((val) { - // widget.myAppointmentsViewModel.initAppointmentsViewModel(); - // widget.myAppointmentsViewModel.getPatientAppointments(true, false); - }); - }), - ), - ], - ) - : // Doctor is not active - show only View Details button - CustomButton( - text: LocaleKeys.viewDetails.tr(context: context), - onPressed: () { - Navigator.of(context) - .push( - CustomPageRoute( - page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), - ), - ) - .then((_) { - widget.myAppointmentsViewModel.initAppointmentsViewModel(); - widget.myAppointmentsViewModel.getPatientAppointments(true, false); - }); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: (isFoldable || isTablet) ? 12.f : 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.symmetric(horizontal: 10.w), - height: 40.h, - ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), + _buildAppointmentActionButton(context, appState), ], ).paddingAll(16.w), ), @@ -330,6 +199,170 @@ class _MedicalFileAppointmentCardState extends State ); } + /// Builds the appropriate action button based on appointment state and doctor status + Widget _buildAppointmentActionButton(BuildContext context, AppState appState) { + final isLoading = widget.myAppointmentsViewModel.isMyAppointmentsLoading; + final appointment = widget.patientAppointmentHistoryResponseModel; + final isDoctorActive = appointment.isActiveDoctor ?? true; + + // If doctor is not active, show only View Details button + if (!isDoctorActive) { + return _buildViewDetailsButton(context); + } + + // Doctor is active - check rebooking logic + final isArrived = AppointmentType.isArrived(appointment); + final isRebookingNotAllowed = appointment.isClinicReBookingAllowed == false; + + // If arrived and rebooking not allowed, show button without arrow + if (isArrived && isRebookingNotAllowed) { + return _buildSingleButton(context, isLoading); + } + + // Normal flow - show button with arrow + return _buildButtonWithArrow(context, appState, isLoading); + } + + /// Builds a single button without arrow (for no rebooking scenarios) + Widget _buildSingleButton(BuildContext context, bool isLoading) { + if (isLoading) { + return Container().toShimmer2(isShow: true, height: 40.h, width: 100.w, radius: 12.r); + } + + final isArrived = AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel); + + if (isArrived) { + return getArrivedAppointmentButton(context).toShimmer2(isShow: isLoading); + } + + return _buildNextActionButton(context, isLoading); + } + + /// Builds the next action button (Pay Now, Confirm, etc.) + Widget _buildNextActionButton(BuildContext context, bool isLoading) { + final appointment = widget.patientAppointmentHistoryResponseModel; + + return CustomButton( + text: AppointmentType.getNextActionText(appointment.nextAction), + onPressed: () { + handleAppointmentNextAction(appointment.nextAction, context); + }, + backgroundColor: AppointmentType.getNextActionButtonColor(appointment.nextAction).withValues(alpha: 0.15), + borderColor: AppointmentType.getNextActionButtonColor(appointment.nextAction).withValues(alpha: 0.01), + textColor: AppointmentType.getNextActionTextColor(appointment.nextAction), + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: 40.h, + icon: AppointmentType.getNextActionIcon(appointment.nextAction), + iconColor: AppointmentType.getNextActionTextColor(appointment.nextAction), + iconSize: 14.h, + ).toShimmer2(isShow: isLoading); + } + + /// Builds button with arrow (normal flow with navigation arrow) + Widget _buildButtonWithArrow(BuildContext context, AppState appState, bool isLoading) { + return Row( + children: [ + _buildMainActionButton(context, isLoading), + SizedBox(width: 8.w), + _buildNavigationArrow(context, appState, isLoading), + ], + ); + } + + /// Builds the main action button in the row (left side) + Widget _buildMainActionButton(BuildContext context, bool isLoading) { + if (isLoading) { + return Container().toShimmer2(isShow: true, height: 40.h, width: 100.w, radius: 12.r); + } + + final isArrived = AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel); + + return Expanded( + flex: 7, + child: isArrived ? getArrivedAppointmentButton(context).toShimmer2(isShow: isLoading) : _buildNextActionButton(context, isLoading), + ); + } + + /// Builds the navigation arrow button (right side) + Widget _buildNavigationArrow(BuildContext context, AppState appState, bool isLoading) { + final appointment = widget.patientAppointmentHistoryResponseModel; + final isArrived = AppointmentType.isArrived(appointment); + + // Check if arrow should be hidden + final shouldHideArrow = (appointment.isLiveCareAppointment ?? false) || + (appointment.isExecludeDoctor ?? false) || + !Utils.isClinicAllowedForRebook(appointment.clinicID ?? 0); + + if (shouldHideArrow && isArrived) { + return SizedBox.shrink(); + } + + return Expanded( + flex: 2, + child: Container( + height: 40.h, + width: 40.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.textColor, + borderRadius: 10.r, + ), + child: Padding( + padding: EdgeInsets.all(10.w), + child: Transform.flip( + flipX: appState.isArabic(), + child: Utils.buildSvgWithAssets( + iconColor: AppColors.whiteColor, + icon: AppAssets.forward_arrow_icon_small, + width: 40.h, + height: 40.h, + fit: BoxFit.contain, + ), + ), + ), + ).toShimmer2(isShow: isLoading).onPress(() { + Navigator.of(context) + .push( + CustomPageRoute( + page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: appointment), + ), + ) + .then((val) { + // Can refresh appointments here if needed + }); + }), + ); + } + + /// Builds the View Details button (for inactive doctors) + Widget _buildViewDetailsButton(BuildContext context) { + return CustomButton( + text: LocaleKeys.viewDetails.tr(context: context), + onPressed: () { + Navigator.of(context) + .push( + CustomPageRoute( + page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), + ), + ) + .then((_) { + widget.myAppointmentsViewModel.initAppointmentsViewModel(); + widget.myAppointmentsViewModel.getPatientAppointments(true, false); + }); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: (isFoldable || isTablet) ? 12.f : 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: isFoldable ? 36.h : 40.h, + ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading); + } + Widget getArrivedAppointmentButton(BuildContext context) { // Check if rebooking is not allowed - show View Details button if (widget.patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false) { diff --git a/lib/presentation/medical_file/widgets/medical_file_card.dart b/lib/presentation/medical_file/widgets/medical_file_card.dart index a79d8aa9..ebf569e1 100644 --- a/lib/presentation/medical_file/widgets/medical_file_card.dart +++ b/lib/presentation/medical_file/widgets/medical_file_card.dart @@ -30,11 +30,7 @@ class MedicalFileCard extends StatelessWidget { Widget build(BuildContext context) { final iconS = iconSize ?? 30.w; return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: backgroundColor, - borderRadius: 20.r, - hasShadow: false - ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: backgroundColor, borderRadius: 20.r, hasShadow: false), padding: EdgeInsets.all(12.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -64,5 +60,3 @@ class MedicalFileCard extends StatelessWidget { ); } } - - diff --git a/lib/presentation/smartwatches/activity_detail.dart b/lib/presentation/smartwatches/activity_detail.dart index 2d2532b5..b023e04f 100644 --- a/lib/presentation/smartwatches/activity_detail.dart +++ b/lib/presentation/smartwatches/activity_detail.dart @@ -14,7 +14,7 @@ import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/graph/CustomBarGraph.dart'; import 'package:intl/intl.dart' show DateFormat; import 'package:provider/provider.dart'; -import 'package:hmg_patient_app_new/features/smartwatch_health_data/HealthDataTransformation.dart' as durations; +import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_data_transformations.dart' as durations; import 'package:dartz/dartz.dart' show Tuple2; import '../../core/utils/date_util.dart'; diff --git a/lib/presentation/smartwatches/huawei_health_example.dart b/lib/presentation/smartwatches/huawei_health_example.dart deleted file mode 100644 index 857d26aa..00000000 --- a/lib/presentation/smartwatches/huawei_health_example.dart +++ /dev/null @@ -1,1563 +0,0 @@ -// import 'package:flutter/material.dart'; -// import 'package:flutter/services.dart'; -// import 'package:huawei_health/huawei_health.dart'; -// -// const String packageName = 'com.ejada.hmg'; -// -// class HuaweiHealthExample extends StatefulWidget { -// const HuaweiHealthExample({Key? key}) : super(key: key); -// -// @override -// State createState() => _HuaweiHealthExampleState(); -// } -// -// class _HuaweiHealthExampleState extends State { -// /// Styles -// static const TextStyle cardTitleTextStyle = TextStyle( -// isBold: true, -// fontSize: 18, -// ); -// static const EdgeInsets componentPadding = EdgeInsets.all(8.0); -// -// /// Text Controllers for showing the logs of different modules -// final TextEditingController _activityTextController = TextEditingController(); -// final TextEditingController _dataTextController = TextEditingController(); -// final TextEditingController _settingTextController = TextEditingController(); -// final TextEditingController _autoRecorderTextController = TextEditingController(); -// final TextEditingController _consentTextController = TextEditingController(); -// final TextEditingController _healthTextController = TextEditingController(); -// -// /// Data controller reference to initialize at startup. -// late DataController _dataController; -// -// String? accessToken = ''; -// -// @override -// void initState() { -// super.initState(); -// if (!mounted) return; -// // Initialize Event Callbacks -// AutoRecorderController.autoRecorderStream.listen(_onAutoRecorderEvent); -// // Initialize a DataController -// initDataController(); -// } -// -// /// Prints the specified text on both the console and the specified text controller. -// void log( -// String methodName, -// TextEditingController controller, -// LogOptions logOption, { -// String? result = '', -// String? error = '', -// }) { -// String log = ''; -// switch (logOption) { -// case LogOptions.call: -// log = '$methodName called'; -// break; -// case LogOptions.success: -// log = '$methodName [Success: $result] '; -// break; -// case LogOptions.error: -// log = '$methodName [Error: $error] [Error Description: ${HiHealthStatusCodes.getStatusCodeMessage(error ?? '')}]'; -// break; -// case LogOptions.custom: -// log = methodName; // Custom text -// break; -// } -// debugPrint(log); -// setState(() { -// controller.text = '$log\n${controller.text}'; -// }); -// } -// -// /// Authorizes Huawei Health Kit for the user, with defined scopes. -// void signIn() async { -// // List of scopes to ask for authorization. -// // -// // Note: These scopes should also be authorized on the Huawei Developer Console. -// final List scopes = [ -// Scope.HEALTHKIT_ACTIVITY_READ, -// Scope.HEALTHKIT_ACTIVITY_WRITE, -// Scope.HEALTHKIT_BLOODGLUCOSE_READ, -// Scope.HEALTHKIT_BLOODGLUCOSE_WRITE, -// Scope.HEALTHKIT_CALORIES_READ, -// Scope.HEALTHKIT_CALORIES_WRITE, -// Scope.HEALTHKIT_DISTANCE_READ, -// Scope.HEALTHKIT_DISTANCE_WRITE, -// Scope.HEALTHKIT_HEARTRATE_READ, -// Scope.HEALTHKIT_HEARTRATE_WRITE, -// Scope.HEALTHKIT_HEIGHTWEIGHT_READ, -// Scope.HEALTHKIT_HEIGHTWEIGHT_WRITE, -// Scope.HEALTHKIT_LOCATION_READ, -// Scope.HEALTHKIT_LOCATION_WRITE, -// Scope.HEALTHKIT_PULMONARY_READ, -// Scope.HEALTHKIT_PULMONARY_WRITE, -// Scope.HEALTHKIT_SLEEP_READ, -// Scope.HEALTHKIT_SLEEP_WRITE, -// Scope.HEALTHKIT_SPEED_READ, -// Scope.HEALTHKIT_SPEED_WRITE, -// Scope.HEALTHKIT_STEP_READ, -// Scope.HEALTHKIT_STEP_WRITE, -// Scope.HEALTHKIT_STRENGTH_READ, -// Scope.HEALTHKIT_STRENGTH_WRITE, -// Scope.HEALTHKIT_BODYFAT_READ, -// Scope.HEALTHKIT_BODYFAT_WRITE, -// Scope.HEALTHKIT_NUTRITION_READ, -// Scope.HEALTHKIT_NUTRITION_WRITE, -// Scope.HEALTHKIT_BLOODPRESSURE_READ, -// Scope.HEALTHKIT_BLOODPRESSURE_WRITE, -// Scope.HEALTHKIT_BODYTEMPERATURE_READ, -// Scope.HEALTHKIT_BODYTEMPERATURE_WRITE, -// Scope.HEALTHKIT_OXYGENSTATURATION_READ, -// Scope.HEALTHKIT_OXYGENSTATURATION_WRITE, -// Scope.HEALTHKIT_REPRODUCTIVE_READ, -// Scope.HEALTHKIT_REPRODUCTIVE_WRITE, -// Scope.HEALTHKIT_ACTIVITY_RECORD_READ, -// Scope.HEALTHKIT_ACTIVITY_RECORD_WRITE, -// Scope.HEALTHKIT_HEARTRATE_REALTIME, -// Scope.HEALTHKIT_STEP_REALTIME, -// Scope.HEALTHKIT_HEARTHEALTH_WRITE, -// Scope.HEALTHKIT_HEARTHEALTH_READ, -// Scope.HEALTHKIT_STRESS_WRITE, -// Scope.HEALTHKIT_STRESS_READ, -// Scope.HEALTHKIT_OXYGEN_SATURATION_WRITE, -// Scope.HEALTHKIT_OXYGEN_SATURATION_READ, -// Scope.HEALTHKIT_HISTORYDATA_OPEN_WEEK, -// Scope.HEALTHKIT_HISTORYDATA_OPEN_MONTH, -// Scope.HEALTHKIT_HISTORYDATA_OPEN_YEAR, -// ]; -// try { -// AuthHuaweiId? result = await HealthAuth.signIn(scopes); -// debugPrint( -// 'Granted Scopes for User(${result?.displayName}): ${result?.grantedScopes?.toString()}', -// ); -// showSnackBar( -// 'Authorization Success.', -// color: Colors.green, -// ); -// setState(() => accessToken = result?.accessToken); -// } on PlatformException catch (e) { -// debugPrint('Error on authorization, Error:${e.toString()}'); -// showSnackBar( -// 'Error on authorization, Error:${e.toString()}, Error Description: ' -// '${HiHealthStatusCodes.getStatusCodeMessage(e.message ?? '')}', -// ); -// } -// } -// -// // ActivityRecordsController -// // -// /// Adds an ActivityRecord with an ActivitySummary, time range is 2 hours from now. -// Future addActivityRecord() async { -// log( -// 'addActivityRecord', -// _activityTextController, -// LogOptions.call, -// ); -// DateTime startTime = DateTime.now().subtract(const Duration(hours: 2)); -// DateTime endTime = DateTime.now(); -// // Build an ActivityRecord object -// ActivityRecord activityRecord = ActivityRecord( -// startTime: startTime, -// endTime: endTime, -// id: 'ActivityRecordId0', -// name: 'AddActivityRecord', -// activityTypeId: HiHealthActivities.running, -// description: 'This is a test for ActivityRecord', -// activitySummary: ActivitySummary( -// paceSummary: PaceSummary( -// avgPace: 247.27626, -// bestPace: 212.0, -// britishPaceMap: { -// '102802480': 365.0, -// }, -// britishPartTimeMap: { -// '1.0': 263.0, -// }, -// partTimeMap: { -// '1.0': 456.0, -// }, -// paceMap: { -// '1.0': 263.0, -// }, -// ), -// dataSummary: [ -// SamplePoint( -// dataType: DataType.DT_CONTINUOUS_DISTANCE_TOTAL, -// startTime: startTime.add(Duration(seconds: 1)), -// endTime: endTime.subtract(Duration(seconds: 1)), -// fieldValueOptions: FieldFloat(Field.FIELD_DISTANCE, 400), -// timeUnit: TimeUnit.MILLISECONDS, -// ), -// SamplePoint( -// dataType: DataType.POLYMERIZE_CONTINUOUS_SPEED_STATISTICS, -// fieldValueOptions: FieldFloat(Field.FIELD_AVG, 60.0), -// startTime: startTime.add(Duration(seconds: 1)), -// endTime: endTime.subtract(Duration(seconds: 1)), -// timeUnit: TimeUnit.MILLISECONDS, -// ) -// ..setFieldValue(Field.FIELD_MIN, 40.0) -// ..setFieldValue(Field.FIELD_MAX, 80.0), -// ]), -// ); -// -// // Build the dataCollector object -// DataCollector dataCollector = DataCollector( -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// dataType: DataType.DT_INSTANTANEOUS_STEPS_RATE, -// name: 'AddActivityRecord1923', -// ); -// -// // You can use sampleSets to add more sample points to the sampling dataset. -// // Build a list of sampling point objects and add it to the sampling dataSet -// List samplePoints = [ -// SamplePoint( -// dataCollector: dataCollector, -// startTime: startTime.add(Duration(seconds: 1)), -// endTime: endTime.subtract(Duration(seconds: 1)), -// fieldValueOptions: FieldFloat(Field.FIELD_STEP_RATE, 10.0), -// timeUnit: TimeUnit.MILLISECONDS, -// ), -// ]; -// SampleSet sampleSet = SampleSet( -// dataCollector, -// samplePoints, -// ); -// -// try { -// await ActivityRecordsController.addActivityRecord( -// ActivityRecordInsertOptions( -// activityRecord: activityRecord, -// sampleSets: [ -// sampleSet, -// ], -// ), -// ); -// log( -// 'addActivityRecord', -// _activityTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'addActivityRecord', -// _activityTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Obtains saved ActivityRecords between yesterday and now, -// /// with the DT_CONTINUOUS_STEPS_DELTA data type -// void getActivityRecord() async { -// log( -// 'getActivityRecord', -// _activityTextController, -// LogOptions.call, -// ); -// // Create start time that will be used to read activity record. -// DateTime startTime = DateTime.now().subtract(const Duration(days: 1)); -// -// // Create end time that will be used to read activity record. -// DateTime endTime = DateTime.now().add(const Duration(hours: 3)); -// -// ActivityRecordReadOptions activityRecordReadOptions = ActivityRecordReadOptions( -// activityRecordId: "ActivityRecordId0", -// activityRecordName: null, -// startTime: startTime, -// endTime: endTime, -// timeUnit: TimeUnit.MILLISECONDS, -// dataType: DataType.DT_INSTANTANEOUS_STEPS_RATE, -// ); -// try { -// List result = await ActivityRecordsController.getActivityRecord( -// activityRecordReadOptions, -// ); -// log( -// 'getActivityRecord', -// _activityTextController, -// LogOptions.success, -// result: '[IDs: ${result.map((ActivityRecord e) => e.id).toList()}]', -// ); -// } on PlatformException catch (e) { -// log( -// 'getActivityRecord', -// _activityTextController, -// LogOptions.error, -// result: e.message, -// ); -// } -// } -// -// /// Starts the ActivityRecord with the id:`ActivityRecordRun1` -// void beginActivityRecord() async { -// try { -// log( -// 'beginActivityRecord', -// _activityTextController, -// LogOptions.call, -// ); -// // Build an ActivityRecord object -// ActivityRecord activityRecord = ActivityRecord( -// id: 'ActivityRecordRun0', -// name: 'BeginActivityRecord', -// description: 'This is ActivityRecord begin test!', -// activityTypeId: HiHealthActivities.running, -// startTime: DateTime.now().subtract(const Duration(hours: 1)), -// ); -// await ActivityRecordsController.beginActivityRecord( -// activityRecord, -// ); -// log( -// 'beginActivityRecord', -// _activityTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'beginActivityRecord', -// _activityTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Stops the ActivityRecord with the id:`ActivityRecordRun1` -// void endActivityRecord() async { -// try { -// log( -// 'endActivityRecord', -// _activityTextController, -// LogOptions.call, -// ); -// final List result = await ActivityRecordsController.endActivityRecord( -// 'ActivityRecordRun0', -// ); -// // Return the list of activity records that have stopped -// log( -// 'endActivityRecord', -// _activityTextController, -// LogOptions.success, -// result: result.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'endActivityRecord', -// _activityTextController, -// LogOptions.error, -// result: e.message, -// ); -// } -// } -// -// /// Ends all the ongoing activity records. -// /// -// /// Result list will be null if there is no ongoing activity record. -// void endAllActivityRecords() async { -// try { -// log( -// 'endAllActivityRecords', -// _activityTextController, -// LogOptions.call, -// ); -// // Return the list of activity records that have stopped -// List result = await ActivityRecordsController.endAllActivityRecords(); -// log( -// 'endAllActivityRecords', -// _activityTextController, -// LogOptions.success, -// result: '[IDs: ${result.map((ActivityRecord e) => e.id).toList()}]', -// ); -// } on PlatformException catch (e) { -// log( -// 'endAllActivityRecords', -// _activityTextController, -// LogOptions.error, -// result: e.message, -// ); -// } -// } -// -// // -// // -// // End of ActivityRecordsController Methods -// -// // DataController Methods -// // -// // -// /// Initializes a DataController instance with a list of HiHealtOptions. -// void initDataController() async { -// if (!mounted) return; -// log( -// 'init', -// _dataTextController, -// LogOptions.call, -// ); -// try { -// _dataController = await DataController.init(); -// log( -// 'init', -// _dataTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'init', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Clears all the data inserted by the app. -// void clearAll() async { -// log('clearAll', _dataTextController, LogOptions.call); -// try { -// await _dataController.clearAll(); -// log('clearAll', _dataTextController, LogOptions.success); -// } on PlatformException catch (e) { -// log('clearAll', _dataTextController, LogOptions.error, error: e.message); -// } -// } -// -// /// Deletes DT_CONTINUOUS_STEPS_DELTA type data by the specified time range. -// void delete() async { -// log( -// 'delete', -// _dataTextController, -// LogOptions.call, -// ); -// // Build the dataCollector object -// DataCollector dataCollector = DataCollector( -// dataType: DataType.DT_CONTINUOUS_STEPS_DELTA, -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// dataStreamName: 'STEPS_DELTA', -// ); -// -// // Build the time range for the deletion: start time and end time. -// DeleteOptions deleteOptions = DeleteOptions( -// dataCollectors: [dataCollector], -// startTime: DateTime.parse('2020-10-10 08:00:00'), -// endTime: DateTime.parse('2020-10-10 12:30:00'), -// ); -// -// // Call the api with the constructed DeleteOptions instance. -// try { -// _dataController.delete(deleteOptions); -// log( -// 'delete', -// _dataTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'delete', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Inserts a sampling set with the DT_CONTINUOUS_STEPS_DELTA data type at the -// /// specified start and end dates. -// void insert() async { -// log( -// 'insert', -// _dataTextController, -// LogOptions.call, -// ); -// // Build the dataCollector object -// DataCollector dataCollector = DataCollector( -// dataType: DataType.DT_CONTINUOUS_STEPS_DELTA, -// dataStreamName: 'STEPS_DELTA', -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// ); -// // You can use sampleSets to add more sampling points to the sampling dataset. -// SampleSet sampleSet = SampleSet( -// dataCollector, -// [ -// SamplePoint( -// dataCollector: dataCollector, -// startTime: DateTime.parse('2020-10-10 12:00:00'), -// endTime: DateTime.parse('2020-10-10 12:12:00'), -// fieldValueOptions: FieldInt( -// Field.FIELD_STEPS_DELTA, -// 100, -// ), -// ), -// ], -// ); -// // Call the api with the constructed sample set. -// try { -// _dataController.insert(sampleSet); -// log( -// 'insert', -// _dataTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'insert', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// // Reads the user data between the specified start and end dates. -// void read() async { -// log( -// 'read', -// _dataTextController, -// LogOptions.call, -// ); -// // Build the dataCollector object -// DataCollector dataCollector = DataCollector( -// dataType: DataType.DT_CONTINUOUS_STEPS_DELTA, -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// dataStreamName: 'STEPS_DELTA', -// ); -// -// // Build the time range for the query: start time and end time. -// ReadOptions readOptions = ReadOptions( -// dataCollectors: [ -// dataCollector, -// ], -// startTime: DateTime.parse('2020-10-10 12:00:00'), -// endTime: DateTime.parse('2020-10-10 12:12:00'), -// )..groupByTime(10000); -// -// // Call the api with the constructed ReadOptions instance. -// try { -// ReadReply? readReply = await _dataController.read(readOptions); -// log( -// 'read', -// _dataTextController, -// LogOptions.success, -// result: readReply.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'read', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Reads the daily summation between the dates: `2020.10.02` to `2020.12.15` for multiple data types. -// /// Note that the time format is different for this method. -// void readDailySummationList() async { -// log( -// 'readDailySummationList', -// _dataTextController, -// LogOptions.call, -// ); -// try { -// List? sampleSets = await _dataController.readDailySummationList( -// [DataType.DT_CONTINUOUS_STEPS_DELTA, DataType.DT_CONTINUOUS_CALORIES_BURNT], -// 20201002, -// 20201003, -// ); -// log( -// 'readDailySummationList', -// _dataTextController, -// LogOptions.success, -// result: sampleSets.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'readDailySummationList', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Reads the steps summation for today. -// void readTodaySummation() async { -// log( -// 'readTodaySummation', -// _dataTextController, -// LogOptions.call, -// ); -// try { -// SampleSet? sampleSet = await _dataController.readTodaySummation( -// DataType.DT_CONTINUOUS_STEPS_DELTA, -// ); -// log( -// 'readTodaySummation', -// _dataTextController, -// LogOptions.success, -// result: sampleSet.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'readTodaySummation', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Updates DT_CONTINUOUS_STEPS_DELTA for the specified dates. -// void update() async { -// log( -// 'update', -// _dataTextController, -// LogOptions.call, -// ); -// -// // Build the dataCollector object -// DataCollector dataCollector = DataCollector( -// dataType: DataType.DT_CONTINUOUS_STEPS_DELTA, -// dataStreamName: 'STEPS_DELTA', -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// ); -// -// // You can use sampleSets to add more sampling points to the sampling dataset. -// SampleSet sampleSet = SampleSet( -// dataCollector, -// [ -// SamplePoint( -// dataCollector: dataCollector, -// startTime: DateTime.parse('2020-12-12 09:00:00'), -// endTime: DateTime.parse('2020-12-12 09:05:00'), -// fieldValueOptions: FieldInt( -// Field.FIELD_STEPS_DELTA, -// 120, -// ), -// ), -// ], -// ); -// -// // Build a parameter object for the update. -// // Note: (1) The start time of the modified object updateOptions can not be greater than the minimum -// // value of the start time of all sample data points in the modified data sample set -// // (2) The end time of the modified object updateOptions can not be less than the maximum value of the -// // end time of all sample data points in the modified data sample set -// UpdateOptions updateOptions = UpdateOptions( -// startTime: DateTime.parse('2020-12-12 08:00:00'), -// endTime: DateTime.parse('2020-12-12 09:25:00'), -// sampleSet: sampleSet, -// ); -// try { -// await _dataController.update(updateOptions); -// log( -// 'update', -// _dataTextController, -// LogOptions.success, -// result: sampleSet.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'update', -// _dataTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// // -// // -// // End of DataController Methods -// -// // SettingController Methods -// // -// /// Adds a custom DataType with the FIELD_ALTITUDE. -// void addDataType() async { -// log( -// 'addDataType', -// _settingTextController, -// LogOptions.call, -// ); -// try { -// // The name of the created data type must be prefixed with the package name -// // of the app. Otherwise, the creation fails. If the same data type is tried to -// // be added again an exception will be thrown. -// DataTypeAddOptions options = DataTypeAddOptions( -// '$packageName.myCustomDataType', -// [ -// const Field.newIntField('myIntField'), -// Field.FIELD_ALTITUDE, -// ], -// ); -// final DataType dataTypeResult = await SettingController.addDataType( -// options, -// ); -// log( -// 'addDataType', -// _settingTextController, -// LogOptions.success, -// result: dataTypeResult.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'addDataType', -// _settingTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Reads the inserted data type on the [addDataType] method. -// void readDataType() async { -// log( -// 'readDataType', -// _settingTextController, -// LogOptions.call, -// ); -// try { -// final DataType dataTypeResult = await SettingController.readDataType( -// '$packageName.myCustomDataType', -// ); -// log( -// 'readDataType', -// _settingTextController, -// LogOptions.success, -// result: dataTypeResult.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'readDataType', -// _settingTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Disables the Health Kit function, cancels user authorization, and cancels -// /// all data records. (The task takes effect in 24 hours.) -// void disableHiHealth() async { -// log( -// 'disableHiHealth', -// _settingTextController, -// LogOptions.call, -// ); -// try { -// await SettingController.disableHiHealth(); -// log( -// 'disableHiHealth', -// _settingTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'disableHiHealth', -// _settingTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Checks the user privacy authorization to Health Kit. Redirects the user to -// /// the Authorization screen if the permissions are not given. -// void checkHealthAppAuthorization() async { -// log( -// 'checkHealthAppAuthorization', -// _settingTextController, -// LogOptions.call, -// ); -// try { -// await SettingController.checkHealthAppAuthorization(); -// log( -// 'checkHealthAppAuthorization', -// _settingTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'checkHealthAppAuthorization', -// _settingTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Checks the user privacy authorization to Health Kit. If authorized `true` -// /// value would be returned. -// void getHealthAppAuthorization() async { -// log( -// 'getHealthAppAuthorization', -// _settingTextController, -// LogOptions.call, -// ); -// try { -// final bool result = await SettingController.getHealthAppAuthorization(); -// log( -// 'getHealthAppAuthorization', -// _settingTextController, -// LogOptions.success, -// result: result.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'getHealthAppAuthorization', -// _settingTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// void requestAuth() async { -// final HealthKitAuthResult res = await SettingController.requestAuthorizationIntent( -// [ -// Scope.HEALTHKIT_STEP_READ, -// Scope.HEALTHKIT_STEP_WRITE, -// Scope.HEALTHKIT_HEIGHTWEIGHT_READ, -// Scope.HEALTHKIT_HEIGHTWEIGHT_WRITE, -// Scope.HEALTHKIT_HEARTRATE_READ, -// Scope.HEALTHKIT_HEARTRATE_WRITE, -// Scope.HEALTHKIT_ACTIVITY_RECORD_READ, -// Scope.HEALTHKIT_ACTIVITY_RECORD_WRITE, -// Scope.HEALTHKIT_HEARTHEALTH_READ, -// Scope.HEALTHKIT_HEARTHEALTH_WRITE, -// ], -// true, -// ); -// debugPrint(res.authAccount?.accessToken); -// } -// -// // -// // -// // End of SettingController Methods -// -// // AutoRecorderController Methods -// // -// // -// // Callback function for AutoRecorderStream event. -// void _onAutoRecorderEvent(SamplePoint? res) { -// log( -// '[AutoRecorderEvent] obtained, SamplePoint Field Value is ${res?.fieldValues?.toString()}', -// _autoRecorderTextController, -// LogOptions.custom, -// ); -// } -// -// /// Starts an Android Foreground Service to count the steps of the user. -// /// The steps will be emitted to the AutoRecorderStream. -// void startRecord() async { -// log( -// 'startRecord', -// _autoRecorderTextController, -// LogOptions.call, -// ); -// try { -// await AutoRecorderController.startRecord( -// DataType.DT_CONTINUOUS_STEPS_TOTAL, -// NotificationProperties( -// title: 'HMS Flutter Health Demo', -// text: 'Counting steps', -// subText: 'this is a subtext', -// ticker: 'this is a ticker', -// showChronometer: true, -// ), -// ); -// log( -// 'startRecord', -// _autoRecorderTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'startRecord', -// _autoRecorderTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Ends the Foreground service and stops the step count events. -// void stopRecord() async { -// log( -// 'endRecord', -// _autoRecorderTextController, -// LogOptions.call, -// ); -// try { -// await AutoRecorderController.stopRecord( -// DataType.DT_CONTINUOUS_STEPS_TOTAL, -// ); -// log( -// 'endRecord', -// _autoRecorderTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'endRecord', -// _autoRecorderTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// // -// // -// // End of AutoRecorderController Methods -// -// // ConsentController Methods -// // -// /// Obtains the application id from the agconnect-services.json file. -// void getAppId() async { -// log( -// 'getAppId', -// _consentTextController, -// LogOptions.call, -// ); -// try { -// final String appId = await ConsentsController.getAppId(); -// log( -// 'getAppId', -// _consentTextController, -// LogOptions.success, -// result: appId, -// ); -// } on PlatformException catch (e) { -// log( -// 'getAppId', -// _consentTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Gets the granted permission scopes for the app. -// void getScopes() async { -// log( -// 'getScopes', -// _consentTextController, -// LogOptions.call, -// ); -// try { -// final String appId = await ConsentsController.getAppId(); -// final ScopeLangItem scopeLangItem = await ConsentsController.getScopes( -// 'en-gb', -// appId, -// ); -// log( -// 'getScopes', -// _consentTextController, -// LogOptions.success, -// result: scopeLangItem.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'getScopes', -// _consentTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Revokes all the permissions that authorized for this app. -// void revoke() async { -// log( -// 'revoke', -// _consentTextController, -// LogOptions.call, -// ); -// try { -// final String appId = await ConsentsController.getAppId(); -// await ConsentsController.revoke(appId); -// log( -// 'revoke', -// _consentTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'revoke', -// _consentTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// /// Revokes the distance read/write permissions for the app. -// void revokeWithScopes() async { -// log( -// 'revokeWithScopes', -// _consentTextController, -// LogOptions.call, -// ); -// try { -// // Obtain the application id. -// final String appId = await ConsentsController.getAppId(); -// // Call the revokeWithScopes method with desired scopes. -// await ConsentsController.revokeWithScopes( -// appId, -// [ -// Scope.HEALTHKIT_DISTANCE_WRITE, -// Scope.HEALTHKIT_DISTANCE_READ, -// ], -// ); -// log( -// 'revokeWithScopes', -// _consentTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'revokeWithScopes', -// _consentTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// // -// // -// // End of ConsentController Methods -// -// // HealthController Methods -// // -// void addHealthRecord() async { -// log( -// 'addHealthRecord', -// _healthTextController, -// LogOptions.call, -// ); -// try { -// final DateTime startTime = DateTime(2023, 5, 11); -// final DateTime endTime = DateTime(2023, 5, 13); -// -// DataCollector contDataCollector = DataCollector( -// dataStreamName: 'contDataCollector', -// packageName: packageName, -// dataType: DataType.POLYMERIZE_CONTINUOUS_HEART_RATE_STATISTICS, -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// ); -// -// DataCollector instDataCollector = DataCollector( -// dataStreamName: 'instDataCollector', -// packageName: packageName, -// dataType: DataType.DT_INSTANTANEOUS_HEART_RATE, -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// ); -// -// List subDataDetails = [ -// SampleSet(instDataCollector, [ -// SamplePoint( -// dataCollector: instDataCollector, -// ) -// ..setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS) -// ..setFieldValue(Field.FIELD_BPM, 88.0) -// ]) -// ]; -// -// List subDataSummary = [ -// SamplePoint( -// dataCollector: contDataCollector, -// ) -// ..setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS) -// ..setFieldValue(Field.FIELD_AVG, 90.0) -// ..setFieldValue(Field.FIELD_MAX, 100.0) -// ..setFieldValue(Field.FIELD_MIN, 80.0) -// ..setFieldValue(Field.LAST, 85.0) -// ]; -// -// final HealthRecord healthRecord = HealthRecord( -// startTime: startTime, -// endTime: endTime, -// metadata: 'Data', -// dataCollector: DataCollector( -// dataStreamName: 'such as step count', -// packageName: packageName, -// dataType: HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA, -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// ), -// ) -// ..setSubDataSummary(subDataSummary) -// ..setSubDataDetails(subDataDetails) -// ..setFieldValue(HealthFields.FIELD_THRESHOLD, 42.0) -// ..setFieldValue(HealthFields.FIELD_MAX_HEART_RATE, 48.0) -// ..setFieldValue(HealthFields.FIELD_MIN_HEART_RATE, 42.0) -// ..setFieldValue(HealthFields.FIELD_AVG_HEART_RATE, 45.0); -// -// final String? result = await HealthRecordController.addHealthRecord( -// HealthRecordInsertOptions( -// healthRecord: healthRecord, -// ), -// ); -// log( -// 'addHealthRecord', -// _healthTextController, -// LogOptions.success, -// result: result.toString(), -// ); -// } on PlatformException catch (e) { -// log( -// 'addHealthRecord', -// _healthTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// void getHealthRecord() async { -// log( -// 'getHealthRecord', -// _healthTextController, -// LogOptions.call, -// ); -// try { -// final DateTime startTime = DateTime(2023, 5, 11); -// final DateTime endTime = DateTime(2023, 5, 13); -// -// HealthRecordReply result = await HealthRecordController.getHealthRecord( -// HealthRecordReadOptions( -// packageName: packageName, -// ) -// ..setSubDataTypeList( -// [ -// DataType.DT_INSTANTANEOUS_HEART_RATE, -// ], -// ) -// ..setTimeInterval( -// startTime, -// endTime, -// TimeUnit.MILLISECONDS, -// ) -// ..readByDataType( -// HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA, -// ) -// ..readHealthRecordsFromAllApps(), -// ); -// log( -// 'getHealthRecord', -// _healthTextController, -// LogOptions.success, -// result: result.healthRecords[0].toJson(), -// ); -// } on PlatformException catch (e) { -// log( -// 'getHealthRecord', -// _healthTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// void updateHealthRecord() async { -// log( -// 'updateHealthRecord', -// _healthTextController, -// LogOptions.call, -// ); -// try { -// final DateTime startTime = DateTime(2022, 10, 11); -// final DateTime endTime = DateTime(2022, 10, 12); -// final HealthRecord healthRecord = HealthRecord( -// startTime: startTime, -// endTime: endTime, -// metadata: 'Data', -// dataCollector: DataCollector( -// dataStreamName: 'such as step count', -// packageName: packageName, -// dataType: HealthDataTypes.DT_HEALTH_RECORD_BRADYCARDIA, -// dataGenerateType: DataGenerateType.DATA_TYPE_RAW, -// ), -// ) -// ..setFieldValue(HealthFields.FIELD_THRESHOLD, 41.9) -// ..setFieldValue(HealthFields.FIELD_MAX_HEART_RATE, 49.1) -// ..setFieldValue(HealthFields.FIELD_MIN_HEART_RATE, 41.1) -// ..setFieldValue(HealthFields.FIELD_AVG_HEART_RATE, 45.1); -// await HealthRecordController.updateHealthRecord( -// HealthRecordUpdateOptions( -// healthRecord: healthRecord, -// healthRecordId: '', -// ), -// ); -// log( -// 'updateHealthRecord', -// _healthTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'updateHealthRecord', -// _healthTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// void deleteHealthRecord() async { -// log( -// 'deleteHealthRecord', -// _healthTextController, -// LogOptions.call, -// ); -// try { -// await HealthRecordController.deleteHealthRecord( -// HealthRecordDeleteOptions( -// startTime: DateTime.now().subtract(const Duration(days: 14)), -// endTime: DateTime.now(), -// )..setHealthRecordIds( -// [ -// '', -// ], -// ), -// ); -// log( -// 'deleteHealthRecord', -// _healthTextController, -// LogOptions.success, -// ); -// } on PlatformException catch (e) { -// log( -// 'deleteHealthRecord', -// _healthTextController, -// LogOptions.error, -// error: e.message, -// ); -// } -// } -// -// // -// // -// // End of HealthController Methods -// -// // App's widgets. -// // -// // -// Widget expansionCard({ -// required String titleText, -// required List children, -// }) { -// return Card( -// margin: componentPadding, -// shape: RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10.0), -// ), -// child: ExpansionTile( -// title: Text( -// titleText, -// style: cardTitleTextStyle, -// ), -// children: children, -// ), -// ); -// } -// -// Widget loggingArea( -// TextEditingController moduleTextController, -// ) { -// return Column( -// children: [ -// Container( -// margin: componentPadding, -// padding: const EdgeInsets.all(8.0), -// height: 200, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(5.0), -// border: Border.all(color: Colors.black12), -// ), -// child: TextField( -// readOnly: true, -// maxLines: 15, -// controller: moduleTextController, -// decoration: const InputDecoration( -// enabledBorder: InputBorder.none, -// ), -// ), -// ), -// TextButton( -// child: const Text('Clear Log'), -// onPressed: () => setState(() { -// moduleTextController.text = ''; -// }), -// ) -// ], -// ); -// } -// -// void showSnackBar( -// String text, { -// Color color = Colors.blue, -// }) { -// final SnackBar snackBar = SnackBar( -// content: Text(text), -// backgroundColor: color, -// action: SnackBarAction( -// label: 'Close', -// textColor: Colors.white, -// onPressed: () { -// ScaffoldMessenger.of(context).removeCurrentSnackBar(); -// }, -// ), -// ); -// ScaffoldMessenger.of(context).showSnackBar(snackBar); -// } -// -// @override -// Widget build(BuildContext context) { -// return Scaffold( -// appBar: AppBar( -// backgroundColor: Colors.white, -// title: const Text( -// 'Huawei Health Kit', -// style: TextStyle( -// color: Colors.blue, -// fontWeight: FontWeight.bold, -// ), -// ), -// centerTitle: true, -// elevation: 0.0, -// actions: [ -// IconButton( -// onPressed: requestAuth, -// icon: const Icon(Icons.ac_unit), -// ), -// ], -// ), -// body: Builder( -// builder: (BuildContext context) { -// return ListView( -// physics: const BouncingScrollPhysics( -// parent: AlwaysScrollableScrollPhysics(), -// ), -// children: [ -// // Sign In Widgets -// Card( -// margin: componentPadding, -// shape: RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10.0), -// ), -// child: Column( -// mainAxisAlignment: MainAxisAlignment.center, -// children: [ -// const Padding( -// padding: componentPadding, -// child: Text( -// 'Tap to SignIn button to obtain the HMS Account to complete ' -// 'login and authorization, and then use other buttons ' -// 'to try the related API functions.', -// textAlign: TextAlign.center, -// ), -// ), -// const Padding( -// padding: componentPadding, -// child: Text( -// 'Note: If the login page is not displayed, change the package ' -// 'name, AppID, and configure the signature file by referring ' -// 'to the developer guide on the official website.', -// textAlign: TextAlign.center, -// style: TextStyle( -// color: Colors.blue, -// ), -// ), -// ), -// Container( -// padding: componentPadding, -// width: double.infinity, -// child: OutlinedButton( -// style: ButtonStyle( -// backgroundColor: MaterialStateProperty.all( -// Colors.blue, -// ), -// ), -// child: const Text( -// 'SignIn', -// style: TextStyle( -// color: Colors.white, -// ), -// ), -// onPressed: () => signIn(), -// ), -// ), -// ], -// ), -// ), -// -// // ActivityRecordsController -// expansionCard( -// titleText: 'ActivityRecords Controller', -// children: [ -// loggingArea(_activityTextController), -// ListTile( -// title: const Text('AddActivityRecord'), -// onTap: () => addActivityRecord(), -// ), -// ListTile( -// title: const Text('GetActivityRecord'), -// onTap: () => getActivityRecord(), -// ), -// ListTile( -// title: const Text('beginActivityRecord'), -// onTap: () => beginActivityRecord(), -// ), -// ListTile( -// title: const Text('endActivityRecord'), -// onTap: () => endActivityRecord(), -// ), -// ListTile( -// title: const Text('endAllActivityRecords'), -// onTap: () => endAllActivityRecords(), -// ), -// ], -// ), -// // DataController Widgets -// expansionCard( -// titleText: 'DataController', -// children: [ -// loggingArea(_dataTextController), -// ListTile( -// title: const Text('readTodaySummation'), -// onTap: () => readTodaySummation(), -// ), -// ListTile( -// title: const Text('readDailySummationList'), -// onTap: () => readDailySummationList(), -// ), -// ListTile( -// title: const Text('insert'), -// onTap: () => insert(), -// ), -// ListTile( -// title: const Text('read'), -// onTap: () => read(), -// ), -// ListTile( -// title: const Text('update'), -// onTap: () => update(), -// ), -// ListTile( -// title: const Text('delete'), -// onTap: () => delete(), -// ), -// ListTile( -// title: const Text('clearAll'), -// onTap: () => clearAll(), -// ), -// ], -// ), -// // SettingController Widgets. -// expansionCard( -// titleText: 'SettingController', -// children: [ -// loggingArea(_settingTextController), -// ListTile( -// title: const Text('addDataType'), -// onTap: () => addDataType(), -// ), -// ListTile( -// title: const Text('readDataType'), -// onTap: () => readDataType(), -// ), -// ListTile( -// title: const Text('disableHiHealth'), -// onTap: () => disableHiHealth(), -// ), -// ListTile( -// title: const Text('checkHealthAppAuthorization'), -// onTap: () => checkHealthAppAuthorization(), -// ), -// ListTile( -// title: const Text('getHealthAppAuthorization'), -// onTap: () => getHealthAppAuthorization(), -// ), -// ], -// ), -// // AutoRecorderController Widgets -// expansionCard( -// titleText: 'AutoRecorderController', -// children: [ -// loggingArea(_autoRecorderTextController), -// ListTile( -// title: const Text('startRecord'), -// onTap: () => startRecord(), -// ), -// ListTile( -// title: const Text('stopRecord'), -// onTap: () => stopRecord(), -// ), -// ], -// ), -// // Consent Controller Widgets -// expansionCard( -// titleText: 'ConsentController', -// children: [ -// loggingArea(_consentTextController), -// ListTile( -// title: const Text('getAppId'), -// onTap: () => getAppId(), -// ), -// ListTile( -// title: const Text('getScopes'), -// onTap: () => getScopes(), -// ), -// ListTile( -// title: const Text('revoke'), -// onTap: () => revoke(), -// ), -// ListTile( -// title: const Text('revokeWithScopes'), -// onTap: () => revokeWithScopes(), -// ), -// ], -// ), -// -// // Health Controller Widgets -// expansionCard( -// titleText: 'HealthController', -// children: [ -// loggingArea(_healthTextController), -// ListTile( -// title: const Text('addHealthRecord'), -// onTap: () => addHealthRecord(), -// ), -// ListTile( -// title: const Text('getHealthRecord'), -// onTap: () => getHealthRecord(), -// ), -// ListTile( -// title: const Text('updateHealthRecord'), -// onTap: () => updateHealthRecord(), -// ), -// ListTile( -// title: const Text('deleteHealthRecord'), -// onTap: () => deleteHealthRecord(), -// ), -// ], -// ), -// ], -// ); -// }, -// ), -// ); -// } -// } -// -// /// Options for logging. -// enum LogOptions { -// call, -// success, -// error, -// custom, -// } diff --git a/lib/presentation/smartwatches/smart_watch_activity.dart b/lib/presentation/smartwatches/smart_watch_activity.dart deleted file mode 100644 index f6c1baa6..00000000 --- a/lib/presentation/smartwatches/smart_watch_activity.dart +++ /dev/null @@ -1,252 +0,0 @@ -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/dependencies.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/smartwatch_health_data/health_provider.dart'; -import 'package:hmg_patient_app_new/presentation/smartwatches/activity_detail.dart'; -import 'package:hmg_patient_app_new/services/navigation_service.dart'; -import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; -import 'package:provider/provider.dart'; -import 'package:hmg_patient_app_new/features/smartwatch_health_data/HealthDataTransformation.dart' as durations; - -import '../../core/utils/date_util.dart' show DateUtil; - -class SmartWatchActivity extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: "All Health Data".needTranslation, - child: Column( - spacing: 16.h, - children: [ - resultItem( - leadingIcon: AppAssets.watchActivity, - title: "Activity Calories".needTranslation, - description: "Activity rings give you a quick visual reference of how active you are each day. ".needTranslation, - trailingIcon: AppAssets.watchActivityTrailing, - result: context.read().sumOfNonEmptyData(context.read().vitals?.activity??[]), - unitsOfMeasure: "Kcal" - ).onPress((){ - // Map> getVitals() { - // return { - // "heartRate": heartRate , - // "sleep": sleep, - // "steps": step, - // "activity": activity, - // "bodyOxygen": bodyOxygen, - // "bodyTemperature": bodyTemperature, - // }; - // } - context.read().setDurations(durations.Durations.daily); - - context.read().deleteDataIfSectionIsDifferent("activity"); - context.read().saveSelectedSection("activity"); - context.read().fetchData(); - context.read().navigateToDetails("activity", sectionName:"Activity Calories", uom: "Kcal"); - - }), - resultItem( - leadingIcon: AppAssets.watchSteps, - title: "Steps".needTranslation, - description: "Step count is the number of steps you take throughout the day.".needTranslation, - trailingIcon: AppAssets.watchStepsTrailing, - result: context.read().sumOfNonEmptyData(context.read().vitals?.step??[]), - unitsOfMeasure: "Steps" - ).onPress((){ - // Map> getVitals() { - // return { - // "heartRate": heartRate , - // "sleep": sleep, - // "steps": step, - // "activity": activity, - // "bodyOxygen": bodyOxygen, - // "bodyTemperature": bodyTemperature, - // }; - // } - context.read().setDurations(durations.Durations.daily); - - context.read().deleteDataIfSectionIsDifferent("steps"); - context.read().saveSelectedSection("steps"); - context.read().fetchData(); - context.read().navigateToDetails("steps", sectionName: "Steps", uom: "Steps"); - - }), - resultItem( - leadingIcon: AppAssets.watchSteps, - title: "Distance Covered".needTranslation, - description: "Step count is the distance you take throughout the day.".needTranslation, - trailingIcon: AppAssets.watchStepsTrailing, - result: context.read().sumOfNonEmptyData(context.read().vitals?.distance??[]), - unitsOfMeasure: "Km" - ).onPress((){ - // Map> getVitals() { - // return { - // "heartRate": heartRate , - // "sleep": sleep, - // "steps": step, - // "activity": activity, - // "bodyOxygen": bodyOxygen, - // "bodyTemperature": bodyTemperature, - // }; - // } - context.read().setDurations(durations.Durations.daily); - - context.read().deleteDataIfSectionIsDifferent("distance"); - context.read().saveSelectedSection("distance"); - context.read().fetchData(); - context.read().navigateToDetails("distance", sectionName: "Distance Covered", uom: "km"); - - }), - - resultItem( - leadingIcon: AppAssets.watchSleep, - title: "Sleep Score".needTranslation, - description: "This will keep track of how much hours you sleep in a day".needTranslation, - trailingIcon: AppAssets.watchSleepTrailing, - result: DateUtil.millisToHourMin(int.parse(context.read().firstNonEmptyValue(context.read().vitals?.sleep??[]))).split(" ")[0], - unitsOfMeasure: "hr", - resultSecondValue: DateUtil.millisToHourMin(int.parse(context.read().firstNonEmptyValue(context.read().vitals?.sleep??[]))).split(" ")[2], - unitOfSecondMeasure: "min" - ).onPress((){ - // Map> getVitals() { - // return { - // "heartRate": heartRate , - // "sleep": sleep, - // "steps": step, - // "activity": activity, - // "bodyOxygen": bodyOxygen, - // "bodyTemperature": bodyTemperature, - // }; - // } - context.read().setDurations(durations.Durations.daily); - - context.read().deleteDataIfSectionIsDifferent("sleep"); - context.read().saveSelectedSection("sleep"); - context.read().fetchData(); - context.read().navigateToDetails("sleep", sectionName:"Sleep Score",uom:""); - - }), - - resultItem( - leadingIcon: AppAssets.watchWeight, - title: "Blood Oxygen".needTranslation, - description: "This will calculate your Blood Oxygen to keep track and update history".needTranslation, - trailingIcon: AppAssets.watchWeightTrailing, - result: context.read().firstNonEmptyValue(context.read().vitals?.bodyOxygen??[], ), - unitsOfMeasure: "%" - ).onPress((){ - // Map> getVitals() { - // return { - // "heartRate": heartRate , - // "sleep": sleep, - // "steps": step, - // "activity": activity, - // "bodyOxygen": bodyOxygen, - // "bodyTemperature": bodyTemperature, - // }; - // } - context.read().setDurations(durations.Durations.daily); - - context.read().deleteDataIfSectionIsDifferent("bodyOxygen"); - context.read().saveSelectedSection("bodyOxygen"); - context.read().fetchData(); - context.read().navigateToDetails("bodyOxygen", uom: "%", sectionName:"Blood Oxygen" ); - - }), - resultItem( - leadingIcon: AppAssets.watchWeight, - title: "Body temperature".needTranslation, - description: "This will calculate your Body temprerature to keep track and update history".needTranslation, - trailingIcon: AppAssets.watchWeightTrailing, - result: context.read().firstNonEmptyValue(context.read().vitals?.bodyTemperature??[]), - unitsOfMeasure: "C" - ).onPress((){ - // Map> getVitals() { - // return { - // "heartRate": heartRate , - // "sleep": sleep, - // "steps": step, - // "activity": activity, - // "bodyOxygen": bodyOxygen, - // "bodyTemperature": bodyTemperature, - // }; - // } - context.read().setDurations(durations.Durations.daily); - - context.read().deleteDataIfSectionIsDifferent("bodyTemperature"); - context.read().saveSelectedSection("bodyTemperature"); - context.read().fetchData(); - context.read().navigateToDetails("bodyTemperature" , sectionName: "Body temperature".capitalizeFirstofEach, uom: "C"); - - }), - ], - ).paddingSymmetrical(24.w, 24.h), - )); - } - - Widget resultItem({ - required String leadingIcon, - required String title, - required String description, - required String trailingIcon, - required String result, - required String unitsOfMeasure, - String? resultSecondValue, - String? unitOfSecondMeasure - }) { - return DecoratedBox( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), - child: Row( - spacing: 16.w, - children: [ - Expanded( - child:Column( - spacing: 8.h, - children: [ - Row( - spacing: 8.w, - children: [ - Utils.buildSvgWithAssets(icon: leadingIcon, height: 16.h, width: 14.w), - title.toText16( weight: FontWeight.w600, color: AppColors.textColor), - ], - ), - description.toText12(isBold: true, color: AppColors.greyTextColor), - Row( - crossAxisAlignment: CrossAxisAlignment.baseline, - textBaseline: TextBaseline.alphabetic, - spacing: 2.h, - children: [ - result.toText21(isBold: true, color: AppColors.textColor), - unitsOfMeasure.toText10(isBold: true, color:AppColors.greyTextColor ), - if(resultSecondValue != null) - Visibility( - visible: resultSecondValue != null , - child: Row( - crossAxisAlignment: CrossAxisAlignment.baseline, - textBaseline: TextBaseline.alphabetic, - spacing: 2.h, - children: [ - SizedBox(width: 2.w,), - resultSecondValue.toText21(isBold: true, color: AppColors.textColor), - unitOfSecondMeasure!.toText10(isBold: true, color:AppColors.greyTextColor ) - ], - ), - ) - ], - ), - - ], - ) , - ), - Utils.buildSvgWithAssets(icon: trailingIcon, width: 72.w, height: 72.h), - ], - ).paddingSymmetrical(16.w, 16.h) - ); - } -} diff --git a/lib/presentation/smartwatches/smart_watches_health_data_screen.dart b/lib/presentation/smartwatches/smart_watches_health_data_screen.dart new file mode 100644 index 00000000..baa65b49 --- /dev/null +++ b/lib/presentation/smartwatches/smart_watches_health_data_screen.dart @@ -0,0 +1,188 @@ +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/smartwatch_health_data/health_data_transformations.dart' as durations; +import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_provider.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:provider/provider.dart'; + +import '../../core/utils/date_util.dart' show DateUtil; + +class SmartWatchesHealthDataScreen extends StatelessWidget { + const SmartWatchesHealthDataScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: "All Health Data".needTranslation, + child: Column( + spacing: 16.h, + children: [ + resultItem( + leadingIcon: AppAssets.watchActivity, + title: "Activity Calories".needTranslation, + description: "Activity rings give you a quick visual reference of how active you are each day. ".needTranslation, + trailingIcon: AppAssets.watchActivityTrailing, + result: context.read().sumOfNonEmptyData(context.read().vitals?.activity ?? []), + unitsOfMeasure: "Kcal") + .onPress(() { + context.read().setDurations(durations.Durations.daily); + context.read().deleteDataIfSectionIsDifferent("activity"); + context.read().saveSelectedSection("activity"); + context.read().fetchData(); + context.read().navigateToDetails("activity", sectionName: "Activity Calories", uom: "Kcal"); + }), + resultItem( + leadingIcon: AppAssets.watchSteps, + title: "Steps".needTranslation, + description: "Step count is the number of steps you take throughout the day.".needTranslation, + trailingIcon: AppAssets.watchStepsTrailing, + result: context.read().sumOfNonEmptyData(context.read().vitals?.step ?? []), + unitsOfMeasure: "Steps") + .onPress(() { + // Map> getVitals() { + // return { + // "heartRate": heartRate , + // "sleep": sleep, + // "steps": step, + // "activity": activity, + // "bodyOxygen": bodyOxygen, + // "bodyTemperature": bodyTemperature, + // }; + // } + context.read().setDurations(durations.Durations.daily); + context.read().deleteDataIfSectionIsDifferent("steps"); + context.read().saveSelectedSection("steps"); + context.read().fetchData(); + context.read().navigateToDetails("steps", sectionName: "Steps", uom: "Steps"); + }), + resultItem( + leadingIcon: AppAssets.watchSteps, + title: "Distance Covered".needTranslation, + description: "Step count is the distance you take throughout the day.".needTranslation, + trailingIcon: AppAssets.watchStepsTrailing, + result: context.read().sumOfNonEmptyData(context.read().vitals?.distance ?? []), + unitsOfMeasure: "Km") + .onPress(() { + context.read().setDurations(durations.Durations.daily); + context.read().deleteDataIfSectionIsDifferent("distance"); + context.read().saveSelectedSection("distance"); + context.read().fetchData(); + context.read().navigateToDetails("distance", sectionName: "Distance Covered", uom: "km"); + }), + resultItem( + leadingIcon: AppAssets.watchSleep, + title: "Sleep Score".needTranslation, + description: "This will keep track of how much hours you sleep in a day".needTranslation, + trailingIcon: AppAssets.watchSleepTrailing, + result: DateUtil.millisToHourMin( + int.parse(context.read().firstNonEmptyValue(context.read().vitals?.sleep ?? []))) + .split(" ")[0], + unitsOfMeasure: "hr", + resultSecondValue: DateUtil.millisToHourMin( + int.parse(context.read().firstNonEmptyValue(context.read().vitals?.sleep ?? []))) + .split(" ")[2], + unitOfSecondMeasure: "min") + .onPress(() { + context.read().setDurations(durations.Durations.daily); + context.read().deleteDataIfSectionIsDifferent("sleep"); + context.read().saveSelectedSection("sleep"); + context.read().fetchData(); + context.read().navigateToDetails("sleep", sectionName: "Sleep Score", uom: ""); + }), + resultItem( + leadingIcon: AppAssets.watchWeight, + title: "Blood Oxygen".needTranslation, + description: "This will calculate your Blood Oxygen to keep track and update history".needTranslation, + trailingIcon: AppAssets.watchWeightTrailing, + result: context.read().firstNonEmptyValue( + context.read().vitals?.bodyOxygen ?? [], + ), + unitsOfMeasure: "%") + .onPress(() { + context.read().setDurations(durations.Durations.daily); + context.read().deleteDataIfSectionIsDifferent("bodyOxygen"); + context.read().saveSelectedSection("bodyOxygen"); + context.read().fetchData(); + context.read().navigateToDetails("bodyOxygen", uom: "%", sectionName: "Blood Oxygen"); + }), + resultItem( + leadingIcon: AppAssets.watchWeight, + title: "Body temperature".needTranslation, + description: "This will calculate your Body temprerature to keep track and update history".needTranslation, + trailingIcon: AppAssets.watchWeightTrailing, + result: context.read().firstNonEmptyValue(context.read().vitals?.bodyTemperature ?? []), + unitsOfMeasure: "C") + .onPress(() { + context.read().setDurations(durations.Durations.daily); + context.read().deleteDataIfSectionIsDifferent("bodyTemperature"); + context.read().saveSelectedSection("bodyTemperature"); + context.read().fetchData(); + context.read().navigateToDetails("bodyTemperature", sectionName: "Body temperature".capitalizeFirstofEach, uom: "C"); + }), + ], + ).paddingSymmetrical(24.w, 24.h), + )); + } + + Widget resultItem({ + required String leadingIcon, + required String title, + required String description, + required String trailingIcon, + required String result, + required String unitsOfMeasure, + String? resultSecondValue, + String? unitOfSecondMeasure, + }) { + return DecoratedBox( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), + child: Row( + spacing: 16.w, + children: [ + Expanded( + child: Column( + spacing: 8.h, + children: [ + Row( + spacing: 8.w, + children: [ + Utils.buildSvgWithAssets(icon: leadingIcon, height: 16.h, width: 14.w), + title.toText16(weight: FontWeight.w600, color: AppColors.textColor), + ], + ), + description.toText12(isBold: true, color: AppColors.greyTextColor), + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + spacing: 2.h, + children: [ + result.toText21(isBold: true, color: AppColors.textColor), + unitsOfMeasure.toText10(isBold: true, color: AppColors.greyTextColor), + if (resultSecondValue != null) + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + spacing: 2.h, + children: [ + SizedBox(width: 2.w), + resultSecondValue.toText21(isBold: true, color: AppColors.textColor), + unitOfSecondMeasure!.toText10(isBold: true, color: AppColors.greyTextColor) + ], + ), + ], + ), + ], + ), + ), + Utils.buildSvgWithAssets(icon: trailingIcon, width: 72.w, height: 72.h), + ], + ).paddingSymmetrical(16.w, 16.h)); + } +} diff --git a/lib/presentation/smartwatches/smartwatch_home_page.dart b/lib/presentation/smartwatches/smartwatch_home_page.dart index 6016a803..7367af54 100644 --- a/lib/presentation/smartwatches/smartwatch_home_page.dart +++ b/lib/presentation/smartwatches/smartwatch_home_page.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -54,7 +52,6 @@ class SmartwatchHomePage extends StatelessWidget { fontSize: 16.f, isBold: true, borderRadius: 12.r, - height: 50.h, icon: AppAssets.ask_doctor_icon, iconColor: AppColors.infoColor, @@ -69,11 +66,12 @@ class SmartwatchHomePage extends StatelessWidget { child: GridView( padding: EdgeInsets.zero, shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, - crossAxisSpacing: 16.h, + crossAxisSpacing: 16.h, mainAxisSpacing: 16.w, - mainAxisExtent: 240.h, + childAspectRatio: isFoldable ? 1.1 : (isTablet ? 1.3 : 0.7), ), children: [ Container( @@ -83,20 +81,24 @@ class SmartwatchHomePage extends StatelessWidget { ), child: Column( children: [ - Image.asset("assets/images/png/smartwatches/apple-watch-5.jpg", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h), + Image.asset("assets/images/png/smartwatches/apple-watch-5.jpg", width: 136.h, height: 136.h).paddingSymmetrical(24.w, 8.h), "Apple Watch".needTranslation.toText16(isBold: true), CustomButton( text: LocaleKeys.selectSmartWatch.tr(context: context), onPressed: () { - context.read().setSelectedWatchType(SmartWatchTypes.apple, "assets/images/png/smartwatches/apple-watch-5.jpg"); - getIt.get().pushPage(page: SmartwatchInstructionsPage( - smartwatchDetails: SmartwatchDetails(SmartWatchTypes.apple, - "assets/images/png/smartwatches/apple-watch-5.jpg", - AppAssets.bluetooth, - LocaleKeys.applehealthapplicationshouldbeinstalledinyourphone.tr(context: context), - LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context), - LocaleKeys.applewatchshouldbeconnected.tr(context: context)), - )); + context + .read() + .setSelectedWatchType(SmartWatchTypes.apple, "assets/images/png/smartwatches/apple-watch-5.jpg"); + getIt.get().pushPage( + page: SmartwatchInstructionsPage( + smartwatchDetails: SmartwatchDetails( + SmartWatchTypes.apple, + "assets/images/png/smartwatches/apple-watch-5.jpg", + AppAssets.bluetooth, + LocaleKeys.applehealthapplicationshouldbeinstalledinyourphone.tr(context: context), + LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context), + LocaleKeys.applewatchshouldbeconnected.tr(context: context)), + )); }, backgroundColor: AppColors.primaryRedColor.withAlpha(40), borderColor: AppColors.primaryRedColor.withAlpha(0), @@ -110,26 +112,29 @@ class SmartwatchHomePage extends StatelessWidget { ), ), Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), child: Column( children: [ - Image.asset("assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", fit: BoxFit.contain, width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h), + Image.asset("assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", fit: BoxFit.contain, width: 136.w, height: 136.h) + .paddingSymmetrical(24.w, 8.h), "Samsung Watch".needTranslation.toText16(isBold: true), CustomButton( text: LocaleKeys.selectSmartWatch.tr(context: context), onPressed: () { - context.read().setSelectedWatchType(SmartWatchTypes.samsung, "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg"); - getIt.get().pushPage(page: SmartwatchInstructionsPage( - smartwatchDetails: SmartwatchDetails(SmartWatchTypes.samsung, - "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", - AppAssets.bluetooth, - LocaleKeys.samsunghealthapplicationshouldbeinstalledinyourphone.tr(context: context), - LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context), - LocaleKeys.samsungwatchshouldbeconnected.tr(context: context)), - )); }, + context + .read() + .setSelectedWatchType(SmartWatchTypes.samsung, "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg"); + getIt.get().pushPage( + page: SmartwatchInstructionsPage( + smartwatchDetails: SmartwatchDetails( + SmartWatchTypes.samsung, + "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", + AppAssets.bluetooth, + LocaleKeys.samsunghealthapplicationshouldbeinstalledinyourphone.tr(context: context), + LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context), + LocaleKeys.samsungwatchshouldbeconnected.tr(context: context)), + )); + }, backgroundColor: AppColors.primaryRedColor.withAlpha(40), borderColor: AppColors.primaryRedColor.withAlpha(0), textColor: AppColors.primaryRedColor, @@ -187,7 +192,6 @@ class SmartwatchHomePage extends StatelessWidget { CustomButton( text: LocaleKeys.selectSmartWatch.tr(context: context), onPressed: () { - showUnavailableDialog(context); // context.read().setSelectedWatchType(SmartWatchTypes.whoop, "assets/images/png/smartwatches/Whoop_Watch.png"); // getIt.get().pushPage(page: SmartwatchInstructionsPage( @@ -221,18 +225,16 @@ class SmartwatchHomePage extends StatelessWidget { } void showUnavailableDialog(BuildContext context) { - showCommonBottomSheetWithoutHeight( title: LocaleKeys.notice.tr(context: context), context, child: Utils.getWarningWidget( - loadingText: LocaleKeys.featureComingSoonDescription.tr(context: context), + loadingText: LocaleKeys.featureComingSoonDescription.tr(context: context), isShowActionButtons: false, showOkButton: true, onConfirmTap: () async { context.pop(); - } - ), + }), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, diff --git a/lib/presentation/smartwatches/smartwatch_instructions_page.dart b/lib/presentation/smartwatches/smartwatch_instructions_page.dart index 6a2aae29..a4f6c0c0 100644 --- a/lib/presentation/smartwatches/smartwatch_instructions_page.dart +++ b/lib/presentation/smartwatches/smartwatch_instructions_page.dart @@ -2,13 +2,10 @@ 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/common_models/smart_watch.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/extensions/string_extensions.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/smartwatches/smart_watch_activity.dart' show SmartWatchActivity; -import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; @@ -26,62 +23,66 @@ class SmartwatchInstructionsPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: "How does it work".needTranslation, - bottomChild: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - ), - child: CustomButton( - text: LocaleKeys.getStarted.tr(context: context), - onPressed: () { - context.read().initDevice(); - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: AppColors.whiteColor, - fontSize: 16.f, - isBold: true, - borderRadius: 12.r, - height: 50.h, - ).paddingSymmetrical(24.w, 30.h), + body: CollapsingListView( + title: "How does it work".needTranslation, + bottomChild: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, ), - child: Column( - mainAxisSize: MainAxisSize.max, - spacing: 18.h, - children: [ - Image.asset(smartwatchDetails.watchIcon, fit: BoxFit.contain, height: 280.h,width: 280.w,), - DecoratedBox( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), - child: Column( - children: [ - watchContentDetails( - title: smartwatchDetails.detailsTitle, - description: smartwatchDetails.details, - icon: smartwatchDetails.smallIcon, - descriptionTextColor: AppColors.primaryRedColor - ), - Divider( - color: AppColors.dividerColor, - thickness: 1.h, - ).paddingOnly(top: 16.h, bottom: 16.h), - watchContentDetails( - title: smartwatchDetails.secondTitle, - description: LocaleKeys.updatetheinformation.tr(), - icon: AppAssets.bluetooth, - descriptionTextColor: AppColors.greyTextColor - ), - ], - ).paddingSymmetrical(16.w, 16.h), - ) - ], - ).paddingSymmetrical(24.w, 16.h), + child: CustomButton( + text: LocaleKeys.getStarted.tr(context: context), + onPressed: () { + context.read().initDevice(); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16.f, + isBold: true, + borderRadius: 12.r, + height: 50.h, + ).paddingSymmetrical(24.w, 30.h), ), + child: Column( + mainAxisSize: MainAxisSize.max, + spacing: 18.h, + children: [ + Image.asset( + smartwatchDetails.watchIcon, + fit: BoxFit.contain, + height: 280.h, + width: 280.w, + ), + DecoratedBox( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), + child: Column( + children: [ + watchContentDetails( + title: smartwatchDetails.detailsTitle, + description: smartwatchDetails.details, + icon: smartwatchDetails.smallIcon, + descriptionTextColor: AppColors.primaryRedColor, + ), + Divider( + color: AppColors.dividerColor, + thickness: 1.h, + ).paddingOnly(top: 16.h, bottom: 16.h), + watchContentDetails( + title: smartwatchDetails.secondTitle, + description: LocaleKeys.updatetheinformation.tr(), + icon: AppAssets.bluetooth, + descriptionTextColor: AppColors.greyTextColor, + ), + ], + ).paddingSymmetrical(16.w, 16.h), + ) + ], + ).paddingSymmetrical(24.w, 16.h), + ), ); } - Widget watchContentDetails({required String title, required String description, required String icon, required Color descriptionTextColor}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -90,9 +91,7 @@ class SmartwatchInstructionsPage extends StatelessWidget { DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), child: Utils.buildSvgWithAssets(icon: icon, width: 40.w, height: 40.h), - ), - title.toText16(isBold: true, color: AppColors.textColor), description.toText12(isBold: true, color: descriptionTextColor) ], diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 41cb6331..861cf455 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -19,7 +19,6 @@ import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_procedures_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/servicesPriceList/services_price_list_page.dart'; -import 'package:hmg_patient_app_new/presentation/smartwatches/huawei_health_example.dart'; import 'package:hmg_patient_app_new/presentation/smartwatches/smartwatch_home_page.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/organ_selector_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/possible_conditions_screen.dart'; @@ -42,7 +41,6 @@ import '../features/monthly_reports/monthly_reports_repo.dart'; import '../features/monthly_reports/monthly_reports_view_model.dart'; import '../features/qr_parking/qr_parking_view_model.dart'; import '../presentation/parking/paking_page.dart'; -import '../presentation/smartwatches/smartwatch_instructions_page.dart'; import '../services/error_handler_service.dart'; class AppRoutes {