Merge branch 'master' into haroon_dev

# Conflicts:
#	assets/langs/ar-SA.json
#	assets/langs/en-US.json
#	lib/generated/locale_keys.g.dart
pull/204/head
haroon amjad 1 day ago
commit 078b236b67

@ -1596,7 +1596,9 @@
"verifyInsurance": "التحقق من التأمين", "verifyInsurance": "التحقق من التأمين",
"tests": "تحليل", "tests": "تحليل",
"calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.", "calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.",
"sortByLocation": "الترتيب حسب الموقع",
"sortByNearestLocation": "فرز حسب الأقرب إلى موقعك", "sortByNearestLocation": "فرز حسب الأقرب إلى موقعك",
"giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع." "giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع."
"sortByLocation": "الترتيب حسب الموقع",
"timeForFirstReminder": "وقت التذكير الأول",
"reminderRemovalNote": "يمكنك إزالتها من التقويم الخاص بك لاحقاً عن طريق إيقاف تشغيل التذكير"
} }

@ -1590,6 +1590,8 @@
"verifyInsurance": "Verify Insurance", "verifyInsurance": "Verify Insurance",
"tests": "tests", "tests": "tests",
"calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.", "calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.",
"timeForFirstReminder": "Time for 1st reminder",
"reminderRemovalNote": "You can remove it from your calendar later by switching off the reminder"
"sortByLocation": "Sort by location", "sortByLocation": "Sort by location",
"sortByNearestLocation": "Sort by nearest to your location", "sortByNearestLocation": "Sort by nearest to your location",
"giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations." "giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations."

@ -101,9 +101,11 @@ class CalenderUtilsNew {
required String itemDescriptionN, required String itemDescriptionN,
required String route, required String route,
Function(String)? onFailure, Function(String)? onFailure,
String? prescriptionNumber}) async { String? prescriptionNumber,
DateTime? scheduleDateTime,
}) async {
DateTime currentDay = DateTime.now(); DateTime currentDay = DateTime.now();
DateTime actualDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0); DateTime actualDate = scheduleDateTime??DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0);
print("the frequency is $frequencyNumber"); print("the frequency is $frequencyNumber");
frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2 frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2
int interval = calculateIntervalAsPerFrequency(frequencyNumber); int interval = calculateIntervalAsPerFrequency(frequencyNumber);

@ -52,6 +52,8 @@ class PrescriptionsViewModel extends ChangeNotifier {
bool isPrescriptionsDataNeedsReloading = true; bool isPrescriptionsDataNeedsReloading = true;
List<PrescriptionDeliveryResponseModel> prescriptionsOrderList = []; List<PrescriptionDeliveryResponseModel> prescriptionsOrderList = [];
DateTime? selectedReminderTime;
PrescriptionsViewModel({required this.prescriptionsRepo, required this.errorHandlerService, required this.navServices}); PrescriptionsViewModel({required this.prescriptionsRepo, required this.errorHandlerService, required this.navServices});
initPrescriptionsViewModel() { initPrescriptionsViewModel() {
@ -71,6 +73,7 @@ class PrescriptionsViewModel extends ChangeNotifier {
Future<bool> checkIfReminderExistForPrescription(int index) async { Future<bool> checkIfReminderExistForPrescription(int index) async {
prescriptionDetailsList[index].hasReminder = await CalenderUtilsNew.instance.checkIfEventExist(prescriptionDetailsList[index].itemID?.toString() ?? ""); prescriptionDetailsList[index].hasReminder = await CalenderUtilsNew.instance.checkIfEventExist(prescriptionDetailsList[index].itemID?.toString() ?? "");
notifyListeners();
return prescriptionDetailsList[index].hasReminder ?? false; return prescriptionDetailsList[index].hasReminder ?? false;
} }
@ -308,4 +311,9 @@ class PrescriptionsViewModel extends ChangeNotifier {
}, },
); );
} }
void serSelectedTime(DateTime dateTime) {
selectedReminderTime = dateTime;
notifyListeners();
}
} }

@ -1593,5 +1593,7 @@ abstract class LocaleKeys {
static const sortByLocation = 'sortByLocation'; static const sortByLocation = 'sortByLocation';
static const sortByNearestLocation = 'sortByNearestLocation'; static const sortByNearestLocation = 'sortByNearestLocation';
static const giveLocationPermissionForNearestList = 'giveLocationPermissionForNearestList'; static const giveLocationPermissionForNearestList = 'giveLocationPermissionForNearestList';
static const timeForFirstReminder = 'timeForFirstReminder';
static const reminderRemovalNote = 'reminderRemovalNote';
} }

