diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 5450f004..2ad381a8 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1570,7 +1570,7 @@ "prediction": "التوقعات", "prevention": "الوقاية", "disclaimer": "إخلاء مسؤولية", - "thisAboveInfo": "المعلومات أعلاه مُوَلّدة بواسطة الذكاء الاصطناعي بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك.", + "thisAboveInfo": "تم تحليل نتائج المختبرهذه بواسطة الذكاء الاصطناعي، وهي لا تُعدّ نصيحة طبية. استشر طبيبك المختص للتشخيص والعلاج.", "aiDisclaimer": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟", "consent": "نتائج المختبر", "bmiNormalDescription": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت.", @@ -1755,5 +1755,9 @@ "errorFetchingData": "حدث خطأ أثناء تحميل البيانات", "negative": "سلبي", "calculateCaloriesBasedOnFactors": "حساب السعرات الحرارية اليومية بناءً على عدة عوامل مثل الطول، الوزن، العمر، الجنس، والنشاط البدني اليومي.", - "conformationCall": "ستتلقى مكالمة لتأكيد طلبك قريباً." + "conformationCall": "ستتلقى مكالمة لتأكيد طلبك قريباً.", + "radiologyLabResults": "نتائج الأشعة", + "disclaimerRadiology": "تم تحليل نتائج الأشعة هذه بواسطة الذكاء الاصطناعي، وهي لا تُعدّ نصيحة طبية. استشر طبيبك المختص للتشخيص والعلاج." + + } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 6a245261..7c4f2ab4 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1572,7 +1572,7 @@ "prediction": "Prediction", "prevention": "Prevention", "disclaimer": "Disclaimer", - "thisAboveInfo": "The above information is generated by AI based on your lab results and is intended for informational purposes only. It should not be considered a medical diagnosis or treatment plan. Always consult with your healthcare provider for personalized medical advice and before making any health-related decisions.", + "thisAboveInfo": "This Lab result was analyzed by AI, and it is not medical advice. Consult your healthcare provider for diagnosis and treatment.", "aiDisclaimer": "Your lab result data will be securely shared with our AI Analyzer for analysis. This helps provide personalized health insights. Do you want to proceed?", "consent": "Consent", "bmiNormalDescription": "Your BMI is within the healthy range. Continue a balanced diet, regular physical activity, and routine checkups to maintain good health. Monitor any significant changes over time.", @@ -1743,7 +1743,11 @@ "finda": "Find a", "calculateCaloriesBasedOnFactors": "Calculates daily calorie intake based on several factors including: height, weight, age, gender and daily physical activity.", "insurance2": "Insurance", - "conformationCall": "You will receive a call from HMG for confirmation " + "conformationCall": "You will receive a call from HMG for confirmation ", + "radiologyLabResults": "Radiology Results", + "disclaimerRadiology": "This radiology result was analyzed by AI, and it is not medical advice. Consult your healthcare provider for diagnosis and treatment." + + } diff --git a/lib/core/utils/push_notification_handler.dart b/lib/core/utils/push_notification_handler.dart index 6fc248f9..770961de 100644 --- a/lib/core/utils/push_notification_handler.dart +++ b/lib/core/utils/push_notification_handler.dart @@ -51,12 +51,15 @@ _incomingCall(Map data) async { // GetIt.instance().saveString(key: CacheConst.zoomRoomID, value: roomID); // GetIt.instance().saveBool(key: CacheConst.isAppOpenedFromCall, value: true); - Utils.saveStringFromPrefs(CacheConst.zoomRoomID, roomID); - Utils.saveStringFromPrefs(CacheConst.callTypeID, callTypeID); - Utils.saveBoolFromPrefs(CacheConst.isAppOpenedFromCall, true); + await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, roomID); + await Utils.saveStringFromPrefs(CacheConst.callTypeID, callTypeID); + await Utils.saveBoolFromPrefs(CacheConst.isAppOpenedFromCall, true); + WidgetsFlutterBinding.ensureInitialized(); + int callKitType = callTypeID == '2' ? 0 : 1; + var _currentUuid = Uuid().v4(); CallKitParams callKitParams = CallKitParams( id: _currentUuid, @@ -64,7 +67,7 @@ _incomingCall(Map data) async { appName: 'Dr Al Habib', avatar: 'https://play-lh.googleusercontent.com/FBNNpxb7m6eM6wtW7MV1Ffp6OXOGLI38q47zcvP29OCYA1yhYH5mZzl5itZi0TgOyZpG', // handle: LandingPage.incomingCallData.name, - type: 1, + type: callKitType, textAccept: 'Accept', textDecline: 'Decline', missedCallNotification: NotificationParams( @@ -80,7 +83,11 @@ _incomingCall(Map data) async { callbackText: 'Hang Up', ), duration: 30000, - extra: {'userId': '1a2b3c4d'}, + extra: { + 'userId': '1a2b3c4d', + 'callTypeID': callTypeID, // Store actual callTypeID here + 'roomID': roomID, // Store roomID here for backup + }, headers: {'apiKey': 'Abc@123!', 'platform': 'flutter'}, android: const AndroidParams( isImportant: true, diff --git a/lib/features/radiology/radiology_repo.dart b/lib/features/radiology/radiology_repo.dart index 30b078ef..7374b247 100644 --- a/lib/features/radiology/radiology_repo.dart +++ b/lib/features/radiology/radiology_repo.dart @@ -42,7 +42,7 @@ class RadiologyRepoImp implements RadiologyRepo { failure = failureType; }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { - final radOrders; + List radOrders = []; try { if (response['FinalRadiologyList'] != null && response['FinalRadiologyList'].length != 0) { final list = response['FinalRadiologyList']; @@ -52,10 +52,18 @@ class RadiologyRepoImp implements RadiologyRepo { .cast(); } else { final list = response['FinalRadiologyListAPI']; - radOrders = list - .map((item) => PatientRadiologyResponseModel.fromJson(item as Map)) - .toList() - .cast(); + if(list != null && list.length != 0) { + radOrders = list + .map((item) => PatientRadiologyResponseModel.fromJson(item as Map)) + .toList() + .cast(); + } + } + + // Check if radOrders is empty and set failure + if (radOrders.isEmpty) { + failure = ServerFailure(errorMessage ?? "No radiology orders found"); + return; } apiResponse = GenericApiModel>( @@ -203,6 +211,12 @@ class RadiologyRepoImp implements RadiologyRepo { } } + // Check if radOrders is empty and set failure + if (radOrders.isEmpty) { + failure = ServerFailure(errorMessage ?? "No radiology orders found for this appointment"); + return; + } + apiResponse = GenericApiModel>( messageStatus: messageStatus, statusCode: statusCode, diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 2cba788e..5ced1efb 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1746,5 +1746,7 @@ abstract class LocaleKeys { static const negative = 'negative'; static const calculateCaloriesBasedOnFactors = 'calculateCaloriesBasedOnFactors'; static const conformationCall = 'conformationCall'; + static const radiologyLabResults = 'radiologyLabResults'; + static const disclaimerRadiology = 'disclaimerRadiology'; } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 66d2b151..dfdde83a 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -430,8 +430,8 @@ class _AppointmentDetailsPageState extends State { const Spacer(), BellAnimatedSwitch( key: _bellSwitchKey, - width: 48.w, - height: 30.h, + width: 56.w, + height: 38.h, initialValue: widget.patientAppointmentHistoryResponseModel.hasReminder ?? false, activeColor: AppColors.successColor.withOpacity(0.2), inactiveColor: AppColors.lightGrayBGColor, diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index fabb9043..505afcdf 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -717,35 +717,37 @@ class _AppointmentCardState extends State { // Countdown Timer - DD : HH : MM : SS format with labels - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // // Days - // _buildTimeUnit( - // _timeRemaining != null ? _timeRemaining!.inDays.toString().padLeft(2, '0') : '00', - // LocaleKeys.days.tr(context: context), - // ), - // _buildTimeSeparator(), - // // Hours - // _buildTimeUnit( - // _timeRemaining != null ? _timeRemaining!.inHours.remainder(24).toString().padLeft(2, '0') : '00', - // LocaleKeys.hours.tr(context: context), - // ), - // _buildTimeSeparator(), - // // Minutes - // _buildTimeUnit( - // _timeRemaining != null ? _timeRemaining!.inMinutes.remainder(60).toString().padLeft(2, '0') : '00', - // LocaleKeys.minutes.tr(context: context), - // ), - // _buildTimeSeparator(), - // // Seconds - // _buildTimeUnit( - // _timeRemaining != null ? _timeRemaining!.inSeconds.remainder(60).toString().padLeft(2, '0') : '00', - // LocaleKeys.seconds.tr(context: context), - // ), - // ], - // ), + Directionality( + textDirection: ui.TextDirection.ltr, + child:Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Days + _buildTimeUnit( + _timeRemaining != null ? _timeRemaining!.inDays.toString().padLeft(2, '0') : '00', + LocaleKeys.days.tr(context: context), + ), + _buildTimeSeparator(), + // Hours + _buildTimeUnit( + _timeRemaining != null ? _timeRemaining!.inHours.remainder(24).toString().padLeft(2, '0') : '00', + LocaleKeys.hours.tr(context: context), + ), + _buildTimeSeparator(), + // Minutes + _buildTimeUnit( + _timeRemaining != null ? _timeRemaining!.inMinutes.remainder(60).toString().padLeft(2, '0') : '00', + LocaleKeys.minutes.tr(context: context), + ), + _buildTimeSeparator(), + // Seconds + _buildTimeUnit( + _timeRemaining != null ? _timeRemaining!.inSeconds.remainder(60).toString().padLeft(2, '0') : '00', + LocaleKeys.seconds.tr(context: context), + ), + ], + )), SizedBox(height: 24.h), // Green Acknowledge button with checkmark icon CustomButton( diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 0e4e2aeb..05358243 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -151,7 +151,7 @@ class AppointmentDoctorCard extends StatelessWidget { ), ), - patientAppointmentHistoryResponseModel.isLiveCareAppointment! || patientAppointmentHistoryResponseModel.isClinicReBookingAllowed! || patientAppointmentHistoryResponseModel.isActiveDoctor! == false + patientAppointmentHistoryResponseModel.isLiveCareAppointment! || patientAppointmentHistoryResponseModel.isClinicReBookingAllowed! ==false || patientAppointmentHistoryResponseModel.isActiveDoctor! == false ? SizedBox.shrink() : Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown).onPress(() async { DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel(); diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index bbb6b4eb..05164dec 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -70,7 +70,8 @@ class LoginScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Utils.showLottie(context: context, assetPath: AppAnimations.login, width: 200.h, height: 200.h, repeat: true, fit: BoxFit.cover), - SizedBox(height: 130.h), // Adjusted to sizer unit + // SizedBox(height: 130.h), + SizedBox(height: MediaQuery.of(context).size.height * 0.12), // based on the screen height Adjusted to sizer unit LocaleKeys.welcomeToDrSulaiman.tr(context: context).toText32(isBold: true, color: AppColors.textColor ), SizedBox(height: 32.h), Localizations.override(context: context, locale: Locale('en', 'US'), child: Container()), // Force English locale for this widget diff --git a/lib/presentation/health_calculators_and_converts/health_calculators_page.dart b/lib/presentation/health_calculators_and_converts/health_calculators_page.dart index 877a5d9b..a7fe0ef5 100644 --- a/lib/presentation/health_calculators_and_converts/health_calculators_page.dart +++ b/lib/presentation/health_calculators_and_converts/health_calculators_page.dart @@ -135,8 +135,8 @@ class _HealthCalculatorsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - LocaleKeys.bloodSugar.tr().toText16(isBold: true), - LocaleKeys.trackYourGlucoseLevels.tr().toText12( + LocaleKeys.bloodSugar.tr(context: context).toText16(isBold: true), + LocaleKeys.trackYourGlucoseLevels.tr(context: context).toText12( isBold: true, color: Color(0xFF8F9AA3), ) @@ -168,7 +168,7 @@ class _HealthCalculatorsPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, - children: [LocaleKeys.bloodCholesterol.tr().toText16(isBold: true), LocaleKeys.monitorCholesterolLevels.tr().toText12(isBold: true, color: Color(0xFF8F9AA3))], + children: [LocaleKeys.bloodCholesterol.tr(context: context).toText16(isBold: true), LocaleKeys.monitorCholesterolLevels.tr(context: context).toText12(isBold: true, color: Color(0xFF8F9AA3))], ), ), SizedBox(width: 12.w), @@ -195,8 +195,8 @@ class _HealthCalculatorsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - LocaleKeys.triglyceridesFatBlood.tr().toText16(isBold: true), - LocaleKeys.understandTriglyceridesImpact.tr().toText12(isBold: true, color: Color(0xFF8F9AA3)) + LocaleKeys.triglyceridesFatBlood.tr(context: context).toText16(isBold: true), + LocaleKeys.understandTriglyceridesImpact.tr(context: context).toText12(isBold: true, color: Color(0xFF8F9AA3)) ], ), ), diff --git a/lib/presentation/health_trackers/add_health_tracker_entry_page.dart b/lib/presentation/health_trackers/add_health_tracker_entry_page.dart index 0305eebf..829c4a95 100644 --- a/lib/presentation/health_trackers/add_health_tracker_entry_page.dart +++ b/lib/presentation/health_trackers/add_health_tracker_entry_page.dart @@ -154,7 +154,8 @@ class _AddHealthTrackerEntryPageState extends State { } // Show success message and pop back - void _showSuccessAndPop() { + + void _showSuccessAndPop() async{ showCommonBottomSheetWithoutHeight( context, child: Utils.getSuccessWidget( @@ -164,7 +165,13 @@ class _AddHealthTrackerEntryPageState extends State { }, isCloseButtonVisible: false, isDismissible: true, - isFullScreen: false, isAutoDismiss: true); + isFullScreen: false, isAutoDismiss: false); + await Future.delayed(Duration(milliseconds: 2000)).then((value) { + if (mounted){ + Navigator.pop(context); + Navigator.pop(context); + } + }); } // Reusable method to build selection row widget @@ -366,7 +373,7 @@ class _AddHealthTrackerEntryPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - "Unit".toText12(isBold: true, color: AppColors.inputLabelTextColor), + LocaleKeys.unit.tr(context: context).toText12(isBold: true, color: AppColors.inputLabelTextColor), unit.toText12(isBold: true, color: AppColors.textColor), ], ), @@ -473,7 +480,7 @@ class _AddHealthTrackerEntryPageState extends State { controller: dateController, isReadOnly: true, isArrowTrailing: true, - labelText: "Date", + labelText: LocaleKeys.date.tr(context: context), hintText: LocaleKeys.pickADate.tr(context: context), focusNode: FocusNode(), isEnable: true, @@ -503,7 +510,7 @@ class _AddHealthTrackerEntryPageState extends State { controller: timeController, isReadOnly: true, isArrowTrailing: true, - labelText: "Time", + labelText: LocaleKeys.time.tr(context: context), hintText: LocaleKeys.selectMeasureTime.tr(context: context), focusNode: FocusNode(), isEnable: true, diff --git a/lib/presentation/health_trackers/health_trackers_page.dart b/lib/presentation/health_trackers/health_trackers_page.dart index e974773c..e066b106 100644 --- a/lib/presentation/health_trackers/health_trackers_page.dart +++ b/lib/presentation/health_trackers/health_trackers_page.dart @@ -84,7 +84,7 @@ class _HealthTrackersPageState extends State { iconBgColor: AppColors.primaryRedColor, icon: AppAssets.bloodSugarOnlyIcon, title: LocaleKeys.bloodSugar.tr(context: context), - description: "Track your glucose levels, understand trends, and get personalized insights for better health.", + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), onTap: () { context.navigateWithName( AppRoutes.healthTrackerDetailPage, diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 4f648c96..56923038 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -32,6 +32,7 @@ import 'package:hmg_patient_app_new/presentation/hmg_services/services_view.dart import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; import 'package:hmg_patient_app_new/presentation/home/service_info_page.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; +import 'package:hmg_patient_app_new/presentation/hmg_services/widgets/weather_widget.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/parking/paking_page.dart'; import 'package:hmg_patient_app_new/presentation/servicesPriceList/services_price_list_page.dart'; @@ -378,8 +379,8 @@ class _ServicesPageState extends State { void initState() { // TODO: implement initState super.initState(); - //weatherVM = getIt(); - // weatherVM.fetchCityInfoList(); + weatherVM = getIt(); + weatherVM.fetchCityInfoList(); } @@ -390,85 +391,18 @@ class _ServicesPageState extends State { medicalFileViewModel = Provider.of(context); hmgServices.removeWhere((element) => Utils.havePrivilege(element.action) == false); - return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: LocaleKeys.exploreServices.tr(), - isLeading: widget.showBackIcon, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Row( - // children: [ - // Flexible( - // child: Container( - // padding: EdgeInsets.all(16.w), - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: false), - // child: Column( - // children: [ - // Row( - // children: [ - // Utils.buildSvgWithAssets(icon: "assets/images/svg/cloudyweather.svg", width: 64.w, height: 64.w).onPress(() { - // // locationUtils?.getCurrentLocation(); - // print(getIt.get().userLat); - // print(getIt.get().userLong); - // }), - // SizedBox(width: 12.w), - // Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // "August 19, 2025 - Tuesday, 11:25 ".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), - // SizedBox( - // height: 4.w, - // ), - // "Cloudy 38oC".toText16(isBold: true, weight: FontWeight.w600), - // SizedBox( - // height: 4.w, - // ), - // "Health tips based on current weather".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500) - // ], - // ), - // ], - // ), - // SizedBox(height: 16.w), - // Container( - // padding: EdgeInsets.all(16.w), - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // color: AppColors.lightGrayBGColor, - // borderRadius: 10.r, - // hasShadow: false, - // ), - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.center, - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Row( - // children: [ - // Utils.buildSvgWithAssets(icon: "assets/images/svg/morning.svg", width: 24.w, height: 24.h), - // SizedBox(width: 4.w), - // DateTime.now().toLocal().toString().substring(11, 16).toText14(isBold: true), - // ], - // ), - // SizedBox(width: 25.w), - // DateTime.now().toLocal().toString().substring(11, 16).toText14(isBold: true), - // SizedBox(width: 25.w), - // Row( - // children: [ - // Utils.buildSvgWithAssets(icon: "assets/images/svg/evening.svg", width: 24.w, height: 24.h), - // SizedBox(width: 4.w), - // DateTime.now().toLocal().toString().substring(11, 16).toText14(isBold: true), - // ], - // ), - // ], - // ).expanded, - // ).paddingSymmetrical(0.w, 8.w) - // ], - // ), - // ), - // ) - // ], - // ).paddingSymmetrical(24.w, 0.w), - SizedBox(height: 16.h), + return ChangeNotifierProvider.value( + value: weatherVM, + child: Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.exploreServices.tr(), + isLeading: widget.showBackIcon, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const WeatherWidget(), + SizedBox(height: 16.h), LocaleKeys.medicalAndCareServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), GridView.builder( @@ -910,6 +844,7 @@ class _ServicesPageState extends State { ], ), ), + ), ); } } diff --git a/lib/presentation/hmg_services/widgets/weather_widget.dart b/lib/presentation/hmg_services/widgets/weather_widget.dart new file mode 100644 index 00000000..4c353763 --- /dev/null +++ b/lib/presentation/hmg_services/widgets/weather_widget.dart @@ -0,0 +1,194 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.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/weather/weather_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/weather/weather_details_page.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/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; + +class WeatherWidget extends StatelessWidget { + final bool showButton; + + const WeatherWidget({super.key, this.showButton = true}); + + String _getWeatherIcon(String? categoryValue) { + if (categoryValue == null) return "assets/images/svg/cloudyweather.svg"; + + final lowerValue = categoryValue.toLowerCase(); + if (lowerValue.contains('sunny') || lowerValue.contains('clear')) { + return "assets/images/svg/morning.svg"; + } else if (lowerValue.contains('cloudy') || lowerValue.contains('cloud')) { + return "assets/images/svg/cloudyweather.svg"; + } else if (lowerValue.contains('rain')) { + return "assets/images/svg/cloudyweather.svg"; + } + return "assets/images/svg/cloudyweather.svg"; + } + + String _formatDateTime(DateTime dateTime) { + final formatter = DateFormat('MMMM dd, yyyy - EEEE, HH:mm'); + return formatter.format(dateTime); + } + + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, weatherVM, child) { + final currentCity = weatherVM.cityInfoList.isNotEmpty + ? weatherVM.cityInfoList.first + : null; + + final now = DateTime.now(); + final temperature = currentCity?.temperature; + final healthTip = LocaleKeys.healthTipsBasedOnCurrentWeather.tr(); + + return Row( + children: [ + Flexible( + child: Container( + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, + ), + child: weatherVM.isLoading + ? _buildLoadingState() + : Column( + children: [ + Row( + children: [ + Utils.buildSvgWithAssets( + icon: _getWeatherIcon(currentCity?.categoryValue), + width: 64.w, + height: 64.w, + ), + SizedBox(width: 12.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _formatDateTime(now).toText12( + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + SizedBox(height: 4.w), + "$temperature°C" + .toText16( + isBold: true, + weight: FontWeight.w600, + ), + SizedBox(height: 4.w), + healthTip.toText12( + color: AppColors.greyTextColor, + fontWeight: FontWeight.w500, + maxLine: 2, + ), + ], + ), + ), + ], + ), + if (showButton) ...[ + SizedBox(height: 16.w), + CustomButton( + text: LocaleKeys.viewDetails.tr(context: context), + onPressed: () { + Navigator.of(context).push( + CustomPageRoute( + page: ChangeNotifierProvider.value( + value: weatherVM, + child: const WeatherDetailsPage(), + ), + ), + ); + }, + padding: EdgeInsets.zero, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 10.r, + height: 40.h, + ), + ], + ], + ), + ), + ), + ], + ).paddingSymmetrical(24.w, 0.w); + }, + ); + } + + Widget _buildLoadingState() { + return Column( + children: [ + Row( + children: [ + Container( + width: 64.w, + height: 64.w, + decoration: BoxDecoration( + color: AppColors.lightGrayBGColor, + borderRadius: BorderRadius.circular(12.r), + ), + ), + SizedBox(width: 12.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + height: 12.h, + decoration: BoxDecoration( + color: AppColors.lightGrayBGColor, + borderRadius: BorderRadius.circular(6.r), + ), + ), + SizedBox(height: 8.h), + Container( + width: 100.w, + height: 16.h, + decoration: BoxDecoration( + color: AppColors.lightGrayBGColor, + borderRadius: BorderRadius.circular(8.r), + ), + ), + SizedBox(height: 8.h), + Container( + width: double.infinity, + height: 12.h, + decoration: BoxDecoration( + color: AppColors.lightGrayBGColor, + borderRadius: BorderRadius.circular(6.r), + ), + ), + ], + ), + ), + ], + ), + SizedBox(height: 16.w), + Container( + height: 56.h, + decoration: BoxDecoration( + color: AppColors.lightGrayBGColor, + borderRadius: BorderRadius.circular(10.r), + ), + ), + ], + ); + } +} + diff --git a/lib/presentation/insurance/insurance_approval_details_page.dart b/lib/presentation/insurance/insurance_approval_details_page.dart index 6589bc4e..6d8e2524 100644 --- a/lib/presentation/insurance/insurance_approval_details_page.dart +++ b/lib/presentation/insurance/insurance_approval_details_page.dart @@ -53,8 +53,16 @@ class InsuranceApprovalDetailsPage extends StatelessWidget { children: [ AppCustomChipWidget( labelText: insuranceApprovalResponseModel.approvalStatusDescption, - backgroundColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor.withOpacity(0.1) : AppColors.primaryRedColor.withOpacity(0.1), - textColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor : AppColors.primaryRedColor, + backgroundColor: insuranceApprovalResponseModel.status == 9 + ? AppColors.successColor.withValues(alpha: 0.1) + : (insuranceApprovalResponseModel.approvalStatusDescption?.toLowerCase().contains('partial') == true || insuranceApprovalResponseModel.status == 8) + ? AppColors.warningColorYellow.withValues(alpha: 0.1) + : AppColors.primaryRedColor.withValues(alpha: 0.1), + textColor: insuranceApprovalResponseModel.status == 9 + ? AppColors.successColor + : (insuranceApprovalResponseModel.approvalStatusDescption?.toLowerCase().contains('partial') == true || insuranceApprovalResponseModel.status == 8) + ? AppColors.warningColorYellow + : AppColors.primaryRedColor, ), AppCustomChipWidget( icon: (!insuranceApprovalResponseModel.isLiveCareAppointment! ? AppAssets.walkin_appointment_icon : AppAssets.small_livecare_icon), @@ -65,7 +73,7 @@ class InsuranceApprovalDetailsPage extends StatelessWidget { ), AppCustomChipWidget( labelText: appState.isArabic() ? insuranceApprovalResponseModel.isInOutPatientDescriptionN! : insuranceApprovalResponseModel.isInOutPatientDescription!, - backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1), textColor: AppColors.warningColorYellow, ), ], diff --git a/lib/presentation/insurance/widgets/insurance_approval_card.dart b/lib/presentation/insurance/widgets/insurance_approval_card.dart index b50e199f..a12a26b6 100644 --- a/lib/presentation/insurance/widgets/insurance_approval_card.dart +++ b/lib/presentation/insurance/widgets/insurance_approval_card.dart @@ -24,6 +24,34 @@ class InsuranceApprovalCard extends StatelessWidget { AppState appState; bool isLoading; + /// Helper method to determine if approval is partially approved + bool _isPartiallyApproved() { + final description = insuranceApprovalResponseModel.approvalStatusDescption?.toLowerCase() ?? ''; + return description.contains('partial') || insuranceApprovalResponseModel.status == 8; + } + + /// Helper method to get chip background color based on approval status + Color _getChipBackgroundColor() { + if (insuranceApprovalResponseModel.status == 9) { + return AppColors.successColor.withValues(alpha: 0.1); + } else if (_isPartiallyApproved()) { + return AppColors.warningColorYellow.withValues(alpha: 0.1); + } else { + return AppColors.primaryRedColor.withValues(alpha: 0.1); + } + } + + /// Helper method to get chip text color based on approval status + Color _getChipTextColor() { + if (insuranceApprovalResponseModel.status == 9) { + return AppColors.successColor; + } else if (_isPartiallyApproved()) { + return AppColors.warningColorYellow; + } else { + return AppColors.primaryRedColor; + } + } + @override Widget build(BuildContext context) { return Container( @@ -45,8 +73,8 @@ class InsuranceApprovalCard extends StatelessWidget { children: [ AppCustomChipWidget( labelText: isLoading ? "Approved" : insuranceApprovalResponseModel.approvalStatusDescption, - backgroundColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor.withOpacity(0.1) : AppColors.primaryRedColor.withOpacity(0.1), - textColor: insuranceApprovalResponseModel.status == 9 ? AppColors.successColor : AppColors.primaryRedColor, + backgroundColor: isLoading ? AppColors.successColor.withValues(alpha: 0.1) : _getChipBackgroundColor(), + textColor: isLoading ? AppColors.successColor : _getChipTextColor(), ).toShimmer2(isShow: isLoading), AppCustomChipWidget( icon: isLoading ? AppAssets.walkin_appointment_icon : (!insuranceApprovalResponseModel.isLiveCareAppointment! ? AppAssets.walkin_appointment_icon : AppAssets.small_livecare_icon), @@ -69,7 +97,7 @@ class InsuranceApprovalCard extends StatelessWidget { : appState.isArabic() ? insuranceApprovalResponseModel.isInOutPatientDescriptionN! : insuranceApprovalResponseModel.isInOutPatientDescription!, - backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1), textColor: AppColors.warningColorYellow, ).toShimmer2(isShow: isLoading), ], diff --git a/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart b/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart index 2e769609..a67a6765 100644 --- a/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart +++ b/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart @@ -350,7 +350,8 @@ class _MedicalFileAppointmentCardState extends State ), SizedBox(height: 24.h), // Countdown Timer - DD : HH : MM : SS format with labels - Row( + Directionality( + textDirection: ui.TextDirection.ltr, child:Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -378,7 +379,7 @@ class _MedicalFileAppointmentCardState extends State LocaleKeys.seconds.tr(context: context), ), ], - ), + )), SizedBox(height: 24.h), // Green Acknowledge button with checkmark icon CustomButton( diff --git a/lib/presentation/radiology/radiology_ai_analysis_detailed_page.dart b/lib/presentation/radiology/radiology_ai_analysis_detailed_page.dart index 78a3a097..a3e00e79 100644 --- a/lib/presentation/radiology/radiology_ai_analysis_detailed_page.dart +++ b/lib/presentation/radiology/radiology_ai_analysis_detailed_page.dart @@ -79,7 +79,7 @@ class _RadiologyAiAnalysisDetailedPageState extends State { } // Case 2: Should stop flag is true OR Case 3: Probability >= 70% OR Case 4: 7 or more questions answered - if (viewModel.shouldStopTriage || highestProbability >= 70.0 || viewModel.triageQuestionCount >= 15) { + if (viewModel.shouldStopTriage || highestProbability >= 70.0 || viewModel.triageQuestionCount >= 30) { // Navigate to results/possible conditions screen context.navigateWithName(AppRoutes.possibleConditionsPage); return; diff --git a/lib/presentation/weather/weather_details_page.dart b/lib/presentation/weather/weather_details_page.dart new file mode 100644 index 00000000..0057f9b6 --- /dev/null +++ b/lib/presentation/weather/weather_details_page.dart @@ -0,0 +1,185 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.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/dependencies.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/weather/models/waether_cities_model.dart'; +import 'package:hmg_patient_app_new/features/weather/weather_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/hmg_services/widgets/weather_widget.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'; + +class WeatherDetailsPage extends StatelessWidget { + const WeatherDetailsPage({super.key}); + + Color _getColorFromColorName(ColorName? colorName) { + if (colorName == null) return AppColors.successColor; + + switch (colorName) { + case ColorName.GREEN: + return AppColors.successColor; + case ColorName.ORANGE: + return AppColors.warningColor; + case ColorName.RED: + return AppColors.errorColor; + } + } + + Color _getBackgroundColorFromColorName(ColorName? colorName) { + if (colorName == null) return AppColors.successLightColor.withValues(alpha: 0.1); + + switch (colorName) { + case ColorName.GREEN: + return AppColors.successLightColor.withValues(alpha: 0.1); + case ColorName.ORANGE: + return AppColors.warningLightColor.withValues(alpha: 0.1); + case ColorName.RED: + return AppColors.errorLightColor.withValues(alpha: 0.1); + } + } + + IconData _getIconFromCategory(String? category) { + if (category == null) return Icons.wb_sunny_outlined; + + final lowerCategory = category.toLowerCase(); + if (lowerCategory.contains('walking') || lowerCategory.contains('activity')) { + return Icons.directions_walk; + } else if (lowerCategory.contains('weather') || lowerCategory.contains('temperature')) { + return Icons.thermostat_outlined; + } else if (lowerCategory.contains('elderly') || lowerCategory.contains('hiking')) { + return Icons.elderly; + } + return Icons.wb_sunny_outlined; + } + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, weatherVM, child) { + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.healthWeatherIndicators.tr(), + isLeading: true, + child: weatherVM.isLoading + ? Center( + child: CircularProgressIndicator( + color: AppColors.primaryRedColor, + ), + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Reuse WeatherWidget at the top (without the button) + const WeatherWidget(showButton: false), + + SizedBox(height: 16.h), + + // Categories List (Sliders) + ...weatherVM.cityInfoList.map((cityInfo) { + return _buildCategoryCard( + description: cityInfo.name ?? '', + categoryLabel: cityInfo.category ?? '', + color: _getColorFromColorName(cityInfo.colorName), + backgroundColor: _getBackgroundColorFromColorName(cityInfo.colorName), + icon: _getIconFromCategory(cityInfo.category), + ); + }), + + SizedBox(height: 24.h), + ], + ), + ), + ); + }, + ); + } + + Widget _buildCategoryCard({ + required String description, + required String categoryLabel, + required Color color, + required Color backgroundColor, + required IconData icon, + }) { + return Container( + margin: EdgeInsets.only(bottom: 16.h), + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 16.r, + hasShadow: false, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Icon + Container( + width: 40.w, + height: 40.w, + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(8.r), + ), + child: Icon( + icon, + color: color, + size: 24.w, + ), + ), + SizedBox(width: 12.w), + // Content + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + description.toText14( + isBold: true, + color: AppColors.textColor, + ), + SizedBox(height: 8.h), + // Progress bar + Container( + height: 4.h, + decoration: BoxDecoration( + color: AppColors.lightGrayBGColor, + borderRadius: BorderRadius.circular(2.r), + ), + child: FractionallySizedBox( + alignment: Alignment.centerLeft, + widthFactor: 0.7, + child: Container( + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(2.r), + ), + ), + ), + ), + ], + ), + ), + SizedBox(width: 12.w), + // Category Label + Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h), + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(8.r), + ), + child: categoryLabel.toText12( + color: color, + fontWeight: FontWeight.w600, + maxLine: 1 + ), + ), + ], + ), + ).paddingSymmetrical(24.w, 0.w); + } +} + diff --git a/lib/splashPage.dart b/lib/splashPage.dart index f17d8bc3..c7be036f 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -79,10 +79,9 @@ class _SplashScreenState extends State { } navigateToTeleConsult() async { + String roomID = await Utils.getStringFromPrefs(CacheConst.zoomRoomID); String callTypeID = await Utils.getStringFromPrefs(CacheConst.callTypeID); - print('RoomID: $roomID'); - print('callTypeID: $callTypeID'); // GetIt.instance().remove(key: CacheConst.isAppOpenedFromCall); Utils.removeFromPrefs(CacheConst.isAppOpenedFromCall); @@ -116,6 +115,18 @@ class _SplashScreenState extends State { print('actionCallAccept Event Received: ------->'); FlutterCallkitIncoming.endAllCalls(); try { + // Get callTypeID and roomID from event's extra data + String? eventCallTypeID = event.body['extra']?['callTypeID']; + String? eventRoomID = event.body['extra']?['roomID']; + + // Re-save to SharedPreferences to ensure they're available + if (eventCallTypeID != null && eventCallTypeID.isNotEmpty) { + await Utils.saveStringFromPrefs(CacheConst.callTypeID, eventCallTypeID); + } + if (eventRoomID != null && eventRoomID.isNotEmpty) { + await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, eventRoomID); + } + navigateToTeleConsult(); // String roomID = await Utils.getStringFromPrefs(SharedPrefsConsts.ZOOM_ROOM_ID); // String roomPass = await Utils.getStringFromPrefs(SharedPrefsConsts.ZOOM_ROOM_PASS); diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 51948f01..8b43d1ed 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -9,7 +9,7 @@ import 'package:hmg_patient_app_new/core/enums.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/generated/locale_kesy.g.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/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/date_range_calender.dart'; @@ -274,10 +274,10 @@ class TextInputWidget extends StatelessWidget { final picked = await TimePickerWidget.show( context, initialTime: initialTime, - use24HourFormat: false, // You can make this configurable if needed + use24HourFormat: true, onTimeSelected: (time) { if (onChange != null) { - final formattedTime = TimePickerWidget.formatTime(time); + final formattedTime = TimePickerWidget.formatTime(time, use24HourFormat: true); onChange!(formattedTime); } }, @@ -285,7 +285,7 @@ class TextInputWidget extends StatelessWidget { // Update controller if time was picked if (picked != null && controller != null) { - controller!.text = TimePickerWidget.formatTime(picked); + controller!.text = TimePickerWidget.formatTime(picked, use24HourFormat: true); } }, child: Utils.buildSvgWithAssets(icon: isArrowTrailing ? AppAssets.arrow_down : AppAssets.alarm_clock_icon), diff --git a/lib/widgets/language_switcher.dart b/lib/widgets/language_switcher.dart index 3ee10df3..15237363 100644 --- a/lib/widgets/language_switcher.dart +++ b/lib/widgets/language_switcher.dart @@ -56,8 +56,7 @@ class _LanguageSelectorState extends State { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.language), - SizedBox(width: 6.h), + Text( // currentLangData['name']?.toUpperCase() ?? 'EN', widget.currentLanguage == 'ar' ? "ENGLISH" : "العربية", @@ -69,6 +68,9 @@ class _LanguageSelectorState extends State { isLanguageSwitcher: true, fontFamily: widget.currentLanguage == 'ar' ? "Poppins" : "CairoArabic"), ), + SizedBox(width: 6.h), + Utils.buildSvgWithAssets(icon: AppAssets.language), + ], ), ), diff --git a/lib/widgets/time_picker_widget.dart b/lib/widgets/time_picker_widget.dart index fd5cb409..eadbf5f3 100644 --- a/lib/widgets/time_picker_widget.dart +++ b/lib/widgets/time_picker_widget.dart @@ -1,3 +1,5 @@ +import 'dart:ui' as ui; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -126,48 +128,50 @@ class _TimePickerBottomSheetState extends State<_TimePickerBottomSheet> { @override Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: AppColors.whiteColor, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20.r), - topRight: Radius.circular(20.r), + return Directionality( + textDirection: ui.TextDirection.ltr, + child: Container( + decoration: BoxDecoration( + color: AppColors.whiteColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20.r), + topRight: Radius.circular(20.r), + ), ), - ), - child: SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // Header - Container( - padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: AppColors.dividerColor, - width: 1, + child: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Header + Container( + padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: AppColors.dividerColor, + width: 1, + ), ), ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.selectTime.tr(context: context).toText18( - weight: FontWeight.w600, - color: AppColors.textColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.selectTime.tr(context: context).toText18( + weight: FontWeight.w600, + color: AppColors.textColor, + ), + GestureDetector( + onTap: () => Navigator.pop(context), + child: Utils.buildSvgWithAssets( + icon: AppAssets.cancel, + width: 24.h, + height: 24.h, + iconColor: AppColors.textColor, ), - GestureDetector( - onTap: () => Navigator.pop(context), - child: Utils.buildSvgWithAssets( - icon: AppAssets.cancel, - width: 24.h, - height: 24.h, - iconColor: AppColors.textColor, ), - ), - ], + ], + ), ), - ), // Time Picker SizedBox( @@ -345,6 +349,7 @@ class _TimePickerBottomSheetState extends State<_TimePickerBottomSheet> { ], ), ), + ), ); } }