From 77a04e637e914493198d91ca979a58febbb6f6e3 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 14 Jan 2026 10:15:49 +0300 Subject: [PATCH 1/8] 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 0000000..cae9694 --- /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 d09107e..18b65b8 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 0000000..1b7b937 --- /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 0000000..e00aaf9 --- /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 599ce85..e00aaf9 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 0000000..bb7c6a2 --- /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 1bf82f9..70c3f1f 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 0000000..30ed655 --- /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 0000000..a5afffb --- /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 813805e..a21fb4b 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 0000000..e4916e0 --- /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 82f9dcf..6ed40d3 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 0000000..ed9697c --- /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 baa3d6b..2b0733f 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 0000000..41f4f5b --- /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 bc72971..e9b3bd0 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 0000000..7192ae8 --- /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 a581e78..c5a03ca 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 4fdc09c..3adf7ad 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 03ff6b5..c25481f 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 309dde1..1df051e 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 a7ec23d..444d856 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 74eebec..c2b378d 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 f2cab90..a17b04b 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 c693479..0a6c600 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 b25ae82..e93a2fa 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 43cc3b9..8264ba6 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 b2649f9..5f27404 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 5274d5b..ee8ac4f 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 6216880..ecc34b5 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 90651f1..6bd6748 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 6dde958..d294688 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 a40a27b..721db75 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 e463ae7..ffd005c 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 fb153ea..8e11ce8 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 2da1d44..8c40a4c 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 6ff5cc5..4d88320 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 2/8] 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 d294688..8782736 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 5409fcf..df7f163 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 3/8] 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 4ae2a1c..e81bd87 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 b005e42..543d60d 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 df7f163..759a3e7 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 4/8] 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 759a3e7..fdea8ab 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 5/8] 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 2f7d130..c6d93f1 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 6e1eb0d0bb46b1468185250ffbacc096da866fea Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 26 Jan 2026 10:48:07 +0300 Subject: [PATCH 6/8] 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 736f1ac..d04ad70 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 e15e8a7..82b758e 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 36bd3a1..59babf8 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 2b453ef..7a771d1 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 26903b6..a8978ca 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 9c7cfde5f464ab0c42d102bf8dede392d667c60f Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Mon, 26 Jan 2026 11:38:20 +0300 Subject: [PATCH 7/8] 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 6ebbb5e..10b9342 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 99085a5..3dd5c46 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 a7782d7..2762a6e 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 7a771d1..575de03 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 8c40a4c..bbe8d81 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 b9350afead7d07edcc253413f3af454a3840cbe5 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 27 Jan 2026 14:59:42 +0300 Subject: [PATCH 8/8] 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 62ae1d3..8f10bc5 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 59babf8..940fcd3 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 2762a6e..8222635 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 008ff50..cf49a26 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 ad2a579..cf1b132 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,