Design fixes on Fold

faiz_dev
faizatflutter 22 hours ago
parent cb299c5bca
commit 7b1684c455

@ -1,4 +1,3 @@
import 'dart:developer';
import 'dart:math' as math; import 'dart:math' as math;
import 'package:flutter/material.dart'; // These are the Viewport values of your Figma Design. 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 /// Check if device is likely a foldable
bool get _isFoldable { bool get _isFoldable {
double aspectRatio = _screenWidth / _screenHeight; double aspectRatio = _screenWidth / _screenHeight;
// Foldable devices typically have aspect ratios close to 1:1 when unfolded double shorterSide = _screenWidth < _screenHeight ? _screenWidth : _screenHeight;
return (aspectRatio > 0.9 && aspectRatio < 1.1) && (_screenWidth > 700 || _screenHeight > 700);
// 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 /// Scale text size - enhanced for foldable devices
@ -225,10 +230,16 @@ class SizeUtils {
deviceType = DeviceType.mobile; deviceType = DeviceType.mobile;
} }
log("longerSide: $longerSide"); debugPrint("============ Device Detection ============");
log("shorterSide: $shorterSide"); debugPrint("longerSide: $longerSide");
log("isTablet: $isTablet"); debugPrint("shorterSide: $shorterSide");
log("isFoldable: $isFoldable"); 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 { bool get isFoldable {
double aspectRatio = SizeUtils.width / SizeUtils.height; double aspectRatio = SizeUtils.width / SizeUtils.height;
// Foldable devices typically have aspect ratios close to 1:1 when unfolded double shorterSide = SizeUtils.width < SizeUtils.height ? SizeUtils.width : SizeUtils.height;
return (aspectRatio > 0.9 && aspectRatio < 1.1) && (SizeUtils.width > 700 || SizeUtils.height > 700);
// 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);
} }

@ -3,7 +3,7 @@ import 'dart:math';
import 'package:hmg_patient_app_new/core/common_models/data_points.dart'; import 'package:hmg_patient_app_new/core/common_models/data_points.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'model/Vitals.dart'; import 'model/vitals_data_model.dart';
enum Durations { enum Durations {
daily("daily"), daily("daily"),

@ -1,18 +1,17 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:health/health.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/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/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/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 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import '../../core/common_models/data_points.dart'; import 'health_data_transformations.dart';
import '../../core/dependencies.dart'; import 'model/vitals_data_model.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';
class HealthProvider with ChangeNotifier { class HealthProvider with ChangeNotifier {
final HealthService _healthService = HealthService(); final HealthService _healthService = HealthService();
@ -23,6 +22,7 @@ class HealthProvider with ChangeNotifier {
int selectedTabIndex = 0; int selectedTabIndex = 0;
SmartWatchTypes? selectedWatchType; SmartWatchTypes? selectedWatchType;
String selectedWatchURL = 'assets/images/png/smartwatches/apple-watch-5.jpg'; String selectedWatchURL = 'assets/images/png/smartwatches/apple-watch-5.jpg';
HealthDataTransformation healthDataTransformation = HealthDataTransformation(); HealthDataTransformation healthDataTransformation = HealthDataTransformation();
@ -90,7 +90,7 @@ class HealthProvider with ChangeNotifier {
healthData[type] = data; healthData[type] = data;
notifyListeners(); notifyListeners();
} catch (e) { } catch (e) {
print('Error refreshing metric $type: $e'); debugPrint('Error refreshing metric $type: $e');
} }
} }
@ -129,14 +129,12 @@ class HealthProvider with ChangeNotifier {
await getVitals(); await getVitals();
// LoaderBottomSheet.hideLoader(); // LoaderBottomSheet.hideLoader();
// await Future.delayed(Duration(seconds: 5)); // await Future.delayed(Duration(seconds: 5));
getIt.get<NavigationService>().pushPage(page: SmartWatchActivity()); getIt.get<NavigationService>().pushPage(page: SmartWatchesHealthDataScreen());
print('Device initialized successfully');
} }
notifyListeners(); notifyListeners();
} }
Future<void> getVitals() async { Future<void> getVitals() async {
final result = await _healthService.getVitals(); final result = await _healthService.getVitals();
vitals = result; vitals = result;
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
@ -186,15 +184,17 @@ class HealthProvider with ChangeNotifier {
} }
selectedData = yearly = healthDataTransformation.transformVitalsToDataPoints(vitals!, Durations.yearly.value, selectedSection); selectedData = yearly = healthDataTransformation.transformVitalsToDataPoints(vitals!, Durations.yearly.value, selectedSection);
break; break;
default:
{}
;
} }
notifyListeners(); notifyListeners();
} }
void navigateToDetails(String value, {required String sectionName, required String uom}) { void navigateToDetails(String value, {required String sectionName, required String uom}) {
getIt.get<NavigationService>().pushPage(page: ActivityDetails(selectedActivity: value, sectionName:sectionName, uom: uom,)); getIt.get<NavigationService>().pushPage(
page: ActivityDetails(
selectedActivity: value,
sectionName: sectionName,
uom: uom,
));
} }
void saveSelectedSection(String value) { void saveSelectedSection(String value) {
@ -243,7 +243,6 @@ class HealthProvider with ChangeNotifier {
count++; count++;
} }
}); });
print("total count is $count and total is $total");
averageValue = count > 0 ? total / count : null; averageValue = count > 0 ? total / count : null;
notifyListeners(); notifyListeners();
} }
@ -261,7 +260,7 @@ class HealthProvider with ChangeNotifier {
String firstNonEmptyValue(List<Vitals> dataPoints) { String firstNonEmptyValue(List<Vitals> dataPoints) {
try { try {
return dataPoints.firstWhere((dp) => dp.value != null && dp.value!.trim().isNotEmpty).value; return dataPoints.firstWhere((dp) => dp.value.trim().isNotEmpty).value;
} catch (e) { } catch (e) {
return "0"; // no non-empty value found return "0"; // no non-empty value found
} }

@ -5,7 +5,7 @@ import 'dart:io';
import 'package:health/health.dart'; import 'package:health/health.dart';
import 'package:hmg_patient_app_new/core/common_models/smart_watch.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/create_watch_helper.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/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'; import 'package:permission_handler/permission_handler.dart';

@ -16,11 +16,6 @@ class Vitals {
unitOfMeasure: map['uom'] ?? "", unitOfMeasure: map['uom'] ?? "",
); );
} }
toString(){
return "{\"value\": \"$value\", \"timeStamp\": \"$timestamp\", \"uom\": \"$unitOfMeasure\"}";
}
} }
class VitalsWRTType { class VitalsWRTType {
@ -38,8 +33,14 @@ class VitalsWRTType {
double maxBloodOxygen = double.negativeInfinity; double maxBloodOxygen = double.negativeInfinity;
double maxBodyTemperature = double.negativeInfinity; double maxBodyTemperature = double.negativeInfinity;
VitalsWRTType(
VitalsWRTType({required this.distance, required this.bodyOxygen, required this.bodyTemperature, required this.heartRate, required this.sleep, required this.step, required this.activity}); {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<dynamic, dynamic> map) { factory VitalsWRTType.fromMap(Map<dynamic, dynamic> map) {
List<Vitals> activity = []; List<Vitals> activity = [];
@ -86,7 +87,14 @@ class VitalsWRTType {
distance.add(data); 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<String, List<Vitals>> getVitals() { Map<String, List<Vitals>> getVitals() {

@ -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:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart' show WatchHelper;
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import '../model/Vitals.dart'; import '../model/vitals_data_model.dart';
class HealthConnectHelper extends WatchHelper { class HealthConnectHelper extends WatchHelper {
final Health health = Health(); final Health health = Health();

@ -364,10 +364,6 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
); );
// var isEventAddedOrRemoved = await CalenderUtilsNew.instance.checkAndRemove( id:"${widget.patientAppointmentHistoryResponseModel.appointmentNo}", );
// setState(() {
// myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel);
// });
}, },
onRescheduleTap: () async { onRescheduleTap: () async {
openDoctorScheduleCalendar(); openDoctorScheduleCalendar();
@ -507,67 +503,11 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
} }
}, },
) )
// 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) ).paddingSymmetrical(16.w, 0)
], ],
), ),
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
!AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) !AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? Column( ? Column(
@ -602,48 +542,6 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
SizedBox(height: 16.h), 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 //TODO Add countdown timer in case of LiveCare Appointment
@ -748,148 +646,6 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
); );
}), }),
SizedBox(height: 16.h), 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), SizedBox(height: 16.h),
], ],
) )
@ -900,7 +656,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
crossAxisCount: 3, crossAxisCount: 3,
crossAxisSpacing: 16.h, crossAxisSpacing: 16.h,
mainAxisSpacing: 16.w, mainAxisSpacing: 16.w,
mainAxisExtent: 115.h, childAspectRatio: isFoldable ? 1.2 : (isTablet ? 1.1 : 0.78),
), ),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
@ -1093,213 +849,6 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
], ],
); );
}), }),
// 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<PrescriptionsViewModel>(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), ).paddingAll(24.w),
), ),

