From 7cc12bd1cf8707fba9d901810d87f7790f40b9f0 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 9 Sep 2025 13:07:51 +0300 Subject: [PATCH] prescription calender reminder added. --- lib/core/utils/calendar_utils.dart | 236 ++++++++++-------- lib/extensions/widget_extensions.dart | 14 ++ .../prescriptions_view_model.dart | 4 + .../prescription_detail_page.dart | 194 +------------- .../prescriptions/prescription_item_view.dart | 233 +++++++++++++++++ 5 files changed, 394 insertions(+), 287 deletions(-) create mode 100644 lib/presentation/prescriptions/prescription_item_view.dart diff --git a/lib/core/utils/calendar_utils.dart b/lib/core/utils/calendar_utils.dart index 297ae2f..979ce1b 100644 --- a/lib/core/utils/calendar_utils.dart +++ b/lib/core/utils/calendar_utils.dart @@ -1,11 +1,16 @@ import 'dart:async'; +import 'dart:collection'; import 'dart:convert'; import 'dart:io'; import 'dart:ui'; import 'package:device_calendar/device_calendar.dart'; import 'package:flutter/widgets.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/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_reminder_view.dart'; +import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/permission_service.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:jiffy/jiffy.dart'; @@ -50,106 +55,6 @@ class CalendarUtils { // return _completer!.future; // } - Future> requestPermissions() async { - var permissionResults = [Permission.calendarFullAccess].request(); - return permissionResults; - } - - showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, - {required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async { - if (Platform.isAndroid) { - if (await PermissionService.isCalendarPermissionEnabled()) { - _showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); - } else { - // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async { - // if (await Permission.calendarFullAccess.request().isGranted) { - // _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - // onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); - // } - // }); - } - } else { - if (await Permission.calendarWriteOnly.request().isGranted) { - if (await Permission.calendarFullAccess.request().isGranted) { - _showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); - } - } - } - } - - Future _showReminderBottomSheet(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, - {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async { - // showCommonBottomSheet( - // providedContext, - // child: Column(children: [ - // - // ],), - // callBackFunc: () {}, - // title: "", - // isCloseButtonVisible: false, - // isFullScreen: false, height: null, - // ); - - // return showDialog( - // context: providedContext, - // barrierDismissible: true, // user must tap button! - // builder: (BuildContext context) { - // return Dialog( - // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)), - // insetPadding: EdgeInsets.all(21), - // child: ReminderDialog( - // onClick: (int i) async { - // String text = ""; - // if (i == 0) { - // // Before 30 mints - // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(minutes: 30).dateTime; - // text = "30 minutes"; - // // dateTime.add(new Duration(minutes: -30)); - // } else if (i == 1) { - // // Before 1 hour - // // dateTime.add(new Duration(minutes: -60)); - // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1).dateTime; - // text = "1 hours"; - // } else if (i == 2) { - // // Before 1 hour and 30 mints - // // dateTime.add(new Duration(minutes: -90)); - // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1, minutes: 30).dateTime; - // text = "1 hours 30 minutes"; - // } else if (i == 3) { - // // Before 2 hours - // // dateTime.add(new Duration(minutes: -120)); - // dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 2).dateTime; - // text = "2 hours"; - // } - // if (!isMultiAllowed!) { - // if (onMultiDateSuccess == null) { - // CalendarUtils calendarUtils = await CalendarUtils.getInstance(); - // await calendarUtils.createOrUpdateEvent( - // title: title ?? "TranslationBase.of(providedContext).reminderTitle".needTranslation + " " + doctorName, - // description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, - // scheduleDateTime: dateTime, - // eventId: eventId, - // location: ''); - // onSuccess(); - // } - // } else { - // onMultiDateSuccess!(i); - // } - // // await _analytics.logEvent( - // // name: name.trim().toLowerCase(), - // // parameters: safeParameters, - // // ); - // // todo @sikander discuss analytics for reminder - // // locator().appointment.appointment_reminder_time(reminde_before: text); - // }, - // ), - // ); - // }, - // ); - } - static Future getInstance() async { tzl.initializeTimeZones(); if (_completer != null) { @@ -278,3 +183,134 @@ class CalendarUtils { return await deviceCalendarPlugin.createCalendar(calendarName, calendarColor: calendarColor, localAccountName: localAccountName); } } + +Future> requestPermissions() async { + var permissionResults = [Permission.calendarFullAccess].request(); + return permissionResults; +} + +showReminderBottomSheet(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, + {required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async { + if (Platform.isAndroid) { + if (await PermissionService.isCalendarPermissionEnabled()) { + _showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + } else { + // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async { + // if (await Permission.calendarFullAccess.request().isGranted) { + // _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + // onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + // } + // }); + } + } else { + if (await Permission.calendarWriteOnly.request().isGranted) { + if (await Permission.calendarFullAccess.request().isGranted) { + _showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, + onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + } + } + } +} + +Future _showReminderBottomSheet(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, + {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async { + showCommonBottomSheetWithoutHeight(providedContext, title: "Set the timer of reminder".needTranslation, child: PrescriptionReminderView( + setReminder: (int value) async { + if (!isMultiAllowed!) { + if (onMultiDateSuccess == null) { + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + await calendarUtils.createOrUpdateEvent( + title: title ?? "You have appointment with Dr. ".needTranslation + doctorName, + description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, + scheduleDateTime: dateTime, + eventId: eventId, + location: ''); + onSuccess(); + } + } else { + onMultiDateSuccess!(value); + } + }, + ), callBackFunc: () {}, isFullScreen: false); +} + +setCalender(BuildContext context, + {required String eventId, required int selectedMinutes, int? frequencyNumber, required int days, required String orderDate, required String itemDescriptionN, required String route}) async { + DateTime actualDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0); + frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2 + + int remainingDays = days - (Jiffy.parseFromDateTime(DateTime.now()).diff(Jiffy.parseFromDateTime(DateUtil.convertStringToDate(orderDate)), unit: Unit.day) as int); + if (remainingDays.isNegative) { + getIt.get().showErrorBottomSheet(message: "Prescription date has been already passed you can not add a reminder for this prescription."); + return; + } + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + + try { + for (int i = 0; i < remainingDays; i++) { + //event for number of days. + for (int j = 0; j < frequencyNumber; j++) { + // event for number of times per day. + if (j != 0) { + actualDate.add(new Duration(hours: 8)); // 8 hours addition for daily dose. + } + //Time subtraction from actual reminder time. like before 30, or 1 hour. + + actualDate = Jiffy.parseFromDateTime(actualDate).subtract(minutes: selectedMinutes).dateTime; + + calendarUtils.createOrUpdateEvent( + title: "$itemDescriptionN} Prescription Reminder", + description: "$itemDescriptionN $frequencyNumber $route ", + scheduleDateTime: actualDate, + eventId: eventId + (i.toString() + j.toString()), + location: '', //event id with varitions + ); + + actualDate = DateTime(actualDate.year, actualDate.month, actualDate.day, 8, 0); + } + actualDate = Jiffy.parseFromDateTime(actualDate).add(days: 1).dateTime; + } + } catch (ex) { + getIt.get().showErrorBottomSheet(message: "catch:$ex"); + } +} + +Future checkAndRemove(hasReminder, {bool delete = false, String itemDescriptionN = ""}) async { + final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin(); + CalendarUtils calendarUtils = await CalendarUtils.getInstance(); + DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime; + DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime; + RetrieveEventsParams params = RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate); + + if (calendarUtils.calendars != null) { + if (Platform.isAndroid) { + await processEvents(calendarUtils.calendars, calendarUtils, params, delete, itemDescriptionN,hasReminder); + } else { + List? iosCalendars = await _myPlugin.getCalendars(); + if (iosCalendars != null) { + await processEvents(iosCalendars.map((cal) => Calendar(id: cal.id, name: cal.name, accountName: cal.accountName)).toList(), calendarUtils, params, delete, itemDescriptionN,hasReminder); + } + } + } +} + +Future processEvents(List calendars, calendarUtils, params, delete, String itemDescriptionN, hasReminder) async { + for (var calendar in calendars) { + Result> events = await calendarUtils.retrieveEvents(calendar.id!, params); + for (var event in events.data!) { + if (event.title!.contains(itemDescriptionN)) { + if (delete) { + await calendarUtils.deleteEvent(calendar, event); + // AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess); + hasReminder = false; + } else { + hasReminder = false; + // setState(() { + // hasReminder = true; + // }); + } + } + } + } +} diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index d1a3db4..f576d0c 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -39,6 +39,20 @@ extension WidgetExtensions on Widget { child: this, ); + Widget toShimmer2({bool isShow = true, double radius = 20}) => isShow + ? Shimmer.fromColors( + baseColor: const Color(0xffe8eff0), + highlightColor: Colors.white, + child: ClipRRect( + borderRadius: BorderRadius.circular(radius), + child: Container( + color: Colors.white, + child: this, + ), + ), + ) + : this; + Widget animatedSwither() => AnimatedSwitcher( duration: const Duration(milliseconds: 500), // transitionBuilder: (Widget child, Animation animation) { diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index ff93f84..306551d 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -51,6 +51,10 @@ class PrescriptionsViewModel extends ChangeNotifier { } } + notify() { + notifyListeners(); + } + setIsSortByClinic(bool value) { isSortByClinic = value; if (isSortByClinic) { diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index fbc44ba..77fc273 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/calendar_utils.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -12,6 +13,7 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_item_view.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_reminder_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; @@ -35,6 +37,9 @@ class _PrescriptionDetailPageState extends State { @override void initState() { + checkAndRemove(false); + // locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + // WidgetsBinding.instance.addPostFrameCallback((_) => locationUtils.getCurrentLocation()); scheduleMicrotask(() { prescriptionsViewModel.getPrescriptionDetails(widget.prescriptionsResponseModel); }); @@ -177,199 +182,14 @@ class _PrescriptionDetailPageState extends State { itemCount: prescriptionVM.isPrescriptionsDetailsLoading ? 5 : prescriptionVM.prescriptionDetailsList.length, itemBuilder: (context, index) { return prescriptionVM.isPrescriptionsDetailsLoading - ? const MoviesShimmerWidget() + ? PrescriptionItemView(prescriptionVM: prescriptionVM, index: index, isLoading: true) : AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( - child: AnimatedContainer( - duration: Duration(milliseconds: 300), - curve: Curves.easeInOut, - margin: EdgeInsets.symmetric(vertical: 8.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 16.h), - Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Image.network( - prescriptionVM.prescriptionDetailsList[index].imageThumbUrl!, - width: 60.h, - height: 60.h, - fit: BoxFit.fill, - ).circle(100), - SizedBox(width: 8.h), - Expanded( - child: prescriptionVM.prescriptionDetailsList[index].itemDescription!.toText16(isBold: true, maxlines: 2), - ), - ], - ).paddingSymmetrical(16.h, 0.h), - SizedBox(height: 16.h), - Wrap( - direction: Axis.horizontal, - spacing: 6.h, - runSpacing: 6.h, - children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - text: "${LocaleKeys.route.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].route}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - text: "${LocaleKeys.frequency.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].frequency}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - text: "${LocaleKeys.dailyDoses.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - text: "${LocaleKeys.days.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].days}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - ], - ).paddingSymmetrical(16.h, 0.h), - SizedBox(height: 8.h), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.h, height: 18.h), - SizedBox(width: 9.h), - Expanded(child: "${LocaleKeys.remarks.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true)), - ], - ).paddingSymmetrical(16.h, 0.h), - SizedBox(height: 14.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), - SizedBox(height: 14.h), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), - "Notify me before the consumption time".toText10(color: AppColors.textColorLight), - ], - ).expanded, - Switch( - activeColor: AppColors.successColor, - activeTrackColor: AppColors.successColor.withValues(alpha: .15), - value: prescriptionVM.prescriptionDetailsList[index].hasReminder!, - onChanged: (newValue) { - setState(() { - prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); - }); - showCommonBottomSheetWithoutHeight(context, title: "Set the timer of reminder".needTranslation, child: PrescriptionReminderView( - setReminder: (int value) { - DateTime startDate = DateTime.now(); - DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt()); - }, - ), callBackFunc: () {}, isFullScreen: false); - }, - ), - ], - ).paddingSymmetrical(16.h, 0.h), - SizedBox(height: 14.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), - Row( - children: [ - Expanded( - child: CustomButton( - text: LocaleKeys.checkAvailability.tr(context: context), - onPressed: () {}, - backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), - borderColor: AppColors.primaryRedColor.withOpacity(0.0), - textColor: AppColors.primaryRedColor, - fontSize: 13, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), - ), - SizedBox(width: 16.h), - Expanded( - child: CustomButton( - text: LocaleKeys.readInstructions.tr(context: context), - onPressed: () {}, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: AppColors.whiteColor, - fontSize: 13, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), - ), - ], - ).paddingSymmetrical(16.h, 16.h), - ], - ) - ], - ), - ), + child: PrescriptionItemView(prescriptionVM: prescriptionVM, index: index), ), ), ); diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart new file mode 100644 index 0000000..8357033 --- /dev/null +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -0,0 +1,233 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/utils/calendar_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; + +class PrescriptionItemView extends StatelessWidget { + int index; + PrescriptionsViewModel prescriptionVM; + bool isLoading; + + PrescriptionItemView({Key? key, required this.prescriptionVM, required this.index, this.isLoading = false}) : super(key: key); + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + margin: EdgeInsets.symmetric(vertical: 8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + spacing: 8.h, + children: [ + Image.network( + isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].imageThumbUrl!, + width: 60.h, + height: 60.h, + errorBuilder: (cxt, child, tr) { + return SizedBox(height: 60, width: 60); + }, + fit: BoxFit.fill, + ).toShimmer2(isShow: isLoading).circle(100), + Expanded( + child: (isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].itemDescription!).toText16(isBold: true, maxlines: 2).toShimmer2(isShow: isLoading), + ), + ], + ).paddingSymmetrical(16.h, 0.h), + SizedBox(height: 16.h), + Wrap( + direction: Axis.horizontal, + spacing: 6.h, + runSpacing: 6.h, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + CustomButton( + text: "${LocaleKeys.route.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].route}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ).toShimmer2(isShow: isLoading), + ], + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + CustomButton( + text: "${LocaleKeys.frequency.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].frequency}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ).toShimmer2(isShow: isLoading), + ], + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + CustomButton( + text: "${LocaleKeys.dailyDoses.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ).toShimmer2(isShow: isLoading), + ], + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + CustomButton( + text: "${LocaleKeys.days.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].days}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ).toShimmer2(isShow: isLoading), + ], + ), + ], + ).paddingSymmetrical(16.h, 0.h), + SizedBox(height: 8.h), + if (!isLoading) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.h, height: 18.h), + SizedBox(width: 9.h), + Expanded(child: "${LocaleKeys.remarks.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true)), + ], + ).paddingSymmetrical(16.h, 0.h), + SizedBox(height: 14.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + SizedBox(height: 14.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h).toShimmer2(isShow: isLoading), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), + "Notify me before the consumption time".toText10(color: AppColors.textColorLight), + ], + ).toShimmer2(isShow: isLoading).expanded, + Switch( + activeColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + value: isLoading ? false : prescriptionVM.prescriptionDetailsList[index].hasReminder!, + onChanged: (newValue) async { + if (prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false) { + await checkAndRemove(prescriptionVM.prescriptionDetailsList[index].hasReminder, delete: true); + prescriptionVM.notify(); + return; + } + + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt()); + showReminderBottomSheet( + context, + endDate, + "", + prescriptionVM.prescriptionDetailsList[index].itemID.toString(), + "", + "", + title: "${prescriptionVM.prescriptionDetailsList[index].itemDescription} Prescription Reminder", + description: + "${prescriptionVM.prescriptionDetailsList[index].itemDescription} ${prescriptionVM.prescriptionDetailsList[index].frequency} ${prescriptionVM.prescriptionDetailsList[index].route} ", + onSuccess: () { + prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); + }, + isMultiAllowed: true, + onMultiDateSuccess: (int selectedIndex) { + setCalender(context, + eventId: prescriptionVM.prescriptionDetailsList[index].itemID.toString(), + selectedMinutes: selectedIndex, + frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(), + days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(), + orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!, + itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!, + route: prescriptionVM.prescriptionDetailsList[index].route!); + }, + ); + }, + ).toShimmer2(isShow: isLoading), + ], + ).paddingSymmetrical(16.h, 0.h), + SizedBox(height: 14.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + Row( + children: [ + Expanded( + child: CustomButton( + text: LocaleKeys.checkAvailability.tr(context: context), + onPressed: () {}, + backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), + borderColor: AppColors.primaryRedColor.withOpacity(0.0), + textColor: AppColors.primaryRedColor, + fontSize: 13, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ).toShimmer2(isShow: isLoading), + ), + SizedBox(width: 16.h), + Expanded( + child: CustomButton( + text: LocaleKeys.readInstructions.tr(context: context), + onPressed: () {}, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 13, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ).toShimmer2(isShow: isLoading), + ), + ], + ).paddingSymmetrical(16.h, 16.h), + ], + ), + ); + } +}