@ -13,6 +13,7 @@ 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/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/scroll_wheel_time_picker.dart';
class PrescriptionItemView extends StatelessWidget { class PrescriptionItemView extends StatelessWidget {
int index; int index;
@ -110,51 +111,60 @@ class PrescriptionItemView extends StatelessWidget {
if (await prescriptionVM.checkIfReminderExistForPrescription(index)) { if (await prescriptionVM.checkIfReminderExistForPrescription(index)) {
prescriptionVM.prescriptionDetailsList[index].hasReminder = true; prescriptionVM.prescriptionDetailsList[index].hasReminder = true;
if (prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false) {
LoaderBottomSheet.showLoader(loadingText: "Removing Reminders"); LoaderBottomSheet.showLoader(loadingText: "Removing Reminders");
bool resultValue = await calender.checkAndRemoveMultipleItems(id: prescriptionVM.prescriptionDetailsList[index].itemID.toString()); bool resultValue = await calender.checkAndRemoveMultipleItems(id: prescriptionVM.prescriptionDetailsList[index].itemID.toString());
prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]);
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
return; return;
}
} else { } else {
DateTime startDate = DateTime.now(); DateTime startDate = DateTime.now();
prescriptionVM.serSelectedTime(startDate);
DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt()); DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt());
BottomSheetUtils().showReminderBottomSheet( showCommonBottomSheetWithoutHeight(
context, context,
endDate, child: bottomSheetContent(context),
"", title: LocaleKeys.timeForFirstReminder.tr(),
prescriptionVM.prescriptionDetailsList[index].itemID.toString(),
"", isCloseButtonVisible: true
"",
title: "${prescriptionVM.prescriptionDetailsList[index].itemDescription} Prescription Reminder",
description:
"${prescriptionVM.prescriptionDetailsList[index].itemDescription} ${prescriptionVM.prescriptionDetailsList[index].frequency} ${prescriptionVM.prescriptionDetailsList[index].route} ",
onSuccess: () {},
isMultiAllowed: true,
onMultiDateSuccess: (int selectedIndex) async {
bool isEventAdded = await calender.createMultipleEvents(
reminderMinutes: 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!,
onFailure: (errorMessage) => prescriptionVM.showError(errorMessage),
prescriptionNumber: prescriptionVM.prescriptionDetailsList[index].itemID.toString(),
); );
prescriptionVM.setPrescriptionItemReminder(isEventAdded, prescriptionVM.prescriptionDetailsList[index]);
// setCalender(context, // BottomSheetUtils().showReminderBottomSheet(
// eventId: prescriptionVM.prescriptionDetailsList[index].itemID.toString(), // context,
// selectedMinutes: selectedIndex, // 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: () {},
// isMultiAllowed: true,
// onMultiDateSuccess: (int selectedIndex) async {
// bool isEventAdded = await calender.createMultipleEvents(
// reminderMinutes: selectedIndex,
// frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(), // frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(),
// days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(), // days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(),
// orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!, // orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!,
// itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!, // itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!,
// route: prescriptionVM.prescriptionDetailsList[index].route!); // route: prescriptionVM.prescriptionDetailsList[index].route!,
}, // onFailure: (errorMessage) => prescriptionVM.showError(errorMessage),
); // prescriptionNumber: prescriptionVM.prescriptionDetailsList[index].itemID.toString(),
// );
// prescriptionVM.setPrescriptionItemReminder(isEventAdded, prescriptionVM.prescriptionDetailsList[index]);
// // 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), ).toShimmer2(isShow: isLoading),
@ -186,4 +196,47 @@ class PrescriptionItemView extends StatelessWidget {
), ),
); );
} }
Widget bottomSheetContent(BuildContext context) {
return Column(
children: [
SizedBox(height: 4.h),
LocaleKeys.reminderRemovalNote.tr().toText14(isBold: true, color: AppColors.warningColorYellow),
SizedBox(height: 8.h),
ScrollWheelTimePicker(
initialHour: DateTime.now().hour,
initialMinute: DateTime.now().minute,
use24HourFormat: true,
pickerHeight: 120.h,
itemExtent: 100.h,
onTimeChanged: (time) {
// Handle selected time
debugPrint('Selected time: ${time.hour}:${time.minute}');
prescriptionVM.serSelectedTime(DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, time.hour, time.minute));
},
),
SizedBox(height: 8.h),
CustomButton(
backgroundColor: AppColors.successColor,
borderColor: AppColors.successColor,
text: LocaleKeys.confirm.tr(), onPressed: () async {
CalenderUtilsNew calender = CalenderUtilsNew.instance;
bool isEventAdded = await calender.createMultipleEvents(
reminderMinutes: 10,
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!,
onFailure: (errorMessage) => prescriptionVM.showError(errorMessage),
prescriptionNumber: prescriptionVM.prescriptionDetailsList[index].itemID.toString(),
scheduleDateTime: prescriptionVM.selectedReminderTime,
);
prescriptionVM.setPrescriptionItemReminder(isEventAdded, prescriptionVM.prescriptionDetailsList[index]);
Navigator.of(context).pop();
})
],
);
}
} }