@ -1,3 +1,5 @@
import 'dart:ui' as ui;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.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/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/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
@ -67,8 +67,8 @@ class AppointmentDoctorCard extends StatelessWidget {
Transform.translate( Transform.translate(
offset: Offset(0.0, -20.h), offset: Offset(0.0, -20.h),
child: Container( child: Container(
width: 40.w, width: 50.h,
height: 40.h, height: 50.h,
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
shape: BoxShape.circle, // Makes the container circular shape: BoxShape.circle, // Makes the container circular
@ -80,9 +80,10 @@ class AppointmentDoctorCard extends StatelessWidget {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ 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), 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), ).circle(100),
@ -97,9 +98,14 @@ class AppointmentDoctorCard extends StatelessWidget {
children: [ children: [
Row( Row(
children: [ 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), SizedBox(width: 12.w),
(patientAppointmentHistoryResponseModel.doctorNationalityFlagURL != null && patientAppointmentHistoryResponseModel.doctorNationalityFlagURL!.isNotEmpty) (patientAppointmentHistoryResponseModel.doctorNationalityFlagURL != null &&
patientAppointmentHistoryResponseModel.doctorNationalityFlagURL!.isNotEmpty)
? Image.network( ? Image.network(
patientAppointmentHistoryResponseModel.doctorNationalityFlagURL ?? "https://hmgwebservices.com/Images/flag/SAU.png", patientAppointmentHistoryResponseModel.doctorNationalityFlagURL ?? "https://hmgwebservices.com/Images/flag/SAU.png",
width: 20.h, width: 20.h,
@ -130,7 +136,8 @@ class AppointmentDoctorCard extends StatelessWidget {
child: AppCustomChipWidget( child: AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
icon: AppAssets.doctor_calendar_icon, 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), DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate),
false, false,
)}" )}"
@ -139,10 +146,15 @@ class AppointmentDoctorCard extends StatelessWidget {
), ),
AppCustomChipWidget( AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), 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, iconColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white,
labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? LocaleKeys.livecare.tr(context: context) : LocaleKeys.walkin.tr(context: context), labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment!
backgroundColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor, ? LocaleKeys.livecare.tr(context: context)
: LocaleKeys.walkin.tr(context: context),
backgroundColor:
!patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor,
textColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white, textColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white,
), ),
], ],
@ -150,10 +162,12 @@ class AppointmentDoctorCard extends StatelessWidget {
], ],
), ),
), ),
patientAppointmentHistoryResponseModel.isLiveCareAppointment! ||
patientAppointmentHistoryResponseModel.isLiveCareAppointment! || patientAppointmentHistoryResponseModel.isClinicReBookingAllowed! ==false || patientAppointmentHistoryResponseModel.isActiveDoctor! == false patientAppointmentHistoryResponseModel.isClinicReBookingAllowed! == false ||
patientAppointmentHistoryResponseModel.isActiveDoctor! == false
? SizedBox.shrink() ? 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(); DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel();
selectedDoctor.doctorID = patientAppointmentHistoryResponseModel.doctorID; selectedDoctor.doctorID = patientAppointmentHistoryResponseModel.doctorID;
selectedDoctor.doctorImageURL = patientAppointmentHistoryResponseModel.doctorImageURL; selectedDoctor.doctorImageURL = patientAppointmentHistoryResponseModel.doctorImageURL;
@ -197,8 +211,7 @@ class AppointmentDoctorCard extends StatelessWidget {
AppointmentType.isArrived(patientAppointmentHistoryResponseModel), AppointmentType.isArrived(patientAppointmentHistoryResponseModel),
), ),
), ),
if (timerWidget != null) if (timerWidget != null) timerWidget ?? SizedBox()
timerWidget ?? SizedBox()
], ],
), ),
), ),

