From fc0f98da1de46b98602c6faa202cf54620e40885 Mon Sep 17 00:00:00 2001 From: tahaalam Date: Wed, 26 Nov 2025 14:24:56 +0300 Subject: [PATCH] calender reminder added --- .../reports/problems/problems-report.html | 2 +- lib/core/utils/calender_utils_new.dart | 94 +++++++++++++++++++ lib/core/utils/date_util.dart | 3 +- .../appointment_details_page.dart | 70 ++++++++++++-- .../prescription_reminder_view.dart | 2 +- pubspec.yaml | 1 + 6 files changed, 159 insertions(+), 13 deletions(-) create mode 100644 lib/core/utils/calender_utils_new.dart diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html index 82570ba..866b270 100644 --- a/android/build/reports/problems/problems-report.html +++ b/android/build/reports/problems/problems-report.html @@ -650,7 +650,7 @@ code + .copy-button { diff --git a/lib/core/utils/calender_utils_new.dart b/lib/core/utils/calender_utils_new.dart new file mode 100644 index 0000000..b4c4bd7 --- /dev/null +++ b/lib/core/utils/calender_utils_new.dart @@ -0,0 +1,94 @@ +import 'dart:async'; + +import 'package:device_calendar_plus/device_calendar_plus.dart'; +import 'package:jiffy/jiffy.dart' show Jiffy; + +class CalenderUtilsNew { + final DeviceCalendar calender = DeviceCalendar.instance; + List writableCalender = []; + + CalenderUtilsNew._instance() { + getCalenders(); + } + + static final CalenderUtilsNew instance = CalenderUtilsNew._instance(); + + Future getCalenders() async { + CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions(); + if(result != CalendarPermissionStatus.granted) await DeviceCalendar.instance.requestPermissions(); + var calenders = await calender.listCalendars(); + calenders.forEach((calender) { + if (!calender.readOnly) { + writableCalender.add(calender); + } + }); + } + + FutureOr createOrUpdateEvent({required String title, required String description, required String location, DateTime? scheduleDateTime, String? eventId, int? reminderMinutes}) async { + print("the reminder minutes are $reminderMinutes"); + if (writableCalender.isEmpty) { + await getCalenders(); + } + var writableCalendars = writableCalender.first; + + print("writableCalendars-name: " + writableCalendars.name); + print("writableCalendars-Id: " + writableCalendars.id); + print("writableCalendarsToString: " + writableCalendars.toString()); + print("writableCalendarsToString: " + writableCalendars!.id!); + + CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions(); + if(result != CalendarPermissionStatus.granted) await DeviceCalendar.instance.requestPermissions(); + print(result); + String eventResult = await DeviceCalendar.instance.createEvent( + calendarId: writableCalendars!.id, + title: title, + description: description, + startDate: scheduleDateTime!, + endDate: scheduleDateTime!.add(Duration(minutes: 30)), + reminderMinutes: reminderMinutes + ); + + print("the event Result is ${eventResult}"); + return eventResult.isNotEmpty; + } + + + + FutureOr> getEvents() async { + var availableCalender = writableCalender.first; + DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime; + DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime; + return await calender.listEvents(startEventsDate, endEventsDate, calendarIds: [availableCalender.id]); + + } + + + FutureOr checkIfEventExist(String admissionId) async { + if(writableCalender.isEmpty)return false; + List events = await getEvents(); + if(events.isEmpty) return false; + for(var event in events){ + List title = event.title!.split("#"); + print("the splitted admission id is ${title}"); + if(title.contains(admissionId)) return true; + } + return false; + } + + FutureOr checkAndRemove({required String id}) async { + if(writableCalender.isEmpty)return false; + List events = await getEvents(); + if(events.isEmpty) return false; + for(var event in events){ + List title = event.title!.split("#"); + print("the splitted admission id is ${title}"); + if(title.contains(id)) { + calender.deleteEvent(eventId: event.eventId); + return true; + } + } + return false; + } + + +} diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart index a918706..ee2b4ec 100644 --- a/lib/core/utils/date_util.dart +++ b/lib/core/utils/date_util.dart @@ -17,8 +17,7 @@ class DateUtil { final endIndex = date.indexOf(end, startIndex + start.length); return DateTime.fromMillisecondsSinceEpoch(int.parse( date.substring(startIndex + start.length, endIndex), - )) - ; + )); } static DateTime convertStringToDateSaudiTimezone(String date, int projectId) { diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index e620783..ba110a2 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -1,10 +1,16 @@ import 'dart:async'; +import 'dart:collection'; +import 'dart:io'; +import 'package:device_calendar/device_calendar.dart'; 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/app_state.dart'; +import 'package:hmg_patient_app_new/core/utils/calendar_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/calender_utils_new.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'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -62,11 +68,13 @@ class _AppointmentDetailsPageState extends State { @override void initState() { - scheduleMicrotask(() { - // if (AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) { - // prescriptionsViewModel.setPrescriptionsDetailsLoading(); - // prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel()); - // } + scheduleMicrotask(() async { + CalenderUtilsNew calendarUtils = await CalenderUtilsNew.instance; + var doesExist = await calendarUtils.checkIfEventExist("${widget.patientAppointmentHistoryResponseModel.appointmentNo}"); + print("the appointment reminder exist $doesExist"); + myAppointmentsViewModel.setAppointmentReminder(doesExist, widget.patientAppointmentHistoryResponseModel); + + }); super.initState(); } @@ -272,10 +280,54 @@ class _AppointmentDetailsPageState extends State { // activeThumbColor: AppColors.successColor, activeTrackColor: AppColors.successColor.withValues(alpha: .15), value: widget.patientAppointmentHistoryResponseModel.hasReminder!, - onChanged: (newValue) { - setState(() { - myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - }); + onChanged: (newValue) async { + CalenderUtilsNew calender = CalenderUtilsNew.instance; + bool isEventAddedOrRemoved = false; + if(newValue == true){ + DateTime startDate = DateTime.now(); + DateTime endDate = DateUtil.convertStringToDate(widget + .patientAppointmentHistoryResponseModel.appointmentDate); + showReminderBottomSheet( + context, + endDate, + widget.patientAppointmentHistoryResponseModel.doctorNameObj??"", + "${widget.patientAppointmentHistoryResponseModel.appointmentNo}"??"", + "", + "", + title: "Appointment with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}".needTranslation, + description:"${widget.patientAppointmentHistoryResponseModel.doctorNameObj} will be having an appointment on ${widget.patientAppointmentHistoryResponseModel.appointmentDate}".needTranslation, + 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}".needTranslation, + 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); + }); + } + + }, ), ], diff --git a/lib/presentation/prescriptions/prescription_reminder_view.dart b/lib/presentation/prescriptions/prescription_reminder_view.dart index 8b7df0b..2f1154f 100644 --- a/lib/presentation/prescriptions/prescription_reminder_view.dart +++ b/lib/presentation/prescriptions/prescription_reminder_view.dart @@ -100,7 +100,7 @@ class _PrescriptionReminderViewState extends State { text: LocaleKeys.setReminder.tr(), onPressed: () { Navigator.of(context).pop(); - widget.setReminder(_selectedOption); + widget.setReminder(_options[_selectedOption]); }, backgroundColor: AppColors.bgGreenColor, borderColor: AppColors.bgGreenColor, diff --git a/pubspec.yaml b/pubspec.yaml index 3d6604c..23e3ea9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: file_picker: ^10.3.2 local_auth: ^2.3.0 share_plus: ^11.1.0 + device_calendar_plus: ^0.3.1 device_calendar: git: https://github.com/bardram/device_calendar manage_calendar_events: ^2.0.3