@ -0,0 +1,181 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class ScrollWheelTimePicker extends StatefulWidget {
final int initialHour;
final int initialMinute;
final bool use24HourFormat;
final ValueChanged<TimeOfDay>? onTimeChanged;
final double itemExtent;
final double pickerHeight;
final TextStyle? digitTextStyle;
final TextStyle? separatorTextStyle;
const ScrollWheelTimePicker({
super.key,
this.initialHour = 8,
this.initialMinute = 15,
this.use24HourFormat = true,
this.onTimeChanged,
this.itemExtent = 60,
this.pickerHeight = 180,
this.digitTextStyle,
this.separatorTextStyle,
});
@override
State<ScrollWheelTimePicker> createState() => _ScrollWheelTimePickerState();
}
class _ScrollWheelTimePickerState extends State<ScrollWheelTimePicker> {
late FixedExtentScrollController _hourController;
late FixedExtentScrollController _minuteController;
late int _selectedHour;
late int _selectedMinute;
int get _maxHour => widget.use24HourFormat ? 24 : 12;
@override
void initState() {
super.initState();
_selectedHour = widget.initialHour;
_selectedMinute = widget.initialMinute;
final hourIndex =
widget.use24HourFormat ? _selectedHour : (_selectedHour == 0 ? 11 : _selectedHour - 1);
_hourController = FixedExtentScrollController(initialItem: hourIndex);
_minuteController = FixedExtentScrollController(initialItem: _selectedMinute);
}
@override
void dispose() {
_hourController.dispose();
_minuteController.dispose();
super.dispose();
}
void _notifyChange() {
widget.onTimeChanged?.call(TimeOfDay(hour: _selectedHour, minute: _selectedMinute));
}
TextStyle get _defaultDigitStyle => TextStyle(
fontSize: 72.f,
fontWeight: FontWeight.w800,
color: AppColors.textColor,
letterSpacing: 0,
);
TextStyle get _defaultSeparatorStyle => TextStyle(
fontSize: 40.f,
fontWeight: FontWeight.w800,
color: AppColors.textColor,
letterSpacing: 0,
);
@override
Widget build(BuildContext context) {
final digitStyle = widget.digitTextStyle ?? _defaultDigitStyle;
final separatorStyle = widget.separatorTextStyle ?? _defaultSeparatorStyle;
return SizedBox(
height: widget.pickerHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 150.w,
child: ListWheelScrollView.useDelegate(
controller: _hourController,
itemExtent: widget.itemExtent,
physics: const FixedExtentScrollPhysics(),
perspective: 0.005,
diameterRatio: 1.2,
onSelectedItemChanged: (index) {
setState(() {
_selectedHour =
widget.use24HourFormat ? index : index + 1;
});
_notifyChange();
},
childDelegate: ListWheelChildBuilderDelegate(
childCount: _maxHour,
builder: (context, index) {
final hour =
widget.use24HourFormat ? index : index + 1;
final isSelected = hour == _selectedHour;
return Visibility(
visible: isSelected,
child: Center(
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 200),
style: digitStyle.copyWith(
color: isSelected
? AppColors.textColor
: AppColors.textColor.withValues(alpha: 0.3),
),
child: Text(hour.toString().padLeft(2, '0')),
),
));
},
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 2.w),
child: Text(':', style: separatorStyle),
),
SizedBox(
width: 150.w,
child: ListWheelScrollView.useDelegate(
controller: _minuteController,
itemExtent: widget.itemExtent,
physics: const FixedExtentScrollPhysics(),
perspective: 0.005,
diameterRatio: 1.2,
onSelectedItemChanged: (index) {
setState(() {
_selectedMinute = index;
});
_notifyChange();
},
childDelegate: ListWheelChildBuilderDelegate(
childCount: 60,
builder: (context, index) {
final isSelected = index == _selectedMinute;
return Visibility(
visible: isSelected,
child:
Center(
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 200),
style: digitStyle.copyWith(
color: isSelected
? AppColors.textColor
: AppColors.transparent.withValues(alpha: 0.3),
),
child: Text(index.toString().padLeft(2, '0')),
),
));
},
),
),
),
],
),
);
}
}
Loading…
Cancel
Save