@ -92,7 +92,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
// ], // ],
// ), // ),
SizedBox( SizedBox(
height: 350.h, height: MediaQuery.of(context).size.height * 0.45,
child: Directionality( child: Directionality(
textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr, textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr,
child: Localizations.override( child: Localizations.override(
@ -102,7 +102,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
controller: _calendarController, controller: _calendarController,
minDate: DateTime.now(), minDate: DateTime.now(),
showNavigationArrow: true, showNavigationArrow: true,
headerHeight: 60.h, // headerHeight: 60.h,
headerStyle: CalendarHeaderStyle( headerStyle: CalendarHeaderStyle(
backgroundColor: AppColors.transparent, backgroundColor: AppColors.transparent,
textAlign: isArabic ? TextAlign.end : TextAlign.start, textAlign: isArabic ? TextAlign.end : TextAlign.start,
@ -157,8 +157,11 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
), ),
//TODO: Add Next Day Span here //TODO: Add Next Day Span here
dayEvents.isNotEmpty dayEvents.isNotEmpty
? SizedBox( ? ConstrainedBox(
height: 100.h, constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.15,
minHeight: 0,
),
child: Directionality( child: Directionality(
textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr, textDirection: isArabic ? ui.TextDirection.rtl : ui.TextDirection.ltr,
child: SingleChildScrollView( child: SingleChildScrollView(
@ -169,7 +172,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
spacing: 6.h, spacing: 6.h,
runSpacing: 6.h, runSpacing: 6.h,
children: List.generate( children: List.generate(
dayEvents.length, // Generate a large number of items to ensure scrolling dayEvents.length,
(index) => TimeSlotChip( (index) => TimeSlotChip(
label: dayEvents[index].isoTime!, label: dayEvents[index].isoTime!,
isSelected: index == selectedButtonIndex, isSelected: index == selectedButtonIndex,
@ -204,7 +207,8 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
), ),
); );
} else { } 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); bookAppointmentsViewModel.setSelectedAppointmentDateTime(selectedDate, selectedTime, selectedDateDisplay);
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).push( Navigator.of(context).push(
@ -221,7 +225,8 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ 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), SizedBox(height: 8.h),
(LocaleKeys.loginToUseService.tr(context: context)).toText16(color: AppColors.blackColor), (LocaleKeys.loginToUseService.tr(context: context)).toText16(color: AppColors.blackColor),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -320,7 +325,12 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
selectedButtonIndex = 0; selectedButtonIndex = 0;
List<Map<String, dynamic>> timeList = []; List<Map<String, dynamic>> timeList = [];
for (var i = 0; i < dayEvents.length; i++) { for (var i = 0; i < dayEvents.length; i++) {
Map<String, dynamic> timeSlot = {"isoTime": dayEvents[i].isoTime, "start": dayEvents[i].start.toString(), "end": dayEvents[i].end.toString(), "vidaDate": dayEvents[i].vidaDate}; Map<String, dynamic> timeSlot = {
"isoTime": dayEvents[i].isoTime,
"start": dayEvents[i].start.toString(),
"end": dayEvents[i].end.toString(),
"vidaDate": dayEvents[i].vidaDate
};
timeList.add(timeSlot); timeList.add(timeSlot);
} }
if (dayEvents.isNotEmpty) { if (dayEvents.isNotEmpty) {
@ -333,9 +343,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
final DateFormat formatter = DateFormat('yyyy-MM-dd', "en-US"); final DateFormat formatter = DateFormat('yyyy-MM-dd', "en-US");
final isArabic = appState.isArabic(); final isArabic = appState.isArabic();
setState(() { setState(() {
selectedDateDisplay = isArabic selectedDateDisplay = isArabic ? DateUtil.getMonthDayYearDateFormattedAr(day) : DateUtil.getMonthDayYearDateFormatted(day);
? DateUtil.getMonthDayYearDateFormattedAr(day)
: DateUtil.getMonthDayYearDateFormatted(day);
selectedNextDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day.add(Duration(days: 1)), isArabic ? "ar" : "en"); selectedNextDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day.add(Duration(days: 1)), isArabic ? "ar" : "en");
_calendarController.selectedDate = day; _calendarController.selectedDate = day;
openTimeSlotsPickerForDate(day, bookAppointmentsViewModel.docFreeSlots); openTimeSlotsPickerForDate(day, bookAppointmentsViewModel.docFreeSlots);

@ -1,12 +1,10 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.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_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.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/app_state.dart';
import 'package:hmg_patient_app_new/core/enums.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/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.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/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/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/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/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/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/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/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/water_monitor/water_monitor_view_model.dart';
import 'package:hmg_patient_app_new/features/weather/weather_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/habib_wallet_page.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_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/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/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/service_info_page.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.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/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/presentation/servicesPriceList/services_price_list_page.dart';
import 'package:hmg_patient_app_new/services/dialog_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/services/navigation_service.dart';
@ -49,8 +43,6 @@ import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../core/dependencies.dart' show getIt; 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 { class ServicesPage extends StatefulWidget {
bool showBackIcon; bool showBackIcon;
@ -69,7 +61,14 @@ class _ServicesPageState extends State<ServicesPage> {
late WeatherMonitorViewModel weatherVM; late WeatherMonitorViewModel weatherVM;
late final List<HmgServicesComponentModel> hmgServices = [ late final List<HmgServicesComponentModel> 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<AppState>().isAuthenticated) { // if (getIt.get<AppState>().isAuthenticated) {
// getIt.get<EmergencyServicesViewModel>().flushData(); // getIt.get<EmergencyServicesViewModel>().flushData();
// getIt.get<EmergencyServicesViewModel>().getTransportationOrders( // getIt.get<EmergencyServicesViewModel>().getTransportationOrders(
@ -88,11 +87,19 @@ class _ServicesPageState extends State<ServicesPage> {
// await getIt.get<AuthenticationViewModel>().onLoginPressed(); // await getIt.get<AuthenticationViewModel>().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<BookAppointmentsViewModel>().onTabChanged(0); getIt.get<BookAppointmentsViewModel>().onTabChanged(0);
Navigator.of(getIt<NavigationService>().navigatorKey.currentContext!).push(CustomPageRoute(page: BookAppointmentPage())); Navigator.of(getIt<NavigationService>().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<AppState>().isAuthenticated) { if (getIt.get<AppState>().isAuthenticated) {
getIt.get<NavigationService>().pushPageRoute(AppRoutes.comprehensiveCheckupPage); getIt.get<NavigationService>().pushPageRoute(AppRoutes.comprehensiveCheckupPage);
} else { } else {
@ -152,7 +159,8 @@ class _ServicesPageState extends State<ServicesPage> {
// ); // );
// }, // },
// ), // ),
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<AppState>().isAuthenticated) { if (getIt.get<AppState>().isAuthenticated) {
getIt.get<NavigationService>().pushPageRoute(AppRoutes.eReferralPage); getIt.get<NavigationService>().pushPageRoute(AppRoutes.eReferralPage);
} else { } else {
@ -409,8 +417,7 @@ class _ServicesPageState extends State<ServicesPage> {
AppAssets.youtube, AppAssets.youtube,
bgColor: AppColors.whiteColor, bgColor: AppColors.whiteColor,
true, true,
onTap:()=> launchUrl(Uri.parse("https://www.youtube.com/c/DrsulaimanAlhabibHospitals")) onTap: () => launchUrl(Uri.parse("https://www.youtube.com/c/DrsulaimanAlhabibHospitals"))),
),
HmgServicesComponentModel( HmgServicesComponentModel(
104, 104,
LocaleKeys.connectOnLinkedin.tr(), LocaleKeys.connectOnLinkedin.tr(),
@ -420,7 +427,6 @@ class _ServicesPageState extends State<ServicesPage> {
true, 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 @override
@ -431,8 +437,6 @@ class _ServicesPageState extends State<ServicesPage> {
weatherVM.initiateFetchWeather(); weatherVM.initiateFetchWeather();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bloodDonationViewModel = Provider.of<BloodDonationViewModel>(context); bloodDonationViewModel = Provider.of<BloodDonationViewModel>(context);
@ -455,10 +459,8 @@ class _ServicesPageState extends State<ServicesPage> {
SizedBox(height: 16.h), SizedBox(height: 16.h),
GridView.builder( GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row crossAxisCount: (isFoldable || isTablet) ? 5 : 4, // 4 icons per row
crossAxisSpacing: 21.w, ),
mainAxisSpacing: 18.h,
childAspectRatio: 80 / 94),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: hmgServices.length, itemCount: hmgServices.length,
@ -470,8 +472,11 @@ class _ServicesPageState extends State<ServicesPage> {
SizedBox(height: 24.h), SizedBox(height: 24.h),
LocaleKeys.hmgServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), LocaleKeys.hmgServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0),
SizedBox(height: 16.h), SizedBox(height: 16.h),
SizedBox( ConstrainedBox(
height: 350.h, constraints: BoxConstraints(
minHeight: 320.h,
maxHeight: isFoldable ? 400.h : (isTablet ? 360.h : 340.h),
),
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getServiceCardsList.length, itemCount: LandingPageData.getServiceCardsList.length,
@ -527,14 +532,17 @@ class _ServicesPageState extends State<ServicesPage> {
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false),
LocaleKeys.habibWallet.tr().toText14(isBold: true, maxlines: 2).expanded, LocaleKeys.habibWallet.tr().toText14(isBold: true, maxlines: 2).expanded,
Utils.buildSvgWithAssets(icon: getIt.get<AppState>().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), Utils.buildSvgWithAssets(
icon: getIt.get<AppState>().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward),
], ],
), ),
Spacer(), Spacer(),
getIt.get<AppState>().isAuthenticated getIt.get<AppState>().isAuthenticated
? Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) { ? Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return Utils.getPaymentAmountWithSymbol2(num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)), return Utils.getPaymentAmountWithSymbol2(
isExpanded: false, letterSpacing: -1) num.parse(NumberFormat.decimalPattern().format(habibWalletVM.habibWalletAmount)),
isExpanded: false,
letterSpacing: -1)
.toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h);
}) })
: LocaleKeys.loginToViewWalletBalance.tr().toText12(isBold: true, maxLine: 2), : LocaleKeys.loginToViewWalletBalance.tr().toText12(isBold: true, maxLine: 2),
@ -586,9 +594,11 @@ class _ServicesPageState extends State<ServicesPage> {
spacing: 8.w, spacing: 8.w,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h, applyThemeColor: false), 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, LocaleKeys.familyTitle.tr().toText16(isBold: true, maxlines: 2).expanded,
Utils.buildSvgWithAssets(icon: getIt.get<AppState>().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), Utils.buildSvgWithAssets(
icon: getIt.get<AppState>().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward),
], ],
), ),
Spacer(), Spacer(),
@ -681,10 +691,8 @@ class _ServicesPageState extends State<ServicesPage> {
SizedBox(height: 16.h), SizedBox(height: 16.h),
GridView.builder( GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row crossAxisCount: (isFoldable || isTablet) ? 5 : 4, // 4 icons per row
crossAxisSpacing: 21.w,
mainAxisSpacing: 18.h, mainAxisSpacing: 18.h,
childAspectRatio: 80.w / 94.h,
), ),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
@ -705,73 +713,6 @@ class _ServicesPageState extends State<ServicesPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ 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<QrParkingViewModel>(),
// child: const ParkingPage(),
// ),
// ),
// );
// }),
// ),
// ),
// ),
// ],
// ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Row(
children: [ children: [
@ -788,7 +729,7 @@ class _ServicesPageState extends State<ServicesPage> {
children: [ children: [
Utils.buildSvgWithAssets( Utils.buildSvgWithAssets(
icon: AppAssets.latest_news_icon, icon: AppAssets.latest_news_icon,
width: 32.w, width: 32.h,
height: 32.h, height: 32.h,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
@ -817,7 +758,7 @@ class _ServicesPageState extends State<ServicesPage> {
children: [ children: [
Utils.buildSvgWithAssets( Utils.buildSvgWithAssets(
icon: AppAssets.hmg_contact_icon, icon: AppAssets.hmg_contact_icon,
width: 32.w, width: 32.h,
height: 32.h, height: 32.h,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
@ -854,7 +795,8 @@ class _ServicesPageState extends State<ServicesPage> {
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Row( child: Row(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor), Utils.buildSvgWithAssets(
icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded(child: LocaleKeys.termsConditoins.tr().toText14(isBold: true)) Expanded(child: LocaleKeys.termsConditoins.tr().toText14(isBold: true))
], ],
@ -878,7 +820,8 @@ class _ServicesPageState extends State<ServicesPage> {
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Row( child: Row(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor), Utils.buildSvgWithAssets(
icon: AppAssets.privacy_terms, width: 32.w, height: 32.h, fit: BoxFit.contain, iconColor: AppColors.blackColor),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded(child: LocaleKeys.privacyPolicy.tr().toText14(isBold: true)) Expanded(child: LocaleKeys.privacyPolicy.tr().toText14(isBold: true))
], ],
@ -897,10 +840,8 @@ class _ServicesPageState extends State<ServicesPage> {
SizedBox(height: 16.h), SizedBox(height: 16.h),
GridView.builder( GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row crossAxisCount: (isFoldable || isTablet) ? 5 : 4, // 4 icons per row
crossAxisSpacing: 21.w,
mainAxisSpacing: 18.h, mainAxisSpacing: 18.h,
childAspectRatio: 80.w / 94.h,
), ),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'dart:ui' as ui;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.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/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.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/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/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/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/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/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/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/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/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_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/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/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/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/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/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/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/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/small_service_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.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/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/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/my_family/my_family.dart';
import 'package:hmg_patient_app_new/presentation/notifications/notifications_list_page.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/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/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/todo_page.dart';
import 'package:hmg_patient_app_new/presentation/todo_section/widgets/ancillary_orders_list.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/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/cache_service.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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.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/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.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/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/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:lottie/lottie.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:smooth_corner/smooth_corner.dart'; import 'package:smooth_corner/smooth_corner.dart';
import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart';
import 'dart:ui' as ui;
class LandingPage extends StatefulWidget { class LandingPage extends StatefulWidget {
const LandingPage({super.key}); const LandingPage({super.key});
@ -160,9 +149,12 @@ class _LandingPageState extends State<LandingPage> {
// Commented as per new requirement to remove rating popup from the app // Commented as per new requirement to remove rating popup from the app
if (!appState.isRatedVisible) { if (!appState.isRatedVisible) {
appointmentRatingViewModel.getLastRatingAppointment(onSuccess: (response) { appointmentRatingViewModel.getLastRatingAppointment(
onSuccess: (response) {
if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) { if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) {
appointmentRatingViewModel.getAppointmentDetails(appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!, appointmentRatingViewModel.appointmentRatedList.last.projectID!, appointmentRatingViewModel.getAppointmentDetails(
appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!,
appointmentRatingViewModel.appointmentRatedList.last.projectID!,
onSuccess: ((response) { onSuccess: ((response) {
appointmentRatingViewModel.setClinicOrDoctor(false); appointmentRatingViewModel.setClinicOrDoctor(false);
appointmentRatingViewModel.setTitle(LocaleKeys.rateDoctor.tr(context: context)); appointmentRatingViewModel.setTitle(LocaleKeys.rateDoctor.tr(context: context));
@ -222,15 +214,16 @@ class _LandingPageState extends State<LandingPage> {
controller: _scrollController, controller: _scrollController,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.only( 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) ? (MediaQuery.paddingOf(context).top + 70.h)
: kToolbarHeight + 0.h, : kToolbarHeight + 0.h,
bottom: 24), bottom: 24),
child: Column( child: Column(
spacing: 16.h, spacing: 16.h,
children: [ children: [
Row( Row(
spacing: 8.h, spacing: 8.h,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -275,8 +268,6 @@ class _LandingPageState extends State<LandingPage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
// spacing: 18.h, // spacing: 18.h,
children: [ children: [
Stack(clipBehavior: Clip.none, children: [ Stack(clipBehavior: Clip.none, children: [
if (appState.isAuthenticated) if (appState.isAuthenticated)
Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async { Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async {
@ -321,7 +312,9 @@ class _LandingPageState extends State<LandingPage> {
) )
: SizedBox.shrink(), : SizedBox.shrink(),
]), ]),
SizedBox(width: 24.w,), SizedBox(
width: 24.w,
),
Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() { Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() {
// openIndoorNavigationBottomSheet(context); // openIndoorNavigationBottomSheet(context);
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
@ -343,9 +336,16 @@ class _LandingPageState extends State<LandingPage> {
// ); // );
// }), // }),
!appState.isAuthenticated !appState.isAuthenticated
?Row(children: [ SizedBox(width: 24.w,), Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { ? 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')); context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA'));
})]) })
])
: SizedBox() : SizedBox()
], ],
); );
@ -480,14 +480,15 @@ class _LandingPageState extends State<LandingPage> {
// ), // ),
// ); // );
}, },
separatorBuilder: (BuildContext cxt, int index) => separatorBuilder: (BuildContext cxt, int index) => SizedBox(
SizedBox(
width: 10.w, width: 10.w,
), ),
), ),
) )
: SizedBox( : SizedBox(
height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space height: 255.h +
20 +
30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space
child: Builder( child: Builder(
builder: (context) { builder: (context) {
final int swiperItemCount = myAppointmentsVM.isMyAppointmentsLoading final int swiperItemCount = myAppointmentsVM.isMyAppointmentsLoading
@ -532,7 +533,8 @@ class _LandingPageState extends State<LandingPage> {
? _buildLiveCareRequestCard().paddingSymmetrical(24.h, 16.h) ? _buildLiveCareRequestCard().paddingSymmetrical(24.h, 16.h)
: Container( : Container(
width: double.infinity, 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( child: Padding(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Column( child: Column(
@ -632,7 +634,9 @@ class _LandingPageState extends State<LandingPage> {
LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true), LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true),
Row( Row(
children: [ children: [
LocaleKeys.viewMedicalFileLandingPage.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true), LocaleKeys.viewMedicalFileLandingPage
.tr(context: context)
.toText14(color: AppColors.primaryRedColor, isBold: true),
SizedBox(width: 2.h), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h),
], ],
@ -644,7 +648,6 @@ class _LandingPageState extends State<LandingPage> {
SizedBox(height: 16.h), SizedBox(height: 16.h),
Consumer(builder: (BuildContext context, TodoSectionViewModel todoSectionVM, Widget? child) { Consumer(builder: (BuildContext context, TodoSectionViewModel todoSectionVM, Widget? child) {
return Container( return Container(
// height: 121.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Column( child: Column(
children: [ children: [
@ -661,16 +664,15 @@ class _LandingPageState extends State<LandingPage> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.pendingAncillaryOrders.tr(context: context).toText14(color: AppColors.eReferralCardColor, isBold: true).paddingSymmetrical(24.h, 0.h), LocaleKeys.pendingAncillaryOrders
.tr(context: context)
.toText14(color: AppColors.eReferralCardColor, isBold: true)
.paddingSymmetrical(24.h, 0.h),
CustomButton( CustomButton(
text: LocaleKeys.view.tr(context: context), text: LocaleKeys.view.tr(context: context),
onPressed: () { onPressed: () {
todoSectionVM.setIsAncillaryOrdersNeedReloading(true); todoSectionVM.setIsAncillaryOrdersNeedReloading(true);
Navigator.of(context).push( Navigator.of(context).push(CustomPageRoute(page: ToDoPage()));
CustomPageRoute(
page: ToDoPage(),
),
);
}, },
backgroundColor: AppColors.eReferralCardColor, backgroundColor: AppColors.eReferralCardColor,
borderColor: AppColors.eReferralCardColor, borderColor: AppColors.eReferralCardColor,
@ -696,11 +698,10 @@ class _LandingPageState extends State<LandingPage> {
trackColor: Color(0xffD9D9D9), trackColor: Color(0xffD9D9D9),
trackBorderColor: Colors.transparent, trackBorderColor: Colors.transparent,
trackRadius: Radius.circular(10.0), trackRadius: Radius.circular(10.0),
padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery padding: EdgeInsets.only(
.sizeOf(context) top: 92.h + 32.h,
.width / 2.5 - 10, right: MediaQuery left: MediaQuery.sizeOf(context).width / 2.5 - 10,
.sizeOf(context) right: MediaQuery.sizeOf(context).width / 2.5 - 10),
.width / 2.5 - 10),
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData().getLoggedInServiceCardsList.length, itemCount: LandingPageData().getLoggedInServiceCardsList.length,
@ -754,11 +755,10 @@ class _LandingPageState extends State<LandingPage> {
trackColor: Color(0xffD9D9D9), trackColor: Color(0xffD9D9D9),
trackBorderColor: Colors.transparent, trackBorderColor: Colors.transparent,
trackRadius: Radius.circular(10.0), trackRadius: Radius.circular(10.0),
padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery padding: EdgeInsets.only(
.sizeOf(context) top: 92.h + 32.h,
.width / 2.5 - 10, right: MediaQuery left: MediaQuery.sizeOf(context).width / 2.5 - 10,
.sizeOf(context) right: MediaQuery.sizeOf(context).width / 2.5 - 10),
.width / 2.5 - 10),
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, itemCount: LandingPageData.getNotLoggedInServiceCardsList.length,
@ -809,8 +809,8 @@ class _LandingPageState extends State<LandingPage> {
}), }),
], ],
).paddingSymmetrical(24.w, 0.h), ).paddingSymmetrical(24.w, 0.h),
SizedBox( ConstrainedBox(
height: 431.h, constraints: BoxConstraints(maxHeight: isFoldable ? 450.h : (isTablet ? 440.h : 431.h), minHeight: 411.h),
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getServiceCardsList.length, itemCount: LandingPageData.getServiceCardsList.length,
@ -862,7 +862,10 @@ class _LandingPageState extends State<LandingPage> {
), ),
), ),
), ),
(appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) (appState.isAuthenticated &&
!insuranceVM.isInsuranceLoading &&
insuranceVM.isInsuranceExpired &&
insuranceVM.isInsuranceExpiryBannerShown)
? Container( ? Container(
height: MediaQuery.paddingOf(context).top + 50.h, height: MediaQuery.paddingOf(context).top + 50.h,
decoration: ShapeDecoration( decoration: ShapeDecoration(
@ -879,17 +882,24 @@ class _LandingPageState extends State<LandingPage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ 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( Row(
children: [ children: [
CustomButton( CustomButton(
text: LocaleKeys.updateInsurance.tr(context: context), text: LocaleKeys.updateInsurance.tr(context: context),
onPressed: () { onPressed: () {
insuranceVM.setIsInsuranceUpdateDetailsLoading(true); insuranceVM.setIsInsuranceUpdateDetailsLoading(true);
insuranceVM.getPatientInsuranceDetailsForUpdate( insuranceVM.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(),
appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
showCommonBottomSheetWithoutHeight(context, showCommonBottomSheetWithoutHeight(context,
child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); child: PatientInsuranceCardUpdateCard(),
callBackFunc: () {},
title: "",
isCloseButtonVisible: false,
isFullScreen: false);
}, },
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.secondaryLightRedBorderColor, borderColor: AppColors.secondaryLightRedBorderColor,
@ -1029,7 +1039,8 @@ class _LandingPageState extends State<LandingPage> {
SizedBox(height: 6.h), SizedBox(height: 6.h),
_buildServingNowSection(), _buildServingNowSection(),
SizedBox(height: 5.h), 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<LandingPage> {
hasShadow: false, hasShadow: false,
), ),
padding: EdgeInsets.all(6.h), 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<LandingPage> {
height: 40.h, height: 40.h,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
iconSize: 18.h, iconSize: 18.h,
), ),
// _buildLiveCareWaitingTime(), // _buildLiveCareWaitingTime(),
], ],
@ -1238,7 +1249,8 @@ class _LandingPageState extends State<LandingPage> {
hasShadow: false, hasShadow: false,
), ),
padding: EdgeInsets.all(6.h), 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( // Utils.buildSvgWithAssets(
// icon: AppAssets.waiting_icon, // icon: AppAssets.waiting_icon,
// width: 24.h, // width: 24.h,
@ -1286,12 +1298,8 @@ class _LandingPageState extends State<LandingPage> {
// Appointment Card Wrapper (reusable) // Appointment Card Wrapper (reusable)
Widget _buildAppointmentCardWrapper(appointment) { Widget _buildAppointmentCardWrapper(appointment) {
return Container( return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration:
color: AppColors.whiteColor, RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true, hasDenseShadow: true),
borderRadius: 24.r,
hasShadow: true,
hasDenseShadow: true
),
child: AppointmentCard( child: AppointmentCard(
patientAppointmentHistoryResponseModel: appointment, patientAppointmentHistoryResponseModel: appointment,
myAppointmentsViewModel: myAppointmentsViewModel, myAppointmentsViewModel: myAppointmentsViewModel,
@ -1447,9 +1455,7 @@ class _DirectionalDotPaginationBuilder extends SwiperPlugin {
@override @override
Widget build(BuildContext context, SwiperPluginConfig config) { Widget build(BuildContext context, SwiperPluginConfig config) {
final int activeIndex = isRTL final int activeIndex = isRTL ? (totalCount - 1 - config.activeIndex) : config.activeIndex;
? (totalCount - 1 - config.activeIndex)
: config.activeIndex;
print("the index is $activeIndex"); print("the index is $activeIndex");
print("the config.activeIndex is ${config.activeIndex}"); print("the config.activeIndex is ${config.activeIndex}");
@ -1471,4 +1477,3 @@ class _DirectionalDotPaginationBuilder extends SwiperPlugin {
); );
} }
} }

@ -43,38 +43,37 @@ class LargeServiceCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
height: 350.h,
width: 230.w, width: 230.w,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.transparent, borderRadius: 24.r), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
child: Stack( color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [ children: [
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(24.r), borderRadius: BorderRadius.only(
topLeft: Radius.circular(24.r),
topRight: Radius.circular(24.r),
),
child: Image.asset( child: Image.asset(
serviceCardData.largeCardIcon, serviceCardData.largeCardIcon,
fit: BoxFit.cover, fit: BoxFit.cover,
width: double.infinity,
height: isFoldable ? 190.h : (isTablet ? 200.h : 180.h),
), ),
), ),
Positioned( Container(
bottom: 0.0, // Positions the child 0 logical pixels from the bottom padding: EdgeInsets.all(16.w),
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( child: Column(
mainAxisSize: MainAxisSize.min,
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
isPNG ? Image.asset(serviceCardData.icon, width: 35.h, height: 35.h) : Container( isPNG
? Image.asset(serviceCardData.icon, width: 35.h, height: 35.h)
: Container(
height: 48.h, height: 48.h,
width: 48.h, width: 48.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -97,13 +96,19 @@ class LargeServiceCard extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
serviceCardData.title.tr(context: context).toText14(isBold: true, color: AppColors.textColor), 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), serviceCardData.subtitle.tr(context: context).toText12(isBold: true, color: AppColors.textColorLight, maxLine: 2),
], ],
), ),
), ),
], ],
).paddingSymmetrical(8.w, 0.h).expanded, ),
SizedBox(height: 24.h),
CustomButton( CustomButton(
text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context), text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context),
onPressed: () { onPressed: () {
@ -117,9 +122,8 @@ class LargeServiceCard extends StatelessWidget {
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
borderRadius: 10.r, borderRadius: 10.r,
height: 40.h, height: 40.h,
).paddingSymmetrical(16.w, 0.h),
],
), ),
],
), ),
), ),
], ],
@ -229,7 +233,9 @@ class FadedLargeServiceCard extends StatelessWidget {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
isPNG ? Image.asset(serviceCardData.icon, width: 32.h, height: 32.h).circle(100.h) : Container( isPNG
? Image.asset(serviceCardData.icon, width: 32.h, height: 32.h).circle(100.h)
: Container(
height: 32.h, height: 32.h,
width: 32.h, width: 32.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
@ -242,11 +248,7 @@ class FadedLargeServiceCard extends StatelessWidget {
child: Transform.flip( child: Transform.flip(
flipX: getIt.get<AppState>().isArabic(), flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: serviceCardData.icon, icon: serviceCardData.icon, iconColor: serviceCardData.iconColor, fit: BoxFit.contain, applyThemeColor: false),
iconColor: serviceCardData.iconColor,
fit: BoxFit.contain,
applyThemeColor: false
),
), ),
), ),
), ),

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui' as ui;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.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_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.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/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/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/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_config.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/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.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/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_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/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/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_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/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/lab/lab_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/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_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/medical_file/models/patient_sickleave_response_model.dart';
import 'package:hmg_patient_app_new/features/monthly_report/monthly_report_view_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/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/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/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/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_appointments_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_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/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/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/doctor_profile_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.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_approvals_page.dart';
import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_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'; 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/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/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/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/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_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/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_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_family/my_family.dart';
import 'package:hmg_patient_app_new/presentation/my_invoices/my_invoices_list.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'; 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/todo_section/todo_page.dart';
import 'package:hmg_patient_app_new/presentation/vital_sign/vital_sign_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/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/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.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/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/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.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/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/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.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/shimmer/common_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/user_avatar_widget.dart'; import 'package:hmg_patient_app_new/widgets/user_avatar_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../features/active_prescriptions/active_prescriptions_view_model.dart'; import '../../features/active_prescriptions/active_prescriptions_view_model.dart';
import '../prescriptions/prescription_detail_page.dart'; import '../prescriptions/prescription_detail_page.dart';
import 'widgets/medical_file_appointment_card.dart'; import 'widgets/medical_file_appointment_card.dart';
import 'dart:ui' as ui;
class MedicalFilePage extends StatefulWidget { class MedicalFilePage extends StatefulWidget {
bool showBackIcon; bool showBackIcon;
@ -119,10 +104,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
int currentIndex = 0; int currentIndex = 0;
// Used to make the PageView height follow the card's intrinsic height
final GlobalKey _vitalSignMeasureKey = GlobalKey();
double? _vitalSignMeasuredHeight;
@override @override
void initState() { void initState() {
appState = getIt.get<AppState>(); appState = getIt.get<AppState>();
@ -143,22 +124,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
super.initState(); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
labViewModel = Provider.of<LabViewModel>(context, listen: false); labViewModel = Provider.of<LabViewModel>(context, listen: false);
@ -251,7 +216,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
UserAvatarWidget( UserAvatarWidget(
width: 56.w, width: 56.h,
height: 56.h, height: 56.h,
fit: BoxFit.cover, fit: BoxFit.cover,
isCircular: true, isCircular: true,
@ -273,7 +238,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
children: [ children: [
AppCustomChipWidget( AppCustomChipWidget(
icon: AppAssets.file_icon, 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), labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
), ),
AppCustomChipWidget( AppCustomChipWidget(
@ -297,7 +263,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
runSpacing: 4.h, runSpacing: 4.h,
children: [ children: [
AppCustomChipWidget( 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), labelPadding: EdgeInsetsDirectional.only(start: 8.w, end: 8.w),
), ),
AppCustomChipWidget( AppCustomChipWidget(
@ -340,9 +308,14 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
onChipTap: () { onChipTap: () {
if (!insuranceVM.isInsuranceActive) { if (!insuranceVM.isInsuranceActive) {
insuranceVM.setIsInsuranceUpdateDetailsLoading(true); insuranceVM.setIsInsuranceUpdateDetailsLoading(true);
insuranceVM.getPatientInsuranceDetailsForUpdate( insuranceVM.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(),
appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); appState.getAuthenticatedUser()!.patientIdentificationNo.toString());
showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); showCommonBottomSheetWithoutHeight(context,
child: PatientInsuranceCardUpdateCard(),
callBackFunc: () {},
title: "",
isCloseButtonVisible: false,
isFullScreen: false);
// showCommonBottomSheetWithoutHeight( // showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!), // title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!),
// navigationService.navigatorKey.currentContext!, // navigationService.navigatorKey.currentContext!,
@ -438,17 +411,16 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
); );
} }
// The cards define their own height; measure the first rendered page once // Responsive PageView with dynamic height constraint
_scheduleVitalSignMeasure(); return ConstrainedBox(
final double hostHeight = _vitalSignMeasuredHeight ?? (135.h); constraints: BoxConstraints(
minHeight: 135.h,
return SizedBox( maxHeight: isFoldable ? 160.h : (isTablet ? 165.h : 135.h),
height: hostHeight, ),
child: PageView( child: PageView(
controller: hmgServicesVM.vitalSignPageController, controller: hmgServicesVM.vitalSignPageController,
onPageChanged: (index) { onPageChanged: (index) {
hmgServicesVM.setVitalSignCurrentPage(index); hmgServicesVM.setVitalSignCurrentPage(index);
_scheduleVitalSignMeasure();
}, },
children: _buildVitalSignPages( children: _buildVitalSignPages(
vitalSign: hmgServicesVM.vitalSignList.first, vitalSign: hmgServicesVM.vitalSignList.first,
@ -459,7 +431,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
); );
}, },
measureKey: _vitalSignMeasureKey,
currentPageIndex: hmgServicesVM.vitalSignCurrentPage, currentPageIndex: hmgServicesVM.vitalSignCurrentPage,
), ),
), ),
@ -517,7 +488,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
getSelectedTabData(0), 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: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
getSelectedTabData(2), getSelectedTabData(2),
@ -588,10 +561,137 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
}); });
} }
Widget getSelectedTabData(int index) { Widget buildInsuranceTab(int index) {
switch (index) { return Column(
case 0: children: [
//General Tab Data Consumer<InsuranceViewModel>(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: [
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<TodoSectionViewModel>().setIsAncillaryOrdersNeedReloading(true);
Navigator.of(context).push(
CustomPageRoute(
page: ToDoPage(),
),
);
}),
],
).paddingSymmetrical(0.w, 0.0),
SizedBox(height: 16.h),
],
);
}
Widget buildMedicalServicesTab() {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -608,17 +708,16 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
], ],
).paddingSymmetrical(0.w, 0.h).onPress(() { ).paddingSymmetrical(0.w, 0.h).onPress(() {
Navigator.of(context).push( Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage()));
CustomPageRoute(
page: MyAppointmentsPage(),
),
);
}), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) { Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
// Provide an explicit height so the horizontal ListView has a bounded height // Dynamic height that adapts to device and content
return SizedBox( return ConstrainedBox(
height: 192.h, constraints: BoxConstraints(
minHeight: 150.h,
maxHeight: isFoldable ? 230.h : (isTablet ? 240.h : 180.h),
),
child: myAppointmentsVM.isMyAppointmentsLoading child: myAppointmentsVM.isMyAppointmentsLoading
? MedicalFileAppointmentCard( ? MedicalFileAppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
@ -630,7 +729,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
? Container( ? Container(
padding: EdgeInsets.all(12.w), padding: EdgeInsets.all(12.w),
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: false), decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: false),
child: Column( child: Column(
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h),
@ -789,7 +889,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
? const CommonShimmerWidget().paddingSymmetrical(0.w, 0.h) ? const CommonShimmerWidget().paddingSymmetrical(0.w, 0.h)
: prescriptionVM.patientPrescriptionOrders.isNotEmpty : prescriptionVM.patientPrescriptionOrders.isNotEmpty
? Container( ? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.r, hasShadow: false), decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.r, hasShadow: false),
child: Padding( child: Padding(
padding: EdgeInsets.all(16.w), padding: EdgeInsets.all(16.w),
child: Column( child: Column(
@ -810,7 +911,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
children: [ children: [
Image.network( Image.network(
prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!, prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!,
width: 40.w, width: 40.h,
height: 40.h, height: 40.h,
fit: BoxFit.cover, fit: BoxFit.cover,
).circle(100.r), ).circle(100.r),
@ -826,13 +927,15 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
spacing: 3.w, spacing: 3.w,
runSpacing: 4.w, runSpacing: 4.w,
children: [ children: [
AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), AppCustomChipWidget(
labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!),
Directionality( Directionality(
textDirection: ui.TextDirection.ltr, textDirection: ui.TextDirection.ltr,
child: AppCustomChipWidget( child: AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon, icon: AppAssets.doctor_calendar_icon,
labelText: DateUtil.formatDateToDate( labelText: DateUtil.formatDateToDate(
DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), DateUtil.convertStringToDate(
prescriptionVM.patientPrescriptionOrders[index].appointmentDate),
false, false,
), ),
isEnglishOnly: true, isEnglishOnly: true,
@ -847,13 +950,19 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Transform.flip( Transform.flip(
flipX: appState.isArabic(), flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon_small, width: 15.w, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), icon: AppAssets.forward_arrow_icon_small,
width: 15.w,
height: 15.h,
fit: BoxFit.contain,
iconColor: AppColors.textColor)),
], ],
).onPress(() { ).onPress(() {
prescriptionVM.setPrescriptionsDetailsLoading(); prescriptionVM.setPrescriptionsDetailsLoading();
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: PrescriptionDetailPage(isFromAppointments: false, prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), page: PrescriptionDetailPage(
isFromAppointments: false,
prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]),
), ),
); );
}), }),
@ -961,7 +1070,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
children: [ children: [
Image.network( Image.network(
"https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
width: 64.w, width: 64.h,
height: 64.h, height: 64.h,
fit: BoxFit.cover, fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: true, radius: 50.r), ).circle(100).toShimmer2(isShow: true, radius: 50.r),
@ -985,8 +1094,11 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
height: 62.h, height: 62.h,
), ),
).paddingSymmetrical(0.w, 0.h) ).paddingSymmetrical(0.w, 0.h)
: SizedBox( : ConstrainedBox(
height: 110.h, constraints: BoxConstraints(
minHeight: 100.h,
maxHeight: isFoldable ? 130.h : (isTablet ? 140.h : 115.h),
),
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: myAppointmentsVM.patientMyDoctorsList.length, itemCount: myAppointmentsVM.patientMyDoctorsList.length,
@ -1005,7 +1117,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
children: [ children: [
Image.network( Image.network(
myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!,
width: 64.w, width: 64.h,
height: 64.h, height: 64.h,
fit: BoxFit.cover, fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: false, radius: 50.r), ).circle(100).toShimmer2(isShow: false, radius: 50.r),
@ -1013,7 +1125,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox( SizedBox(
width: 80.w, width: 80.w,
child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName) child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName)
.toString().toText12(isBold: true, isCenter: true, maxLine: 2).toShimmer2(isShow: false), .toString()
.toText12(isBold: true, isCenter: true, maxLine: 2)
.toShimmer2(isShow: false),
), ),
], ],
), ),
@ -1028,7 +1142,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: DoctorProfilePage(isDoctorAllowedToBook: !(myAppointmentsVM.patientMyDoctorsList[index].isLiveCareClinic ?? false)), page: DoctorProfilePage(
isDoctorAllowedToBook: !(myAppointmentsVM.patientMyDoctorsList[index].isLiveCareClinic ?? false)),
), ),
); );
}, onError: (err) { }, onError: (err) {
@ -1055,9 +1170,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
GridView( GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10.h, crossAxisSpacing: 10.h,
mainAxisSpacing: 16.w,
mainAxisExtent: 115.h,
), ),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
@ -1114,132 +1228,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox(height: 24.h), SizedBox(height: 24.h),
], ],
); );
case 1: }
//Insurance Tab Data
return Column( Widget buildRequestsTab() {
children: [
Consumer<InsuranceViewModel>(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<TodoSectionViewModel>().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( return Column(
children: [ children: [
Row( Row(
@ -1289,79 +1280,23 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
).paddingSymmetrical(0.w, 0.h); ).paddingSymmetrical(0.w, 0.h);
}), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Selector<MedicalFileViewModel,({bool isLoading, List<PatientMedicalReportResponseModel> listRequest, List<PatientMedicalReportResponseModel> listReady})>( Selector<MedicalFileViewModel,
selector: (context, vm) => (isLoading: vm.isPatientMedicalReportsListLoading, listRequest: vm.patientMedicalReportRequestedList, listReady: vm.patientMedicalReportReadyList), ({bool isLoading, List<PatientMedicalReportResponseModel> listRequest, List<PatientMedicalReportResponseModel> listReady})>(
selector: (context, vm) => (
isLoading: vm.isPatientMedicalReportsListLoading,
listRequest: vm.patientMedicalReportRequestedList,
listReady: vm.patientMedicalReportReadyList
),
builder: (context, data, _) { builder: (context, data, _) {
return MedicalReportCard( return MedicalReportCard(isLoading: data.isLoading, listRequest: data.listRequest, listReady: data.listReady);
isLoading: data.isLoading, listRequest: data.listRequest, listReady: data.listReady
);
}, },
) ),
// GridView( SizedBox(height: 24.h),
// 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),
], ],
); );
case 3: }
// Health Tools Tab Data
Widget buildHealthToolsTab() {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -1370,7 +1305,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
crossAxisCount: 3, crossAxisCount: 3,
crossAxisSpacing: 10.h, crossAxisSpacing: 10.h,
mainAxisSpacing: 16.w, mainAxisSpacing: 16.w,
mainAxisExtent: 120.h,
), ),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.only(top: 12.h), padding: EdgeInsets.only(top: 12.h),
@ -1453,6 +1387,22 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox(height: 24.h), 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 buildHealthToolsTab();
default: default:
return Container(); return Container();
} }
@ -1538,13 +1488,12 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
List<Widget> _buildVitalSignPages({ List<Widget> _buildVitalSignPages({
required VitalSignResModel vitalSign, required VitalSignResModel vitalSign,
required VoidCallback onTap, required VoidCallback onTap,
required GlobalKey measureKey,
required int currentPageIndex, required int currentPageIndex,
}) { }) {
return [ return [
// Page 1: BMI + Height // Page 1: BMI + Height
Padding( Padding(
padding: EdgeInsets.only(left: 24.w), padding: EdgeInsets.symmetric(horizontal: 24.w),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
@ -1574,7 +1523,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
// Page 2: Weight + Blood Pressure // Page 2: Weight + Blood Pressure
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 12.w), padding: EdgeInsets.symmetric(horizontal: 24.w),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
@ -1592,13 +1541,17 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.bloodPressure, icon: AppAssets.bloodPressure,
label: LocaleKeys.bloodPressure.tr(context: context), label: LocaleKeys.bloodPressure.tr(context: context),
value: (vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null && value: (vitalSign.bloodPressureLower != null &&
vitalSign.bloodPressureLower != 0 && vitalSign.bloodPressureHigher != 0) vitalSign.bloodPressureHigher != null &&
vitalSign.bloodPressureLower != 0 &&
vitalSign.bloodPressureHigher != 0)
? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}"
: '--', : '--',
unit: '', unit: '',
status: (vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null && status: (vitalSign.bloodPressureLower != null &&
vitalSign.bloodPressureLower != 0 && vitalSign.bloodPressureHigher != 0) vitalSign.bloodPressureHigher != null &&
vitalSign.bloodPressureLower != 0 &&
vitalSign.bloodPressureHigher != 0)
? _getBloodPressureStatus( ? _getBloodPressureStatus(
systolic: vitalSign.bloodPressureHigher, systolic: vitalSign.bloodPressureHigher,
diastolic: vitalSign.bloodPressureLower, diastolic: vitalSign.bloodPressureLower,
@ -1682,7 +1635,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
weight: FontWeight.w600, weight: FontWeight.w600,
), ),
), ),
Utils.buildSvgWithAssets(icon: getIt.get<AppState>().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward, width: 18.w, height: 18.h), Utils.buildSvgWithAssets(
icon: getIt.get<AppState>().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward, width: 18.w, height: 18.h),
], ],
), ),
SizedBox(height: 14.h), SizedBox(height: 14.h),
@ -1702,11 +1656,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Flexible( Flexible(
child: value.toText17( child: value.toText17(isBold: true, color: AppColors.textColor, isEnglishOnly: true),
isBold: true,
color: AppColors.textColor,
isEnglishOnly: true
),
), ),
if (unit.isNotEmpty && value != '--' && value != '0') ...[ if (unit.isNotEmpty && value != '--' && value != '0') ...[
SizedBox(width: 3.w), SizedBox(width: 3.w),

@ -152,7 +152,7 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
backgroundColor: backgroundColor:
AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? AppColors.greyColor : AppColors.secondaryLightRedColor, AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? AppColors.greyColor : AppColors.secondaryLightRedColor,
textColor: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor, 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), ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading),
SizedBox(height: 16.h), SizedBox(height: 16.h),
IntrinsicWidth( IntrinsicWidth(
@ -166,10 +166,10 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
Image.network( Image.network(
widget.patientAppointmentHistoryResponseModel.doctorImageURL ?? widget.patientAppointmentHistoryResponseModel.doctorImageURL ??
"https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
width: 25.w, width: 30.h,
height: 27.h, height: 30.h,
fit: BoxFit.fill, fit: BoxFit.fill,
).circle(100).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), ).circle(100.r).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded( Expanded(
child: Column( child: Column(
@ -190,81 +190,121 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
], ],
), ),
SizedBox(height: 8.h), SizedBox(height: 8.h),
// Check if doctor is active - if not, show only View Details button _buildAppointmentActionButton(context, appState),
(widget.patientAppointmentHistoryResponseModel.isActiveDoctor ?? true) ],
? // Doctor is active - check rebooking logic ).paddingAll(16.w),
(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) /// Builds the appropriate action button based on appointment state and doctor status
: CustomButton( Widget _buildAppointmentActionButton(BuildContext context, AppState appState) {
text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), 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: () { onPressed: () {
handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction, context); handleAppointmentNextAction(appointment.nextAction, context);
}, },
backgroundColor: backgroundColor: AppointmentType.getNextActionButtonColor(appointment.nextAction).withValues(alpha: 0.15),
AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction) borderColor: AppointmentType.getNextActionButtonColor(appointment.nextAction).withValues(alpha: 0.01),
.withValues(alpha: 0.15), textColor: AppointmentType.getNextActionTextColor(appointment.nextAction),
borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction)
.withValues(alpha: 0.01),
textColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction),
fontSize: 14.f, fontSize: 14.f,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
borderRadius: 12.r, borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w), padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h, height: 40.h,
icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), icon: AppointmentType.getNextActionIcon(appointment.nextAction),
iconColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), iconColor: AppointmentType.getNextActionTextColor(appointment.nextAction),
iconSize: 14.h, iconSize: 14.h,
).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading) ).toShimmer2(isShow: isLoading);
: // Normal flow - show button with arrow }
Row(
/// Builds button with arrow (normal flow with navigation arrow)
Widget _buildButtonWithArrow(BuildContext context, AppState appState, bool isLoading) {
return Row(
children: [ children: [
widget.myAppointmentsViewModel.isMyAppointmentsLoading _buildMainActionButton(context, isLoading),
? 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), SizedBox(width: 8.w),
((((widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) || _buildNavigationArrow(context, appState, isLoading),
(widget.patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) || ],
!Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID ?? 0))) && );
AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) }
? SizedBox.shrink()
: Expanded( /// 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, flex: 2,
child: Container( child: Container(
height: 40.h, height: 40.h,
width: 40.w, width: 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor, color: AppColors.textColor,
borderRadius: 10.r, borderRadius: 10.r,
@ -276,30 +316,29 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
icon: AppAssets.forward_arrow_icon_small, icon: AppAssets.forward_arrow_icon_small,
width: 40.w, width: 40.h,
height: 40.h, height: 40.h,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
), ),
), ),
).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading).onPress(() { ).toShimmer2(isShow: isLoading).onPress(() {
Navigator.of(context) Navigator.of(context)
.push( .push(
CustomPageRoute( CustomPageRoute(
page: AppointmentDetailsPage( page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: appointment),
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
), ),
) )
.then((val) { .then((val) {
// widget.myAppointmentsViewModel.initAppointmentsViewModel(); // Can refresh appointments here if needed
// widget.myAppointmentsViewModel.getPatientAppointments(true, false);
}); });
}), }),
), );
], }
)
: // Doctor is not active - show only View Details button /// Builds the View Details button (for inactive doctors)
CustomButton( Widget _buildViewDetailsButton(BuildContext context) {
return CustomButton(
text: LocaleKeys.viewDetails.tr(context: context), text: LocaleKeys.viewDetails.tr(context: context),
onPressed: () { onPressed: () {
Navigator.of(context) Navigator.of(context)
@ -320,14 +359,8 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
borderRadius: 12.r, borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w), padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h, height: isFoldable ? 36.h : 40.h,
).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading), ).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading);
],
).paddingAll(16.w),
),
),
],
);
} }
Widget getArrivedAppointmentButton(BuildContext context) { Widget getArrivedAppointmentButton(BuildContext context) {

@ -30,11 +30,7 @@ class MedicalFileCard extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final iconS = iconSize ?? 30.w; final iconS = iconSize ?? 30.w;
return Container( return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: backgroundColor, borderRadius: 20.r, hasShadow: false),
color: backgroundColor,
borderRadius: 20.r,
hasShadow: false
),
padding: EdgeInsets.all(12.w), padding: EdgeInsets.all(12.w),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -64,5 +60,3 @@ class MedicalFileCard extends StatelessWidget {
); );
} }
} }

