From 77a04e637e914493198d91ca979a58febbb6f6e3 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 14 Jan 2026 10:15:49 +0300 Subject: [PATCH 01/14] UI/UX improvements. --- assets/images/svg/arrow-back_new.svg | 4 + assets/images/svg/book_appo_bottom.svg | 4 +- assets/images/svg/close_bottom_nav_new.svg | 4 + assets/images/svg/close_bottom_nav_trans.svg | 3 + assets/images/svg/close_bottom_sheet_icon.svg | 5 +- assets/images/svg/feedback_fill.svg | 5 + assets/images/svg/home_bottom.svg | 5 +- assets/images/svg/home_bottom_fill.svg | 3 + assets/images/svg/location_fill.svg | 3 + assets/images/svg/my_files_bottom.svg | 4 +- assets/images/svg/my_files_bottom_fill.svg | 4 + assets/images/svg/news.svg | 10 +- assets/images/svg/news_fill.svg | 3 + assets/images/svg/services_bottom.svg | 8 +- assets/images/svg/services_bottom_fill.svg | 6 + assets/images/svg/symptom_bottom_icon.svg | 2 +- .../images/svg/symptom_bottom_icon_fill.svg | 3 + lib/core/app_assets.dart | 10 + lib/core/utils/size_utils.dart | 4 +- lib/core/utils/utils.dart | 3 +- lib/extensions/string_extensions.dart | 3 +- .../habib_wallet/habib_wallet_page.dart | 26 +- .../habib_wallet/recharge_wallet_page.dart | 71 +-- .../hmg_services/services_page.dart | 92 ++- .../home/data/landing_page_data.dart | 2 +- lib/presentation/home/landing_page.dart | 398 ++++++------ lib/presentation/home/navigation_screen.dart | 4 +- .../home/widgets/habib_wallet_card.dart | 114 ++-- .../home/widgets/large_service_card.dart | 127 ++++ .../home/widgets/small_service_card.dart | 43 +- lib/presentation/lab/lab_orders_page.dart | 2 +- .../medical_file/medical_file_page.dart | 454 +++++++------- .../onboarding/onboarding_screen.dart | 23 +- .../profile_settings/profile_settings.dart | 21 +- .../radiology/radiology_orders_page.dart | 589 +++++++++--------- .../bottom_navigation/bottom_navigation.dart | 47 +- lib/widgets/common_bottom_sheet.dart | 96 ++- 37 files changed, 1205 insertions(+), 1000 deletions(-) create mode 100644 assets/images/svg/arrow-back_new.svg create mode 100644 assets/images/svg/close_bottom_nav_new.svg create mode 100644 assets/images/svg/close_bottom_nav_trans.svg create mode 100644 assets/images/svg/feedback_fill.svg create mode 100644 assets/images/svg/home_bottom_fill.svg create mode 100644 assets/images/svg/location_fill.svg create mode 100644 assets/images/svg/my_files_bottom_fill.svg create mode 100644 assets/images/svg/news_fill.svg create mode 100644 assets/images/svg/services_bottom_fill.svg create mode 100644 assets/images/svg/symptom_bottom_icon_fill.svg 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/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/lib/core/app_assets.dart b/lib/core/app_assets.dart index a581e786..c5a03caf 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'; @@ -225,13 +227,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'; @@ -248,6 +257,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'; // Water Monitor static const String waterBottle = '$svgBasePath/water_bottle.svg'; diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart index 4fdc09cf..3adf7ad3 100644 --- a/lib/core/utils/size_utils.dart +++ b/lib/core/utils/size_utils.dart @@ -4,8 +4,8 @@ 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, +const num figmaDesignHeight = 927; // iPhone X / 12 base height extension ConstrainedResponsive on num { diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 03ff6b59..c25481f6 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -387,7 +387,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), @@ -839,6 +839,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/presentation/habib_wallet/habib_wallet_page.dart b/lib/presentation/habib_wallet/habib_wallet_page.dart index a7ec23db..444d8566 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: "Recharge".needTranslation, + 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 74eebec3..c2b378dd 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(), "SAR".needTranslation.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 f2cab90b..a17b04b7 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -38,19 +38,15 @@ import 'package:provider/provider.dart'; import '../../core/dependencies.dart' show getIt; class ServicesPage extends StatelessWidget { - ServicesPage({super.key}); + bool showBackIcon; + + ServicesPage({super.key, this.showBackIcon = true}); late BloodDonationViewModel bloodDonationViewModel; late MedicalFileViewModel medicalFileViewModel; late final List hmgServices = [ - HmgServicesComponentModel( - 11, - "Emergency Services".needTranslation, - "".needTranslation, - AppAssets.emergency_services_icon, - bgColor: AppColors.primaryRedColor, - true, route: null, onTap: () { + HmgServicesComponentModel(11, "Emergency Services".needTranslation, "".needTranslation, AppAssets.emergency_services_icon, bgColor: AppColors.primaryRedColor, true, route: null, onTap: () { getIt.get().flushData(); getIt.get().getTransportationOrders( showLoader: false, @@ -102,14 +98,7 @@ class ServicesPage extends StatelessWidget { true, route: AppRoutes.eReferralPage, ), - HmgServicesComponentModel( - 3, - "Blood Donation".needTranslation, - "".needTranslation, - AppAssets.blood_donation_icon, - bgColor: AppColors.bloodDonationCardColor, - true, - route: null, onTap: () async { + HmgServicesComponentModel(3, "Blood Donation".needTranslation, "".needTranslation, AppAssets.blood_donation_icon, bgColor: AppColors.bloodDonationCardColor, true, route: null, onTap: () async { LoaderBottomSheet.showLoader(loadingText: "Fetching Data..."); await bloodDonationViewModel.getRegionSelectedClinics(onSuccess: (val) async { // await bloodDonationViewModel.getPatientBloodGroupDetails(onSuccess: (val) { @@ -239,20 +228,19 @@ class ServicesPage extends StatelessWidget { backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: "Explore Services".needTranslation, - isLeading: false, + isLeading: showBackIcon, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 16.h), - "Medical & Care Services".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0), + "Medical & Care Services".needTranslation.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, @@ -262,7 +250,7 @@ class ServicesPage extends StatelessWidget { }, ).paddingSymmetrical(24.w, 0), SizedBox(height: 24.h), - "HMG Services".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0), + "HMG Services".needTranslation.toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), SizedBox( height: 350.h, @@ -293,13 +281,14 @@ class ServicesPage extends StatelessWidget { ), ), SizedBox(height: 24.h), - "Personal Services".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0), + "Personal Services".needTranslation.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, @@ -313,21 +302,21 @@ class ServicesPage extends StatelessWidget { spacing: 8.w, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 30.w, height: 30.h), - "Habib Wallet".needTranslation.toText14(weight: FontWeight.w600, maxlines: 2).expanded, + Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h), + "Habib Wallet".needTranslation.toText16(weight: FontWeight.w600, maxlines: 2).expanded, Utils.buildSvgWithAssets(icon: AppAssets.arrow_forward), ], ), Spacer(), Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false) + return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false, iconColor: AppColors.textColor.withValues(alpha: .31)) .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); }), Spacer(), CustomButton( height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 16.w, + iconSize: 24.w, iconColor: AppColors.infoColor, textColor: AppColors.infoColor, text: "Recharge".needTranslation, @@ -336,7 +325,7 @@ class ServicesPage extends StatelessWidget { borderColor: Colors.transparent, backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), padding: EdgeInsets.all(8.w), - fontSize: 12.f, + fontSize: 14.f, onPressed: () { Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); }, @@ -350,7 +339,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, @@ -364,36 +354,36 @@ 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), - "Medical Files".needTranslation.toText14(weight: FontWeight.w600, maxlines: 2).expanded, + Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h), + "Medical Files".needTranslation.toText16(weight: FontWeight.w600, maxlines: 2).expanded, Utils.buildSvgWithAssets(icon: AppAssets.arrow_forward), ], ), Spacer(), 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, ), Utils.buildImgWithAssets( icon: AppAssets.maleImg, - height: 28.h, - width: 28.w, + height: 32.h, + width: 32.w, border: 1, borderRadius: 50.r, fit: BoxFit.contain, @@ -404,7 +394,7 @@ class ServicesPage extends StatelessWidget { CustomButton( height: 40.h, icon: AppAssets.add_icon, - iconSize: 16.w, + iconSize: 24.h, iconColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor, text: "Add Member".needTranslation, @@ -413,7 +403,7 @@ class ServicesPage extends StatelessWidget { borderColor: Colors.transparent, backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), padding: EdgeInsets.all(8.w), - fontSize: 12.f, + fontSize: 14.f, onPressed: () { DialogService dialogService = getIt.get(); medicalFileViewModel.clearAuthValues(); @@ -438,14 +428,14 @@ class ServicesPage extends StatelessWidget { ], ).paddingSymmetrical(24.w, 0), SizedBox(height: 24.h), - "Health Tools".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0), + "Health Tools".needTranslation.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 / 94, ), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -461,7 +451,7 @@ class ServicesPage extends StatelessWidget { }, ).paddingSymmetrical(24.w, 0), SizedBox(height: 24.h), - "Support Services".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0), + "Support Services".needTranslation.toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -486,7 +476,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - "Virtual Tour".needTranslation.toText12(fontWeight: FontWeight.w500) + "Virtual Tour".needTranslation.toText14(weight: FontWeight.w500) ], ), ), @@ -515,7 +505,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - "Car Parking".needTranslation.toText12(fontWeight: FontWeight.w500) + "Car Parking".needTranslation.toText14(weight: FontWeight.w500) ], ), ), @@ -544,7 +534,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - "Latest News".needTranslation.toText12(fontWeight: FontWeight.w500) + "Latest News".needTranslation.toText14(weight: FontWeight.w500) ], ), ), @@ -573,7 +563,7 @@ class ServicesPage extends StatelessWidget { fit: BoxFit.contain, ), SizedBox(width: 8.w), - "HMG Contact".needTranslation.toText12(fontWeight: FontWeight.w500) + "HMG Contact".needTranslation.toText14(weight: FontWeight.w500) ], ), ), diff --git a/lib/presentation/home/data/landing_page_data.dart b/lib/presentation/home/data/landing_page_data.dart index c6934790..0a6c600a 100644 --- a/lib/presentation/home/data/landing_page_data.dart +++ b/lib/presentation/home/data/landing_page_data.dart @@ -100,7 +100,7 @@ class LandingPageData { ServiceCardData( serviceName: "prescriptions", icon: AppAssets.my_prescription_icon, - title: "Prescriptions", + title: "Prescription", subtitle: "Details", backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index b25ae823..e93a2fa4 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -83,6 +83,15 @@ 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(); @@ -106,11 +115,14 @@ class _LandingPageState extends State { myAppointmentsViewModel.getPatientAppointments(true, false); emergencyServicesViewModel.checkPatientERAdvanceBalance(); myAppointmentsViewModel.getPatientAppointmentQueueDetails(); - if(!appState.isRatedVisible) { - appointmentRatingViewModel.getLastRatingAppointment(onSuccess: (response) { - if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) { - appointmentRatingViewModel.getAppointmentDetails(appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!, appointmentRatingViewModel.appointmentRatedList.last.projectID!, - onSuccess: ((response) { + if (!appState.isRatedVisible) { + appointmentRatingViewModel.getLastRatingAppointment( + onSuccess: (response) { + if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) { + appointmentRatingViewModel.getAppointmentDetails( + appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!, + appointmentRatingViewModel.appointmentRatedList.last.projectID!, + onSuccess: ((response) { appointmentRatingViewModel.setClinicOrDoctor(false); appointmentRatingViewModel.setTitle("Rate Doctor".needTranslation); appointmentRatingViewModel.setSubTitle("How was your last visit with doctor?".needTranslation); @@ -177,22 +189,23 @@ 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, ), Row( mainAxisSize: MainAxisSize.min, - spacing: 12.h, + spacing: 18.h, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: MedicalFilePage(), - // page: LoginScreen(), - ), - ); - }), - Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 18.h, width: 18.h).onPress(() { + if (appState.isAuthenticated) + Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: MedicalFilePage(), + // page: LoginScreen(), + ), + ); + }), + Utils.buildSvgWithAssets(icon: AppAssets.locationFill, height: 24.h, width: 24.h).onPress(() { // Navigator.of(context).push( // CustomPageRoute( // page: MedicalFilePage(), @@ -200,7 +213,7 @@ class _LandingPageState extends State { // ), // ); }), - 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(), @@ -234,7 +247,7 @@ class _LandingPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "How are you feeling today?".needTranslation.toText14(isBold: true), + "How are you feeling today?".needTranslation.toText14(weight: FontWeight.w600), "Check your symptoms with this scale".needTranslation.toText12(fontWeight: FontWeight.w500), SizedBox(height: 14.h), CustomButton( @@ -242,6 +255,7 @@ class _LandingPageState extends State { onPressed: () async { context.navigateWithName(AppRoutes.userInfoSelection); }, + padding: EdgeInsetsGeometry.zero, backgroundColor: Color(0xFF2B353E), borderColor: Color(0xFF2B353E), textColor: AppColors.whiteColor, @@ -251,7 +265,7 @@ class _LandingPageState extends State { height: 40.h, ), ], - ) + ).expanded ], ), ), @@ -264,12 +278,12 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Appointments & Visits".toText16(isBold: true), + "Appointments & Visits".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), ], ), ], @@ -362,29 +376,38 @@ class _LandingPageState extends State { SizedBox(height: 8.h), myAppointmentsVM.currentPatientQueueDetails.queueNo!.toText28(isBold: true), SizedBox(height: 6.h), - myAppointmentsVM.patientQueueDetailsList.isNotEmpty ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - "Serving Now: ".needTranslation.toText14(isBold: true), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - myAppointmentsVM.patientQueueDetailsList.first.queueNo!.toText12(isBold: true), - SizedBox(width: 8.w), - AppCustomChipWidget( - deleteIcon: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppAssets.call_for_vitals : AppAssets.call_for_doctor, - labelText: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? "Call for vital signs".needTranslation : "Call for Doctor".needTranslation, - iconColor: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, - textColor: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, - iconSize: 14.w, - backgroundColor: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor.withValues(alpha: 0.1) : AppColors.successColor.withValues(alpha: 0.1), - labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: -2.h), - ), - ], - ), - ], - ) : SizedBox(height: 12.h), + myAppointmentsVM.patientQueueDetailsList.isNotEmpty + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + "Serving Now: ".needTranslation.toText14(isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + myAppointmentsVM.patientQueueDetailsList.first.queueNo!.toText12(isBold: true), + SizedBox(width: 8.w), + AppCustomChipWidget( + deleteIcon: + myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppAssets.call_for_vitals : AppAssets.call_for_doctor, + labelText: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 + ? "Call for vital signs".needTranslation + : "Call for Doctor".needTranslation, + iconColor: + myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, + textColor: + myAppointmentsVM.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, + iconSize: 14.w, + backgroundColor: myAppointmentsVM.patientQueueDetailsList.first.callType == 1 + ? AppColors.primaryRedColor.withValues(alpha: 0.1) + : AppColors.successColor.withValues(alpha: 0.1), + labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: -2.h), + ), + ], + ), + ], + ) + : SizedBox(height: 12.h), SizedBox(height: 5.h), CustomButton( text: Utils.getCardButtonText(myAppointmentsVM.currentQueueStatus, myAppointmentsVM.currentPatientQueueDetails.roomNo ?? ""), @@ -415,86 +438,86 @@ class _LandingPageState extends State { children: [ SizedBox(height: 12.h), Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: true, - side: BorderSide(color: AppColors.ratingColorYellow, width: 3.h), - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Immediate LiveCare Request".needTranslation.toText16(isBold: true), - SizedBox(height: 10.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: true, + side: BorderSide(color: AppColors.ratingColorYellow, width: 3.h), + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + "Immediate LiveCare Request".needTranslation.toText16(isBold: true), + SizedBox(height: 10.h), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AppCustomChipWidget( - labelText: immediateLiveCareVM.patientLiveCareHistoryList[0].stringCallStatus, - backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.20), - textColor: AppColors.alertColor, + Row( + children: [ + AppCustomChipWidget( + labelText: immediateLiveCareVM.patientLiveCareHistoryList[0].stringCallStatus, + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.20), + textColor: AppColors.alertColor, + ), + SizedBox(width: 8.w), + AppCustomChipWidget( + icon: AppAssets.appointment_calendar_icon, + labelText: DateUtil.formatDateToDate( + DateUtil.convertStringToDate(immediateLiveCareVM.patientLiveCareHistoryList[0].arrivalTime), false)), + ], ), - SizedBox(width: 8.w), - AppCustomChipWidget( - icon: AppAssets.appointment_calendar_icon, - labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate(immediateLiveCareVM.patientLiveCareHistoryList[0].arrivalTime), false)), + Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), + // Lottie.asset(AppAnimations.pending_loading_animation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.cover), ], ), - Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), - // Lottie.asset(AppAnimations.pending_loading_animation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.cover), - ], - ), - SizedBox(height: 10.h), - "Hala ${appState.getAuthenticatedUser()!.firstName}!!!".needTranslation.toText16(isBold: true), - SizedBox(height: 8.h), + SizedBox(height: 10.h), + "Hala ${appState.getAuthenticatedUser()!.firstName}!!!".needTranslation.toText16(isBold: true), + SizedBox(height: 8.h), "Your turn is after ${immediateLiveCareVM.patientLiveCareHistoryList[0].patCount} patients.".needTranslation.toText14(isBold: true), SizedBox(height: 8.h), Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ + crossAxisAlignment: CrossAxisAlignment.start, + children: [ "Expected waiting time: ".needTranslation.toText12(isBold: true), SizedBox(height: 7.h), ValueListenableBuilder( valueListenable: immediateLiveCareVM.durationNotifier, - builder: (context, duration, child) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - buildTime(duration), - ], - ); - }, - ), + builder: (context, duration, child) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + buildTime(duration), + ], + ); + }, + ), ], ), - // CustomButton( - // text: "View Details".needTranslation, - // onPressed: () async { - // Navigator.of(context).push(CustomPageRoute(page: ImmediateLiveCarePendingRequestPage())); - // }, - // backgroundColor: Color(0xffFEE9EA), - // borderColor: Color(0xffFEE9EA), - // textColor: Color(0xffED1C2B), - // fontSize: 14.f, - // fontWeight: FontWeight.w500, - // borderRadius: 12.r, - // padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), - // height: 40.h, - // ), - ], - ), - ), - ).paddingSymmetrical(0.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: ImmediateLiveCarePendingRequestPage())); - }), - SizedBox(height: 12.h), - ], - ) + // CustomButton( + // text: "View Details".needTranslation, + // onPressed: () async { + // Navigator.of(context).push(CustomPageRoute(page: ImmediateLiveCarePendingRequestPage())); + // }, + // backgroundColor: Color(0xffFEE9EA), + // borderColor: Color(0xffFEE9EA), + // textColor: Color(0xffED1C2B), + // fontSize: 14.f, + // fontWeight: FontWeight.w500, + // borderRadius: 12.r, + // padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), + // height: 40.h, + // ), + ], + ), + ), + ).paddingSymmetrical(0.h, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: ImmediateLiveCarePendingRequestPage())); + }), + SizedBox(height: 12.h), + ], + ) : (todoSectionVM.patientAncillaryOrdersList.isNotEmpty && index == 1) ? AncillaryOrderCard( order: todoSectionVM.patientAncillaryOrdersList.first, @@ -530,7 +553,7 @@ class _LandingPageState extends State { isLoading: false, isFromHomePage: true, ), - ); + ); }, ) : Container( @@ -629,12 +652,13 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Quick Links".needTranslation.toText16(isBold: true), + "Quick Links".needTranslation.toText16(weight: FontWeight.w600), + Row( children: [ - "View medical file".needTranslation.toText12(color: AppColors.primaryRedColor), + "View medical file".needTranslation.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), ], ), ], @@ -643,92 +667,119 @@ 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, + 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, + 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: [ - "Services".toText16(isBold: true), + "Services".toText18(weight: FontWeight.w600), Row( children: [ - "View all services".toText12(color: AppColors.primaryRedColor), + "View all services".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())); @@ -736,7 +787,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, @@ -749,7 +800,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, @@ -822,7 +873,6 @@ class _LandingPageState extends State { isCloseButtonVisible: true, child: StatefulBuilder( builder: (context, setState) { - return RateAppointmentDoctor(); }, ), diff --git a/lib/presentation/home/navigation_screen.dart b/lib/presentation/home/navigation_screen.dart index 43cc3b90..8264ba6f 100644 --- a/lib/presentation/home/navigation_screen.dart +++ b/lib/presentation/home/navigation_screen.dart @@ -34,12 +34,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 b2649f9c..5f27404e 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -6,6 +6,7 @@ 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/habib_wallet/habib_wallet_view_model.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'; @@ -21,12 +22,12 @@ class HabibWalletCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "My Balance".toText16(isBold: true), + "My Balance".toText16(weight: FontWeight.w600), Row( children: [ - "View all services".toText12(color: AppColors.primaryRedColor), + "View all services".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), ], ), ], @@ -45,31 +46,31 @@ 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: [ - "Habib Wallet".toText15(isBold: true), - Container( - height: 40.h, - width: 40.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.textColor, - borderRadius: 8.h, - ), - child: Padding( - padding: EdgeInsets.all(8.h), - child: Utils.buildSvgWithAssets( - icon: AppAssets.show_icon, - width: 12.h, - height: 12.h, - fit: BoxFit.contain, - ), - ), - ), + "Habib Wallet".toText16(weight: FontWeight.w500, letterSpacing: -0.2), + // Container( + // height: 40.h, + // width: 40.h, + // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + // color: AppColors.textColor, + // borderRadius: 8.h, + // ), + // child: Padding( + // padding: EdgeInsets.all(8.h), + // child: Utils.buildSvgWithAssets( + // icon: AppAssets.show_icon, + // width: 12.h, + // height: 12.h, + // fit: BoxFit.contain, + // ), + // ), + // ), ], ), SizedBox(height: 4.h), @@ -78,32 +79,37 @@ class HabibWalletCard extends StatelessWidget { children: [ Utils.buildSvgWithAssets( icon: AppAssets.saudi_riyal_icon, - iconColor: AppColors.dividerColor, + iconColor: AppColors.textColor.withValues(alpha: .31), width: 24.h, height: 24.h, fit: BoxFit.contain, ), SizedBox(width: 8.h), - habibWalletVM.habibWalletAmount.toString().toText32(isBold: true).toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h), + habibWalletVM.habibWalletAmount + .toDouble() + .toStringAsFixed(2) + .toText32(isBold: true) + .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 40.h), + Container( + height: 40.h, + width: 40.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.textColor, + borderRadius: 8.h, + ), + child: Padding( + padding: EdgeInsets.all(8.h), + child: Utils.buildSvgWithAssets( + icon: AppAssets.show_icon, + width: 12.h, + height: 12.h, + fit: BoxFit.contain, + ), + ), + ), ], ); }), - Padding( - padding: EdgeInsets.symmetric(horizontal: 50.h), - child: Row( - children: [ - "View details".toText12(color: AppColors.primaryRedColor), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), - ], - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: HabibWalletPage(), - ), - ); - }), - ), SizedBox(height: 16.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -113,18 +119,20 @@ class HabibWalletCard extends StatelessWidget { child: Utils.getPaymentMethods(), ), CustomButton( + height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 18.h, - text: "Recharge".needTranslation, - onPressed: () {}, + iconSize: 24.w, 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, + text: "Recharge".needTranslation, + 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())); + }, ), ], ), @@ -132,7 +140,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 5274d5b6..ee8ac4f3 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -146,3 +146,130 @@ 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.w, + 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.toText18(weight: FontWeight.w500, color: AppColors.textColor).expanded, + ], + ), + SizedBox(height: 10.h), + serviceCardData.subtitle.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(); + }, + 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 62168808..ecc34b59 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -46,25 +46,22 @@ 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.toText11(color: textColor, isBold: isBold, isCenter: true), - subtitle.toText11(color: textColor, isBold: isBold, isCenter: true), - ], - ), - ), + return Container( + height: 92.h, + width: 92.w, + padding: EdgeInsets.all(6.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), + title.toText12(color: textColor, fontWeight: FontWeight.w500, isCenter: true), + subtitle.toText12(color: textColor, fontWeight: FontWeight.w500, isCenter: true), + ], ), ).onPress(() { switch (serviceName) { @@ -114,8 +111,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/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 90651f13..6bd67489 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(), 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, "By Visit".needTranslation), CustomTabBarModel(null, "By Test".needTranslation), // 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} ${'results'.needTranslation}"), 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: ("Order No: ".needTranslation + 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: "View Results".needTranslation, 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), ], ); }).toList(), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: "You don't have any lab results yet.".needTranslation)) : // 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(), 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, "By Visit".needTranslation), CustomTabBarModel(null, "By Test".needTranslation), // 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} ${'results'.needTranslation}"), 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: ("Order No: ".needTranslation + 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: "View Results".needTranslation, 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: "You don't have any lab results yet.".needTranslation)) : // 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 6dde9580..d2946886 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -78,7 +78,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(); @@ -156,21 +158,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, @@ -178,6 +180,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, @@ -187,7 +190,7 @@ class _MedicalFilePageState extends State { SizedBox(width: 4.h), Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w) ], - ).withHorizontalPadding(24.w).onPress(() { + ).onPress(() { DialogService dialogService = getIt.get(); dialogService.showFamilyBottomSheetWithoutH( label: "Family Files".needTranslation, @@ -197,15 +200,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: [ @@ -243,9 +246,9 @@ class _MedicalFilePageState extends State { labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), onChipTap: () { navigationService.pushPage( - page: FamilyMedicalScreen( - profiles: medicalFileViewModel.patientFamilyFiles, - onSelect: (FamilyFileResponseModelLists p1) {}, + page: FamilyMedicalScreen( + profiles: medicalFileViewModel.patientFamilyFiles, + onSelect: (FamilyFileResponseModelLists p1) {}, ), ); }, @@ -390,9 +393,7 @@ class _MedicalFilePageState extends State { width: hmgServicesVM.vitalSignCurrentPage == index ? 24.w : 8.w, height: 8.h, decoration: BoxDecoration( - color: hmgServicesVM.vitalSignCurrentPage == index - ? AppColors.primaryRedColor - : AppColors.dividerColor, + color: hmgServicesVM.vitalSignCurrentPage == index ? AppColors.primaryRedColor : AppColors.dividerColor, borderRadius: BorderRadius.circular(4.r), ), ), @@ -564,7 +565,7 @@ class _MedicalFilePageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Appointments & visits".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), + "Appointments & Visits".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), Row( children: [ LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), @@ -633,57 +634,57 @@ class _MedicalFilePageState extends State { itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length, itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 500), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOut, - child: MedicalFileAppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - onRescheduleTap: () { - openDoctorScheduleCalendar(myAppointmentsVM.patientAppointmentsHistoryList[index]); - }, - onAskDoctorTap: () async { - LoaderBottomSheet.showLoader(loadingText: "Checking doctor availability...".needTranslation); - await myAppointmentsViewModel.isDoctorAvailable( - projectID: myAppointmentsVM.patientAppointmentsHistoryList[index].projectID, - doctorId: myAppointmentsVM.patientAppointmentsHistoryList[index].doctorID, - clinicId: myAppointmentsVM.patientAppointmentsHistoryList[index].clinicID, - onSuccess: (value) async { - if (value) { - await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) { + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + child: MedicalFileAppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + onRescheduleTap: () { + openDoctorScheduleCalendar(myAppointmentsVM.patientAppointmentsHistoryList[index]); + }, + onAskDoctorTap: () async { + LoaderBottomSheet.showLoader(loadingText: "Checking doctor availability...".needTranslation); + await myAppointmentsViewModel.isDoctorAvailable( + projectID: myAppointmentsVM.patientAppointmentsHistoryList[index].projectID, + doctorId: myAppointmentsVM.patientAppointmentsHistoryList[index].doctorID, + clinicId: myAppointmentsVM.patientAppointmentsHistoryList[index].clinicID, + onSuccess: (value) async { + if (value) { + await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.askDoctor.tr(context: context), + child: AskDoctorRequestTypeSelect( + askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList, + myAppointmentsViewModel: myAppointmentsViewModel, + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], + ), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + } else { LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - title: LocaleKeys.askDoctor.tr(context: context), - child: AskDoctorRequestTypeSelect( - askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList, - myAppointmentsViewModel: myAppointmentsViewModel, - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], - ), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - } else { + print("Doctor is not available"); + } + }, + onError: (_) { LoaderBottomSheet.hideLoader(); - print("Doctor is not available"); - } - }, - onError: (_) { - LoaderBottomSheet.hideLoader(); - }, - ); - }, + }, + ); + }, + ), ), ), - ), - )); + )); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.h), ), @@ -748,110 +749,110 @@ class _MedicalFilePageState extends State { physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 500), - child: SlideAnimation( - verticalOffset: 100.0, - child: FadeInAnimation( - child: Row( - children: [ - Image.network( - prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!, - width: 40.w, - height: 40.h, - fit: BoxFit.cover, - ).circle(100.r), - SizedBox(width: 16.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - prescriptionVM.patientPrescriptionOrders[index].doctorName!.toText16(isBold: true), - SizedBox(height: 4.h), - Wrap( - direction: Axis.horizontal, - spacing: 3.w, - runSpacing: 4.w, - children: [ - AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), - AppCustomChipWidget( - icon: AppAssets.doctor_calendar_icon, - labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), - false, + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: Row( + children: [ + Image.network( + prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!, + width: 40.w, + height: 40.h, + fit: BoxFit.cover, + ).circle(100.r), + SizedBox(width: 16.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + prescriptionVM.patientPrescriptionOrders[index].doctorName!.toText16(isBold: true), + SizedBox(height: 4.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.w, + runSpacing: 4.w, + children: [ + AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), + AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: DateUtil.formatDateToDate( + DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), + false, + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), - ), - // SizedBox(width: 40.h), - Transform.flip( - flipX: appState.isArabic(), - child: Utils.buildSvgWithAssets( - icon: AppAssets.forward_arrow_icon_small, width: 15.w, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), - ], - ).onPress(() { - prescriptionVM.setPrescriptionsDetailsLoading(); - Navigator.of(context).push( - CustomPageRoute( - page: PrescriptionDetailPage(isFromAppointments: false, prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), - ), - ); - }), - ), - )); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ), - SizedBox(height: 16.h), - const Divider(color: AppColors.dividerColor), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: CustomButton( - text: "All Prescriptions".needTranslation, - onPressed: () { - Navigator.of(context).push( - CustomPageRoute( - page: PrescriptionsListPage(), - ), - ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.r, - height: 40.h, - icon: AppAssets.requests, - iconColor: AppColors.primaryRedColor, - iconSize: 16.w, - ), + // SizedBox(width: 40.h), + Transform.flip( + flipX: appState.isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon_small, width: 15.w, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), + ], + ).onPress(() { + prescriptionVM.setPrescriptionsDetailsLoading(); + Navigator.of(context).push( + CustomPageRoute( + page: PrescriptionDetailPage(isFromAppointments: false, prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), + ), + ); + }), + ), + )); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ), + SizedBox(height: 16.h), + const Divider(color: AppColors.dividerColor), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: CustomButton( + text: "All Prescriptions".needTranslation, + onPressed: () { + Navigator.of(context).push( + CustomPageRoute( + page: PrescriptionsListPage(), + ), + ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 12.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + height: 40.h, + icon: AppAssets.requests, + iconColor: AppColors.primaryRedColor, + iconSize: 16.w, ), - SizedBox(width: 6.w), - Expanded( - child: CustomButton( - text: "All Medications".needTranslation, - onPressed: () {}, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.h, - height: 40.h, - icon: AppAssets.all_medications_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 16.h, - ), + ), + SizedBox(width: 6.w), + Expanded( + child: CustomButton( + text: "All Medications".needTranslation, + onPressed: () {}, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 12.f, + fontWeight: FontWeight.w500, + borderRadius: 12.h, + height: 40.h, + icon: AppAssets.all_medications_icon, + iconColor: AppColors.primaryRedColor, + iconSize: 16.h, ), - ], - ), - ], + ), + ], + ), + ], ), ), ).paddingSymmetrical(0.w, 0.h) @@ -932,58 +933,58 @@ class _MedicalFilePageState extends State { shrinkWrap: true, itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SizedBox( - // width: 80.w, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.network( - myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, - width: 64.w, - height: 64.h, - fit: BoxFit.cover, - ).circle(100).toShimmer2(isShow: false, radius: 50.r), - SizedBox(height: 8.h), - Expanded( - child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName) - .toString() - .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2) - .toShimmer2(isShow: false), - ), - ], - ), - ).onPress(() async { - bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( - clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, - projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, - doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, - )); - LoaderBottomSheet.showLoader(); - await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { - LoaderBottomSheet.hideLoader(); - Navigator.of(context).push( - CustomPageRoute( - page: DoctorProfilePage(), - ), - ); - }, onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - }), - ), - )); + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SizedBox( + // width: 80.w, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.network( + myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, + width: 64.w, + height: 64.h, + fit: BoxFit.cover, + ).circle(100).toShimmer2(isShow: false, radius: 50.r), + SizedBox(height: 8.h), + Expanded( + child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName) + .toString() + .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2) + .toShimmer2(isShow: false), + ), + ], + ), + ).onPress(() async { + bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( + clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, + projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, + doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, + )); + LoaderBottomSheet.showLoader(); + await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage(), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }), + ), + )); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h), ), @@ -1489,9 +1490,7 @@ class _MedicalFilePageState extends State { child: _buildVitalSignCard( icon: AppAssets.bloodPressure, label: "Blood Pressure", - value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null - ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" - : '--', + value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" : '--', unit: '', status: _getBloodPressureStatus( systolic: vitalSign.bloodPressureHigher, @@ -1563,7 +1562,6 @@ class _MedicalFilePageState extends State { ], ), SizedBox(height: 14.h), - Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h), decoration: BoxDecoration( @@ -1601,7 +1599,6 @@ class _MedicalFilePageState extends State { ), ), SizedBox(height: 8.h), - Align( alignment: AlignmentDirectional.centerEnd, child: Utils.buildSvgWithAssets( @@ -1619,6 +1616,3 @@ class _MedicalFilePageState extends State { ); } } - - - diff --git a/lib/presentation/onboarding/onboarding_screen.dart b/lib/presentation/onboarding/onboarding_screen.dart index a40a27b4..721db75e 100644 --- a/lib/presentation/onboarding/onboarding_screen.dart +++ b/lib/presentation/onboarding/onboarding_screen.dart @@ -36,7 +36,7 @@ class _OnboardingScreenState extends State { CustomPageRoute( page: LandingNavigation(), ), - (r) => false); + (r) => false); // Navigator.of(context).pushReplacement(FadePage(page: LandingNavigation())); } @@ -88,15 +88,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), @@ -121,7 +119,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, @@ -134,7 +132,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: "".needTranslation, backgroundColor: Colors.transparent, @@ -153,7 +151,7 @@ class _OnboardingScreenState extends State { ), ), ], - ).paddingOnly(bottom: (isFoldable || isTablet) ? 20.h : 10.h), + ).paddingOnly(bottom: (isFoldable || isTablet) ? 20.h : 32.h), ], ), ), @@ -170,16 +168,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 e463ae78..ffd005c4 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -183,10 +183,7 @@ class ProfileSettingsState extends State { ), ], ), - "Quick Actions" - .needTranslation - .toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) - .paddingOnly(left: 24.w, right: 24.w), + "Quick Actions".needTranslation.toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h), @@ -194,8 +191,7 @@ class ProfileSettingsState extends State { child: Column( children: [ actionItem(AppAssets.language_change, "Language".needTranslation, () { - showCommonBottomSheetWithoutHeight(context, - title: "Application Language".needTranslation, child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false); + showCommonBottomSheetWithoutHeight(context, title: "Application Language".needTranslation, child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false); }, trailingLabel: Utils.appState.isArabic() ? "العربية".needTranslation : "English".needTranslation), 1.divider, actionItem(AppAssets.accessibility, "Accessibility".needTranslation, () {}), @@ -206,10 +202,7 @@ class ProfileSettingsState extends State { ], ), ), - "Personal Information" - .needTranslation - .toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) - .paddingOnly(left: 24.w, right: 24.w), + "Personal Information".needTranslation.toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h), @@ -226,10 +219,7 @@ class ProfileSettingsState extends State { ], ), ), - "Help & Support" - .needTranslation - .toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) - .paddingOnly(left: 24.w, right: 24.w), + "Help & Support".needTranslation.toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h), @@ -290,8 +280,7 @@ class ProfileSettingsState extends State { children: [ Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.greyTextColor), label.toText14(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).expanded, - if (trailingLabel.isNotEmpty) - trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1), + if (trailingLabel.isNotEmpty) trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1), switchValue != null ? Switch( value: switchValue, diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index fb153ead..8e11ce81 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,320 +59,320 @@ 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, - ), - ], - ), - - 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, - ), - ); - } + 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, + ), + ], + ), - if (model.patientRadiologyOrdersViewList.isEmpty) { - return Utils.getNoDataWidget(ctx, noDataText: "You don't have any radiology results yet.".needTranslation); - } + 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: model.patientRadiologyOrdersViewList.length, - itemBuilder: (context, index) { - final group = model.patientRadiologyOrdersViewList[index]; - final displayName = model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'); - final isExpanded = expandedIndex == index; - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 400), - child: SlideAnimation( - verticalOffset: 50.0, - child: FadeInAnimation( - child: AnimatedContainer( - duration: const 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; - }); - WidgetsBinding.instance.addPostFrameCallback((_) { - final key = _groupKeys.putIfAbsent(index, () => GlobalKey()); - if (key.currentContext != null && expandedIndex == index) { - Future.delayed(const Duration(milliseconds: 450), () { - if (key.currentContext != null) { - Scrollable.ensureVisible( - key.currentContext!, - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - alignment: 0.0, - ); - } - }); - } - }); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - key: _groupKeys.putIfAbsent(index, () => GlobalKey()), - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppCustomChipWidget(labelText: "${group.length} ${'results'.needTranslation}"), - Icon(isExpanded ? Icons.expand_less : Icons.expand_more), - ], - ), - SizedBox(height: 8.h), - Text( - displayName, - style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - AnimatedSwitcher( - duration: const 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, - ), + itemCount: 5, + itemBuilder: (context, index) => LabResultItemView( + onTap: () {}, + labOrder: null, + index: index, + isLoading: true, + ), + ); + } + + if (model.patientRadiologyOrdersViewList.isEmpty) { + return Utils.getNoDataWidget(ctx, noDataText: "You don't have any radiology results yet.".needTranslation); + } + + return ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + itemCount: model.patientRadiologyOrdersViewList.length, + itemBuilder: (context, index) { + final group = model.patientRadiologyOrdersViewList[index]; + final displayName = model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'); + final isExpanded = expandedIndex == index; + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 400), + child: SlideAnimation( + verticalOffset: 50.0, + child: FadeInAnimation( + child: AnimatedContainer( + duration: const 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; + }); + WidgetsBinding.instance.addPostFrameCallback((_) { + final key = _groupKeys.putIfAbsent(index, () => GlobalKey()); + if (key.currentContext != null && expandedIndex == index) { + Future.delayed(const Duration(milliseconds: 450), () { + if (key.currentContext != null) { + Scrollable.ensureVisible( + key.currentContext!, + duration: const Duration(milliseconds: 350), + curve: Curves.easeInOut, + alignment: 0.0, ); - }, - child: isExpanded - ? Container( - key: ValueKey(index), - padding: EdgeInsets.symmetric(horizontal: 16.w), - 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 ?? '').toString().toText14(weight: FontWeight.w500), - ), - ], - ), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 4.h, - runSpacing: 4.h, - children: [ - if ((order.description ?? '').isNotEmpty) - AppCustomChipWidget( - labelText: (order.description ?? '').toString(), - ), + } + }); + } + }); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + key: _groupKeys.putIfAbsent(index, () => GlobalKey()), + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppCustomChipWidget(labelText: "${group.length} ${'results'.needTranslation}"), + Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + ], + ), + SizedBox(height: 8.h), + Text( + displayName, + style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + AnimatedSwitcher( + duration: const 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), + 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 ?? '').toString().toText14(weight: FontWeight.w500), + ), + ], + ), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, + children: [ + if ((order.description ?? '').isNotEmpty) AppCustomChipWidget( - labelText: DateUtil.formatDateToDate( - (order.orderDate ?? order.appointmentDate), - false, - ), + labelText: (order.description ?? '').toString(), ), - AppCustomChipWidget( - labelText: model.isSortByClinic ? (order.clinicDescription ?? '') : (order.projectName ?? ''), + AppCustomChipWidget( + labelText: DateUtil.formatDateToDate( + (order.orderDate ?? order.appointmentDate), + false, ), - ], - ), - SizedBox(height: 12.h), - Row( - children: [ - Expanded(flex: 2, child: const SizedBox()), - Expanded( - flex: 2, - child: CustomButton( - icon: AppAssets.view_report_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 16.h, - text: "View Results".needTranslation, - onPressed: () { - model.navigationService.push( - CustomPageRoute( - page: RadiologyResultPage(patientRadiologyResponseModel: order), - ), - ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), + ), + AppCustomChipWidget( + labelText: model.isSortByClinic ? (order.clinicDescription ?? '') : (order.projectName ?? ''), + ), + ], + ), + SizedBox(height: 12.h), + Row( + children: [ + Expanded(flex: 2, child: const SizedBox()), + Expanded( + flex: 2, + child: CustomButton( + icon: AppAssets.view_report_icon, + iconColor: AppColors.primaryRedColor, + iconSize: 16.h, + text: "View Results".needTranslation, + onPressed: () { + model.navigationService.push( + CustomPageRoute( + page: RadiologyResultPage(patientRadiologyResponseModel: order), + ), + ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: const 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), - ], - ); - }).toList(), - ], - ), - ) - : const SizedBox.shrink(), - ), - ], - ), + ), + ], + ), + SizedBox(height: 12.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + SizedBox(height: 12.h), + ], + ); + }).toList(), + ], + ), + ) + : const SizedBox.shrink(), + ), + ], ), ), ), ), - ); - }, - ); - }), - ], - ), - ); - }, - ), + ), + ); + }, + ); + }), + ], + ), + ); + }, ), ), - ); + ), + ); } Color getLabOrderStatusColor(num status) { diff --git a/lib/widgets/bottom_navigation/bottom_navigation.dart b/lib/widgets/bottom_navigation/bottom_navigation.dart index 2da1d443..8c40a4ce 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: 50.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 6ff5cc59..4d88320a 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -12,9 +12,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()) { @@ -44,7 +43,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 ?? "You have appointment with Dr. ".needTranslation + doctorName, description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, @@ -60,6 +59,7 @@ class BottomSheetUtils{ ), callBackFunc: () {}, isFullScreen: false); } } + void showCommonBottomSheet(BuildContext context, {required Widget child, Function(String?)? callBackFunc, @@ -108,7 +108,7 @@ class ButtonSheetContent extends StatelessWidget { @override Widget build(BuildContext context) { return Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 20.h, @@ -127,9 +127,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, @@ -168,7 +166,7 @@ void showCommonBottomSheetWithoutHeight( Widget? titleWidget, bool useSafeArea = false, bool hasBottomPadding = true, - EdgeInsets? padding, + EdgeInsets? padding, Color backgroundColor = AppColors.bottomSheetBgColor, VoidCallback? onCloseClicked, }) { @@ -177,10 +175,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, @@ -201,46 +197,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, ), ), From 1599cfed4e2fc76edc35d6003c3c53290dc2cbc6 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 14 Jan 2026 12:06:59 +0300 Subject: [PATCH 02/14] UI/UX improvements-1. --- .../medical_file/medical_file_page.dart | 4 ++-- lib/widgets/appbar/collapsing_list_view.dart | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index d2946886..8782736c 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -1022,7 +1022,7 @@ class _MedicalFilePageState extends State { ); }), MedicalFileCard( - label: "Allergy Info".needTranslation, + label: "Allergy Information".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.allergy_info_icon, @@ -1037,7 +1037,7 @@ class _MedicalFilePageState extends State { ); }), MedicalFileCard( - label: "Vaccine Info".needTranslation, + label: "Vaccine Information".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.vaccine_info_icon, diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 5409fcf5..df7f1630 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -64,7 +63,7 @@ class CollapsingListView extends StatelessWidget { SliverAppBar( automaticallyImplyLeading: isLeading, pinned: true, - // toolbarHeight: isLeading ? 24.h : kToolbarHeight, + toolbarHeight: isLeading ? 40.h : kToolbarHeight, leadingWidth: isLeading ? null : double.infinity, systemOverlayStyle: SystemUiOverlayStyle(statusBarBrightness: Brightness.light), surfaceTintColor: Colors.transparent, @@ -89,8 +88,10 @@ class CollapsingListView extends StatelessWidget { ? Transform.flip( flipX: appState.isArabic(), child: IconButton( - icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.closeBottomNav : AppAssets.arrow_back, width: 24.h, height: 24.h), - padding: EdgeInsets.only(left: 12), + icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h), + padding: EdgeInsets.zero, + constraints: BoxConstraints(), + style: const ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap), onPressed: () { if (leadingCallback != null) { leadingCallback!(); @@ -206,7 +207,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget }); @override - Size get preferredSize => const Size.fromHeight(50); + Size get preferredSize => const Size.fromHeight(50.0); @override State createState() => _ScrollAnimatedTitleState(); @@ -252,9 +253,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: 60.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: [ From 45b013a048f863bbf6a0814953214ee5fd01cea8 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 14 Jan 2026 12:36:06 +0300 Subject: [PATCH 03/14] UI/UX improvements - insurance update. --- assets/images/svg/insurance_history_icon.svg | 6 +- .../insurance/insurance_home_page.dart | 115 +++++++++--------- lib/widgets/appbar/collapsing_list_view.dart | 4 +- 3 files changed, 61 insertions(+), 64 deletions(-) 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/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart index b005e42d..543d60de 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: "You don't have insurance registered with HMG.".needTranslation, - 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: "You don't have insurance registered with HMG.".needTranslation, + 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/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index df7f1630..759a3e76 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -289,7 +289,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, @@ -301,7 +301,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, From 0b9df1f22bc087b9cfd0ebb0cbeaf0335725c4a5 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 14 Jan 2026 14:43:43 +0300 Subject: [PATCH 04/14] collapsing toolbar behaviour changed as like barq --- lib/widgets/appbar/collapsing_list_view.dart | 116 ++++++++++--------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 759a3e76..fdea8aba 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -61,62 +61,66 @@ class CollapsingListView extends StatelessWidget { controller: _controller, slivers: [ SliverAppBar( - automaticallyImplyLeading: isLeading, - pinned: true, - toolbarHeight: isLeading ? 40.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, - bottomChild: bottomChild, - trailing: trailing, - ) - : null, - leading: isLeading - ? Transform.flip( - flipX: appState.isArabic(), - child: IconButton( - icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h), - padding: EdgeInsets.zero, - constraints: BoxConstraints(), - style: const ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap), - 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, - bottomChild: bottomChild, - trailing: trailing, + automaticallyImplyLeading: isLeading, + pinned: true, + toolbarHeight: 40, + 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, + bottomChild: bottomChild, + trailing: trailing, + ), + // : null, + leading: Visibility( + visible: isLeading, + child: Transform.flip( + flipX: appState.isArabic(), + child: IconButton( + icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h), + padding: EdgeInsets.zero, + constraints: BoxConstraints(), + style: const ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap), + 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, + // bottomChild: bottomChild, + // trailing: trailing, + // ), + ), SliverList( delegate: SliverChildBuilderDelegate( (context, index) => child, @@ -267,7 +271,7 @@ class _ScrollAnimatedTitleState extends State { style: TextStyle( fontSize: _fontSize, fontWeight: FontWeight.bold, - letterSpacing: -1.0, + letterSpacing: -0.5, ), ).expanded, ...[ From 40ba1bd246fefaec87ec79d8d0df48c9a614592b Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 18 Jan 2026 11:53:50 +0300 Subject: [PATCH 05/14] ui improvements --- lib/presentation/home/landing_page.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 2f7d1305..c6d93f15 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -711,14 +711,14 @@ class _LandingPageState extends State { : SizedBox(height: 12.h); }, ), - + SizedBox(height: 24.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.quickLinks.tr(context: context).toText16(weight: FontWeight.w600), Row( children: [ - LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, weight: FontWeight.w500), + 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: 14.h), ], From ae3ed83dd004a7af85c864ecdc6fa56ff42eb75d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 25 Jan 2026 14:07:34 +0300 Subject: [PATCH 06/14] contact us page changes --- lib/core/api_consts.dart | 8 ++ .../contact_us/live_chat_page.dart | 78 +++++++++++++++++-- 2 files changed, 80 insertions(+), 6 deletions(-) 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/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, From 940ce5ff140fa1ea595ba2debad60c3b7425b5b1 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 26 Jan 2026 09:44:19 +0300 Subject: [PATCH 07/14] updates --- lib/presentation/my_family/my_family.dart | 2 +- lib/services/dialog_service.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/presentation/my_family/my_family.dart b/lib/presentation/my_family/my_family.dart index b16c587a..cd727dac 100644 --- a/lib/presentation/my_family/my_family.dart +++ b/lib/presentation/my_family/my_family.dart @@ -50,7 +50,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/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, From 6e1eb0d0bb46b1468185250ffbacc096da866fea Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 26 Jan 2026 10:48:07 +0300 Subject: [PATCH 08/14] ui improvements --- lib/core/utils/size_utils.dart | 17 +- lib/main.dart | 234 ++++++++++--------- lib/presentation/home/landing_page.dart | 4 +- lib/widgets/appbar/collapsing_list_view.dart | 38 ++- pubspec.yaml | 1 + 5 files changed, 150 insertions(+), 144 deletions(-) diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart index 736f1acd..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 = 430; // iPhone X / 12 base width, -const num figmaDesignHeight = 927; // 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/main.dart b/lib/main.dart index e15e8a74..82b758ec 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,10 @@ import 'dart:io'; +import 'package:device_preview/device_preview.dart'; 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'; @@ -89,120 +91,123 @@ Future callInitializations() async { void main() async { await callInitializations(); runApp( - EasyLocalization( - supportedLocales: const [ - Locale('en', 'US'), - Locale('ar', 'SA'), - ], - path: 'assets/langs', - fallbackLocale: Locale('en', 'US'), - child: MultiProvider(providers: [ - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ) - ], child: MyApp()), + DevicePreview( + enabled: false, + builder: (context) => EasyLocalization( + supportedLocales: const [ + Locale('en', 'US'), + Locale('ar', 'SA'), + ], + path: 'assets/langs', + fallbackLocale: Locale('en', 'US'), + child: MultiProvider(providers: [ + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ) + ], child: MyApp()), + ), // Wrap your app ), ); } @@ -243,4 +248,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/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 36bd3a1b..59babf8a 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -299,9 +299,9 @@ class _LandingPageState extends State { 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, ), ], diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 2b453ef1..7a771d1a 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'; @@ -69,7 +68,7 @@ class CollapsingListView extends StatelessWidget { automaticallyImplyLeading: isLeading, pinned: true, toolbarHeight: 40.h, - leadingWidth: isLeading ? null : double.infinity, + leadingWidth: isLeading ? 40.w + 32.w : double.infinity, systemOverlayStyle: SystemUiOverlayStyle(statusBarBrightness: Brightness.light), surfaceTintColor: Colors.transparent, backgroundColor: AppColors.bgScaffoldColor, @@ -93,23 +92,22 @@ class CollapsingListView extends StatelessWidget { // : null, leading: Visibility( visible: isLeading, - child: Transform.flip( - flipX: appState.isArabic(), - child: IconButton( - icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.close_bottom_nav_trans : AppAssets.arrow_back_new, width: 24.h, height: 24.h), - padding: EdgeInsets.zero, - constraints: BoxConstraints(), - style: const ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap), - onPressed: () { - if (leadingCallback != null) { - leadingCallback!(); - } else { - context.pop(); - } - }, - highlightColor: Colors.transparent, + 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: 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, @@ -218,7 +216,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget }); @override - Size get preferredSize => const Size.fromHeight(50.0); + Size get preferredSize => const Size.fromHeight(56.0); @override State createState() => _ScrollAnimatedTitleState(); @@ -265,7 +263,7 @@ class _ScrollAnimatedTitleState extends State { final isRtl = Directionality.of(context) == TextDirection.RTL; return Container( // height: (widget.preferredSize.height - _fontSize / 2).h, - height: 60.h, + height: 56.h, alignment: isRtl ? (widget.showBack ? Alignment.topRight : Alignment.centerRight) : (widget.showBack ? Alignment.topLeft : Alignment.centerLeft), padding: EdgeInsets.fromLTRB(24.w, 0, 24.w, 0), child: Row( diff --git a/pubspec.yaml b/pubspec.yaml index 26903b65..a8978ca6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 From f78eb5da677bb41a3208f0a1fbe365eacf001390 Mon Sep 17 00:00:00 2001 From: tahaalam Date: Mon, 26 Jan 2026 11:18:52 +0300 Subject: [PATCH 09/14] Wd: Unware clinic bottom sheet shown on appointment page. --- assets/langs/ar-SA.json | 6 +- assets/langs/en-US.json | 5 +- lib/generated/locale_keys.g.dart | 2 + .../book_appointment_page.dart | 71 ++++++++++++++++--- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 90103c09..49b03c9b 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1524,7 +1524,7 @@ "medicalServices": "الخدمات الطبية", "insuranceAndPayments": "التأمين والمدفوعات", "trackerAndOthers": "المتتبع وأخرى", - "bmi": "مؤشر كتلة الجسم" - - + "bmi": "مؤشر كتلة الجسم", + "yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة", + "noThanksIKnowTheClinic": "لا شكراً، أعرف العيادة" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 50d44816..e2e3f14d 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1515,7 +1515,8 @@ "medicalServices": "Medical Services", "insuranceAndPayments": "Insurance & Payments", "trackerAndOthers": "Tracker & Others", - "bmi": "BMI" - + "bmi": "BMI", + "yesPleaseINeedHelp": "Yes, Please I need help", + "noThanksIKnowTheClinic": "No, Thanks. I Know the clinic" } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 41cb64fb..44951a58 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1512,5 +1512,7 @@ abstract class LocaleKeys { static const insuranceAndPayments = 'insuranceAndPayments'; static const trackerAndOthers = 'trackerAndOthers'; static const bmi = 'bmi'; + static const yesPleaseINeedHelp = 'yesPleaseINeedHelp'; + static const noThanksIKnowTheClinic = 'noThanksIKnowTheClinic'; } 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: () {}, + ); + } } From 9c7cfde5f464ab0c42d102bf8dede392d667c60f Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Mon, 26 Jan 2026 11:38:20 +0300 Subject: [PATCH 10/14] ui improvements --- lib/presentation/hmg_services/services_page.dart | 2 +- lib/presentation/hmg_services/services_view.dart | 4 ++-- lib/presentation/home/widgets/large_service_card.dart | 2 ++ lib/widgets/appbar/collapsing_list_view.dart | 2 +- lib/widgets/bottom_navigation/bottom_navigation.dart | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 6ebbb5e4..10b93423 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -529,7 +529,7 @@ class ServicesPage extends StatelessWidget { crossAxisCount: (isFoldable || isTablet) ? 6 : 4, // 4 icons per row crossAxisSpacing: 21.w, mainAxisSpacing: 18.h, - childAspectRatio: 80 / 94, + childAspectRatio: 80.w / 94.h, ), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, 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/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index a7782d75..2762a6ee 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -101,6 +101,7 @@ class LargeServiceCard extends StatelessWidget { 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, @@ -232,6 +233,7 @@ class FadedLargeServiceCard extends StatelessWidget { 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, diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 7a771d1a..575de03c 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -274,7 +274,7 @@ class _ScrollAnimatedTitleState extends State { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: _fontSize, + fontSize: _fontSize.f, fontWeight: FontWeight.bold, letterSpacing: -0.5, ), diff --git a/lib/widgets/bottom_navigation/bottom_navigation.dart b/lib/widgets/bottom_navigation/bottom_navigation.dart index 8c40a4ce..bbe8d81f 100644 --- a/lib/widgets/bottom_navigation/bottom_navigation.dart +++ b/lib/widgets/bottom_navigation/bottom_navigation.dart @@ -59,7 +59,7 @@ class BottomNavigation extends StatelessWidget { onTap: () => onTap(index), behavior: HitTestBehavior.opaque, child: SizedBox( - height: 50.h, + height: 56.h, child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, From 4e6d3d3178aa6844245034b45e574e6c465a0297 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 26 Jan 2026 13:43:39 +0300 Subject: [PATCH 11/14] SmartWatch implementation contd. --- .../images/png/smartwatches/Huawei_Watch.png | Bin 0 -> 97460 bytes .../images/png/smartwatches/Whoop_Watch.png | Bin 0 -> 53130 bytes .../radiology/radiology_view_model.dart | 3 +- .../health_provider.dart | 9 + .../smartwatches/smartwatch_home_page.dart | 180 +++++++ .../smartwatch_instructions_page.dart | 464 +----------------- .../widgets/supported_watches_list.dart | 71 +++ lib/routes/app_routes.dart | 4 +- 8 files changed, 284 insertions(+), 447 deletions(-) create mode 100644 assets/images/png/smartwatches/Huawei_Watch.png create mode 100644 assets/images/png/smartwatches/Whoop_Watch.png create mode 100644 lib/presentation/smartwatches/smartwatch_home_page.dart create mode 100644 lib/presentation/smartwatches/widgets/supported_watches_list.dart diff --git a/assets/images/png/smartwatches/Huawei_Watch.png b/assets/images/png/smartwatches/Huawei_Watch.png new file mode 100644 index 0000000000000000000000000000000000000000..97c416e4719dbc4035e7c1a39eed9fba866428b1 GIT binary patch literal 97460 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%0Dir_sAmG=b=0R%MD{Z?vn;yPn!iT&p;PmE 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 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/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(), From b9350afead7d07edcc253413f3af454a3840cbe5 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 27 Jan 2026 14:59:42 +0300 Subject: [PATCH 12/14] ui improvements --- .../contact_us/feedback_page.dart | 26 +++++++++---------- lib/presentation/home/landing_page.dart | 2 ++ .../home/widgets/large_service_card.dart | 7 ++--- .../home/widgets/small_service_card.dart | 13 +++++++--- lib/widgets/input_widget.dart | 2 +- 5 files changed, 28 insertions(+), 22 deletions(-) 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/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 59babf8a..940fcd31 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -555,6 +555,7 @@ class _LandingPageState extends State { 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( @@ -608,6 +609,7 @@ class _LandingPageState extends State { 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) { diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 2762a6ee..82226355 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,7 +96,7 @@ 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: () { @@ -206,7 +207,7 @@ class FadedLargeServiceCard extends StatelessWidget { children: [ Container( height: 32.h, - width: 32.w, + width: 32.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: serviceCardData.backgroundColor, borderRadius: 30.r, diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart index 008ff50f..cf49a263 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -53,8 +53,8 @@ class SmallServiceCard extends StatelessWidget { Widget build(BuildContext context) { return Container( height: 92.h, - width: 92.w, - padding: EdgeInsets.all(6.0), + width: 92.h, + padding: EdgeInsets.all(4.0), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: backgroundColor, borderRadius: 16, @@ -64,8 +64,13 @@ class SmallServiceCard extends StatelessWidget { children: [ Utils.buildSvgWithAssets(icon: icon, iconColor: iconColor, width: 32.h, height: 32.h), SizedBox(height: 6.h), - title.tr(context: context).toText12(color: textColor, fontWeight: FontWeight.w500, isCenter: true), - subtitle.tr(context: context).toText12(color: textColor, fontWeight: FontWeight.w500, isCenter: true), + 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(() { 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, From 537d93915e50beee2fefadf6af57c4df546161a4 Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Tue, 27 Jan 2026 23:10:27 +0300 Subject: [PATCH 13/14] Zoom SDK fixes --- lib/presentation/home/landing_page.dart | 1 + lib/services/zoom_service.dart | 33 +++++++++++++++++++++++++ lib/splashPage.dart | 15 +++++------ pubspec.yaml | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 lib/services/zoom_service.dart diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index ab0d247e..eca4eb70 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'; 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/pubspec.yaml b/pubspec.yaml index 26903b65..491cf9af 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 From 49542a91129b8c61e1fba3b55932391d96c83725 Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Tue, 27 Jan 2026 23:26:21 +0300 Subject: [PATCH 14/14] updates & fixes --- lib/main.dart | 234 +++++++++--------- .../widgets/appointment_card.dart | 6 +- lib/presentation/home/landing_page.dart | 44 ++-- .../home/widgets/large_service_card.dart | 4 +- .../profile_settings/profile_settings.dart | 6 +- pubspec.yaml | 2 +- 6 files changed, 143 insertions(+), 153 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 82b758ec..6010a05d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:device_preview/device_preview.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; @@ -91,124 +90,121 @@ Future callInitializations() async { void main() async { await callInitializations(); runApp( - DevicePreview( - enabled: false, - builder: (context) => EasyLocalization( - supportedLocales: const [ - Locale('en', 'US'), - Locale('ar', 'SA'), - ], - path: 'assets/langs', - fallbackLocale: Locale('en', 'US'), - child: MultiProvider(providers: [ - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ), - ChangeNotifierProvider( - create: (_) => getIt.get(), - ) - ], child: MyApp()), - ), // Wrap your app - ), + EasyLocalization( + supportedLocales: const [ + Locale('en', 'US'), + Locale('ar', 'SA'), + ], + path: 'assets/langs', + fallbackLocale: Locale('en', 'US'), + child: MultiProvider(providers: [ + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), + ) + ], child: MyApp()), + ), // Wrap your app ); } 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/home/landing_page.dart b/lib/presentation/home/landing_page.dart index d0d107bc..e0c15d0f 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -97,7 +97,6 @@ class _LandingPageState extends State { super.dispose(); } - @override void initState() { authVM = context.read(); @@ -207,20 +206,20 @@ class _LandingPageState extends State { children: [ 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(); - } - }), + 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, @@ -245,7 +244,7 @@ class _LandingPageState extends State { ) : SizedBox.shrink(), ]), - Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 24.h, width: 24.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: 24.h, width: 24.h).onPress(() { @@ -258,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() @@ -322,7 +321,7 @@ class _LandingPageState extends State { LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(weight: FontWeight.w600), Row( children: [ - LocaleKeys.viewAll.tr(context: context).toText14(color: AppColors.primaryRedColor,weight: FontWeight.w500), + 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: 14.h), ], @@ -423,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( @@ -484,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), diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 82226355..e25ed0b3 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -223,11 +223,11 @@ class FadedLargeServiceCard extends StatelessWidget { ), ), SizedBox(width: 12.w), - serviceCardData.title.toText18(weight: FontWeight.w500, color: AppColors.textColor).expanded, + serviceCardData.title.tr(context: context).toText18(weight: FontWeight.w500, color: AppColors.textColor).expanded, ], ), SizedBox(height: 10.h), - serviceCardData.subtitle.toText14(weight: FontWeight.w500, color: AppColors.blackBgColor, letterSpacing: 0), + 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), 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/pubspec.yaml b/pubspec.yaml index a8f62c87..02acec84 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -83,7 +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 +# device_preview: ^1.3.1 location: ^8.0.1 gms_check: ^1.0.4