diff --git a/assets/images/png/smartwatches/Huawei_Watch.png b/assets/images/png/smartwatches/Huawei_Watch.png new file mode 100644 index 00000000..97c416e4 Binary files /dev/null and b/assets/images/png/smartwatches/Huawei_Watch.png differ diff --git a/assets/images/png/smartwatches/Whoop_Watch.png b/assets/images/png/smartwatches/Whoop_Watch.png new file mode 100644 index 00000000..b3ac20cd Binary files /dev/null and b/assets/images/png/smartwatches/Whoop_Watch.png differ diff --git a/assets/images/svg/arrow-back_new.svg b/assets/images/svg/arrow-back_new.svg new file mode 100644 index 00000000..cae96941 --- /dev/null +++ b/assets/images/svg/arrow-back_new.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/book_appo_bottom.svg b/assets/images/svg/book_appo_bottom.svg index d09107ec..18b65b8f 100644 --- a/assets/images/svg/book_appo_bottom.svg +++ b/assets/images/svg/book_appo_bottom.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/svg/close_bottom_nav_new.svg b/assets/images/svg/close_bottom_nav_new.svg new file mode 100644 index 00000000..1b7b9378 --- /dev/null +++ b/assets/images/svg/close_bottom_nav_new.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/close_bottom_nav_trans.svg b/assets/images/svg/close_bottom_nav_trans.svg new file mode 100644 index 00000000..e00aaf96 --- /dev/null +++ b/assets/images/svg/close_bottom_nav_trans.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/close_bottom_sheet_icon.svg b/assets/images/svg/close_bottom_sheet_icon.svg index 599ce85f..e00aaf96 100644 --- a/assets/images/svg/close_bottom_sheet_icon.svg +++ b/assets/images/svg/close_bottom_sheet_icon.svg @@ -1,4 +1,3 @@ - - - + + diff --git a/assets/images/svg/feedback_fill.svg b/assets/images/svg/feedback_fill.svg new file mode 100644 index 00000000..bb7c6a23 --- /dev/null +++ b/assets/images/svg/feedback_fill.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/svg/home_bottom.svg b/assets/images/svg/home_bottom.svg index 1bf82f98..70c3f1f2 100644 --- a/assets/images/svg/home_bottom.svg +++ b/assets/images/svg/home_bottom.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/assets/images/svg/home_bottom_fill.svg b/assets/images/svg/home_bottom_fill.svg new file mode 100644 index 00000000..30ed655f --- /dev/null +++ b/assets/images/svg/home_bottom_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/insurance_history_icon.svg b/assets/images/svg/insurance_history_icon.svg index 4ae2a1c5..e81bd873 100644 --- a/assets/images/svg/insurance_history_icon.svg +++ b/assets/images/svg/insurance_history_icon.svg @@ -1,4 +1,4 @@ - - - + + + diff --git a/assets/images/svg/location_fill.svg b/assets/images/svg/location_fill.svg new file mode 100644 index 00000000..a5afffb7 --- /dev/null +++ b/assets/images/svg/location_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/my_files_bottom.svg b/assets/images/svg/my_files_bottom.svg index 813805e0..a21fb4b3 100644 --- a/assets/images/svg/my_files_bottom.svg +++ b/assets/images/svg/my_files_bottom.svg @@ -1,4 +1,4 @@ - - + + diff --git a/assets/images/svg/my_files_bottom_fill.svg b/assets/images/svg/my_files_bottom_fill.svg new file mode 100644 index 00000000..e4916e00 --- /dev/null +++ b/assets/images/svg/my_files_bottom_fill.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/news.svg b/assets/images/svg/news.svg index 82f9dcfc..6ed40d3a 100644 --- a/assets/images/svg/news.svg +++ b/assets/images/svg/news.svg @@ -1,6 +1,6 @@ - - - - - + + + + + diff --git a/assets/images/svg/news_fill.svg b/assets/images/svg/news_fill.svg new file mode 100644 index 00000000..ed9697cc --- /dev/null +++ b/assets/images/svg/news_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/services_bottom.svg b/assets/images/svg/services_bottom.svg index baa3d6b8..2b0733f2 100644 --- a/assets/images/svg/services_bottom.svg +++ b/assets/images/svg/services_bottom.svg @@ -1,6 +1,6 @@ - - - - + + + + diff --git a/assets/images/svg/services_bottom_fill.svg b/assets/images/svg/services_bottom_fill.svg new file mode 100644 index 00000000..41f4f5b2 --- /dev/null +++ b/assets/images/svg/services_bottom_fill.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/svg/symptom_bottom_icon.svg b/assets/images/svg/symptom_bottom_icon.svg index bc729711..e9b3bd03 100644 --- a/assets/images/svg/symptom_bottom_icon.svg +++ b/assets/images/svg/symptom_bottom_icon.svg @@ -1,3 +1,3 @@ - + diff --git a/assets/images/svg/symptom_bottom_icon_fill.svg b/assets/images/svg/symptom_bottom_icon_fill.svg new file mode 100644 index 00000000..7192ae8a --- /dev/null +++ b/assets/images/svg/symptom_bottom_icon_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 7a9b34c2..178b4c05 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1525,6 +1525,8 @@ "insuranceAndPayments": "التأمين والمدفوعات", "trackerAndOthers": "المتتبع وأخرى", "bmi": "مؤشر كتلة الجسم", + "yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة", + "noThanksIKnowTheClinic": "لا شكراً، أعرف العيادة" "unableToSendOTP": "تعذر إرسال رمز التحقق لمرة واحدة" diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index afcb5987..d6f52289 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1516,6 +1516,8 @@ "insuranceAndPayments": "Insurance & Payments", "trackerAndOthers": "Tracker & Others", "bmi": "BMI", + "yesPleaseINeedHelp": "Yes, Please I need help", + "noThanksIKnowTheClinic": "No, Thanks. I Know the clinic" "unableToSendOTP": "Unable to send Verification OTP" diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index f7153052..8319c9de 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -702,6 +702,8 @@ class ApiConsts { static String QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + static String CHAT_URL = "https://chat.hmg.com/Index.aspx?RequestedId="; + // static String GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments"; // var payFortEnvironment = FortEnvironment.test; @@ -719,6 +721,7 @@ class ApiConsts { GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid='; rcBaseUrl = 'https://rc.hmg.com/'; QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + CHAT_URL = "https://chat.hmg.com/Index.aspx?RequestedId="; break; case AppEnvironmentTypeEnum.dev: baseUrl = "https://uat.hmgwebservices.com/"; @@ -730,6 +733,7 @@ class ApiConsts { GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid='; rcBaseUrl = 'https://rc.hmg.com/uat/'; QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId"; break; case AppEnvironmentTypeEnum.uat: baseUrl = "https://uat.hmgwebservices.com/"; @@ -741,6 +745,7 @@ class ApiConsts { GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid='; rcBaseUrl = 'https://rc.hmg.com/uat/'; QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId"; break; case AppEnvironmentTypeEnum.preProd: baseUrl = "https://webservices.hmg.com/"; @@ -752,6 +757,7 @@ class ApiConsts { GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid='; rcBaseUrl = 'https://rc.hmg.com/'; QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId"; break; case AppEnvironmentTypeEnum.qa: baseUrl = "https://uat.hmgwebservices.com/"; @@ -763,6 +769,7 @@ class ApiConsts { GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid='; rcBaseUrl = 'https://rc.hmg.com/uat/'; QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId"; break; case AppEnvironmentTypeEnum.staging: baseUrl = "https://uat.hmgwebservices.com/"; @@ -774,6 +781,7 @@ class ApiConsts { GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid='; rcBaseUrl = 'https://rc.hmg.com/uat/'; QLINE_URL = "https://ms.hmg.com/nscapi/api/PatientCall/PatientInQueue_Detail"; + CHAT_URL = "https://chat.hmg.com/geneysChat/Index.aspx?RequestedId"; break; } } diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 35d48d69..5b8d2ed5 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -4,6 +4,7 @@ class AppAssets { static const String hmg = '$svgBasePath/hmg.svg'; static const String arrow_back = '$svgBasePath/arrow-back.svg'; + static const String arrow_back_new = '$svgBasePath/arrow-back_new.svg'; static const String arrow_forward = '$svgBasePath/arrow_forward.svg'; static const String externalLink = '$svgBasePath/external_link.svg'; static const String calendar = '$svgBasePath/calendar.svg'; @@ -25,6 +26,7 @@ class AppAssets { static const String download = '$svgBasePath/download.svg'; static const String language = '$svgBasePath/language.svg'; static const String location = '$svgBasePath/location.svg'; + static const String locationFill = '$svgBasePath/location_fill.svg'; static const String pin_location = '$svgBasePath/pin_location.svg'; static const String whatsapp = '$svgBasePath/whatsapp.svg'; static const String card_user = '$svgBasePath/card_user.svg'; @@ -231,13 +233,20 @@ class AppAssets { //bottom navigation// static const String homeBottom = '$svgBasePath/home_bottom.svg'; + static const String homeBottomFill = '$svgBasePath/home_bottom_fill.svg'; static const String bookAppoBottom = '$svgBasePath/book_appo_bottom.svg'; static const String myFilesBottom = '$svgBasePath/my_files_bottom.svg'; + static const String myFilesBottomFill = '$svgBasePath/my_files_bottom_fill.svg'; static const String toDoBottom = '$svgBasePath/todo_bottom.svg'; static const String servicesBottom = '$svgBasePath/services_bottom.svg'; + static const String servicesBottomFill = '$svgBasePath/services_bottom_fill.svg'; static const String closeBottomNav = '$svgBasePath/close_bottom_nav.svg'; + static const String close_bottom_nav_new = '$svgBasePath/close_bottom_nav_new.svg'; + static const String close_bottom_nav_trans = '$svgBasePath/close_bottom_nav_trans.svg'; static const String feedback = '$svgBasePath/feedback.svg'; + static const String feedbackFill = '$svgBasePath/feedback_fill.svg'; static const String news = '$svgBasePath/news.svg'; + static const String newsFill = '$svgBasePath/news_fill.svg'; static const String heart = '$svgBasePath/heart.svg'; static const String alertSquare = '$svgBasePath/alert-square.svg'; static const String arrowRight = '$svgBasePath/arrow-right.svg'; @@ -254,6 +263,7 @@ class AppAssets { static const String homeBorderedIcon = '$svgBasePath/home_bordered.svg'; static const String symptomCheckerIcon = '$svgBasePath/symptom_checker_icon.svg'; static const String symptomCheckerBottomIcon = '$svgBasePath/symptom_bottom_icon.svg'; + static const String symptomCheckerBottomFillIcon = '$svgBasePath/symptom_bottom_icon_fill.svg'; static const String coloredDotsIcon = '$svgBasePath/colored_dots_icon.svg'; // Water Monitor diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart index 02b81957..d04ad70d 100644 --- a/lib/core/utils/size_utils.dart +++ b/lib/core/utils/size_utils.dart @@ -4,8 +4,11 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; // These are the Viewport values of your Figma Design. // These are used in the code as a reference to create your UI Responsively. -const num figmaDesignWidth = 375; // iPhone X / 12 base width -const num figmaDesignHeight = 812; // iPhone X / 12 base height +const num figmaDesignWidth = 430; // iPhone X / 12 base width, 375 +const num figmaDesignHeight = 927; // iPhone X / 12 base height 812 + +const num figmaDesignWidthTF = 375; +const num figmaDesignHeightTF = 812; extension ConstrainedResponsive on num { /// Width with max cap for tablets @@ -50,9 +53,9 @@ extension ResponsiveExtension on num { double get w { double baseScale = (this * _screenWidth) / figmaDesignWidth; - if (_isFoldable) { + if (_isFoldable|| isTablet ) { // For foldables, use more conservative width scaling - double scale = _screenWidth / figmaDesignWidth; + double scale = _screenWidth / figmaDesignWidthTF; scale = scale.clamp(0.8, 1.4); return this * scale; } @@ -64,9 +67,9 @@ extension ResponsiveExtension on num { double get h { double baseScale = (this * _screenHeight) / figmaDesignHeight; - if (_isFoldable) { + if (_isFoldable || isTablet ) { // For foldables, use height-based scaling but with constraints - double scale = (_screenHeight / figmaDesignHeight).clamp(0.8, 1.4); + double scale = (_screenHeight / figmaDesignHeightTF).clamp(0.8, 1.4); return this * scale; } @@ -79,7 +82,7 @@ extension ResponsiveExtension on num { if (_isFoldable || isTablet) { // Use the same logic as enhanced width for foldables - double scale = _screenWidth / figmaDesignWidth; + double scale = _screenWidth / figmaDesignWidthTF; scale = scale.clamp(0.8, 1.4); return this * scale; } diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 59954385..10d37675 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -367,7 +367,7 @@ class Utils { crossAxisAlignment: CrossAxisAlignment.center, children: [ Lottie.asset(AppAnimations.loadingAnimation, - repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), + repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.fill), SizedBox(height: 8.h), (loadingText ?? LocaleKeys.loadingText.tr()).toText16(color: AppColors.blackColor, isCenter: true), SizedBox(height: 8.h), @@ -820,6 +820,7 @@ class Utils { color: textColor, fontSize: fontSize ?? 32.f, letterSpacing: letterSpacing ?? -4, + fontFamily: "Poppins", fontWeight: fontWeight ?? FontWeight.w600, height: 1), ), diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 309dde19..1df051ea 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -92,6 +92,7 @@ extension EmailValidator on String { FontWeight? fontWeight, bool isCenter = false, double? height, + double? letterSpacing, int maxLine = 0}) => Text( this, @@ -101,7 +102,7 @@ extension EmailValidator on String { fontSize: 12.f, fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, - letterSpacing: 0, + letterSpacing: letterSpacing ?? 0, height: height, decorationColor: isUnderLine ? AppColors.blackColor : null, decoration: isUnderLine ? TextDecoration.underline : null, diff --git a/lib/features/radiology/radiology_view_model.dart b/lib/features/radiology/radiology_view_model.dart index 46a27bfc..c8150c12 100644 --- a/lib/features/radiology/radiology_view_model.dart +++ b/lib/features/radiology/radiology_view_model.dart @@ -112,7 +112,8 @@ class RadiologyViewModel extends ChangeNotifier { final result = await radiologyRepo.getRadiologyImage(patientRadiologyResponseModel: patientRadiologyResponseModel); result.fold( - (failure) async => await errorHandlerService.handleError(failure: failure), + // (failure) async => await errorHandlerService.handleError(failure: failure), + (failure) async {}, (apiResponse) { if (apiResponse.messageStatus == 2) { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); diff --git a/lib/features/smartwatch_health_data/health_provider.dart b/lib/features/smartwatch_health_data/health_provider.dart index fc9dacc5..0acb25bb 100644 --- a/lib/features/smartwatch_health_data/health_provider.dart +++ b/lib/features/smartwatch_health_data/health_provider.dart @@ -10,6 +10,15 @@ class HealthProvider with ChangeNotifier { String selectedTimeRange = '7D'; int selectedTabIndex = 0; + String selectedWatchType = 'apple'; + String selectedWatchURL = 'assets/images/png/smartwatches/apple-watch-5.jpg'; + + setSelectedWatchType(String type, String imageURL) { + selectedWatchType = type; + selectedWatchURL = imageURL; + notifyListeners(); + } + void onTabChanged(int index) { selectedTabIndex = index; notifyListeners(); diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index cccad9e8..416d2a47 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1512,6 +1512,8 @@ abstract class LocaleKeys { static const insuranceAndPayments = 'insuranceAndPayments'; static const trackerAndOthers = 'trackerAndOthers'; static const bmi = 'bmi'; + static const yesPleaseINeedHelp = 'yesPleaseINeedHelp'; + static const noThanksIKnowTheClinic = 'noThanksIKnowTheClinic'; static const unableToSendOTP = 'unableToSendOTP'; } diff --git a/lib/main.dart b/lib/main.dart index e15e8a74..6010a05d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; @@ -203,7 +204,7 @@ void main() async { create: (_) => getIt.get(), ) ], child: MyApp()), - ), + ), // Wrap your app ); } @@ -243,4 +244,3 @@ class MyApp extends StatelessWidget { } } // flutter pub run easy_localization:generate -S assets/langs -f keys -o locale_keys.g.dart - diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 6b0439f1..e1748c3a 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -175,15 +175,15 @@ class AppointmentCard extends StatelessWidget { AppCustomChipWidget( labelText: isLoading ? 'Cardiology' - : (patientAppointmentHistoryResponseModel.clinicName!.length > 15 - ? '${patientAppointmentHistoryResponseModel.clinicName!.substring(0, 12)}...' + : (patientAppointmentHistoryResponseModel.clinicName!.length > 20 + ? '${patientAppointmentHistoryResponseModel.clinicName!.substring(0, 20)}...' : patientAppointmentHistoryResponseModel.clinicName!), ).toShimmer2(isShow: isLoading), AppCustomChipWidget( labelText: isLoading ? 'Olaya' : patientAppointmentHistoryResponseModel.projectName!.length > 15 - ? '${patientAppointmentHistoryResponseModel.projectName!.substring(0, 12)}...' + ? '${patientAppointmentHistoryResponseModel.projectName!.substring(0, 15)}...' : patientAppointmentHistoryResponseModel.projectName!) .toShimmer2(isShow: isLoading), AppCustomChipWidget( diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index b95e0c26..cf5eef34 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -60,6 +60,9 @@ class _BookAppointmentPageState extends State { bookAppointmentsViewModel.getLocation(); immediateLiveCareViewModel.initImmediateLiveCare(); }); + WidgetsBinding.instance.addPostFrameCallback((_) { + showUnKnownClinicBottomSheet(); + }); super.initState(); } @@ -313,10 +316,10 @@ class _BookAppointmentPageState extends State { ], ).paddingSymmetrical(24.h, 0.h); case 1: - //TODO: Get LiveCare type Select UI from Hussain + //TODO: Get LiveCare type Select UI from Hussain return appState.isAuthenticated ? Column( - children: [ + children: [ Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -447,9 +450,9 @@ class _BookAppointmentPageState extends State { LocaleKeys.notSureHelpMeChooseClinic.tr(context: context).toText16(weight: FontWeight.w600, color: AppColors.textColor), SizedBox(height: 8.h), LocaleKeys.mentionYourSymptomsAndFindDoctors.tr(context: context).toText12( - fontWeight: FontWeight.w500, - color: AppColors.greyTextColor, - ), + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), ], ), ), @@ -470,10 +473,13 @@ class _BookAppointmentPageState extends State { regionalViewModel.flush(); regionalViewModel.setBottomSheetType(type); // AppointmentViaRegionViewmodel? viewmodel = null; - showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer(builder: (_, data, __) => getTitle(data)), isDismissible: false, + showCommonBottomSheetWithoutHeight(context, title: "", + titleWidget: Consumer(builder: (_, data, __) => getTitle(data)), + isDismissible: false, child: Consumer(builder: (_, data, __) { - return getRegionalSelectionWidget(data); - }), callBackFunc: () {}); + return getRegionalSelectionWidget(data); + }), + callBackFunc: () {}); } Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data) { @@ -632,4 +638,53 @@ class _BookAppointmentPageState extends State { ], ).paddingSymmetrical(24.h, 0.h); } + + void showUnKnownClinicBottomSheet() { + showCommonBottomSheetWithoutHeight( + context, + title: "", + isDismissible: true, + isCloseButtonVisible: false, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.notSureHelpMeChooseClinic.tr(context: context).toText28(color: AppColors.textColor, isBold: true, height: 1.5), + SizedBox(height: 4.h), + LocaleKeys.mentionYourSymptomsAndFindDoctors.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500,), + SizedBox(height: 24.h), + CustomButton( + text: LocaleKeys.yesPleaseINeedHelp.tr(context: context), + onPressed: () { + context.pop(); + context.navigateWithName(AppRoutes.userInfoSelection); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 56.h, + ), + SizedBox(height: 8.h), + CustomButton( + text: LocaleKeys.noThanksIKnowTheClinic.tr(context: context), + onPressed: () { + context.pop(); + }, + backgroundColor: AppColors.chipSecondaryLightRedColor, + borderColor: AppColors.chipSecondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 56.h, + ), + ], + ).paddingSymmetrical(24.w, 20.h), + callBackFunc: () {}, + ); + } } diff --git a/lib/presentation/contact_us/feedback_page.dart b/lib/presentation/contact_us/feedback_page.dart index 62ae1d36..8f10bc54 100644 --- a/lib/presentation/contact_us/feedback_page.dart +++ b/lib/presentation/contact_us/feedback_page.dart @@ -148,20 +148,18 @@ class FeedbackPage extends StatelessWidget { ), child: Padding( padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.ask_doctor_icon, width: 24.w, height: 24.h, iconColor: AppColors.greyTextColor), - SizedBox(width: 12.w), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.feedbackType.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.ask_doctor_icon, width: 24.w, height: 24.h, iconColor: AppColors.greyTextColor), + SizedBox(width: 12.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.feedbackType.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500), (getIt.get().isArabic() ? contactUsViewModel.selectedFeedbackType.nameAR : contactUsViewModel.selectedFeedbackType.nameEN) .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), ], diff --git a/lib/presentation/contact_us/live_chat_page.dart b/lib/presentation/contact_us/live_chat_page.dart index 2b86ccb4..a602eb14 100644 --- a/lib/presentation/contact_us/live_chat_page.dart +++ b/lib/presentation/contact_us/live_chat_page.dart @@ -1,6 +1,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/api_consts.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/dependencies.dart'; @@ -8,12 +9,17 @@ 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'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.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/routes/custom_page_route.dart'; +import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -23,10 +29,12 @@ class LiveChatPage extends StatelessWidget { String chatURL = ""; late AppState appState; + late AuthenticationViewModel authVm; @override Widget build(BuildContext context) { appState = getIt.get(); + authVm = context.read(); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: Consumer(builder: (context, contactUsVM, child) { @@ -158,13 +166,71 @@ class LiveChatPage extends StatelessWidget { child: CustomButton( text: LocaleKeys.liveChat.tr(context: context), onPressed: () async { - if (contactUsVM.chatRequestID != null) { - chatURL = "https://chat.hmg.com/Index.aspx?RequestedId=${contactUsVM.chatRequestID}"; - debugPrint("Chat URL: $chatURL"); - Uri uri = Uri.parse(chatURL); - launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); + if(appState.isAuthenticated) { + if (contactUsVM.chatRequestID != null) { + chatURL = "${ApiConsts.CHAT_URL}${contactUsVM.chatRequestID}"; + debugPrint("Chat URL: $chatURL"); + Uri uri = Uri.parse(chatURL); + launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); + } else { + debugPrint("Chat Request ID is null"); + } } else { - debugPrint("Chat Request ID is null"); + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.notice.tr(context: context), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), + SizedBox(height: 8.h), + (LocaleKeys.loginToUseService.tr(context: context)).toText16(color: AppColors.blackColor), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: CustomButton( + text: LocaleKeys.cancel.tr(context: context), + onPressed: () { + Navigator.of(context).pop(); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + icon: AppAssets.cancel, + iconColor: AppColors.primaryRedColor, + ), + ), + SizedBox(width: 8.h), + Expanded( + child: CustomButton( + text: LocaleKeys.confirm.tr(context: context), + onPressed: () async { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil( + context, + CustomPageRoute( + page: LandingNavigation(), + ), + (r) => false); + await authVm.onLoginPressed(); + }, + backgroundColor: AppColors.bgGreenColor, + borderColor: AppColors.bgGreenColor, + textColor: Colors.white, + icon: AppAssets.confirm, + ), + ), + ], + ), + SizedBox(height: 16.h), + ], + ).center, + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); } }, backgroundColor: contactUsVM.selectedLiveChatProjectIndex == -1 ? AppColors.greyColor : AppColors.primaryRedColor, diff --git a/lib/presentation/habib_wallet/habib_wallet_page.dart b/lib/presentation/habib_wallet/habib_wallet_page.dart index b096e946..c90003a8 100644 --- a/lib/presentation/habib_wallet/habib_wallet_page.dart +++ b/lib/presentation/habib_wallet/habib_wallet_page.dart @@ -82,28 +82,26 @@ class _HabibWalletState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ CustomButton( + height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 21.h, + iconSize: 24.w, + backgroundColor: AppColors.infoColor, + textColor: AppColors.whiteColor, text: LocaleKeys.recharge.tr(context: context), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + padding: EdgeInsets.fromLTRB(4, 0, 12, 0), + fontSize: 14.f, onPressed: () { Navigator.of(context) - .push( - CustomPageRoute( - page: RechargeWalletPage(), - ), - ) + .push(CustomPageRoute( + page: RechargeWalletPage(), + )) .then((val) { habibWalletVM.getPatientBalanceAmount(); }); }, - backgroundColor: AppColors.infoColor, - borderColor: AppColors.infoColor, - textColor: AppColors.whiteColor, - fontSize: 14, - fontWeight: FontWeight.bold, - borderRadius: 12, - // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, ), ], ), diff --git a/lib/presentation/habib_wallet/recharge_wallet_page.dart b/lib/presentation/habib_wallet/recharge_wallet_page.dart index 33de5e6a..b8e2d01f 100644 --- a/lib/presentation/habib_wallet/recharge_wallet_page.dart +++ b/lib/presentation/habib_wallet/recharge_wallet_page.dart @@ -85,30 +85,26 @@ class _RechargeWalletPageState extends State { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Utils.getPaymentAmountWithSymbol( - SizedBox( - width: 150.h, - child: TextInputWidget( - controller: amountTextController, - labelText: "", - hintText: "", - isEnable: true, - prefix: null, - isAllowRadius: true, - isBorderAllowed: false, - isAllowLeadingIcon: true, - autoFocus: true, - fontSize: 40, - padding: EdgeInsets.symmetric(horizontal: 8.h, vertical: 0.h), - focusNode: textFocusNode, - isWalletAmountInput: true, - keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), - // leadingIcon: AppAssets.student_card, - ), - ), - AppColors.textColor, - 13.h, - isExpanded: false), + SizedBox( + width: 150.h, + child: TextInputWidget( + controller: amountTextController, + labelText: "", + hintText: "", + isEnable: true, + prefix: null, + isAllowRadius: true, + isBorderAllowed: false, + isAllowLeadingIcon: true, + autoFocus: true, + fontSize: 40, + padding: EdgeInsets.symmetric(horizontal: 8.h, vertical: 0.h), + focusNode: textFocusNode, + isWalletAmountInput: true, + keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), + // leadingIcon: AppAssets.student_card, + ), + ), const Spacer(), LocaleKeys.sar.tr(context: context).toText20(color: AppColors.greyTextColor, weight: FontWeight.w500), ], @@ -140,9 +136,9 @@ class _RechargeWalletPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (habibWalletVM.getSelectedRechargeTypeValue()).toText16(color: AppColors.textColor, weight: FontWeight.w500), + (habibWalletVM.getSelectedRechargeTypeValue()).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), "${LocaleKeys.medicalFile.tr(context: context)}: ${habibWalletVM.fileNumber}" - .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + .toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2), ], ), ], @@ -178,11 +174,11 @@ class _RechargeWalletPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.hospital.tr(context: context).toText16(color: AppColors.textColor, weight: FontWeight.w500), + LocaleKeys.hospital.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), SizedBox( width: MediaQuery.of(context).size.width * 0.55, child: (habibWalletVM.selectedHospital != null ? habibWalletVM.selectedHospital!.name : LocaleKeys.selectHospital.tr(context: context))! - .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + .toText14(color: AppColors.textColor, weight: FontWeight.w500), ), ], ), @@ -198,19 +194,14 @@ class _RechargeWalletPageState extends State { Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), SizedBox(height: 16.h), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( + Utils.buildSvgWithAssets(icon: AppAssets.email_icon, width: 40.h, height: 40.h), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.email_icon, width: 40.h, height: 40.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), - "${appState.getAuthenticatedUser()!.emailAddress}".toText16(color: AppColors.textColor, weight: FontWeight.w500), - ], - ), + LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + "${appState.getAuthenticatedUser()!.emailAddress}".toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2), ], ), ], @@ -229,7 +220,7 @@ class _RechargeWalletPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.notes.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), - "Lorem Ipsum".toText16(color: AppColors.textColor, weight: FontWeight.w500), + "Lorem Ipsum".toText14(color: AppColors.textColor, weight: FontWeight.w500, letterSpacing: -0.2), ], ), ], diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index bf4ef3e3..10b93423 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -44,7 +44,9 @@ import '../../features/qr_parking/qr_parking_view_model.dart'; import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; class ServicesPage extends StatelessWidget { - ServicesPage({super.key}); + bool showBackIcon; + + ServicesPage({super.key, this.showBackIcon = true}); late BloodDonationViewModel bloodDonationViewModel; late MedicalFileViewModel medicalFileViewModel; @@ -174,39 +176,39 @@ class ServicesPage extends StatelessWidget { // route: AppRoutes.covid19Test, // ), -// HmgServicesComponentModel( -// 11, -// "Vital Sign".needTranslation, -// "".needTranslation, -// AppAssets.covid19icon, -// bgColor: AppColors.covid29Color, -// true, -// route: AppRoutes.vitalSign, -// ) + // HmgServicesComponentModel( + // 11, + // "Vital Sign".needTranslation, + // "".needTranslation, + // AppAssets.covid19icon, + // bgColor: AppColors.covid29Color, + // true, + // route: AppRoutes.vitalSign, + // ) -// HmgServicesComponentModel( -// 3, -// "Home Health Care".needTranslation, -// "".needTranslation, -// AppAssets.homeBottom, -// bgColor: AppColors.primaryRedColor, -// true, -// route: AppRoutes.homeHealthCarePage, -// ), -// HmgServicesComponentModel( -// 11, -// "Virtual Tour".needTranslation, -// "".needTranslation, -// AppAssets.my_address, -// bgColor: AppColors.quickLoginColor, -// true, -// route: null, -// onTap:(){ -// Utils.openWebView( -// url: 'https://hmgwebservices.com/vt_mobile/html/index.html', -// ); -// }, -// ) + // HmgServicesComponentModel( + // 3, + // "Home Health Care".needTranslation, + // "".needTranslation, + // AppAssets.homeBottom, + // bgColor: AppColors.primaryRedColor, + // true, + // route: AppRoutes.homeHealthCarePage, + // ), + // HmgServicesComponentModel( + // 11, + // "Virtual Tour".needTranslation, + // "".needTranslation, + // AppAssets.my_address, + // bgColor: AppColors.quickLoginColor, + // true, + // route: null, + // onTap:(){ + // Utils.openWebView( + // url: 'https://hmgwebservices.com/vt_mobile/html/index.html', + // ); + // }, + // ) ]; late final List hmgHealthToolServices = [ @@ -304,20 +306,19 @@ class ServicesPage extends StatelessWidget { backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: LocaleKeys.exploreServices.tr(), - isLeading: false, + isLeading: showBackIcon, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 16.h), - LocaleKeys.medicalAndCareServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + LocaleKeys.medicalAndCareServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row - crossAxisSpacing: 12.w, - mainAxisSpacing: 18.h, - childAspectRatio: 0.8, - ), + crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row + crossAxisSpacing: 21.w, + mainAxisSpacing: 18.h, + childAspectRatio: 80 / 94), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: hmgServices.length, @@ -327,7 +328,7 @@ class ServicesPage extends StatelessWidget { }, ).paddingSymmetrical(24.w, 0), SizedBox(height: 24.h), - LocaleKeys.hmgServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + LocaleKeys.hmgServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), SizedBox( height: 350.h, @@ -358,13 +359,14 @@ class ServicesPage extends StatelessWidget { ), ), SizedBox(height: 24.h), - LocaleKeys.personalServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + LocaleKeys.personalServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), Row( children: [ Expanded( child: Container( - height: 170.h, + height: 183.h, + width: 183.h, padding: EdgeInsets.all(16.w), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -378,7 +380,7 @@ class ServicesPage extends StatelessWidget { spacing: 8.w, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 30.w, height: 30.h), + Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h), LocaleKeys.habibWallet.tr().toText14(weight: FontWeight.w600, maxlines: 2).expanded, Utils.buildSvgWithAssets(icon: AppAssets.arrow_forward), ], @@ -395,19 +397,19 @@ class ServicesPage extends StatelessWidget { ? CustomButton( height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 16.w, - iconColor: AppColors.infoColor, - textColor: AppColors.infoColor, - text: LocaleKeys.recharge.tr(), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 12.f, - onPressed: () { - Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); - }, + iconSize: 24.w, + iconColor: AppColors.infoColor, + textColor: AppColors.infoColor, + text: LocaleKeys.recharge.tr(), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 14.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, ) : SizedBox.shrink(), ], @@ -423,7 +425,8 @@ class ServicesPage extends StatelessWidget { SizedBox(width: 16.w), Expanded( child: Container( - height: 170.h, + height: 183.h, + width: 183.h, padding: EdgeInsets.all(16.w), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -437,69 +440,69 @@ class ServicesPage extends StatelessWidget { spacing: 8.w, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 30.w, height: 30.h), - LocaleKeys.medicalFile.tr().toText14(weight: FontWeight.w600, maxlines: 2).expanded, + Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h), + LocaleKeys.medicalFile.tr().toText16(weight: FontWeight.w600, maxlines: 2).expanded, Utils.buildSvgWithAssets(icon: AppAssets.arrow_forward), ], ), Spacer(), getIt.get().isAuthenticated ? Wrap( - spacing: -8.h, - // runSpacing: 0.h, - children: [ - Utils.buildImgWithAssets( - icon: AppAssets.babyGirlImg, - height: 28.h, - width: 28.w, - border: 1, - fit: BoxFit.contain, - borderRadius: 50.r, - ), - Utils.buildImgWithAssets( - icon: AppAssets.femaleImg, - height: 28.h, - width: 28.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - Utils.buildImgWithAssets( - icon: AppAssets.maleImg, - height: 28.h, - width: 28.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - ], + spacing: -12.h, + // runSpacing: 0.h, + children: [ + Utils.buildImgWithAssets( + icon: AppAssets.babyGirlImg, + height: 32.h, + width: 32.w, + border: 1, + fit: BoxFit.contain, + borderRadius: 50.r, + ), + Utils.buildImgWithAssets( + icon: AppAssets.femaleImg, + height: 32.h, + width: 32.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + Utils.buildImgWithAssets( + icon: AppAssets.maleImg, + height: 32.h, + width: 32.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + ], ) : LocaleKeys.loginToViewMedicalFile.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2), Spacer(), getIt.get().isAuthenticated ? CustomButton( height: 40.h, - icon: AppAssets.add_icon, - iconSize: 16.w, - iconColor: AppColors.primaryRedColor, - textColor: AppColors.primaryRedColor, - text: LocaleKeys.addMember.tr(), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 12.f, - onPressed: () { - DialogService dialogService = getIt.get(); - medicalFileViewModel.clearAuthValues(); - dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), - onVerificationPress: () { - medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, + icon: AppAssets.add_icon, + iconSize: 24.h, + iconColor: AppColors.primaryRedColor, + textColor: AppColors.primaryRedColor, + text: LocaleKeys.addMember.tr(), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 14.f, + onPressed: () { + DialogService dialogService = getIt.get(); + medicalFileViewModel.clearAuthValues(); + dialogService.showAddFamilyFileSheet( + label: LocaleKeys.addFamilyMember.tr(), + message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), + onVerificationPress: () { + medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + }); + }, ) : SizedBox.shrink(), ], @@ -519,14 +522,14 @@ class ServicesPage extends StatelessWidget { ], ).paddingSymmetrical(24.w, 0), SizedBox(height: 24.h), - LocaleKeys.healthTools.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + LocaleKeys.healthTools.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row - crossAxisSpacing: 12.w, + crossAxisSpacing: 21.w, mainAxisSpacing: 18.h, - childAspectRatio: 0.8, + childAspectRatio: 80.w / 94.h, ), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -542,7 +545,7 @@ class ServicesPage extends StatelessWidget { }, ).paddingSymmetrical(24.w, 0), SizedBox(height: 24.h), - LocaleKeys.supportServices.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0), + LocaleKeys.supportServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -567,7 +570,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - LocaleKeys.virtualTour.tr().toText12(fontWeight: FontWeight.w500) + LocaleKeys.virtualTour.tr().toText14(weight: FontWeight.w500) ], ), ), @@ -596,7 +599,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - LocaleKeys.carParking.tr().toText12(fontWeight: FontWeight.w500) + LocaleKeys.carParking.tr().toText14(weight: FontWeight.w500) ], ).onPress(() { Navigator.push( @@ -635,7 +638,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - LocaleKeys.latestNews.tr().toText12(fontWeight: FontWeight.w500) + LocaleKeys.latestNews.tr().toText14(weight: FontWeight.w500) ], ), ), @@ -664,7 +667,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - LocaleKeys.hmgContact.tr().toText12(fontWeight: FontWeight.w500) + LocaleKeys.hmgContact.tr().toText14(weight: FontWeight.w500) ], ), ), diff --git a/lib/presentation/hmg_services/services_view.dart b/lib/presentation/hmg_services/services_view.dart index 99085a53..3dd5c462 100644 --- a/lib/presentation/hmg_services/services_view.dart +++ b/lib/presentation/hmg_services/services_view.dart @@ -36,7 +36,7 @@ class ServiceGridViewItem extends StatelessWidget { children: [ Container( height: 48.h, - width: 48.w, + width: 48.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: hmgServiceComponentModel.bgColor, borderRadius: 12.r, @@ -51,7 +51,7 @@ class ServiceGridViewItem extends StatelessWidget { ), ), ), - SizedBox(height: 5.h), + SizedBox(height: 4.h), hmgServiceComponentModel.title.toText12( fontWeight: FontWeight.w500, color: AppColors.textColor, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index ab0d247e..e0c15d0f 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -52,6 +52,7 @@ import 'package:hmg_patient_app_new/presentation/todo_section/ancillary_procedur import 'package:hmg_patient_app_new/presentation/todo_section/widgets/ancillary_orders_list.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; +import 'package:hmg_patient_app_new/services/zoom_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; @@ -88,6 +89,14 @@ class _LandingPageState extends State { final SwiperController _controller = SwiperController(); + final ScrollController _horizontalScrollController = ScrollController(); + + @override + void dispose() { + _horizontalScrollController.dispose(); + super.dispose(); + } + @override void initState() { authVM = context.read(); @@ -187,30 +196,30 @@ class _LandingPageState extends State { fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), + padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0), height: 40.h, ), Consumer(builder: (context, todoSectionVM, child) { return Row( mainAxisSize: MainAxisSize.min, - spacing: 12.h, + spacing: 18.h, children: [ - appState.isAuthenticated - ? Stack(children: [ - Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h).onPress(() async { - if (appState.isAuthenticated) { - notificationsViewModel.setNotificationStatusID(2); - notificationsViewModel.getAllNotifications(); - Navigator.of(context).push( - CustomPageRoute( - page: NotificationsListPage(), - // page: LoginScreen(), - ), - ); - } else { - await authVM.onLoginPressed(); - } - }), + Stack(children: [ + if (appState.isAuthenticated) + Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async { + if (appState.isAuthenticated) { + notificationsViewModel.setNotificationStatusID(2); + notificationsViewModel.getAllNotifications(); + Navigator.of(context).push( + CustomPageRoute( + page: NotificationsListPage(), + // page: LoginScreen(), + ), + ); + } else { + await authVM.onLoginPressed(); + } + }), (appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0)) ? Positioned( right: 0, @@ -234,12 +243,11 @@ class _LandingPageState extends State { ), ) : SizedBox.shrink(), - ]) - : SizedBox.shrink(), - Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 18.h, width: 18.h).onPress(() { + ]), + Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 24.h, width: 24.w).onPress(() { openIndoorNavigationBottomSheet(context); }), - Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 18.h, width: 18.h).onPress(() { + Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() { showCommonBottomSheetWithoutHeight( context, title: LocaleKeys.contactUs.tr(), @@ -249,7 +257,7 @@ class _LandingPageState extends State { ); }), !appState.isAuthenticated - ? Utils.buildSvgWithAssets(icon: AppAssets.changeLanguageHomePageIcon, height: 18.h, width: 18.h).onPress(() { + ? Utils.buildSvgWithAssets(icon: AppAssets.changeLanguageHomePageIcon, height: 24.h, width: 24.h).onPress(() { context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); }) : SizedBox.shrink() @@ -279,7 +287,7 @@ class _LandingPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(isBold: true), + LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(weight: FontWeight.w600), LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(fontWeight: FontWeight.w500), SizedBox(height: 14.h), CustomButton( @@ -287,16 +295,17 @@ class _LandingPageState extends State { onPressed: () async { context.navigateWithName(AppRoutes.userInfoSelection); }, + padding: EdgeInsetsGeometry.zero, backgroundColor: Color(0xFF2B353E), borderColor: Color(0xFF2B353E), textColor: AppColors.whiteColor, - fontSize: 14, + fontSize: 14.f, fontWeight: FontWeight.w600, - borderRadius: 12, + borderRadius: 12.r, height: 40.h, ), ], - ) + ).expanded ], ), ), @@ -309,12 +318,12 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true), + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(weight: FontWeight.w600), Row( children: [ - LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor), + LocaleKeys.viewAll.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500), SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), ], ), ], @@ -413,8 +422,7 @@ class _LandingPageState extends State { ) : Container( width: double.infinity, - decoration: RoundedRectangleBorder() - .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Padding( padding: EdgeInsets.all(16.h), child: Column( @@ -474,11 +482,7 @@ class _LandingPageState extends State { backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), textColor: AppColors.primaryRedColor, ), - Utils.buildSvgWithAssets( - icon: AppAssets.appointment_checkin_icon, - width: 24.h, - height: 24.h, - iconColor: AppColors.primaryRedColor), + Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), ], ), SizedBox(height: 8.h), @@ -508,16 +512,16 @@ class _LandingPageState extends State { : SizedBox(height: 12.h); }, ), - + SizedBox(height: 24.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true), + LocaleKeys.quickLinks.tr(context: context).toText16(weight: FontWeight.w600), Row( children: [ - LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor), + LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), ], ), ], @@ -526,92 +530,121 @@ class _LandingPageState extends State { }), SizedBox(height: 16.h), Container( - height: 121.h, + // height: 121.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), child: Column( children: [ - Expanded( - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getLoggedInServiceCardsList.length, - shrinkWrap: true, - padding: EdgeInsets.only(left: 16.h, right: 16.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - icon: LandingPageData.getLoggedInServiceCardsList[index].icon, - title: LandingPageData.getLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, - serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2 - 35, right: MediaQuery.sizeOf(context).width / 2 - 35), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + icon: LandingPageData.getLoggedInServiceCardsList[index].icon, + title: LandingPageData.getLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, + serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + ), ), ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 10.width, + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 10.width, + ), ), ), + SizedBox(height: 16.h), ], ), ).paddingSymmetrical(24.h, 0.h), ], ) : Container( - height: 127.h, + // height: 141.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), child: Column( children: [ - Expanded( - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, - shrinkWrap: true, - padding: EdgeInsets.only(left: 16.h, right: 16.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, - icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, - title: LandingPageData.getNotLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2 - 35, right: MediaQuery.sizeOf(context).width / 2 - 35), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), + // padding: EdgeInsets.zero, + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, + icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, + title: LandingPageData.getNotLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, + ), ), ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 0.width, + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 0.width, + ), ), ), + SizedBox(height: 16.h), ], ), ).paddingSymmetrical(24.h, 0.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.services2.tr(context: context).toText16(isBold: true), + LocaleKeys.services2.tr(context: context).toText18(weight: FontWeight.w600), Row( children: [ - LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor), + LocaleKeys.viewAllServices.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500), SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), ], ).onPress(() { Navigator.of(context).push(CustomPageRoute(page: ServicesPage())); @@ -619,7 +652,7 @@ class _LandingPageState extends State { ], ).paddingSymmetrical(24.w, 0.h), SizedBox( - height: 340.h, + height: 411.h, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: LandingPageData.getServiceCardsList.length, @@ -632,7 +665,7 @@ class _LandingPageState extends State { child: SlideAnimation( horizontalOffset: 100.0, child: FadeInAnimation( - child: LargeServiceCard( + child: FadedLargeServiceCard( serviceCardData: LandingPageData.getServiceCardsList[index], image: LandingPageData.getServiceCardsList[index].icon, title: LandingPageData.getServiceCardsList[index].title, diff --git a/lib/presentation/home/navigation_screen.dart b/lib/presentation/home/navigation_screen.dart index b22e46b9..5cfc8ff7 100644 --- a/lib/presentation/home/navigation_screen.dart +++ b/lib/presentation/home/navigation_screen.dart @@ -31,12 +31,12 @@ class _LandingNavigationState extends State { physics: const NeverScrollableScrollPhysics(), children: [ const LandingPage(), - appState.isAuthenticated ? MedicalFilePage() : /* need add feedback page */ FeedbackPage(), + appState.isAuthenticated ? MedicalFilePage(showBackIcon: false) : /* need add feedback page */ FeedbackPage(), SizedBox(), // const ToDoPage(), // appState.isAuthenticated ? UserInfoSelectionScreen() : /* need add news page */ SizedBox(), SizedBox(), - ServicesPage(), + ServicesPage(showBackIcon: false), ], ), bottomNavigationBar: BottomNavigation( diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index 1ce16006..e09b1621 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart'; +import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; import 'package:hmg_patient_app_new/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'; @@ -23,12 +24,12 @@ class HabibWalletCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.myBalance.tr(context: context).toText16(isBold: true), + LocaleKeys.myBalance.tr(context: context).toText16(weight: FontWeight.w600), // Row( // children: [ - // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor), + // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor, weight: FontWeight.w500), // SizedBox(width: 2.h), - // Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + // Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), // ], // ), ], @@ -47,14 +48,14 @@ class HabibWalletCard extends StatelessWidget { child: ClipRRect(borderRadius: BorderRadius.circular(24.0), child: Utils.buildSvgWithAssets(icon: AppAssets.habib_background_icon, width: 150.h, height: 150.h)), ), Padding( - padding: EdgeInsets.all(14.h), + padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.habibWallet.tr(context: context).toText15(isBold: true), + LocaleKeys.habibWallet.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), Container( height: 40.h, width: 40.h, @@ -115,19 +116,20 @@ class HabibWalletCard extends StatelessWidget { child: Utils.getPaymentMethods(), ), CustomButton( + height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 18.h, - text: LocaleKeys.recharge.tr(context: context), - onPressed: () {}, + iconSize: 24.h, backgroundColor: AppColors.infoColor, - borderColor: AppColors.infoColor, textColor: AppColors.whiteColor, - fontSize: 12, - fontWeight: FontWeight.bold, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 35.h, - // width: 35.w, + text: LocaleKeys.recharge.tr(context: context), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + padding: EdgeInsets.fromLTRB(4, 0, 12, 0), + fontSize: 14.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, ), ], ), @@ -135,7 +137,13 @@ class HabibWalletCard extends StatelessWidget { ), ), ]), - ).paddingSymmetrical(24.h, 0.h), + ).paddingSymmetrical(24.h, 0.h).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: HabibWalletPage(), + ), + ); + }), ], ); } diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 9292004d..e25ed0b3 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -55,6 +55,7 @@ class LargeServiceCard extends StatelessWidget { right: 0.0, child: Container( height: 180.h, + padding: EdgeInsets.only(bottom: 16.h, top: 16.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, customBorder: BorderRadius.only( @@ -69,7 +70,7 @@ class LargeServiceCard extends StatelessWidget { children: [ Container( height: 48.h, - width: 48.w, + width: 48.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: serviceCardData.backgroundColor, borderRadius: 12.r, @@ -95,12 +96,13 @@ class LargeServiceCard extends StatelessWidget { ), ), ], - ).paddingSymmetrical(12.w, 24.h), + ).paddingSymmetrical(16.w, 0.h).expanded, CustomButton( text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context), onPressed: () { handleOnTap(); }, + padding: EdgeInsets.zero, backgroundColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.2) : AppColors.bgRedLightColor, borderColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.01) : AppColors.bgRedLightColor, textColor: serviceCardData.isBold ? AppColors.successColor : AppColors.primaryRedColor, @@ -145,3 +147,131 @@ class LargeServiceCard extends StatelessWidget { } } } + +class FadedLargeServiceCard extends StatelessWidget { + final ServiceCardData serviceCardData; + final String image; + final String icon; + final String title; + final String subtitle; + + const FadedLargeServiceCard({ + super.key, + required this.serviceCardData, + this.image = "", + this.icon = "", + this.title = "", + this.subtitle = "", + }); + + @override + Widget build(BuildContext context) { + return Container( + height: 411.h, + width: 252.w, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.transparent, borderRadius: 24.r), + child: Column( + children: [ + Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(24.r), + child: Image.asset(serviceCardData.largeCardIcon, fit: BoxFit.cover, width: 520.w, height: 250.h), + ), + Positioned( + top: 0, + left: 0, + right: 0, + height: 250.h, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24.r), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + stops: [0.536, 1.0], // 53.6% and 100% + colors: [ + Color(0xFFF8F8F8).withValues(alpha: 0), // Transparent + Color(0xFFF8F8F8), // Solid #F8F8F8 + ], + ), + ), + ), + ), + ], + ), + SizedBox(height: 16.h), + Spacer(), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + height: 32.h, + width: 32.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: serviceCardData.backgroundColor, + borderRadius: 30.r, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(8.h), + child: Utils.buildSvgWithAssets( + icon: serviceCardData.icon, + iconColor: serviceCardData.iconColor, + fit: BoxFit.contain, + ), + ), + ), + SizedBox(width: 12.w), + serviceCardData.title.tr(context: context).toText18(weight: FontWeight.w500, color: AppColors.textColor).expanded, + ], + ), + SizedBox(height: 10.h), + serviceCardData.subtitle.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.blackBgColor, letterSpacing: 0), + SizedBox(height: 12.h), + CustomButton( + text: serviceCardData.isBold ? "Visit Pharmacy Online".needTranslation : LocaleKeys.bookNow.tr(context: context), + onPressed: () { + handleOnTap(); + }, + padding: EdgeInsets.zero, + backgroundColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.2) : AppColors.blackBgColor, + borderColor: serviceCardData.isBold ? AppColors.successLightColor.withValues(alpha: 0.01) : AppColors.blackBgColor, + textColor: serviceCardData.isBold ? AppColors.successColor : AppColors.whiteColor, + fontSize: 14.f, + fontWeight: FontWeight.w500, + borderRadius: 10.r, + height: 40.h, + ), + ], + ), + ); + } + + void handleOnTap() { + switch (serviceCardData.serviceName) { + case "livecare": + { + getIt.get().onTabChanged(1); + Navigator.of(getIt.get().navigatorKey.currentContext!).push( + CustomPageRoute( + page: BookAppointmentPage(), + ), + ); + } + case "home_health_care": + { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: HhcProceduresPage(), + ), + ); + } + case "pharmacy": + { + Uri uri = Uri.parse(PHARMACY_REDIRECT_URL); + launchUrl(uri, mode: LaunchMode.externalApplication); + } + } + } +} diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart index 390c0013..cf49a263 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -51,25 +51,27 @@ class SmallServiceCard extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 0.h, vertical: 12.h), - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: backgroundColor, - borderRadius: 16, - ), - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Utils.buildSvgWithAssets(icon: icon, iconColor: iconColor, width: 32.h, height: 32.h), - SizedBox(height: 6.h), - title.tr(context: context).toText11(color: textColor, isBold: isBold, isCenter: true), - subtitle.tr(context: context).toText11(color: textColor, isBold: isBold, isCenter: true), - ], - ), - ), + return Container( + height: 92.h, + width: 92.h, + padding: EdgeInsets.all(4.0), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: backgroundColor, + borderRadius: 16, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets(icon: icon, iconColor: iconColor, width: 32.h, height: 32.h), + SizedBox(height: 6.h), + if (isFoldable || isTablet) ...[ + title.tr(context: context).toText11(color: textColor, weight: FontWeight.w500, isCenter: true, letterSpacing: -0.2), + subtitle.tr(context: context).toText11(color: textColor, weight: FontWeight.w500, isCenter: true, letterSpacing: -0.2), + ] else ...[ + title.tr(context: context).toText12(color: textColor, fontWeight: FontWeight.w500, isCenter: true, letterSpacing: -0.2), + subtitle.tr(context: context).toText12(color: textColor, fontWeight: FontWeight.w500, isCenter: true, letterSpacing: -0.2), + ] + ], ), ).onPress(() { switch (serviceName) { @@ -119,8 +121,12 @@ class SmallServiceCard extends StatelessWidget { break; case "emergency": context.read().flushData(); - context.read().getTransportationOrders(showLoader: false,); - context.read().getRRTOrders(showLoader: false,); + context.read().getTransportationOrders( + showLoader: false, + ); + context.read().getRRTOrders( + showLoader: false, + ); Navigator.of(context).push( CustomPageRoute( page: EmergencyServicesPage(), diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart index 04940fbc..519d8306 100644 --- a/lib/presentation/insurance/insurance_home_page.dart +++ b/lib/presentation/insurance/insurance_home_page.dart @@ -46,66 +46,63 @@ class _InsuranceHomePageState extends State { Widget build(BuildContext context) { appState = getIt.get(); insuranceViewModel = Provider.of(context, listen: false); - return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: "${LocaleKeys.insurance.tr(context: context)} ${LocaleKeys.updateInsurance.tr(context: context)}", - history: () { - insuranceViewModel.setIsInsuranceHistoryLoading(true); - insuranceViewModel.getPatientInsuranceCardHistory(); - showCommonBottomSheetWithoutHeight(context, child: InsuranceHistory(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); - }, - child: SingleChildScrollView( - child: Consumer(builder: (context, insuranceVM, child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - insuranceVM.isInsuranceLoading - ? LabResultItemView( - onTap: () {}, - labOrder: null, - index: 0, - isLoading: true, - ).paddingSymmetrical(24.h, 24.h) - : insuranceVM.patientInsuranceList.isNotEmpty - ? Padding( - padding: EdgeInsets.only(top: 24.h), - child: PatientInsuranceCard( - insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, - isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))).paddingSymmetrical(24.w, 0.h), - ) - : Padding( - padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.12), - child: Utils.getNoDataWidget( - context, - noDataText: LocaleKeys.noInsuranceWithHMG.tr(context: context), - callToActionButton: CustomButton( - icon: AppAssets.update_insurance_card_icon, - iconColor: AppColors.successColor, - iconSize: 15.h, - text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", - onPressed: () { - insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); - insuranceViewModel.getPatientInsuranceDetailsForUpdate( - appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); - showCommonBottomSheetWithoutHeight(context, - child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); - }, - backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - borderColor: AppColors.bgGreenColor.withOpacity(0.0), - textColor: AppColors.bgGreenColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ).paddingSymmetrical(64.h, 0.h), - ), + return CollapsingListView( + title: "${LocaleKeys.insurance.tr(context: context)} ${LocaleKeys.updateInsurance.tr(context: context)}", + history: () { + insuranceViewModel.setIsInsuranceHistoryLoading(true); + insuranceViewModel.getPatientInsuranceCardHistory(); + showCommonBottomSheetWithoutHeight(context, child: InsuranceHistory(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + }, + child: SingleChildScrollView( + child: Consumer(builder: (context, insuranceVM, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + insuranceVM.isInsuranceLoading + ? LabResultItemView( + onTap: () {}, + labOrder: null, + index: 0, + isLoading: true, + ).paddingSymmetrical(24.h, 24.h) + : insuranceVM.patientInsuranceList.isNotEmpty + ? Padding( + padding: EdgeInsets.only(top: 24.h), + child: PatientInsuranceCard( + insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, + isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))) + .paddingSymmetrical(24.w, 0.h), + ) + : Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.12), + child: Utils.getNoDataWidget( + context, + noDataText: LocaleKeys.noInsuranceWithHMG.tr(context: context), + callToActionButton: CustomButton( + icon: AppAssets.update_insurance_card_icon, + iconColor: AppColors.successColor, + iconSize: 15.h, + text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", + onPressed: () { + insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); + insuranceViewModel.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + }, + backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), + borderColor: AppColors.bgGreenColor.withOpacity(0.0), + textColor: AppColors.bgGreenColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ).paddingSymmetrical(64.h, 0.h), ), - ], - ); - }), - ), + ), + ], + ); + }), ), ); } diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 538f250f..006280fa 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; 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_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_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/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingToolbar( title: LocaleKeys.labResults.tr(context: context), search: () async { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: Consumer( builder: (context, model, child) { return SingleChildScrollView( physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.byVisit.tr(context: context)), CustomTabBarModel(null, LocaleKeys.byTest.tr(context: context)), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { model.setIsSortByClinic(true); }, backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { model.setIsSortByClinic(false); }, backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available model.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (model.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = model.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return 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: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...group.map((order) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.w, height: 24.h, fit: BoxFit.cover, ).circle(100), SizedBox(width: 8.h), Expanded(child: (order.doctorName ?? order.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: ("${LocaleKeys.orderNo.tr(context: context)}: ${order.orderNo!}"), ), AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), ), AppCustomChipWidget( labelText: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), ), ], ), // Row( // children: [ // CustomButton( // text: ("Order No: ".needTranslation + order.orderNo!), // 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: 24.h, // ), // SizedBox(width: 8.h), // CustomButton( // text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // 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: 24.h, // ), // ], // ), // SizedBox(height: 8.h), // Row( // children: [ // CustomButton( // text: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), // 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: 24.h, // ), // ], // ), SizedBox(height: 12.h), Row( children: [ Expanded(flex: 2, child: SizedBox()), // Expanded( // flex: 1, // child: Container( // height: 40.h, // width: 40.w, // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( // color: AppColors.textColor, // borderRadius: 12, // ), // child: Padding( // padding: EdgeInsets.all(12.h), // child: Transform.flip( // flipX: _appState.isArabic(), // child: Utils.buildSvgWithAssets( // icon: AppAssets.forward_arrow_icon_small, // iconColor: AppColors.whiteColor, // fit: BoxFit.contain, // ), // ), // ), // ).onPress(() { // model.currentlySelectedPatientOrder = order; // labProvider.getPatientLabResultByHospital(order); // labProvider.getPatientSpecialResult(order); // Navigator.of(context).push( // CustomPageRoute(page: LabResultByClinic(labOrder: order)), // ); // }), // ) Expanded( flex:2, child: CustomButton( icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, text: LocaleKeys.viewResults.tr(context: context), onPressed: () { model.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), SizedBox(height: 12.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), SizedBox(height: 12.h), ], ); }), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], ) ); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file +import 'dart:async'; 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_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_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/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: Consumer( builder: (context, model, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.byVisit.tr()), CustomTabBarModel(null, LocaleKeys.byTest.tr()), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { model.setIsSortByClinic(true); }, backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { model.setIsSortByClinic(false); }, backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available model.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (model.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = model.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return 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: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.w, height: 24.h, fit: BoxFit.cover, ).circle(100), SizedBox(width: 8.h), Expanded(child: (order.doctorName ?? order.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: ("${LocaleKeys.orderNo.tr(context: context)}: ${order.orderNo!}"), ), AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), ), AppCustomChipWidget( labelText: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), ), ], ), // Row( // children: [ // CustomButton( // text: ("Order No: ".needTranslation + order.orderNo!), // 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: 24.h, // ), // SizedBox(width: 8.h), // CustomButton( // text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // 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: 24.h, // ), // ], // ), // SizedBox(height: 8.h), // Row( // children: [ // CustomButton( // text: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), // 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: 24.h, // ), // ], // ), SizedBox(height: 12.h), Row( children: [ Expanded(flex: 2, child: SizedBox()), // Expanded( // flex: 1, // child: Container( // height: 40.h, // width: 40.w, // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( // color: AppColors.textColor, // borderRadius: 12, // ), // child: Padding( // padding: EdgeInsets.all(12.h), // child: Transform.flip( // flipX: _appState.isArabic(), // child: Utils.buildSvgWithAssets( // icon: AppAssets.forward_arrow_icon_small, // iconColor: AppColors.whiteColor, // fit: BoxFit.contain, // ), // ), // ), // ).onPress(() { // model.currentlySelectedPatientOrder = order; // labProvider.getPatientLabResultByHospital(order); // labProvider.getPatientSpecialResult(order); // Navigator.of(context).push( // CustomPageRoute(page: LabResultByClinic(labOrder: order)), // ); // }), // ) Expanded( flex: 2, child: CustomButton( icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, text: LocaleKeys.viewResults.tr(context: context), onPressed: () { model.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), // SizedBox(height: 12.h), // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), // SizedBox(height: 12.h), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.length)) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], ) ); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index dd9e4cc4..a8460ca2 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -84,7 +84,9 @@ import '../prescriptions/prescription_detail_page.dart'; import 'widgets/medical_file_appointment_card.dart'; class MedicalFilePage extends StatefulWidget { - const MedicalFilePage({super.key}); + bool showBackIcon; + + MedicalFilePage({super.key, this.showBackIcon = true}); @override State createState() => _MedicalFilePageState(); @@ -163,21 +165,21 @@ class _MedicalFilePageState extends State { trailing: Row( children: [ Wrap( - spacing: -8.h, + spacing: -12.h, // runSpacing: 0.h, children: [ Utils.buildImgWithAssets( icon: AppAssets.babyGirlImg, - height: 28.h, - width: 28.w, + height: 32.h, + width: 32.w, border: 1, fit: BoxFit.contain, borderRadius: 50.r, ), Utils.buildImgWithAssets( icon: AppAssets.femaleImg, - height: 28.h, - width: 28.w, + height: 32.h, + width: 32.w, border: 1, borderRadius: 50.r, fit: BoxFit.contain, @@ -185,6 +187,7 @@ class _MedicalFilePageState extends State { Utils.buildImgWithAssets( icon: AppAssets.maleImg, height: 32.h, + width: 32.w, border: 1.5, borderRadius: 50.r, fit: BoxFit.contain, @@ -205,15 +208,15 @@ class _MedicalFilePageState extends State { }, profiles: medicalFileViewModel.patientFamilyFiles); }), - isLeading: true, - leadingCallback: () { - Navigator.pushAndRemoveUntil( - navigationService.navigatorKey.currentContext!, - CustomPageRoute( - page: LandingNavigation(), - ), - (r) => false); - }, + isLeading: widget.showBackIcon, + // leadingCallback: () { + // Navigator.pushAndRemoveUntil( + // navigationService.navigatorKey.currentContext!, + // CustomPageRoute( + // page: LandingNavigation(), + // ), + // (r) => false); + // }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -1028,7 +1031,7 @@ class _MedicalFilePageState extends State { ); }), MedicalFileCard( - label: LocaleKeys.allergyInfo.tr(context: context), + label: "Allergy Information".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.allergy_info_icon, @@ -1043,7 +1046,7 @@ class _MedicalFilePageState extends State { ); }), MedicalFileCard( - label: LocaleKeys.vaccineInfo.tr(context: context), + label: "Vaccine Information".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.vaccine_info_icon, diff --git a/lib/presentation/my_family/my_family.dart b/lib/presentation/my_family/my_family.dart index 8383ce7d..bac6f778 100644 --- a/lib/presentation/my_family/my_family.dart +++ b/lib/presentation/my_family/my_family.dart @@ -52,7 +52,7 @@ class _FamilyMedicalScreenState extends State { AppState appState = getIt.get(); return CollapsingListView( - title: LocaleKeys.medicalFiles.tr(context: context), + title: LocaleKeys.familyTitle.tr(context: context), bottomChild: appState.getAuthenticatedUser()!.isParentUser! ? Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( diff --git a/lib/presentation/onboarding/onboarding_screen.dart b/lib/presentation/onboarding/onboarding_screen.dart index bfcdc96b..4855c0cf 100644 --- a/lib/presentation/onboarding/onboarding_screen.dart +++ b/lib/presentation/onboarding/onboarding_screen.dart @@ -38,7 +38,7 @@ class _OnboardingScreenState extends State { CustomPageRoute( page: LandingNavigation(), ), - (r) => false); + (r) => false); // Navigator.of(context).pushReplacement(FadePage(page: LandingNavigation())); } @@ -90,15 +90,13 @@ class _OnboardingScreenState extends State { duration: const Duration(milliseconds: 250), height: 6.h, width: selectedIndex == 0 ? 18.w : 6.w, - decoration: BoxDecoration( - color: selectedIndex == 0 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)), + decoration: BoxDecoration(color: selectedIndex == 0 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)), ), AnimatedContainer( duration: const Duration(milliseconds: 250), height: 6.h, width: selectedIndex == 1 ? 18.w : 6.w, - decoration: BoxDecoration( - color: selectedIndex == 1 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)), + decoration: BoxDecoration(color: selectedIndex == 1 ? AppColors.textColor : AppColors.inputLabelTextColor, borderRadius: BorderRadius.circular(30.r)), ), ], ).paddingOnly(left: 24.w, right: 24.w), @@ -123,7 +121,7 @@ class _OnboardingScreenState extends State { AnimatedContainer( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, - width: selectedIndex == 0 ? 86.w : MediaQuery.of(context).size.width - 48.w, + width: selectedIndex == 0 ? 56.w : MediaQuery.of(context).size.width - 48.w, margin: EdgeInsets.only(left: 24.w, right: 24.w), decoration: BoxDecoration( color: AppColors.primaryRedColor, @@ -136,7 +134,7 @@ class _OnboardingScreenState extends State { ? CustomButton( icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward, iconSize: 32.w, - width: 86.w, + width: 56.w, height: 56.h, text: "", backgroundColor: Colors.transparent, @@ -155,7 +153,7 @@ class _OnboardingScreenState extends State { ), ), ], - ).paddingOnly(bottom: (isFoldable || isTablet) ? 20.h : 10.h), + ).paddingOnly(bottom: (isFoldable || isTablet) ? 20.h : 32.h), ], ), ), @@ -172,16 +170,11 @@ class _OnboardingScreenState extends State { alignment: Alignment.bottomCenter, child: Transform.flip( flipX: getIt.get().isArabic() ? true : false, - child: Lottie.asset(icon, - repeat: true, - reverse: false, - frameRate: FrameRate(60), - width: MediaQuery.sizeOf(context).width - 50.w, - height: MediaQuery.sizeOf(context).width - 50.w))) + child: Lottie.asset(icon, repeat: true, reverse: false, frameRate: FrameRate(60), width: MediaQuery.sizeOf(context).width - 50.w, height: MediaQuery.sizeOf(context).width - 50.w))) .expanded, Text( heading, - style: TextStyle(fontSize: 36.f, fontWeight: FontWeight.w600, color: AppColors.textColor, letterSpacing: -0.4, height: 1), + style: TextStyle(fontSize: 36.f, fontWeight: FontWeight.w600, color: AppColors.textColor, letterSpacing: -1, height: 1.2), ), Text( body, diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 88dfb13f..a3c2667b 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -71,7 +71,7 @@ class ProfileSettingsState extends State { } // Compute and clamp using sensible bounds (uses .h extension) - final double minH = 210.h; + final double minH = 215.h; final double maxH = 380.h; final double computed = (shorter * multiplier); @@ -420,7 +420,7 @@ class FamilyCardWidget extends StatelessWidget { ), ), ], - ).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 12.h), + ).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 0.h), 1.divider.paddingSymmetrical(16.w, 0.h), _buildActionButton(appState), ], @@ -451,7 +451,7 @@ class FamilyCardWidget extends StatelessWidget { borderColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor, textColor: canSwitch ? AppColors.primaryRedColor : AppColors.whiteColor, iconColor: canSwitch ? AppColors.primaryRedColor : AppColors.whiteColor, - height: isFoldable ? 50.h : 40.h, + height: isFoldable ? 50.h : 45.h, fontSize: 14.f, ).paddingOnly(top: 12.h, right: 16.w, left: 16.w, bottom: 16.h); } diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index e1ec426f..f9b94e27 100644 --- a/lib/presentation/radiology/radiology_orders_page.dart +++ b/lib/presentation/radiology/radiology_orders_page.dart @@ -35,6 +35,7 @@ class _RadiologyOrdersPageState extends State { late RadiologyViewModel radiologyViewModel; String selectedFilterText = ''; int? expandedIndex; + // Scroll controller to ensure expanded group is visible late ScrollController _scrollController; final Map _groupKeys = {}; @@ -58,125 +59,125 @@ class _RadiologyOrdersPageState extends State { Widget build(BuildContext context) { radiologyViewModel = Provider.of(context); return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: LocaleKeys.radiology.tr(context: context), - search: () async { - final lavVM = Provider.of(context, listen: false); - if (lavVM.isLabOrdersLoading) { - return; - } else { - String? value = await Navigator.of(context).push( - CustomPageRoute( - page: SearchRadiologyContent(radiologySuggestionsList: radiologyViewModel.radiologySuggestions), - fullScreenDialog: true, - direction: AxisDirection.down, - ), - ); - if (value != null) { - selectedFilterText = value; - radiologyViewModel.filterRadiologyReports(value); - } + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.radiology.tr(context: context), + search: () async { + final lavVM = Provider.of(context, listen: false); + if (lavVM.isLabOrdersLoading) { + return; + } else { + String? value = await Navigator.of(context).push( + CustomPageRoute( + page: SearchRadiologyContent(radiologySuggestionsList: radiologyViewModel.radiologySuggestions), + fullScreenDialog: true, + direction: AxisDirection.down, + ), + ); + if (value != null) { + selectedFilterText = value; + radiologyViewModel.filterRadiologyReports(value); } - }, - child: SingleChildScrollView( - controller: _scrollController, - physics: NeverScrollableScrollPhysics(), - child: Consumer( - builder: (context, model, child) { - // Build grouping lists if we have data and none constructed yet - if (!model.isRadiologyOrdersLoading && model.patientRadiologyOrders.isNotEmpty && model.patientRadiologyOrdersViewList.isEmpty) { - final clinicMap = >{}; - final hospitalMap = >{}; - for (var order in model.patientRadiologyOrders) { - final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); - clinicMap.putIfAbsent(clinicKey, () => []).add(order); - final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); - hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); - } - model.patientRadiologyOrdersByClinic = clinicMap.values.toList(); - model.patientRadiologyOrdersByHospital = hospitalMap.values.toList(); - model.patientRadiologyOrdersViewList = model.isSortByClinic ? model.patientRadiologyOrdersByClinic : model.patientRadiologyOrdersByHospital; + } + }, + child: SingleChildScrollView( + controller: _scrollController, + physics: NeverScrollableScrollPhysics(), + child: Consumer( + builder: (context, model, child) { + // Build grouping lists if we have data and none constructed yet + if (!model.isRadiologyOrdersLoading && model.patientRadiologyOrders.isNotEmpty && model.patientRadiologyOrdersViewList.isEmpty) { + final clinicMap = >{}; + final hospitalMap = >{}; + for (var order in model.patientRadiologyOrders) { + final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); + clinicMap.putIfAbsent(clinicKey, () => []).add(order); + final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); + hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); } + model.patientRadiologyOrdersByClinic = clinicMap.values.toList(); + model.patientRadiologyOrdersByHospital = hospitalMap.values.toList(); + model.patientRadiologyOrdersViewList = model.isSortByClinic ? model.patientRadiologyOrdersByClinic : model.patientRadiologyOrdersByHospital; + } - return Padding( - padding: EdgeInsets.symmetric(horizontal: 24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Clinic / Hospital toggle - SizedBox(height: 16.h), - Row( - children: [ - CustomButton( - text: LocaleKeys.byClinic.tr(context: context), - onPressed: () { - model.setIsSortByClinic(true); - }, - backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, - borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), - textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, - fontSize: 12, - fontWeight: FontWeight.w500, - borderRadius: 10, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), - SizedBox(width: 8.h), - CustomButton( - text: LocaleKeys.byHospital.tr(context: context), - onPressed: () { - model.setIsSortByClinic(false); - }, - backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, - borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, - textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, - fontSize: 12, - fontWeight: FontWeight.w500, - borderRadius: 10, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), - ], - ), + return Padding( + padding: EdgeInsets.symmetric(horizontal: 24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Clinic / Hospital toggle + SizedBox(height: 16.h), + Row( + children: [ + CustomButton( + text: LocaleKeys.byClinic.tr(context: context), + onPressed: () { + model.setIsSortByClinic(true); + }, + backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.byHospital.tr(context: context), + onPressed: () { + model.setIsSortByClinic(false); + }, + backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ), - SizedBox(height: 8.h), - selectedFilterText.isNotEmpty - ? AppCustomChipWidget( - padding: EdgeInsets.symmetric(horizontal: 5.h), - labelText: selectedFilterText, - deleteIcon: 'assets/images/svg/cross_circle.svg', - backgroundColor: AppColors.alertColor, - textColor: AppColors.whiteColor, - deleteIconColor: AppColors.whiteColor, - deleteIconHasColor: true, - onDeleteTap: () { - setState(() { - selectedFilterText = ''; - model.filterRadiologyReports(''); - }); - }, - // chipType: ChipTypeEnum.alert, - // isSelected: true, - ) - : SizedBox(), + SizedBox(height: 8.h), + selectedFilterText.isNotEmpty + ? AppCustomChipWidget( + padding: EdgeInsets.symmetric(horizontal: 5.h), + labelText: selectedFilterText, + deleteIcon: 'assets/images/svg/cross_circle.svg', + backgroundColor: AppColors.alertColor, + textColor: AppColors.whiteColor, + deleteIconColor: AppColors.whiteColor, + deleteIconHasColor: true, + onDeleteTap: () { + setState(() { + selectedFilterText = ''; + model.filterRadiologyReports(''); + }); + }, + // chipType: ChipTypeEnum.alert, + // isSelected: true, + ) + : SizedBox(), - // Grouped view when available - Builder(builder: (ctx) { - if (model.isRadiologyOrdersLoading) { - return ListView.builder( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.zero, - itemCount: 5, - itemBuilder: (context, index) => LabResultItemView( - onTap: () {}, - labOrder: null, - index: index, - isLoading: true, - ), - ); - } + // Grouped view when available + Builder(builder: (ctx) { + if (model.isRadiologyOrdersLoading) { + return ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + itemCount: 5, + itemBuilder: (context, index) => LabResultItemView( + onTap: () {}, + labOrder: null, + index: index, + isLoading: true, + ), + ); + } if (model.patientRadiologyOrdersViewList.isEmpty) { return Utils.getNoDataWidget(ctx, noDataText: LocaleKeys.youDontHaveRadiologyOrders.tr(context: context)); diff --git a/lib/presentation/smartwatches/smartwatch_home_page.dart b/lib/presentation/smartwatches/smartwatch_home_page.dart new file mode 100644 index 00000000..8fd79098 --- /dev/null +++ b/lib/presentation/smartwatches/smartwatch_home_page.dart @@ -0,0 +1,180 @@ +import 'dart:io'; + +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/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_provider.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/smartwatches/widgets/supported_watches_list.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:provider/provider.dart'; + +class SmartwatchHomePage extends StatelessWidget { + const SmartwatchHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.smartWatches.tr(), + bottomChild: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: CustomButton( + text: LocaleKeys.supportedSmartWatches.tr(context: context), + onPressed: () { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.supportedSmartWatches.tr(context: context), + context, + child: SupportedWatchesList(), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }, + backgroundColor: AppColors.infoColor.withAlpha(40), + borderColor: AppColors.infoColor.withAlpha(0), + textColor: AppColors.infoColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 50.h, + icon: AppAssets.ask_doctor_icon, + iconColor: AppColors.infoColor, + iconSize: 18.h, + ).paddingSymmetrical(24.w, 30.h), + ), + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h), + child: GridView( + padding: EdgeInsets.zero, + shrinkWrap: true, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 16.h, + mainAxisSpacing: 16.w, + mainAxisExtent: 240.h, + ), + children: [ + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: Column( + children: [ + Image.asset("assets/images/png/smartwatches/apple-watch-5.jpg", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h), + "Apple Watch".needTranslation.toText16(isBold: true), + CustomButton( + text: LocaleKeys.select.tr(context: context), + onPressed: () { + context.read().setSelectedWatchType("apple", "assets/images/png/smartwatches/apple-watch-5.jpg"); + }, + backgroundColor: AppColors.primaryRedColor.withAlpha(40), + borderColor: AppColors.primaryRedColor.withAlpha(0), + textColor: AppColors.primaryRedColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 40.h, + ).paddingSymmetrical(16.w, 12.h), + ], + ), + ), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: Column( + children: [ + Image.asset("assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", fit: BoxFit.contain, width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h), + "Samsung Watch".needTranslation.toText16(isBold: true), + CustomButton( + text: LocaleKeys.select.tr(context: context), + onPressed: () { + context.read().setSelectedWatchType("samsung", "assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg"); + }, + backgroundColor: AppColors.primaryRedColor.withAlpha(40), + borderColor: AppColors.primaryRedColor.withAlpha(0), + textColor: AppColors.primaryRedColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 40.h, + ).paddingSymmetrical(16.w, 12.h), + ], + ), + ), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: Column( + children: [ + Image.asset("assets/images/png/smartwatches/Huawei_Watch.png", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h), + "Huawei Watch".needTranslation.toText16(isBold: true), + CustomButton( + text: LocaleKeys.select.tr(context: context), + onPressed: () { + context.read().setSelectedWatchType("huawei", "assets/images/png/smartwatches/Huawei_Watch.png"); + }, + backgroundColor: AppColors.primaryRedColor.withAlpha(40), + borderColor: AppColors.primaryRedColor.withAlpha(0), + textColor: AppColors.primaryRedColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 40.h, + ).paddingSymmetrical(16.w, 12.h), + ], + ), + ), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: Column( + children: [ + Image.asset("assets/images/png/smartwatches/Whoop_Watch.png", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h), + "Whoop Watch".needTranslation.toText16(isBold: true), + CustomButton( + text: LocaleKeys.select.tr(context: context), + onPressed: () { + context.read().setSelectedWatchType("whoop", "assets/images/png/smartwatches/Whoop_Watch.png"); + }, + backgroundColor: AppColors.primaryRedColor.withAlpha(40), + borderColor: AppColors.primaryRedColor.withAlpha(0), + textColor: AppColors.primaryRedColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 40.h, + ).paddingSymmetrical(16.w, 12.h), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/presentation/smartwatches/smartwatch_instructions_page.dart b/lib/presentation/smartwatches/smartwatch_instructions_page.dart index 8edbd242..48683d50 100644 --- a/lib/presentation/smartwatches/smartwatch_instructions_page.dart +++ b/lib/presentation/smartwatches/smartwatch_instructions_page.dart @@ -1,19 +1,12 @@ -import 'dart:io'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:health/health.dart'; -import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/smartwatches/health_dashboard/health_dashboard.dart'; -import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; -import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:url_launcher/url_launcher.dart'; class SmartwatchInstructionsPage extends StatelessWidget { const SmartwatchInstructionsPage({super.key}); @@ -22,445 +15,28 @@ class SmartwatchInstructionsPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: LocaleKeys.smartWatches.tr(), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 24.h), - child: SingleChildScrollView( - child: Platform.isIOS ? getIOSInstructionsUI(context) : getAndroidInstructionsUI(context), - ), - ), - ), - ); - } - - Widget getAndroidInstructionsUI(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.supportedSmartWatches.tr().toText20(isBold: true), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/galaxy_watch_ultra.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Galaxy Watch Ultra", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/galaxy_watch_8_classic.jpeg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Galaxy Watch 8 Classic", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - ], - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/galaxy_watch_8.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Galaxy Watch 8", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/galaxy_watch_7_classic.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Galaxy Watch 7 Classic", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/galaxy_watch_7.webp", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Galaxy Watch 7", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/galaxy_fit_3.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Galaxy Fit3", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - ], - ), - ), - SizedBox(height: 12), - LocaleKeys.pleaseMakeSureSamsungWatchConnected.tr().toText14(isBold: true), - SizedBox(height: 8.h), - LocaleKeys.beforeSyncingDataFollowInstructions.tr().toText14(isBold: true), - SizedBox(height: 12), - InkWell( - onTap: () { - showInstructionsDialog(context); - }, - child: LocaleKeys.viewWatchInstructions.tr().toText12(isBold: true, color: AppColors.textColor, isUnderLine: true)), - SizedBox( - height: 130.h, - ), - CustomButton( - text: LocaleKeys.confirm.tr(context: context), - onPressed: () async { - await Health().getHealthConnectSdkStatus().then((val) { - print('Health Connect SDK Status: $val'); - if (val == HealthConnectSdkStatus.sdkAvailable) { - Navigator.of(context).push( - CustomPageRoute( - page: HealthDashboard(), - ), - ); - } else { - getIt.get().showErrorBottomSheet( - message: LocaleKeys.healthConnectAppNotInstalled.tr(), - onOkPressed: () { - Navigator.pop(context); - Uri uri = Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.apps.healthdata"); - launchUrl(uri, mode: LaunchMode.externalApplication); - }); - return; - } - }); - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: AppColors.whiteColor, - fontSize: 16.f, - fontWeight: FontWeight.w500, - borderRadius: 10.r, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 50.h, - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ), - // DefaultButton( - // LocaleKeys.confirm.tr(context: context), - // () async { - // await Health().getHealthConnectSdkStatus().then((val) { - // print('Health Connect SDK Status: $val'); - // if (val == HealthConnectSdkStatus.sdkAvailable) { - // Navigator.of(context).push( - // FadePage( - // page: HealthDashboard(), // Replace with the actual vital signs page - // // page: HealthApp(), // Replace with the actual vital signs page - // ), - // ); - // } else { - // Utils.showAppDialog(context, LocaleKeys.error.tr(context: context), LocaleKeys.healthConnectNotInstalled.tr(), () { - // Navigator.pop(context); - // Uri uri = Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.apps.healthdata"); - // launchUrl(uri, mode: LaunchMode.externalApplication); - // }); - // return; - // } - // }); - // }, - // ) - ], - ); - } - - Widget getIOSInstructionsUI(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Supported Smart Watches".needTranslation.toText20(isBold: true), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/apple-watch-1.jpeg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Apple Watch Series 5", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), + body: CollapsingListView( + title: "How does it work".needTranslation, + bottomChild: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/apple-watch-2.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Apple Watch Series 6", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - ], - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/apple-watch-3.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Apple Watch Series 7", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/apple-watch-4.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Apple Watch Series 8", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - ], - ), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Row( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/apple-watch-5.jpg", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Apple Watch Series 9", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 15.0), - child: Row( - children: [ - Image.asset("assets/images/png/smartwatches/Apple-Watch-6.png", width: 70.0, height: 70.0), - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Container( - width: MediaQuery.of(context).size.width * 0.21, - child: Text("Apple Watch Series 10", overflow: TextOverflow.clip, style: TextStyle(fontSize: 12.0)), - ), - ) - ], - ), - ), - ), - ], + child: CustomButton( + text: LocaleKeys.getStarted.tr(context: context), + onPressed: () { + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 50.h, + ).paddingSymmetrical(24.w, 30.h), ), + child: SingleChildScrollView(), ), - SizedBox(height: 12), - "Please make sure that your Apple Watch is connected to your iPhone, is actively synced & updated.".toText14(isBold: true), - SizedBox(height: 12), - "Before syncing data, please make sure that you have followed the instructions properly.".toText14(isBold: true), - SizedBox(height: 12), - InkWell( - onTap: () { - showInstructionsDialog(context); - }, - child: "View watch instructions".toText12(isBold: true, color: AppColors.textColor, isUnderLine: true), - ), - SizedBox( - height: 130.h, - ), - CustomButton( - text: LocaleKeys.confirm.tr(context: context), - onPressed: () async { - Navigator.of(context).push( - CustomPageRoute( - page: HealthDashboard(), - ), - ); - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: AppColors.whiteColor, - fontSize: 16.f, - fontWeight: FontWeight.w500, - borderRadius: 10.r, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 50.h, - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ), - ], ); } - - showInstructionsDialog(BuildContext context) { - showGeneralDialog( - barrierColor: Colors.black.withOpacity(0.5), - transitionBuilder: (context, a1, a2, widget) { - final curvedValue = Curves.easeInOutBack.transform(a1.value) - 1.0; - return Transform( - transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), - child: Opacity( - opacity: a1.value, - child: Dialog( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 350.0, - padding: EdgeInsets.all(21), - color: Colors.white, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "SmartWatch Tracker".toText18(), - IconButton( - icon: Icon( - Icons.close, - color: Color(0xff2E303A), - ), - onPressed: () { - Navigator.pop(context); - }, - ), - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - (Platform.isIOS - ? "Make sure that you have installed 'Health' App & 'Watch' App from Apple Store." - : "Please make sure that your Samsung Watch is connected to your Phone, is actively synced & updated.") - .needTranslation - .toText14(), - SizedBox(height: 12), - ], - ) - ], - ), - ), - ], - ), - ), - ), - ); - }, - transitionDuration: Duration(milliseconds: 500), - barrierDismissible: true, - barrierLabel: '', - context: context, - pageBuilder: (context, animation1, animation2) { - return SizedBox(); - //Chanbged By Aamir - }); - } } diff --git a/lib/presentation/smartwatches/widgets/supported_watches_list.dart b/lib/presentation/smartwatches/widgets/supported_watches_list.dart new file mode 100644 index 00000000..839af802 --- /dev/null +++ b/lib/presentation/smartwatches/widgets/supported_watches_list.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; + +class SupportedWatchesList extends StatelessWidget { + const SupportedWatchesList({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + ), + child: Padding( + padding: EdgeInsets.all(16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + "Apple Watches".needTranslation.toText16(isBold: true), + ], + ), + SizedBox(height: 4.h), + "• Apple Watch Ultra".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Apple Watch 11".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Apple Watch 10".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Apple Watch 9".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Apple Watch 8".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + SizedBox(height: 16.h), + Row( + children: [ + "Samsung Watches".needTranslation.toText16(isBold: true), + ], + ), + SizedBox(height: 4.h), + "• Samsung Watch Ultra".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Galaxy Watch 8".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Galaxy Watch 7".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Galaxy Watch 6".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Galaxy Watch FE".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Galaxy Watch Fit".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + SizedBox(height: 16.h), + Row( + children: [ + "Huawei Watches".needTranslation.toText16(isBold: true), + ], + ), + SizedBox(height: 4.h), + "• Huawei Watch Ultimate Series".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Huawei Watch Series".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Huawei Watch Fit Series".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Huawei Watch Bands".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + SizedBox(height: 16.h), + Row( + children: [ + "Whoop Watches".needTranslation.toText16(isBold: true), + ], + ), + SizedBox(height: 4.h), + "• Whoop 1".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "• Whoop 2".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + ], + ), + ), + ); + } +} diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 702b37e5..9cf0ed91 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -18,7 +18,7 @@ import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_procedures_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/smartwatches/huawei_health_example.dart'; -import 'package:hmg_patient_app_new/presentation/smartwatches/smartwatch_instructions_page.dart'; +import 'package:hmg_patient_app_new/presentation/smartwatches/smartwatch_home_page.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/organ_selector_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/possible_conditions_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/risk_factors_screen.dart'; @@ -110,7 +110,7 @@ class AppRoutes { bookAppointmentPage: (context) => BookAppointmentPage(), userInfoSelection: (context) => UserInfoSelectionPage(), userInfoFlowManager: (context) => UserInfoFlowManager(), - smartWatches: (context) => SmartwatchInstructionsPage(), + smartWatches: (context) => SmartwatchHomePage(), huaweiHealthExample: (context) => HuaweiHealthExample(), covid19Test: (context) => Covid19LandingPage(), waterConsumptionPage: (context) => WaterConsumptionPage(), diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index 773dfe62..b185d894 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -165,7 +165,7 @@ class DialogServiceImp implements DialogService { SizedBox(height: isShowManageButton ? 15.h : 24.h), if (isShowManageButton) CustomButton( - text: "ManageFamilyFiles", + text: LocaleKeys.manageFiles.tr(context: context), backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedBorderColor, diff --git a/lib/services/zoom_service.dart b/lib/services/zoom_service.dart new file mode 100644 index 00000000..9af543dc --- /dev/null +++ b/lib/services/zoom_service.dart @@ -0,0 +1,33 @@ +// lib/services/zoom_service.dart +import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; + +class ZoomService { + static final ZoomService _instance = ZoomService._internal(); + factory ZoomService() => _instance; + ZoomService._internal(); + + ZoomVideoSdk? _zoom; + bool _isInitialized = false; + + Future initializeZoomSDK() async { + if (_isInitialized) return; + + try { + _zoom = ZoomVideoSdk(); + InitConfig initConfig = InitConfig( + domain: "zoom.us", + enableLog: true, // Enable for debugging + ); + + await _zoom!.initSdk(initConfig); + _isInitialized = true; + print("Zoom SDK initialized successfully"); + } catch (e) { + print("Error initializing Zoom SDK: $e"); + rethrow; + } + } + + ZoomVideoSdk? get zoom => _zoom; + bool get isInitialized => _isInitialized; +} \ No newline at end of file diff --git a/lib/splashPage.dart b/lib/splashPage.dart index b5366618..33d3d23d 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_scr import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/notification_service.dart'; +import 'package:hmg_patient_app_new/services/zoom_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:lottie/lottie.dart'; @@ -55,7 +56,7 @@ class _SplashScreenState extends State { await notificationService.initialize(onNotificationClick: (payload) { // Handle notification click here }); - + await ZoomService().initializeZoomSDK(); if (isAppOpenedFromCall) { navigateToTeleConsult(); } else { @@ -68,12 +69,12 @@ class _SplashScreenState extends State { } } }); - var zoom = ZoomVideoSdk(); - InitConfig initConfig = InitConfig( - domain: "zoom.us", - enableLog: false, - ); - zoom.initSdk(initConfig); + // var zoom = ZoomVideoSdk(); + // InitConfig initConfig = InitConfig( + // domain: "zoom.us", + // enableLog: false, + // ); + // zoom.initSdk(initConfig); } navigateToTeleConsult() async { diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 3cae1082..575de03c 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -1,4 +1,3 @@ - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -66,62 +65,65 @@ class CollapsingListView extends StatelessWidget { controller: _controller, slivers: [ SliverAppBar( - automaticallyImplyLeading: isLeading, - pinned: true, - // toolbarHeight: isLeading ? 24.h : kToolbarHeight, - leadingWidth: isLeading ? null : double.infinity, - systemOverlayStyle: SystemUiOverlayStyle(statusBarBrightness: Brightness.light), - surfaceTintColor: Colors.transparent, - backgroundColor: AppColors.bgScaffoldColor, - bottom: isLeading - ? ScrollAnimatedTitle( - title: title, - showBack: true, - controller: _controller, - search: search, - report: report, - logout: logout, - history: history, - instructions: instructions, - requests: requests, - sendEmail: sendEmail, - doctorResponse: doctorResponse, - bottomChild: bottomChild, - trailing: trailing, - ) - : null, - leading: isLeading - ? Transform.flip( + automaticallyImplyLeading: isLeading, + pinned: true, + toolbarHeight: 40.h, + leadingWidth: isLeading ? 40.w + 32.w : double.infinity, + systemOverlayStyle: SystemUiOverlayStyle(statusBarBrightness: Brightness.light), + surfaceTintColor: Colors.transparent, + backgroundColor: AppColors.bgScaffoldColor, + bottom: + // isLeading + // ? + ScrollAnimatedTitle( + title: title, + showBack: true, + controller: _controller, + search: search, + report: report, + logout: logout, + history: history, + instructions: instructions, + requests: requests, + sendEmail: sendEmail, doctorResponse: doctorResponse, + bottomChild: bottomChild, + trailing: trailing, + ), + // : null, + leading: Visibility( + visible: isLeading, + child: Container( + height: 32.h, + width: 32.w, + alignment: appState.isArabic() ? Alignment.centerRight : Alignment.centerLeft, + margin: EdgeInsets.fromLTRB(24.w, 0, 24.w, 0), + child: Transform.flip( flipX: appState.isArabic(), - child: IconButton( - icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.closeBottomNav : AppAssets.forward_top_nav_icon, width: 24.h, height: 24.h), - padding: EdgeInsets.only(left: 12), - onPressed: () { - if (leadingCallback != null) { - leadingCallback!(); - } else { - context.pop(); - } - }, - highlightColor: Colors.transparent, - ), - ) - : ScrollAnimatedTitle( - title: title, - showBack: false, - controller: _controller, - search: search, - report: report, - logout: logout, - history: history, - instructions: instructions, - requests: requests, - sendEmail: sendEmail, - doctorResponse: doctorResponse, - bottomChild: bottomChild, - trailing: trailing, + child: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h), ), - ), + ).onPress(() { + if (leadingCallback != null) { + leadingCallback!(); + } else { + context.pop(); + } + }), + ) + // : ScrollAnimatedTitle( + // title: title, + // showBack: false, + // controller: _controller, + // search: search, + // report: report, + // logout: logout, + // history: history, + // instructions: instructions, + // requests: requests, + // sendEmail: sendEmail, + // bottomChild: bottomChild, + // trailing: trailing, + // ), + ), SliverList( delegate: SliverChildBuilderDelegate( (context, index) => child, @@ -214,7 +216,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget }); @override - Size get preferredSize => const Size.fromHeight(50); + Size get preferredSize => const Size.fromHeight(56.0); @override State createState() => _ScrollAnimatedTitleState(); @@ -260,9 +262,10 @@ class _ScrollAnimatedTitleState extends State { Widget build(BuildContext context) { final isRtl = Directionality.of(context) == TextDirection.RTL; return Container( - height: (widget.preferredSize.height - _fontSize / 2).h, + // height: (widget.preferredSize.height - _fontSize / 2).h, + height: 56.h, alignment: isRtl ? (widget.showBack ? Alignment.topRight : Alignment.centerRight) : (widget.showBack ? Alignment.topLeft : Alignment.centerLeft), - padding: EdgeInsets.fromLTRB(24, 0, 24, 0), + padding: EdgeInsets.fromLTRB(24.w, 0, 24.w, 0), child: Row( spacing: 4.h, children: [ @@ -271,9 +274,9 @@ class _ScrollAnimatedTitleState extends State { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: _fontSize, + fontSize: _fontSize.f, fontWeight: FontWeight.bold, - letterSpacing: -1.0, + letterSpacing: -0.5, ), ).expanded, ...[ @@ -296,7 +299,7 @@ class _ScrollAnimatedTitleState extends State { return AnimatedSize( duration: Duration(milliseconds: 150), child: Container( - height: 36.h + (4.h * t), + height: 40.h, padding: EdgeInsets.all(8.w), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.secondaryLightRedColor, @@ -308,7 +311,7 @@ class _ScrollAnimatedTitleState extends State { mainAxisSize: MainAxisSize.min, spacing: 8.h, children: [ - Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.primaryRedColor), + Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.primaryRedColor, height: 24.h, width: 24.w), if (t >= .5) Text( title, diff --git a/lib/widgets/bottom_navigation/bottom_navigation.dart b/lib/widgets/bottom_navigation/bottom_navigation.dart index 2da1d443..bbe8d81f 100644 --- a/lib/widgets/bottom_navigation/bottom_navigation.dart +++ b/lib/widgets/bottom_navigation/bottom_navigation.dart @@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/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_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -19,26 +20,28 @@ class BottomNavigation extends StatelessWidget { Widget build(BuildContext context) { AppState appState = getIt.get(); final items = [ - BottomNavItem(icon: AppAssets.homeBottom, label: LocaleKeys.home.tr(context: context)), + BottomNavItem(icon: AppAssets.homeBottom, fillIcon: AppAssets.homeBottomFill, label: LocaleKeys.home.tr(context: context)), appState.isAuthenticated - ? BottomNavItem(icon: AppAssets.myFilesBottom, label: LocaleKeys.medicalFile.tr(context: context)) - : BottomNavItem(icon: AppAssets.feedback, label: LocaleKeys.feedback.tr()), + ? BottomNavItem(icon: AppAssets.myFilesBottom, fillIcon: AppAssets.myFilesBottomFill, label: LocaleKeys.medicalFile.tr(context: context)) + : BottomNavItem(icon: AppAssets.feedback, fillIcon: AppAssets.feedbackFill, label: LocaleKeys.feedback.tr()), BottomNavItem( icon: AppAssets.bookAppoBottom, + fillIcon: AppAssets.bookAppoBottom, label: LocaleKeys.appointment.tr(context: context), - iconSize: 27, + iconSize: 32, isSpecial: true, ), appState.isAuthenticated // ? BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr(context: context)) - ? BottomNavItem(icon: AppAssets.symptomCheckerBottomIcon, label: "Symptoms") - : BottomNavItem(icon: AppAssets.news, label: LocaleKeys.news.tr()), - BottomNavItem(icon: AppAssets.servicesBottom, label: LocaleKeys.services2.tr(context: context)), + ? BottomNavItem(icon: AppAssets.symptomCheckerBottomIcon, fillIcon: AppAssets.symptomCheckerBottomFillIcon, label: "Symptoms") + : BottomNavItem(icon: AppAssets.news, fillIcon: AppAssets.newsFill, label: LocaleKeys.news.tr()), + BottomNavItem(icon: AppAssets.servicesBottom, fillIcon: AppAssets.servicesBottomFill, label: LocaleKeys.services2.tr(context: context)), ]; return Container( decoration: _containerDecoration, padding: _containerPadding, + // height: 84.h, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate( @@ -55,28 +58,33 @@ class BottomNavigation extends StatelessWidget { return GestureDetector( onTap: () => onTap(index), behavior: HitTestBehavior.opaque, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Center( - child: Utils.buildSvgWithAssets( - icon: item.icon, + child: SizedBox( + height: 56.h, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets( + icon: isSelected ? item.fillIcon : item.icon, height: item.iconSize.h, width: item.iconSize.w, // iconColor: isSelected ? Colors.black87 : Colors.black87, ), - ), - const SizedBox(height: 10), - item.label.toText11(weight: FontWeight.w500), - SizedBox(height: item.isSpecial ? 5 : 0) - ], + // const SizedBox(height: 10), + SizedBox(height: item.isSpecial ? 0 : 8.h), + item.label.toText11(weight: FontWeight.w500), + // SizedBox(height: item.isSpecial ? 5 : 0) + ], + ), ), - ); + ).expanded; } } class BottomNavItem { final String icon; + final String fillIcon; final String label; final double iconSize; final bool isSpecial; @@ -84,6 +92,7 @@ class BottomNavItem { const BottomNavItem({ required this.icon, + required this.fillIcon, required this.label, this.iconSize = 24, this.isSpecial = false, diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 1f8593a3..fb51f28e 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -14,9 +14,8 @@ import 'package:hmg_patient_app_new/services/permission_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:permission_handler/permission_handler.dart'; - -class BottomSheetUtils{ - showReminderBottomSheet(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, +class BottomSheetUtils { + 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()) { @@ -46,7 +45,7 @@ class BottomSheetUtils{ setReminder: (int value) async { if (!isMultiAllowed!) { if (onMultiDateSuccess == null) { - CalenderUtilsNew calendarUtils = CalenderUtilsNew.instance; + CalenderUtilsNew calendarUtils = CalenderUtilsNew.instance; await calendarUtils.createOrUpdateEvent( title: title ?? LocaleKeys.youHaveAppointmentWithDr.tr(context: providedContext) + doctorName, description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, @@ -62,6 +61,7 @@ class BottomSheetUtils{ ), callBackFunc: () {}, isFullScreen: false); } } + void showCommonBottomSheet(BuildContext context, {required Widget child, Function(String?)? callBackFunc, @@ -110,7 +110,7 @@ class ButtonSheetContent extends StatelessWidget { @override Widget build(BuildContext context) { return Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 20.h, @@ -129,9 +129,7 @@ class ButtonSheetContent extends StatelessWidget { // Close button isCloseButtonVisible && isFullScreen - ? Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ + ? Row(mainAxisAlignment: MainAxisAlignment.end, children: [ Padding( padding: EdgeInsets.symmetric( horizontal: 16, @@ -170,7 +168,7 @@ void showCommonBottomSheetWithoutHeight( Widget? titleWidget, bool useSafeArea = false, bool hasBottomPadding = true, - EdgeInsets? padding, + EdgeInsets? padding, Color backgroundColor = AppColors.bottomSheetBgColor, VoidCallback? onCloseClicked, }) { @@ -179,10 +177,8 @@ void showCommonBottomSheetWithoutHeight( duration: Duration(milliseconds: 500), reverseDuration: Duration(milliseconds: 300), ), - constraints: BoxConstraints( - - maxWidth: MediaQuery.sizeOf(context).width//MediaQuery.of(context).size.width, // Full width - ), + constraints: BoxConstraints(maxWidth: MediaQuery.sizeOf(context).width //MediaQuery.of(context).size.width, // Full width + ), context: context, isScrollControlled: true, showDragHandle: false, @@ -203,46 +199,48 @@ void showCommonBottomSheetWithoutHeight( physics: ClampingScrollPhysics(), child: isCloseButtonVisible ? Container( - padding: padding ?? const EdgeInsets.only( - left: 24, - top: 24, - right: 24, - bottom: 12, - ), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.bottomSheetBgColor, - borderRadius: 24.h, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: padding != null? EdgeInsets.symmetric(horizontal: 24.w): EdgeInsets.zero, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + padding: padding ?? + const EdgeInsets.only( + left: 24, + top: 24, + right: 24, + bottom: 12, + ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.bottomSheetBgColor, + borderRadius: 24.h, + ), + child: Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ - titleWidget ?? - Expanded( - child: title.toText20(weight: FontWeight.w600), - ), - if (isCloseButtonVisible) ...[ - Utils.buildSvgWithAssets( - icon: AppAssets.close_bottom_sheet_icon, - iconColor: Color(0xff2B353E), - ).onPress(() { - onCloseClicked?.call(); - Navigator.of(context).pop(); - }),], + Padding( + padding: padding != null ? EdgeInsets.symmetric(horizontal: 24.w) : EdgeInsets.zero, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + titleWidget ?? + Expanded( + child: title.toText20(weight: FontWeight.w600), + ), + if (isCloseButtonVisible) ...[ + Utils.buildSvgWithAssets( + icon: AppAssets.close_bottom_sheet_icon, + iconColor: Color(0xff2B353E), + ).onPress(() { + onCloseClicked?.call(); + Navigator.of(context).pop(); + }), + ], + ], + ), + ), + isCloseButtonVisible ? SizedBox(height: 16.h) : SizedBox.shrink(), + child, ], ), - ), - isCloseButtonVisible ? SizedBox(height: 16.h) : SizedBox.shrink(), - child, - ], - ), - ) + ) : child, ), ), diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index ad2a5790..cf1b132f 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -125,7 +125,7 @@ class TextInputWidget extends StatelessWidget { children: [ Container( padding: padding, - height: isMultiline ? null : 64.h, + // height: isMultiline ? null : 64.h, alignment: Alignment.center, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: Colors.white, diff --git a/pubspec.yaml b/pubspec.yaml index 26903b65..02acec84 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,7 +43,7 @@ dependencies: lottie: ^3.3.1 flutter_ios_voip_kit_karmm: ^0.8.0 image_picker: ^1.2.0 - file_picker: ^10.3.2 + file_picker: 10.3.8 local_auth: ^2.3.0 share_plus: ^11.1.0 device_calendar_plus: ^0.3.1 @@ -83,6 +83,7 @@ dependencies: open_filex: ^4.7.0 flutter_swiper_view: ^1.1.8 flutter_callkit_incoming: ^3.0.0 +# device_preview: ^1.3.1 location: ^8.0.1 gms_check: ^1.0.4