@ -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:hmg_patient_app_new/widgets/graph/CustomBarGraph.dart';
import 'package:intl/intl.dart' show DateFormat; import 'package:intl/intl.dart' show DateFormat;
import 'package:provider/provider.dart'; 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 'package:dartz/dartz.dart' show Tuple2;
import '../../core/utils/date_util.dart'; import '../../core/utils/date_util.dart';

File diff suppressed because it is too large Load Diff

@ -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<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.activity??[]),
unitsOfMeasure: "Kcal"
).onPress((){
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("activity");
context.read<HealthProvider>().saveSelectedSection("activity");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.step??[]),
unitsOfMeasure: "Steps"
).onPress((){
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("steps");
context.read<HealthProvider>().saveSelectedSection("steps");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.distance??[]),
unitsOfMeasure: "Km"
).onPress((){
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("distance");
context.read<HealthProvider>().saveSelectedSection("distance");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.sleep??[]))).split(" ")[0],
unitsOfMeasure: "hr",
resultSecondValue: DateUtil.millisToHourMin(int.parse(context.read<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.sleep??[]))).split(" ")[2],
unitOfSecondMeasure: "min"
).onPress((){
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("sleep");
context.read<HealthProvider>().saveSelectedSection("sleep");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.bodyOxygen??[], ),
unitsOfMeasure: "%"
).onPress((){
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("bodyOxygen");
context.read<HealthProvider>().saveSelectedSection("bodyOxygen");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.bodyTemperature??[]),
unitsOfMeasure: "C"
).onPress((){
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("bodyTemperature");
context.read<HealthProvider>().saveSelectedSection("bodyTemperature");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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)
);
}
}

@ -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<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.activity ?? []),
unitsOfMeasure: "Kcal")
.onPress(() {
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("activity");
context.read<HealthProvider>().saveSelectedSection("activity");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.step ?? []),
unitsOfMeasure: "Steps")
.onPress(() {
// Map<String, List<Vitals>> getVitals() {
// return {
// "heartRate": heartRate ,
// "sleep": sleep,
// "steps": step,
// "activity": activity,
// "bodyOxygen": bodyOxygen,
// "bodyTemperature": bodyTemperature,
// };
// }
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("steps");
context.read<HealthProvider>().saveSelectedSection("steps");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.distance ?? []),
unitsOfMeasure: "Km")
.onPress(() {
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("distance");
context.read<HealthProvider>().saveSelectedSection("distance");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.sleep ?? [])))
.split(" ")[0],
unitsOfMeasure: "hr",
resultSecondValue: DateUtil.millisToHourMin(
int.parse(context.read<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.sleep ?? [])))
.split(" ")[2],
unitOfSecondMeasure: "min")
.onPress(() {
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("sleep");
context.read<HealthProvider>().saveSelectedSection("sleep");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().firstNonEmptyValue(
context.read<HealthProvider>().vitals?.bodyOxygen ?? [],
),
unitsOfMeasure: "%")
.onPress(() {
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("bodyOxygen");
context.read<HealthProvider>().saveSelectedSection("bodyOxygen");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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<HealthProvider>().firstNonEmptyValue(context.read<HealthProvider>().vitals?.bodyTemperature ?? []),
unitsOfMeasure: "C")
.onPress(() {
context.read<HealthProvider>().setDurations(durations.Durations.daily);
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("bodyTemperature");
context.read<HealthProvider>().saveSelectedSection("bodyTemperature");
context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().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));
}
}

@ -1,5 +1,3 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -54,7 +52,6 @@ class SmartwatchHomePage extends StatelessWidget {
fontSize: 16.f, fontSize: 16.f,
isBold: true, isBold: true,
borderRadius: 12.r, borderRadius: 12.r,
height: 50.h, height: 50.h,
icon: AppAssets.ask_doctor_icon, icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.infoColor, iconColor: AppColors.infoColor,
@ -69,11 +66,12 @@ class SmartwatchHomePage extends StatelessWidget {
child: GridView( child: GridView(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
crossAxisSpacing: 16.h, crossAxisSpacing: 16.h,
mainAxisSpacing: 16.w, mainAxisSpacing: 16.w,
mainAxisExtent: 240.h, childAspectRatio: isFoldable ? 1.1 : (isTablet ? 1.3 : 0.7),
), ),
children: [ children: [
Container( Container(
@ -83,14 +81,18 @@ class SmartwatchHomePage extends StatelessWidget {
), ),
child: Column( child: Column(
children: [ 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), "Apple Watch".needTranslation.toText16(isBold: true),
CustomButton( CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context), text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () { onPressed: () {
context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.apple, "assets/images/png/smartwatches/apple-watch-5.jpg"); context
getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage( .read<HealthProvider>()
smartwatchDetails: SmartwatchDetails(SmartWatchTypes.apple, .setSelectedWatchType(SmartWatchTypes.apple, "assets/images/png/smartwatches/apple-watch-5.jpg");
getIt.get<NavigationService>().pushPage(
page: SmartwatchInstructionsPage(
smartwatchDetails: SmartwatchDetails(
SmartWatchTypes.apple,
"assets/images/png/smartwatches/apple-watch-5.jpg", "assets/images/png/smartwatches/apple-watch-5.jpg",
AppAssets.bluetooth, AppAssets.bluetooth,
LocaleKeys.applehealthapplicationshouldbeinstalledinyourphone.tr(context: context), LocaleKeys.applehealthapplicationshouldbeinstalledinyourphone.tr(context: context),
@ -110,26 +112,29 @@ class SmartwatchHomePage extends StatelessWidget {
), ),
), ),
Container( Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
color: AppColors.whiteColor,
borderRadius: 24.r,
),
child: Column( child: Column(
children: [ 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), "Samsung Watch".needTranslation.toText16(isBold: true),
CustomButton( CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context), text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () { onPressed: () {
context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.samsung, "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg"); context
getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage( .read<HealthProvider>()
smartwatchDetails: SmartwatchDetails(SmartWatchTypes.samsung, .setSelectedWatchType(SmartWatchTypes.samsung, "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg");
getIt.get<NavigationService>().pushPage(
page: SmartwatchInstructionsPage(
smartwatchDetails: SmartwatchDetails(
SmartWatchTypes.samsung,
"assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg",
AppAssets.bluetooth, AppAssets.bluetooth,
LocaleKeys.samsunghealthapplicationshouldbeinstalledinyourphone.tr(context: context), LocaleKeys.samsunghealthapplicationshouldbeinstalledinyourphone.tr(context: context),
LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context), LocaleKeys.unabletodetectapplicationinstalledpleasecomebackonceinstalled.tr(context: context),
LocaleKeys.samsungwatchshouldbeconnected.tr(context: context)), LocaleKeys.samsungwatchshouldbeconnected.tr(context: context)),
)); }, ));
},
backgroundColor: AppColors.primaryRedColor.withAlpha(40), backgroundColor: AppColors.primaryRedColor.withAlpha(40),
borderColor: AppColors.primaryRedColor.withAlpha(0), borderColor: AppColors.primaryRedColor.withAlpha(0),
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
@ -187,7 +192,6 @@ class SmartwatchHomePage extends StatelessWidget {
CustomButton( CustomButton(
text: LocaleKeys.selectSmartWatch.tr(context: context), text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () { onPressed: () {
showUnavailableDialog(context); showUnavailableDialog(context);
// context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.whoop, "assets/images/png/smartwatches/Whoop_Watch.png"); // context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.whoop, "assets/images/png/smartwatches/Whoop_Watch.png");
// getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage( // getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage(
@ -221,7 +225,6 @@ class SmartwatchHomePage extends StatelessWidget {
} }
void showUnavailableDialog(BuildContext context) { void showUnavailableDialog(BuildContext context) {
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context), title: LocaleKeys.notice.tr(context: context),
context, context,
@ -231,8 +234,7 @@ class SmartwatchHomePage extends StatelessWidget {
showOkButton: true, showOkButton: true,
onConfirmTap: () async { onConfirmTap: () async {
context.pop(); context.pop();
} }),
),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,

@ -2,13 +2,10 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/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/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@ -51,7 +48,12 @@ class SmartwatchInstructionsPage extends StatelessWidget {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
spacing: 18.h, spacing: 18.h,
children: [ children: [
Image.asset(smartwatchDetails.watchIcon, fit: BoxFit.contain, height: 280.h,width: 280.w,), Image.asset(
smartwatchDetails.watchIcon,
fit: BoxFit.contain,
height: 280.h,
width: 280.w,
),
DecoratedBox( DecoratedBox(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
child: Column( child: Column(
@ -60,7 +62,7 @@ class SmartwatchInstructionsPage extends StatelessWidget {
title: smartwatchDetails.detailsTitle, title: smartwatchDetails.detailsTitle,
description: smartwatchDetails.details, description: smartwatchDetails.details,
icon: smartwatchDetails.smallIcon, icon: smartwatchDetails.smallIcon,
descriptionTextColor: AppColors.primaryRedColor descriptionTextColor: AppColors.primaryRedColor,
), ),
Divider( Divider(
color: AppColors.dividerColor, color: AppColors.dividerColor,
@ -70,7 +72,7 @@ class SmartwatchInstructionsPage extends StatelessWidget {
title: smartwatchDetails.secondTitle, title: smartwatchDetails.secondTitle,
description: LocaleKeys.updatetheinformation.tr(), description: LocaleKeys.updatetheinformation.tr(),
icon: AppAssets.bluetooth, icon: AppAssets.bluetooth,
descriptionTextColor: AppColors.greyTextColor descriptionTextColor: AppColors.greyTextColor,
), ),
], ],
).paddingSymmetrical(16.w, 16.h), ).paddingSymmetrical(16.w, 16.h),
@ -81,7 +83,6 @@ class SmartwatchInstructionsPage extends StatelessWidget {
); );
} }
Widget watchContentDetails({required String title, required String description, required String icon, required Color descriptionTextColor}) { Widget watchContentDetails({required String title, required String description, required String icon, required Color descriptionTextColor}) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -90,9 +91,7 @@ class SmartwatchInstructionsPage extends StatelessWidget {
DecoratedBox( DecoratedBox(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h),
child: Utils.buildSvgWithAssets(icon: icon, width: 40.w, height: 40.h), child: Utils.buildSvgWithAssets(icon: icon, width: 40.w, height: 40.h),
), ),
title.toText16(isBold: true, color: AppColors.textColor), title.toText16(isBold: true, color: AppColors.textColor),
description.toText12(isBold: true, color: descriptionTextColor) description.toText12(isBold: true, color: descriptionTextColor)
], ],

@ -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/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/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/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/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/organ_selector_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/possible_conditions_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/monthly_reports/monthly_reports_view_model.dart';
import '../features/qr_parking/qr_parking_view_model.dart'; import '../features/qr_parking/qr_parking_view_model.dart';
import '../presentation/parking/paking_page.dart'; import '../presentation/parking/paking_page.dart';
import '../presentation/smartwatches/smartwatch_instructions_page.dart';
import '../services/error_handler_service.dart'; import '../services/error_handler_service.dart';
class AppRoutes { class AppRoutes {

Loading…
Cancel
Save