From cd81372fc6dad55572e226ec924e8e3906c8247b Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Thu, 9 Oct 2025 11:21:07 +0300 Subject: [PATCH 1/5] family screen add fixes & remove & switch & widgets --- .../medical_file/medical_file_view_model.dart | 7 +-- .../medical_file/medical_file_page.dart | 4 +- lib/presentation/my_family/my_family.dart | 24 ++++++--- .../my_family/widget/family_cards.dart | 53 ++++++++++--------- lib/services/dialog_service.dart | 22 +++++--- 5 files changed, 63 insertions(+), 47 deletions(-) diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index db2d7fe..e4dc854 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -59,6 +59,7 @@ class MedicalFileViewModel extends ChangeNotifier { _selectedFamilyFileTabIndex = value; notifyListeners(); } + } static final DialogService _dialogService = getIt.get(); @@ -89,7 +90,6 @@ class MedicalFileViewModel extends ChangeNotifier { void onFamilyFileTabChange(int index) { setSelectedFamilyFileTabIndex = index; - notifyListeners(); } setIsPatientVaccineListLoading(bool isLoading) { @@ -439,9 +439,6 @@ class MedicalFileViewModel extends ChangeNotifier { ); } - - - Future addFamilyFile({required OTPTypeEnum otpTypeEnum}) async { LoaderBottomSheet.showLoader(); AuthenticationViewModel authVM = getIt.get(); @@ -597,7 +594,7 @@ class MedicalFileViewModel extends ChangeNotifier { getFamilyFiles(status: 0); getAllPendingRecordsByResponseId(); LoaderBottomSheet.hideLoader(); - onFamilyFileTabChange(0); + // onFamilyFileTabChange(0); } }, ); diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 1eff927..19d4335 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -114,8 +114,8 @@ class _MedicalFilePageState extends State { ).onPress(() { DialogService dialogService = getIt.get(); dialogService.showFamilyBottomSheetWithoutH( - label: "Who do you want to book for?".needTranslation, - message: "This clinic or doctor is only available for the below eligible profiles.".needTranslation, + label: "Family Members".needTranslation, + message: "Choose a profile to swithc family file.".needTranslation, onSwitchPress: (FamilyFileResponseModelLists profile) { medicalFileViewModel.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); }, diff --git a/lib/presentation/my_family/my_family.dart b/lib/presentation/my_family/my_family.dart index f9c4799..9b8014a 100644 --- a/lib/presentation/my_family/my_family.dart +++ b/lib/presentation/my_family/my_family.dart @@ -46,7 +46,11 @@ class _FamilyMedicalScreenState extends State { void initState() { super.initState(); medicalVM = context.read(); + WidgetsBinding.instance.addPostFrameCallback((_) { + medicalVM?.onFamilyFileTabChange(0); + }); } + @override Widget build(BuildContext context) { @@ -84,13 +88,17 @@ class _FamilyMedicalScreenState extends State { children: [ appState.isChildLoggedIn ? SizedBox() - : CustomTabBar( - activeBackgroundColor: AppColors.secondaryLightRedColor, - activeTextColor: AppColors.primaryRedColor, - tabs: [CustomTabBarModel(null, LocaleKeys.family.tr()), CustomTabBarModel(null, LocaleKeys.request.tr())], - onTabChange: (index) { - medicalVM!.onFamilyFileTabChange(index); - }, + : Selector( + selector: (_, model) => model.getSelectedFamilyFileTabIndex, + builder: (context, selectedIndex, child) => CustomTabBar( + activeBackgroundColor: AppColors.secondaryLightRedColor, + activeTextColor: AppColors.primaryRedColor, + // selectedIndex: selectedIndex, + tabs: [CustomTabBarModel(null, LocaleKeys.family.tr()), CustomTabBarModel(null, LocaleKeys.request.tr())], + onTabChange: (index) { + medicalVM!.onFamilyFileTabChange(index); + }, + ), ), appState.isChildLoggedIn ? SizedBox() : SizedBox(height: 25.h), Selector(selector: (_, model) => model.getSelectedFamilyFileTabIndex, builder: (context, selectedIndex, child) => getFamilyTabs(index: selectedIndex)), @@ -118,7 +126,7 @@ class _FamilyMedicalScreenState extends State { case 1: return FamilyCards( profiles: medicalVM!.pendingFamilyFiles, - isRequestDesign: true, + isRequestDesign: medicalVM!.getSelectedFamilyFileTabIndex == 1, onSelect: (FamilyFileResponseModelLists profile) { medicalVM!.acceptRejectFileFromFamilyMembers(id: profile.id, status: 3); }, diff --git a/lib/presentation/my_family/widget/family_cards.dart b/lib/presentation/my_family/widget/family_cards.dart index 9b1fb4b..50aec1c 100644 --- a/lib/presentation/my_family/widget/family_cards.dart +++ b/lib/presentation/my_family/widget/family_cards.dart @@ -14,6 +14,7 @@ import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; class FamilyCards extends StatefulWidget { @@ -88,9 +89,9 @@ class _FamilyCardsState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - CustomChipWidget( - height: 30.h, - chipType: ChipTypeEnum.alert, + AppCustomChipWidget( + // height: 30.h, + // chipType: ChipTypeEnum.alert, backgroundColor: profile.status == FamilyFileEnum.pending.toInt ? AppColors.alertLightColor.withValues(alpha: 0.20) : profile.status == FamilyFileEnum.rejected.toInt @@ -98,10 +99,10 @@ class _FamilyCardsState extends State { : profile.status == FamilyFileEnum.active.toInt ? AppColors.lightGreenColor : AppColors.lightGrayBGColor, - chipText: profile.statusDescription ?? "N/A", - iconAsset: null, - isShowBorder: false, - borderRadius: 8.h, + labelText: profile.statusDescription ?? "N/A", + // iconAsset: null, + // isShowBorder: false, + // borderRadius: 8.h, textColor: profile.status == FamilyFileEnum.pending.toInt ? AppColors.alertLightColor : profile.status == FamilyFileEnum.rejected.toInt @@ -116,14 +117,14 @@ class _FamilyCardsState extends State { .toText12(isBold: false, isCenter: false, maxLine: 1, fontWeight: FontWeight.w500, color: AppColors.greyTextColor), ]), SizedBox(height: 8.h), - CustomChipWidget( - height: 30.h, - chipType: ChipTypeEnum.alert, + AppCustomChipWidget( + // height: 30.h, + // chipType: ChipTypeEnum.alert, backgroundColor: AppColors.lightGrayBGColor, - chipText: "Medical File: ${profile.responseId ?? "N/A"}", - iconAsset: null, - isShowBorder: false, - borderRadius: 8.h, + labelText: "Medical File: ${profile.responseId ?? "N/A"}", + // iconAsset: null, + // isShowBorder: false, + // borderRadius: 8.h, textColor: AppColors.textColor), ], ), @@ -172,22 +173,22 @@ class _FamilyCardsState extends State { SizedBox(height: 8.h), (profile.patientName ?? "Unknown").toText14(isBold: false, isCenter: true, maxlines: 1, weight: FontWeight.w600), SizedBox(height: 8.h), - CustomChipWidget( - chipType: ChipTypeEnum.alert, + AppCustomChipWidget( + // chipType: ChipTypeEnum.alert, backgroundColor: AppColors.lightGrayBGColor, - chipText: "Relation:${profile.relationship ?? "N/A"}", - iconAsset: AppAssets.heart, - isShowBorder: false, - borderRadius: 8.h, + labelText: "Relation:${profile.relationship ?? "N/A"}", + icon: AppAssets.heart, + // isShowBorder: false, + // borderRadius: 8.h, textColor: AppColors.textColor), widget.isShowDetails ? SizedBox(height: 4.h) : SizedBox(), widget.isShowDetails - ? CustomChipWidget( - chipType: ChipTypeEnum.alert, + ? AppCustomChipWidget( + // chipType: ChipTypeEnum.alert, backgroundColor: AppColors.lightGrayBGColor, - chipText: "Age:${profile.age ?? "N/A"} Years", - isShowBorder: false, - borderRadius: 8.h, + labelText: "Age:${profile.age ?? "N/A"} Years", + // isShowBorder: false, + // borderRadius: 8.h, textColor: AppColors.textColor, ) : SizedBox(), @@ -208,6 +209,7 @@ class _FamilyCardsState extends State { textColor: isActive || !canSwitch ? AppColors.greyTextColor : AppColors.primaryRedColor, fontSize: 13.h, icon: isActive ? AppAssets.activeCheck : AppAssets.switch_user, + iconSize: 18.h, iconColor: isActive || !canSwitch ? (isActive ? null : AppColors.greyTextColor) : AppColors.primaryRedColor, padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), ).paddingOnly(top: 0, bottom: 0), @@ -318,6 +320,7 @@ class _FamilyCardsState extends State { backgroundColor: AppColors.lightGreenButtonColor, borderColor: AppColors.lightGreenButtonColor, textColor: AppColors.textGreenColor, + borderWidth: 0, icon: null, ), ), diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index 915f795..6c232f5 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -112,13 +112,21 @@ class DialogServiceImp implements DialogService { if (context == null) return; showCommonBottomSheetWithoutHeight(context, title: label ?? "", - child: FamilyCards( - profiles: profiles, - onSelect: (FamilyFileResponseModelLists profile) { - onSwitchPress(profile); - }, - onRemove: (FamilyFileResponseModelLists profile) {}, - isShowDetails: false, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + (message).toText16(isBold: false, color: AppColors.textColor), + SizedBox(height: 24.h), + FamilyCards( + profiles: profiles, + onSelect: (FamilyFileResponseModelLists profile) { + onSwitchPress(profile); + }, + onRemove: (FamilyFileResponseModelLists profile) {}, + isShowDetails: false, + ), + ], ), callBackFunc: () {}); } From 987fe73128664902b3bc503c5a87743de8ac42cc Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Sun, 19 Oct 2025 10:20:47 +0300 Subject: [PATCH 2/5] family screen add fixes & remove & switch & widgets --- lib/core/utils/size_utils.dart | 1 + lib/core/utils/utils.dart | 2 +- lib/presentation/authentication/login.dart | 17 ++++------- .../authentication/quick_login.dart | 30 +++++++++---------- lib/presentation/authentication/register.dart | 7 ++--- .../authentication/register_step2.dart | 20 ++++++------- .../medical_file/medical_file_page.dart | 16 ++++------ .../my_family/widget/family_cards.dart | 8 ++--- 8 files changed, 43 insertions(+), 58 deletions(-) diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart index 0be751e..f2ba0e8 100644 --- a/lib/core/utils/size_utils.dart +++ b/lib/core/utils/size_utils.dart @@ -129,6 +129,7 @@ class SizeUtils { } log("longerSide: $longerSide"); + log("shorterSide: $shorterSide"); log("isTablet: $isTablet"); } } diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index a88d9c2..54d3131 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -315,7 +315,7 @@ class Utils { crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(height: isSmallWidget ? 0.h : 48.h), - Lottie.asset(AppAnimations.noData, repeat: false, reverse: false, frameRate: FrameRate(60), width: width.h, height: height.h, fit: BoxFit.fill), + Lottie.asset(AppAnimations.noData, repeat: false, reverse: false, frameRate: FrameRate(60), width: width, height: height, fit: BoxFit.cover), SizedBox(height: 16.h), (noDataText ?? LocaleKeys.noDataAvailable.tr()) .toText16(weight: FontWeight.w500, color: AppColors.greyTextColor, isCenter: true) diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index 7e5f4a1..a97cbb9 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -87,10 +87,10 @@ class LoginScreenState extends State { isAllowLeadingIcon: true, padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 10.h), leadingIcon: AppAssets.student_card, - errorMessage: "Please enter a valid national ID or file number", + errorMessage: "Please enter a valid national ID or file number".needTranslation, hasError: false, ), - SizedBox(height: 16.h), // Adjusted to sizer unit (approx 16px) + SizedBox(height: 16.h), CustomButton( height: 50.h, text: LocaleKeys.login.tr(), @@ -109,17 +109,12 @@ class LoginScreenState extends State { } }, ), - SizedBox(height: 10.h), // Adjusted to sizer unit (approx 14px) + SizedBox(height: 10.h), Center( child: RichText( textAlign: TextAlign.center, text: TextSpan( - style: context.dynamicTextStyle( - color: Colors.black, - fontSize: 14.f, // Adjusted to sizer unit - height: 26 / 16, // This height is a ratio, may need re-evaluation - fontWeight: FontWeight.w500, - ), + style: context.dynamicTextStyle(color: Colors.black, fontSize: 14.f, height: 26 / 16, fontWeight: FontWeight.w500), children: [ TextSpan(text: LocaleKeys.dontHaveAccount.tr(), style: context.dynamicTextStyle()), TextSpan(text: " "), @@ -139,9 +134,9 @@ class LoginScreenState extends State { ), ], ), - ).withVerticalPadding(2), // Adjusted to sizer unit + ).withVerticalPadding(2.h), ), - SizedBox(height: 20.h), // Adjusted to sizer unit (approx 14px) + SizedBox(height: 20.h), ], ), ), diff --git a/lib/presentation/authentication/quick_login.dart b/lib/presentation/authentication/quick_login.dart index f10d84f..9a12e13 100644 --- a/lib/presentation/authentication/quick_login.dart +++ b/lib/presentation/authentication/quick_login.dart @@ -25,14 +25,14 @@ class QuickLoginState extends State { Widget build(BuildContext context) { NavigationService navigationService = getIt.get(); return Container( - decoration: const BoxDecoration( + decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( - topLeft: Radius.circular(24), - topRight: Radius.circular(24), + topLeft: Radius.circular(24.r), + topRight: Radius.circular(24.r), ), ), - padding: const EdgeInsets.all(24), + padding: EdgeInsets.all(24.w), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, @@ -50,7 +50,7 @@ class QuickLoginState extends State { child: Utils.buildSvgWithAssets(icon: AppAssets.cross_circle)), ], ), - Utils.showLottie(context: context, assetPath: AppAnimations.checkmark, width: 120, height: 120, repeat: true), + Utils.showLottie(context: context, assetPath: AppAnimations.checkmark, width: 120.w, height: 120.h, repeat: true), LocaleKeys.allSet.tr().toText16(textAlign: TextAlign.center, weight: FontWeight.w500) // Text( // ' TranslationBase.of(context).allSet', @@ -67,7 +67,7 @@ class QuickLoginState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Image.asset(AppAssets.lockIcon, height: 100), + Image.asset(AppAssets.lockIcon, height: 100.h), SizedBox(height: 10.h), LocaleKeys.enableQuickLogin.tr().toText26(isBold: true), // Text( @@ -89,7 +89,7 @@ class QuickLoginState extends State { // height: 1.5, // ), //), - const SizedBox(height: 24), + SizedBox(height: 24.h), // Buttons Row( mainAxisAlignment: MainAxisAlignment.end, @@ -115,15 +115,13 @@ class QuickLoginState extends State { children: [ Expanded( child: CustomButton( - text: LocaleKeys.notNow.tr(), - onPressed: () { - Navigator.pop(context, "true"); - }, - backgroundColor: Color(0xffFEE9EA), - borderColor: Color(0xffFEE9EA), - textColor: Colors.red, - // icon: "assets/images/svg/apple-finder.svg", - )), + text: LocaleKeys.notNow.tr(), + onPressed: () { + Navigator.pop(context, "true"); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Colors.red)), ], ), ], diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index 9551ba1..f04f7dd 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -78,8 +78,7 @@ class _RegisterNew extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.showLottie( - context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.h, height: 200.h, fit: BoxFit.cover, repeat: true), + Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.w, height: 200.h, fit: BoxFit.cover, repeat: true), SizedBox(height: 16.h), LocaleKeys.prepareToElevate.tr().toText32(isBold: true), SizedBox(height: 24.h), @@ -113,7 +112,7 @@ class _RegisterNew extends State { Divider(height: 1), TextInputWidget( labelText: LocaleKeys.dob.tr(), - hintText: "11 July, 1994", + hintText: "11 July, 1994".needTranslation, controller: authVm.dobController, focusNode: _dobFocusNode, isEnable: true, @@ -240,7 +239,7 @@ class _RegisterNew extends State { ), ), ), - SizedBox(height: 30), + SizedBox(height: 30.h), ], ), ), diff --git a/lib/presentation/authentication/register_step2.dart b/lib/presentation/authentication/register_step2.dart index 3466497..71cef96 100644 --- a/lib/presentation/authentication/register_step2.dart +++ b/lib/presentation/authentication/register_step2.dart @@ -69,7 +69,7 @@ class _RegisterNew extends State { height: double.infinity, child: SingleChildScrollView( reverse: false, - padding: EdgeInsets.only(left: 24.h, right: 24.h, top: 0.h), + padding: EdgeInsets.only(left: 24.w, right: 24.w, top: 0.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -98,7 +98,7 @@ class _RegisterNew extends State { leadingIcon: AppAssets.user_circle, labelColor: AppColors.textColor, ).paddingSymmetrical(0.h, 16.h), - Divider(height: 1, color: AppColors.greyColor), + Divider(height: 1.h, color: AppColors.greyColor), TextInputWidget( labelText: LocaleKeys.nationalIdNumber.tr(), hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.patientIdentificationId.toString() : (appState.getNHICUserData.idNumber ?? ""), @@ -130,7 +130,7 @@ class _RegisterNew extends State { hasSelectionCustomIcon: true, isAllowRadius: false, labelColor: AppColors.textColor, - padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), + padding: EdgeInsets.only(top: 8.h, bottom: 8.h, left: 0, right: 0), selectionCustomIcon: AppAssets.arrow_down, leadingIcon: AppAssets.user_full, ).withVerticalPadding(8); @@ -167,7 +167,7 @@ class _RegisterNew extends State { hasSelectionCustomIcon: true, isAllowRadius: false, labelColor: AppColors.textColor, - padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), + padding: EdgeInsets.only(top: 8.h, bottom: 8.h, left: 0, right: 0), selectionCustomIcon: AppAssets.arrow_down, leadingIcon: AppAssets.smart_phone, ).withVerticalPadding(8); @@ -188,7 +188,7 @@ class _RegisterNew extends State { leadingIcon: AppAssets.smart_phone, onChange: (value) {}) .paddingSymmetrical(0.h, 16.h), - Divider(height: 1, color: AppColors.greyColor), + Divider(height: 1.h, color: AppColors.greyColor), authVM!.isUserFromUAE() ? Selector? countriesList, NationalityCountries? selectedCountry, bool isArabic})>( selector: (context, authViewModel) { @@ -217,10 +217,10 @@ class _RegisterNew extends State { hasSelectionCustomIcon: true, labelColor: AppColors.textColor, isAllowRadius: false, - padding: const EdgeInsets.only(top: 8, bottom: 8, left: 0, right: 0), + padding: EdgeInsets.only(top: 8.h, bottom: 8.h, left: 0, right: 0), selectionCustomIcon: AppAssets.arrow_down, leadingIcon: AppAssets.globe, - ).withVerticalPadding(8); + ).withVerticalPadding(8.h); }, ) : TextInputWidget( @@ -256,7 +256,7 @@ class _RegisterNew extends State { leadingIcon: AppAssets.call) .paddingSymmetrical(0.h, 16.h), Divider( - height: 1, + height: 1.h, color: AppColors.greyColor, ), TextInputWidget( @@ -292,9 +292,7 @@ class _RegisterNew extends State { iconColor: AppColors.primaryRedColor, ), ), - SizedBox( - width: 16, - ), + SizedBox(width: 16.w), Expanded( child: CustomButton( backgroundColor: AppColors.primaryRedColor, diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index cea3cf1..a435f83 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -235,8 +235,7 @@ class _MedicalFilePageState extends State { iconColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, textColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, iconSize: 12.w, - backgroundColor: - insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1), + backgroundColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1), labelPadding: EdgeInsetsDirectional.only(start: 4.w, end: 8.w), ); }), @@ -517,11 +516,7 @@ class _MedicalFilePageState extends State { 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)), + icon: AppAssets.forward_arrow_icon_small, width: 15.w, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), ], ).onPress(() { prescriptionVM.setPrescriptionsDetailsLoading(); @@ -597,8 +592,8 @@ class _MedicalFilePageState extends State { context, noDataText: "You don't have any prescriptions yet.".needTranslation, isSmallWidget: true, - width: 62.w, - height: 62.h, + width: 30.w, + height: 30.h, ), ).paddingSymmetrical(24.w, 0.h); }), @@ -811,8 +806,7 @@ class _MedicalFilePageState extends State { insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); insuranceViewModel.getPatientInsuranceDetailsForUpdate( appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); - showCommonBottomSheetWithoutHeight(context, - child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); }, backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), borderColor: AppColors.bgGreenColor.withOpacity(0.0), diff --git a/lib/presentation/my_family/widget/family_cards.dart b/lib/presentation/my_family/widget/family_cards.dart index 50aec1c..dfa7d0d 100644 --- a/lib/presentation/my_family/widget/family_cards.dart +++ b/lib/presentation/my_family/widget/family_cards.dart @@ -141,10 +141,10 @@ class _FamilyCardsState extends State { physics: NeverScrollableScrollPhysics(), itemCount: widget.profiles.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, + crossAxisCount: isTablet ? 3 : 2, crossAxisSpacing: 10.h, mainAxisSpacing: 10.h, - childAspectRatio: widget.isShowDetails ? 0.56.h : 0.65.h, + childAspectRatio: widget.isShowDetails ? 0.56 : 0.65, ), padding: EdgeInsets.only(bottom: 20.h), itemBuilder: (context, index) { @@ -153,8 +153,8 @@ class _FamilyCardsState extends State { final isParentUser = appState.getAuthenticatedUser()?.isParentUser ?? false; final canSwitch = isParentUser || (!isParentUser && profile.responseId == appState.getSuperUserID); return Container( - padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24), + padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), child: Opacity( opacity: isActive || profile.status == FamilyFileEnum.pending.toInt || !canSwitch ? 0.4 : 1.0, // Fade all content if active child: Stack( From e113c4c1ee61846de83bf0395131336c5581e03b Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Thu, 30 Oct 2025 14:23:46 +0300 Subject: [PATCH 3/5] updates & fixes & RRT Flow --- ios/Runner/AppDelegate.swift | 3 + lib/core/api_consts.dart | 2 +- lib/core/dependencies.dart | 6 +- .../authentication/authentication_repo.dart | 6 +- .../authentication_view_model.dart | 13 +- .../emergency_services_view_model.dart | 26 +- .../medical_file/medical_file_view_model.dart | 8 +- .../RRT/rrt_request_type_select.dart | 171 ++++++++++-- .../call_ambulance/call_ambulance_page.dart | 243 ++++++---------- .../requesting_services_page.dart | 17 +- .../call_ambulance/tracking_screen.dart | 261 ++++++++---------- .../emergency_services_page.dart | 154 ++++------- lib/presentation/my_family/my_family.dart | 2 +- lib/widgets/appbar/collapsing_list_view.dart | 1 + lib/widgets/common_bottom_sheet.dart | 81 +++--- .../ExpandableBottomSheet.dart | 2 +- lib/widgets/radio/custom_radio_button.dart | 26 +- 17 files changed, 507 insertions(+), 515 deletions(-) diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 69204f3..3d76a5f 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,6 +2,8 @@ import Flutter import UIKit import FirebaseCore import FirebaseMessaging +import GoogleMaps + @main @objc class AppDelegate: FlutterAppDelegate { @@ -10,6 +12,7 @@ import FirebaseMessaging didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { FirebaseApp.configure() + GMSServices.provideAPIKey("AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA") GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index ed2bba1..304b633 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -729,7 +729,7 @@ var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatb class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index a82a9ad..7c8083d 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -158,7 +158,8 @@ class AppDependencies { ); getIt.registerLazySingleton( - () => BookAppointmentsViewModel(bookAppointmentsRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt(), myAppointmentsViewModel: getIt(), locationUtils: getIt(), dialogService: getIt()), + () => BookAppointmentsViewModel( + bookAppointmentsRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt(), myAppointmentsViewModel: getIt(), locationUtils: getIt(), dialogService: getIt()), ); getIt.registerLazySingleton( @@ -185,8 +186,7 @@ class AppDependencies { ); getIt.registerLazySingleton( - () => - AppointmentViaRegionViewmodel( + () => AppointmentViaRegionViewmodel( navigationService: getIt(), appState: getIt(), ), diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index d566996..6266afb 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -101,10 +101,7 @@ class AuthenticationRepoImp implements AuthenticationRepo { } @override - Future>> checkPatientAuthentication({ - required dynamic checkPatientAuthenticationReq, - String? languageID, - }) async { + Future>> checkPatientAuthentication({required dynamic checkPatientAuthenticationReq, String? languageID}) async { int isOutKsa = (checkPatientAuthenticationReq.zipCode == '966' || checkPatientAuthenticationReq.zipCode == '+966') ? 0 : 1; checkPatientAuthenticationReq.patientOutSA = isOutKsa; try { @@ -149,7 +146,6 @@ class AuthenticationRepoImp implements AuthenticationRepo { sendActivationCodeReq.isDentalAllowedBackend = false; final payload = sendActivationCodeReq.toJson(); if (isFormFamilyFile) { - payload.remove("MobileNo"); payload.remove("NationalID"); payload.remove("SMSSignature"); diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 8be2b8e..6af1132 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -851,16 +851,13 @@ class AuthenticationViewModel extends ChangeNotifier { request['isRegister'] = true; _appState.setAppAuthToken = response['LogInTokenID']; if (isPatientOutsideSA(request: response)) { - print("=======OUT SA======="); sendActivationCode( - otpTypeEnum: OTPTypeEnumExtension.fromInt(request["OTP_SendType"]), - nationalIdOrFileNumber: request["PatientIdentificationID"].toString(), - phoneNumber: request["PatientMobileNumber"].toString(), - payload: request, - isForRegister: true, - ); + otpTypeEnum: OTPTypeEnumExtension.fromInt(request["OTP_SendType"]), + nationalIdOrFileNumber: request["PatientIdentificationID"].toString(), + phoneNumber: request["PatientMobileNumber"].toString(), + payload: request, + isForRegister: true); } else { - print("=======IN SA======="); chekUserNHICData(request: request); } } diff --git a/lib/features/emergency_services/emergency_services_view_model.dart b/lib/features/emergency_services/emergency_services_view_model.dart index 77e5823..5d02ca3 100644 --- a/lib/features/emergency_services/emergency_services_view_model.dart +++ b/lib/features/emergency_services/emergency_services_view_model.dart @@ -25,6 +25,7 @@ class EmergencyServicesViewModel extends ChangeNotifier { final LocationUtils? locationUtils; final AppState appState; bool isERListLoading = false; + bool isTermsAccepted = false; List nearestERList = []; List nearestERFilteredList = []; @@ -47,11 +48,14 @@ class EmergencyServicesViewModel extends ChangeNotifier { required this.appState, }); - get isGMSAvailable - { + get isGMSAvailable { return appState.isGMSAvailable; } + void onTermAccepted() { + isTermsAccepted = !isTermsAccepted; + notifyListeners(); + } Future getRRTProcedures({Function(dynamic)? onSuccess, Function(String)? onError}) async { RRTProceduresList.clear(); @@ -89,6 +93,10 @@ class EmergencyServicesViewModel extends ChangeNotifier { }); } + void moveToNextStep() { + navServices.push(CustomPageRoute(page: CallAmbulancePage(isFromRRT: true))); + } + void filterErList(String query) { print("the query is $query"); if (query.isEmpty) { @@ -149,8 +157,7 @@ class EmergencyServicesViewModel extends ChangeNotifier { } GMSMapServices.CameraPosition getGMSLocation() { - return GMSMapServices.CameraPosition( - target: GMSMapServices.LatLng(appState.userLat, appState.userLong), zoom: 18); + return GMSMapServices.CameraPosition(target: GMSMapServices.LatLng(appState.userLat, appState.userLong), zoom: 18); } handleGMSMapCameraMoved(GMSMapServices.CameraPosition value) { @@ -158,9 +165,7 @@ class EmergencyServicesViewModel extends ChangeNotifier { } HMSCameraServices.CameraPosition getHMSLocation() { - return HMSCameraServices.CameraPosition( - target: HMSCameraServices.LatLng(appState.userLat, appState.userLong),zoom: 18); - + return HMSCameraServices.CameraPosition(target: HMSCameraServices.LatLng(appState.userLat, appState.userLong), zoom: 18); } handleHMSMapCameraMoved(HMSCameraServices.CameraPosition value) { @@ -173,11 +178,8 @@ class EmergencyServicesViewModel extends ChangeNotifier { onSuccess: (position) { updateBottomSheetState(BottomSheetType.FIXED); navServices.push( - CustomPageRoute( - page: CallAmbulancePage(), direction: AxisDirection.down - ), + CustomPageRoute(page: CallAmbulancePage(), direction: AxisDirection.down), ); - }); } @@ -187,8 +189,6 @@ class EmergencyServicesViewModel extends ChangeNotifier { } void setIsGMSAvailable(bool value) { - notifyListeners(); - } } diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index f0263f9..3e67a0e 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -59,7 +59,6 @@ class MedicalFileViewModel extends ChangeNotifier { _selectedFamilyFileTabIndex = value; notifyListeners(); } - } static final DialogService _dialogService = getIt.get(); @@ -486,6 +485,13 @@ class MedicalFileViewModel extends ChangeNotifier { }); } + Future clearAuthValues() async { + authVM.nationalIdController.clear(); + authVM.phoneNumberController.clear(); + authVM.emailController.clear(); + authVM.dobController.clear(); + } + Future handleFamilyFileRequestOTPVerification() async { LoaderBottomSheet.showLoader(); if (!_appState.getIsChildLoggedIn) { diff --git a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart index 0e23d49..fd93f8e 100644 --- a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart +++ b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart @@ -1,9 +1,18 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/dependencies.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/emergency_services/emergency_services_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/call_ambulance_page.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/radio/custom_radio_button.dart'; import 'package:provider/provider.dart'; @@ -13,32 +22,160 @@ class RrtRequestTypeSelect extends StatelessWidget { @override Widget build(BuildContext context) { // return Consumer(builder: (context, emergencyServicesVM, child) { + // NavigationService navService = getIt(); + // EmergencyServicesViewModel erServiceVm = Provider.of(context); return Column( children: [ + Padding( + padding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.r), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CustomRadioOption(value: "", groupValue: "", onChanged: (value) {}, text: "Home Visit Emergency".needTranslation).paddingSymmetrical(16, 24), + Divider(height: 1, color: Color(0xFFD2D2D2).withValues(alpha: 0.3)).paddingSymmetrical(16, 0), + CustomRadioOption(value: "", groupValue: "", onChanged: (value) {}, text: "COVID-19 (24 Hour) Home Visit".needTranslation).paddingSymmetrical(16, 24), + Divider(height: 1, color: Color(0xFFD2D2D2).withValues(alpha: 0.3)).paddingSymmetrical(16, 0), + CustomRadioOption(value: "", groupValue: "", onChanged: (value) {}, text: "COVID-19 (6 Hour) Home Visit".needTranslation).paddingSymmetrical(16, 24), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + child: GestureDetector( + onTap: context.read().onTermAccepted, + child: Row( + children: [ + Selector( + selector: (_, vm) => vm.isTermsAccepted, + shouldRebuild: (previous, next) => previous != next, + builder: (context, isTermsAccepted, child) { + return AnimatedContainer( + duration: const Duration(milliseconds: 200), + height: 24.h, + width: 24.h, + decoration: BoxDecoration( + color: isTermsAccepted ? AppColors.primaryRedColor : Colors.transparent, + borderRadius: BorderRadius.circular(6), + border: Border.all(color: isTermsAccepted ? AppColors.primaryRedBorderColor : AppColors.greyColor, width: 2.h), + ), + child: isTermsAccepted ? Icon(Icons.check, size: 16.f, color: Colors.white) : null, + ); + }, + ), + SizedBox(width: 12.h), + Row( + children: [ + Text( + LocaleKeys.iAcceptThe.tr(), + style: context.dynamicTextStyle(fontSize: 14.f, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), + ), + GestureDetector( + onTap: () { + // Navigate to terms and conditions page + Navigator.of(context).pushNamed('/terms'); + }, + child: Text( + LocaleKeys.termsConditoins.tr(), + style: context.dynamicTextStyle( + fontSize: 14.f, fontWeight: FontWeight.w500, color: AppColors.primaryRedColor, decoration: TextDecoration.underline, decorationColor: AppColors.primaryRedBorderColor), + ), + ), + ], + ), + ], + ), + ), + ), Container( - padding: EdgeInsets.all(16.h), - height: 200.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 24.h, + hasShadow: true, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - CustomRadioOption( - value: "", - groupValue: "", - onChanged: (value) {}, - text: "Home Visit Emergency", - ) - ], - ), - ], + child: SizedBox( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // if (widget.patientAppointmentHistoryResponseModel.nextAction == 15 || widget.patientAppointmentHistoryResponseModel.nextAction == 20) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "Total amount to pay".needTranslation.toText18(isBold: true), + Utils.getPaymentAmountWithSymbol("1000".toString().toText16(isBold: true), AppColors.blackColor, 13, isSaudiCurrency: true), + ], + ), + SizedBox(height: 4.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: "Amount will be paid at the hospital".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)), + "VAT 15%(${150})".needTranslation.toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -2), + ], + ), + SizedBox(height: 18.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: 150.h, + child: Utils.getPaymentMethods(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Utils.getPaymentAmountWithSymbol("1,150".toString().toText24(isBold: true), AppColors.blackColor, 17, isSaudiCurrency: true), + ], + ), + ], + ) + ], + ).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h), + // AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) + CustomButton( + text: LocaleKeys.next.tr(), + onPressed: () { + // navService.pop(); + context.read().moveToNextStep(); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50.h, + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ).paddingSymmetrical(16.h, 24.h) + // : CustomButton( + // text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), + // onPressed: () { + // myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + // handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction); + // }, + // backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction), + // borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), + // textColor: widget.patientAppointmentHistoryResponseModel.nextAction == 15 ? AppColors.textColor : AppColors.whiteColor, + // fontSize: 16, + // fontWeight: FontWeight.w500, + // borderRadius: 12, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // height: 50.h, + // icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), + // iconColor: AppColors.whiteColor, + // iconSize: 18.h, + // ).paddingSymmetrical(16.h, 24.h), + ], + ), ), ), - SizedBox(height: 32.h), ], ); // }); diff --git a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart index eb36f92..63cb4e6 100644 --- a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart +++ b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:google_places_flutter/model/prediction.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -26,40 +27,38 @@ import 'package:provider/provider.dart'; import '../../../widgets/common_bottom_sheet.dart'; import 'widgets/AddressItem.dart'; -class CallAmbulancePage extends StatelessWidget { +class CallAmbulancePage extends StatefulWidget { + bool? isFromRRT; + + CallAmbulancePage({super.key, this.isFromRRT = false}); + + @override + State createState() => _CallAmbulancePageState(); +} + +class _CallAmbulancePageState extends State { + TextEditingController addressController = TextEditingController(); + @override Widget build(BuildContext context) { return Scaffold( bottomSheet: ExpandableBottomSheet( - bottomSheetType: - context.watch().bottomSheetType, + bottomSheetType: context.watch().bottomSheetType, children: { - BottomSheetType.EXPANDED: ExpanedBottomSheet(context), - BottomSheetType.FIXED: FixedBottomSheet(context), + BottomSheetType.EXPANDED: expandedBottomSheet(context), + BottomSheetType.FIXED: fixedBottomSheet(context), }, ), body: Stack( children: [ - if (context.read().isGMSAvailable || - Platform.isIOS) - GMSMap( - currentLocation: - context.read().getGMSLocation(), - onCameraMoved: (value) => context - .read() - .handleGMSMapCameraMoved(value)) + if (context.read().isGMSAvailable || Platform.isIOS) + GMSMap(currentLocation: context.read().getGMSLocation(), onCameraMoved: (value) => context.read().handleGMSMapCameraMoved(value)) else - HMSMap( - currentLocation: - context.read().getHMSLocation(), - onCameraMoved: (value) => context - .read() - .handleHMSMapCameraMoved(value)), + HMSMap(currentLocation: context.read().getHMSLocation(), onCameraMoved: (value) => context.read().handleHMSMapCameraMoved(value)), Align( alignment: AlignmentDirectional.topStart, - child: Utils.buildSvgWithAssets( - icon: AppAssets.closeBottomNav, width: 32.h, height: 32.h), - ).paddingOnly(top: 51.h, left: 24.h).onPress((){ + child: Utils.buildSvgWithAssets(icon: AppAssets.closeBottomNav, width: 32.h, height: 32.h), + ).paddingOnly(top: 51.h, left: 24.h).onPress(() { Navigator.pop(context); }) ], @@ -67,13 +66,12 @@ class CallAmbulancePage extends StatelessWidget { ); } - Widget FixedBottomSheet(BuildContext context) { + Widget fixedBottomSheet(BuildContext context) { return GestureDetector( - onVerticalDragUpdate: (details){ + onVerticalDragUpdate: (details) { print("the delta is ${details.delta.dy}"); - if(details.delta.dy<0){ - + if (details.delta.dy < 0) { context.read().updateBottomSheetState(BottomSheetType.EXPANDED); } }, @@ -84,15 +82,11 @@ class CallAmbulancePage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Padding( - - padding: EdgeInsetsDirectional.only(end:24.h, bottom: 24.h), + Padding( + padding: EdgeInsetsDirectional.only(end: 24.h, bottom: 24.h), child: DecoratedBox( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, borderRadius: 12.h), - child: Utils.buildSvgWithAssets( - icon: AppAssets.locate_me, width: 24.h, height: 24.h) - .paddingAll(12.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.h), + child: Utils.buildSvgWithAssets(icon: AppAssets.locate_me, width: 24.h, height: 24.h).paddingAll(12.h), ), ), ], @@ -110,15 +104,15 @@ class CallAmbulancePage extends StatelessWidget { // ), // ), // ), - // .paddingOnly(right: 24.h, bottom: 24.h), + // .paddingOnly(right: 24.h, bottom: 24.h), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, spacing: 24.h, children: [ TextInputWidget( - labelText: "Enter Pickup Location Manually".needTranslation, - hintText: "Enter Pickup Location".needTranslation, + labelText: widget.isFromRRT! ? "Type Address".needTranslation : "Enter Pickup Location Manually".needTranslation, + hintText: widget.isFromRRT! ? "Enter street or area name".needTranslation : "Enter Pickup Location".needTranslation, leadingIcon: AppAssets.location_pickup, isAllowLeadingIcon: true, isEnable: false, @@ -126,50 +120,27 @@ class CallAmbulancePage extends StatelessWidget { autoFocus: false, isBorderAllowed: false, keyboardType: TextInputType.text, - padding: EdgeInsets.symmetric( - vertical: ResponsiveExtension(10).h, - horizontal: ResponsiveExtension(15).h, - ), - ).onPress(() { - context - .read() - .updateBottomSheetState(BottomSheetType.EXPANDED); - }).paddingOnly(right: 24.h, left: 24.h), + controller: addressController, + padding: EdgeInsets.symmetric(vertical: ResponsiveExtension(8).h, horizontal: ResponsiveExtension(12).h), + ).paddingOnly(right: 24.h, left: 24.h), SizedBox( height: 200.h, child: DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.scaffoldBgColor, - customBorder: BorderRadius.only( - topLeft: Radius.circular(24.h), - topRight: Radius.circular(24.h), - ), + customBorder: BorderRadius.only(topLeft: Radius.circular(24.h), topRight: Radius.circular(24.h)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - spacing: 24.h, + spacing: 4, children: [ - Column( - spacing: 4.h, - children: [ - "Select Pickup Location".needTranslation.toText21( - weight: FontWeight.w600, - color: AppColors.textColor, - ), - " Please select the location of pickup" - .needTranslation - .toText12( - fontWeight: FontWeight.w500, - color: AppColors.greyTextColor, - ) - ], - ), + "Select Pickup Location".needTranslation.toText21(weight: FontWeight.w600, color: AppColors.textColor), + " Please select the location of pickup".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + SizedBox(height: 20.h), CustomButton( text: "Select Location".needTranslation, onPressed: () { - context - .read() - .updateBottomSheetState(BottomSheetType.EXPANDED); + context.read().updateBottomSheetState(BottomSheetType.EXPANDED); }) ], ).paddingOnly(top: 24.h, bottom: 32.h, left: 24.h, right: 24.h), @@ -182,23 +153,20 @@ class CallAmbulancePage extends StatelessWidget { ); } - Widget ExpanedBottomSheet(BuildContext context) { + Widget expandedBottomSheet(BuildContext context) { return GestureDetector( - onVerticalDragUpdate: (details){ - if(details.delta.dy>0){ - context.read().updateBottomSheetState(BottomSheetType.FIXED); - } - }, + onVerticalDragUpdate: (details) { + if (details.delta.dy > 0) { + context.read().updateBottomSheetState(BottomSheetType.FIXED); + } + }, child: Column( mainAxisSize: MainAxisSize.min, children: [ DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.scaffoldBgColor, - customBorder: BorderRadius.only( - topLeft: Radius.circular(24.h), - topRight: Radius.circular(24.h), - ), + customBorder: BorderRadius.only(topLeft: Radius.circular(24.h), topRight: Radius.circular(24.h)), ), child: Column( children: [ @@ -207,17 +175,12 @@ class CallAmbulancePage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, spacing: 16.h, children: [ - "Select Pickup Location".needTranslation.toText21( - weight: FontWeight.w600, - color: AppColors.textColor, - ), + "Select Pickup Location".needTranslation.toText21(weight: FontWeight.w600, color: AppColors.textColor), locationsSections(context), - hospitalAndPickUpSection(context), - + widget.isFromRRT! ? SizedBox() : hospitalAndPickUpSection(context), ], - ).paddingOnly(top: 24.h, bottom: 32.h,left: 24.h, right: 24.h), + ).paddingOnly(top: 24.h, bottom: 32.h, left: 24.h, right: 24.h), ), - bottomPriceContent(context) ], ), @@ -249,8 +212,7 @@ class CallAmbulancePage extends StatelessWidget { shrinkWrap: true, itemCount: 3, itemBuilder: (__, index) { - if (index == - 2) // todo means the end of the list so handle as per the viewmodel + if (index == 2) // todo means the end of the list so handle as per the viewmodel { return CustomButton( height: 40.h, @@ -264,11 +226,8 @@ class CallAmbulancePage extends StatelessWidget { } else { return AddressItem( isSelected: index == 0, - address: - "Flat No 301, Building No 12, Palm Spring Apartment, Sector 45, Gurugram, Haryana 122003", - title: index == 0 - ? "Home".needTranslation - : "Work".needTranslation, + address: "Flat No 301, Building No 12, Palm Spring Apartment, Sector 45, Gurugram, Haryana 122003", + title: index == 0 ? "Home".needTranslation : "Work".needTranslation, onTap: () {}, ); } @@ -293,11 +252,9 @@ class CallAmbulancePage extends StatelessWidget { subTitle: "hospital".needTranslation, leadingIcon: AppAssets.hospital, ), - Utils.buildSvgWithAssets(icon: AppAssets.down_cheveron, - width: 24.h, height: 24.h) - .paddingAll(16.h) + Utils.buildSvgWithAssets(icon: AppAssets.down_cheveron, width: 24.h, height: 24.h).paddingAll(16.h) ], - ).onPress((){ + ).onPress(() { showHospitalBottomSheet(context); }), SizedBox(height: 16.h), @@ -307,7 +264,6 @@ class CallAmbulancePage extends StatelessWidget { thickness: 1, ), SizedBox(height: 16.h), - Row( children: [ hospitalAndPickUpItemContent( @@ -317,8 +273,8 @@ class CallAmbulancePage extends StatelessWidget { ), CustomSwitch( value: context.watch().isGMSAvailable, - onChanged: (value){ - context.read().setIsGMSAvailable( value); + onChanged: (value) { + context.read().setIsGMSAvailable(value); }, ) ], @@ -378,68 +334,49 @@ class CallAmbulancePage extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - DecoratedBox( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.scaffoldBgColor, - customBorder: BorderRadius.only( - topLeft: Radius.circular(24.h), - topRight: Radius.circular(24.h), - ), - hasShadow: true - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 12.h, + DecoratedBox( + decoration: RoundedRectangleBorder() + .toSmoothCornerDecoration(color: AppColors.scaffoldBgColor, customBorder: BorderRadius.only(topLeft: Radius.circular(24.h), topRight: Radius.circular(24.h)), hasShadow: true), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 12.h, + children: [ + Row( children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 4.h, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 4.h, + children: [ + "Total amount to pay".needTranslation.toText18(weight: FontWeight.w600, color: AppColors.textColor), + Row( children: [ - "Total amount to pay".needTranslation.toText18( - weight: FontWeight.w600, - color: AppColors.textColor, - ), - Row( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.warning, - height: 18.h, width: 18.h), - SizedBox(width: 4.h,), - "Amount will be paid at the hospital" - .needTranslation - .toText12( - fontWeight: FontWeight.w500, - color: AppColors.greyTextColor, - ), - ], - ) + Utils.buildSvgWithAssets(icon: AppAssets.warning, height: 18.h, width: 18.h), + SizedBox(width: 4.h), + "Amount will be paid at the hospital".needTranslation.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), ], - ), - ), - "\$250".toText24( - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ) - ], + ) + ], + ), ), - CustomButton( - text: "Submit Request".needTranslation, - onPressed: () { - Navigator.push(context, CustomPageRoute(page: RequestingServicesPage())); - }) + Utils.getPaymentAmountWithSymbol("250".toString().toText24(isBold: true), AppColors.blackColor, 17, isSaudiCurrency: true), ], - ).paddingOnly(top: 24.h, bottom: 12.h, left: 24.h, right: 24.h), - ), + ), + CustomButton( + text: "Submit Request".needTranslation, + onPressed: () { + Navigator.push(context, CustomPageRoute(page: RequestingServicesPage())); + }) + ], + ).paddingOnly(top: 24.h, bottom: 24.h, left: 24.h, right: 24.h), + ), ], ); } - showHospitalBottomSheet(BuildContext context){ + showHospitalBottomSheet(BuildContext context) { showCommonBottomSheetWithoutHeight( - title: - LocaleKeys.selectHospital.tr(), + title: LocaleKeys.selectHospital.tr(), context, child: HospitalBottomSheetBody(), isFullScreen: false, diff --git a/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart b/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart index 7f79be0..10c139c 100644 --- a/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart +++ b/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart @@ -7,11 +7,12 @@ 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/presentation/emergency_services/call_ambulance/tracking_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart' - show CustomPageRoute; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart' show CustomPageRoute; import 'package:lottie/lottie.dart'; class RequestingServicesPage extends StatefulWidget { + RequestingServicesPage({super.key}); + @override State createState() => _RequestingServicesPageState(); } @@ -20,8 +21,7 @@ class _RequestingServicesPageState extends State { @override void initState() { Timer(Duration(seconds: 3), () { - Navigator.pushReplacement( - context, CustomPageRoute(page: TrackingScreen())); + Navigator.pushReplacement(context, CustomPageRoute(page: TrackingScreen())); }); super.initState(); } @@ -32,14 +32,7 @@ class _RequestingServicesPageState extends State { color: AppColors.scaffoldBgColor, child: Stack( children: [ - Lottie.asset(AppAnimations.loadingAnimation, - width: 80.h, - height: 80.h, - repeat: true, - reverse: false, - frameRate: FrameRate(60), - fit: BoxFit.fill) - .center, + Lottie.asset(AppAnimations.loadingAnimation, width: 80.h, height: 80.h, repeat: true, reverse: false, frameRate: FrameRate(60), fit: BoxFit.fill).center, Positioned( bottom: 1, child: "Submitting your request. \nPlease wait for a moment" diff --git a/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart b/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart index a48ca10..483da07 100644 --- a/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart +++ b/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart @@ -20,38 +20,37 @@ import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; class TrackingScreen extends StatelessWidget { - final OrderTrackingState state = OrderTrackingState.ended; + final OrderTrackingState state = OrderTrackingState.waitingForCall; + @override Widget build(BuildContext context) { - return Scaffold( - bottomNavigationBar: Visibility( - visible: state == OrderTrackingState.ended, - child: SafeArea( - child: CustomButton( - height: 56.h, - backgroundColor: AppColors.bgGreenColor, - borderColor: Colors.transparent, - text: "Close".needTranslation, - textColor: AppColors.whiteColor, - onPressed: () {}, - ).paddingOnly(left:16.h,right:16.h), - ), + return CollapsingListView( + title: "Tracking Details".needTranslation, + bottomChild: Visibility( + visible: state == OrderTrackingState.ended, + child: CustomButton( + height: 50.h, + backgroundColor: AppColors.bgGreenColor, + borderColor: Colors.transparent, + text: "Close".needTranslation, + textColor: AppColors.whiteColor, + onPressed: () {}, + ).paddingOnly(left: 16.h, right: 16.h, bottom: 16.h), ), - body: CollapsingListView( - title: "Tracking Details".needTranslation, - child: SingleChildScrollView( - child: Column( - children: [ - animationSection(), - Column( - spacing: 16.h, - children: [OrderStatus(context), OrderTrackingId(), ContactSection()], - ).paddingAll(16.h), - ], - ))), + child: SingleChildScrollView( + child: Column( + children: [ + animationSection(), + Column( + spacing: 16.h, + children: [OrderStatus(context), OrderTrackingId(), ContactSection()], + ).paddingAll(16.h), + ], + )), ); } - animationSection(){ + + animationSection() { switch (state) { case OrderTrackingState.waitingForCall: case OrderTrackingState.dispactched: @@ -59,18 +58,14 @@ class TrackingScreen extends StatelessWidget { return Lottie.asset(AppAnimations.ambulance, repeat: true, reverse: false, width: 260.h, height: 200.h); case OrderTrackingState.ended: default: - return Lottie.asset(AppAnimations.checkmark, repeat: true, width: 260.h, height: 200.h); + return Lottie.asset(AppAnimations.checkmark, repeat: true, width: 260.h, height: 200.h); } } OrderStatus(BuildContext context) { return Container( padding: EdgeInsets.all(16.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: false, - ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: false), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -95,7 +90,7 @@ class TrackingScreen extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 16,), + SizedBox(height: 16.h), CustomButton( text: "Cancel Request".needTranslation, onPressed: () async {}, @@ -119,7 +114,7 @@ class TrackingScreen extends StatelessWidget { backgroundColor: AppColors.lightRedButtonColor, borderColor: Colors.transparent, text: "Share Your Live Locatin on Whatsapp".needTranslation, - fontSize: 12.fSize, + fontSize: 12.f, textColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor, onPressed: () {}, @@ -131,11 +126,7 @@ class TrackingScreen extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, spacing: 12.h, - children: [ - dividerSection, - doctorSection(), - mapSection(context) - ], + children: [dividerSection, doctorSection(), mapSection(context)], ); case OrderTrackingState.ended: default: @@ -170,17 +161,14 @@ class TrackingScreen extends StatelessWidget { return Row( spacing: 16.h, children: [ - Utils.buildImgWithNetwork(url: "", iconColor: Colors.transparent) - .circle(52.h), + Utils.buildImgWithNetwork(url: "", iconColor: Colors.transparent).circle(52.h), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Dr. John Doe".toText16( - color: AppColors.textColor, weight: FontWeight.w600), + "Dr. John Doe".toText16(color: AppColors.textColor, weight: FontWeight.w600), SizedBox(height: 4.h), - "MBBS, MD - General Medicine".toText12( - color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + "MBBS, MD - General Medicine".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), ], ), ), @@ -204,96 +192,83 @@ class TrackingScreen extends StatelessWidget { Widget mapForRequestedCoordinate(BuildContext context) { // return SizedBox.shrink(); - if (context.read().isGMSAvailable || - Platform.isIOS) - return GMSMap( - myLocationEnabled: false, - currentLocation: - context.read().getGMSLocation(), - onCameraMoved: (value) => context - .read() - .handleGMSMapCameraMoved(value)); - else + if (context.read().isGMSAvailable || Platform.isIOS) { + return GMSMap( + myLocationEnabled: false, + currentLocation: context.read().getGMSLocation(), + onCameraMoved: (value) => context.read().handleGMSMapCameraMoved(value)); + } else { return HMSMap( myLocationEnabled: false, - currentLocation: - context.read().getHMSLocation(), - onCameraMoved: (value) => context - .read() - .handleHMSMapCameraMoved(value)); + currentLocation: context.read().getHMSLocation(), + onCameraMoved: (value) => context.read().handleHMSMapCameraMoved(value)); + } } informationRegardingTrackingSection() { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - currentStatus(), - SizedBox(height: 4.h), - "You will receive a call from HMG for confirmation ".toText12( - color: AppColors.greyTextColor, fontWeight: FontWeight.w500) - ], + children: [currentStatus(), SizedBox(height: 4.h), "You will receive a call from HMG for confirmation ".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500)], ); } currentStatus() { - switch (state) { - case OrderTrackingState.waitingForCall: - case OrderTrackingState.dispactched: - return RichText( - text: TextSpan(children: [ - TextSpan( - text: "Please wait for the call".needTranslation, - style: TextStyle( - fontSize: 21.fSize, - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ), - ), - TextSpan( - text: "...".needTranslation, - style: TextStyle( - fontSize: 21.fSize, - fontWeight: FontWeight.w600, - color: AppColors.errorColor, - ), - ), - ]), - ); - case OrderTrackingState.returning: - return RichText( - text: TextSpan(children: [ - TextSpan( - text: "15:30".needTranslation, - style: TextStyle( - fontSize: 21.fSize, - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ), - ), - TextSpan( - text: " mins ".needTranslation, - style: TextStyle( - fontSize: 21.fSize, - fontWeight: FontWeight.w600, - color: AppColors.errorColor, - ), - ), - TextSpan( - text: "to hospital".needTranslation, - style: TextStyle( - fontSize: 21.fSize, - fontWeight: FontWeight.w600, - color: AppColors.textColor, - ), - ), - ]), - ); - case OrderTrackingState.ended: - default: - return "Arrived" - .needTranslation - .toText21(color: AppColors.textColor, weight: FontWeight.w600); - } + switch (state) { + case OrderTrackingState.waitingForCall: + case OrderTrackingState.dispactched: + return RichText( + text: TextSpan(children: [ + TextSpan( + text: "Please wait for the call".needTranslation, + style: TextStyle( + fontSize: 21.f, + fontWeight: FontWeight.w600, + color: AppColors.textColor, + ), + ), + TextSpan( + text: "...".needTranslation, + style: TextStyle( + fontSize: 21.f, + fontWeight: FontWeight.w600, + color: AppColors.errorColor, + ), + ), + ]), + ); + case OrderTrackingState.returning: + return RichText( + text: TextSpan(children: [ + TextSpan( + text: "15:30".needTranslation, + style: TextStyle( + fontSize: 21.f, + fontWeight: FontWeight.w600, + color: AppColors.textColor, + ), + ), + TextSpan( + text: " mins ".needTranslation, + style: TextStyle( + fontSize: 21.f, + fontWeight: FontWeight.w600, + color: AppColors.errorColor, + ), + ), + TextSpan( + text: "to hospital".needTranslation, + style: TextStyle( + fontSize: 21.f, + fontWeight: FontWeight.w600, + color: AppColors.textColor, + ), + ), + ]), + ); + case OrderTrackingState.ended: + default: + return "Arrived".needTranslation.toText21(color: AppColors.textColor, weight: FontWeight.w600); + } } OrderTrackingId() { @@ -308,19 +283,15 @@ class TrackingScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, spacing: 8.h, children: [ - "Req ID:1234567890" - .toText16(color: AppColors.textColor, weight: FontWeight.w600), + "Req ID:1234567890".toText16(color: AppColors.textColor, weight: FontWeight.w600), Row( spacing: 8.h, children: [ - Chip("location name".needTranslation, AppAssets.location_pickup, - AppColors.blackBgColor), - Chip("hotel name ".needTranslation, AppAssets.hospital, - AppColors.blackBgColor), + Chip("location name".needTranslation, AppAssets.location_pickup, AppColors.blackBgColor), + Chip("hotel name ".needTranslation, AppAssets.hospital, AppColors.blackBgColor), ], ), - Chip("hotel name ".needTranslation, AppAssets.hospital, - AppColors.blackBgColor), + Chip("hotel name ".needTranslation, AppAssets.hospital, AppColors.blackBgColor), ], ), ); @@ -350,11 +321,8 @@ class TrackingScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, spacing: 4.h, children: [ - "Contact Rapid Response Team (RRT)".needTranslation.toText14( - color: AppColors.textColor, weight: FontWeight.w600), - "1223456789".needTranslation.toText12( - color: AppColors.primaryRedColor, - fontWeight: FontWeight.w500), + "Contact Rapid Response Team (RRT)".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w600), + "1223456789".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), SizedBox(height: 8.h), ], ), @@ -390,27 +358,22 @@ class TrackingScreen extends StatelessWidget { getTitle(OrderTrackingState state) { switch (state) { case OrderTrackingState.waitingForCall: - return "Confirmation Call".needTranslation - .toText16(color: AppColors.textColor, weight: FontWeight.w600); + return "Confirmation Call".needTranslation.toText16(color: AppColors.textColor, weight: FontWeight.w600); case OrderTrackingState.dispactched: - return "Pickup Up from Home".needTranslation - .toText16(color: AppColors.textColor, weight: FontWeight.w600); + return "Pickup Up from Home".needTranslation.toText16(color: AppColors.textColor, weight: FontWeight.w600); case OrderTrackingState.returning: - return " On The Way To Hospital".needTranslation - .toText16(color: AppColors.textColor, weight: FontWeight.w600); + return " On The Way To Hospital".needTranslation.toText16(color: AppColors.textColor, weight: FontWeight.w600); case OrderTrackingState.ended: default: - return "Arrived at Hospital".needTranslation - .toText16(color: AppColors.textColor, weight: FontWeight.w600); + return "Arrived at Hospital".needTranslation.toText16(color: AppColors.textColor, weight: FontWeight.w600); } } mapSection(BuildContext context) { - return SizedBox( + return SizedBox( height: 170.h, width: double.infinity, - child: ClipRRect( - borderRadius: BorderRadius.circular(20.h),child: mapForRequestedCoordinate(context)), + child: ClipRRect(borderRadius: BorderRadius.circular(20.h), child: mapForRequestedCoordinate(context)), ); } } diff --git a/lib/presentation/emergency_services/emergency_services_page.dart b/lib/presentation/emergency_services/emergency_services_page.dart index ddea6fd..cf7c4dc 100644 --- a/lib/presentation/emergency_services/emergency_services_page.dart +++ b/lib/presentation/emergency_services/emergency_services_page.dart @@ -67,8 +67,7 @@ class EmergencyServicesPage extends StatelessWidget { showCommonBottomSheetWithoutHeight( context, child: Container( - decoration: - RoundedRectangleBorder().toSmoothCornerDecoration( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.primaryRedColor, borderRadius: 24.h, ), @@ -92,22 +91,11 @@ class EmergencyServicesPage extends StatelessWidget { }), ], ), - Lottie.asset(AppAnimations.ambulance_alert, - repeat: false, - reverse: false, - frameRate: FrameRate(60), - width: 120.h, - height: 120.h, - fit: BoxFit.contain), + Lottie.asset(AppAnimations.ambulance_alert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), SizedBox(height: 8.h), - "Confirmation".needTranslation.toText28( - color: AppColors.whiteColor, isBold: true), + "Confirmation".needTranslation.toText28(color: AppColors.whiteColor, isBold: true), SizedBox(height: 8.h), - "Are you sure you want to call an ambulance?" - .needTranslation - .toText14( - color: AppColors.whiteColor, - weight: FontWeight.w500), + "Are you sure you want to call an ambulance?".needTranslation.toText14(color: AppColors.whiteColor, weight: FontWeight.w500), SizedBox(height: 24.h), CustomButton( text: LocaleKeys.confirm.tr(context: context), @@ -115,15 +103,11 @@ class EmergencyServicesPage extends StatelessWidget { // Navigator.of(context).pop(); showCommonBottomSheetWithoutHeight( - title: - "Transport Options".needTranslation, + title: "Transport Options".needTranslation, context, - child: AmbulanceOptionSelectionBottomSheet( - onTap: () { + child: AmbulanceOptionSelectionBottomSheet(onTap: () { Navigator.of(context).pop(); - context - .read() - .navigateTOAmbulancePage(); + context.read().navigateTOAmbulancePage(); }), isFullScreen: false, isCloseButtonVisible: true, @@ -182,11 +166,7 @@ class EmergencyServicesPage extends StatelessWidget { SizedBox(height: 16.h), Container( padding: EdgeInsets.all(16.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: false, - ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: false), child: Row( children: [ Utils.buildSvgWithAssets(icon: AppAssets.rrt_icon, width: 40.h, height: 40.h), @@ -195,8 +175,8 @@ class EmergencyServicesPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Rapid Response Team (RRT)".toText16(isBold: true, color: AppColors.blackColor), - "Comprehensive medical service for all sorts of urgent and stable cases".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + "Rapid Response Team (RRT)".needTranslation.toText16(isBold: true, color: AppColors.blackColor), + "Comprehensive medical service for all sorts of urgent and stable cases".needTranslation.toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), ], ), ), @@ -204,71 +184,57 @@ class EmergencyServicesPage extends StatelessWidget { Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, width: 13.h, height: 13.h), ], ).onPress(() { - showCommonBottomSheetWithoutHeight( - context, - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.primaryRedColor, - borderRadius: 24.h, - ), - child: Padding( - padding: EdgeInsets.all(24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "".toText14(), - Utils.buildSvgWithAssets( - icon: AppAssets.cancel_circle_icon, - iconColor: AppColors.whiteColor, - width: 24.h, - height: 24.h, - fit: BoxFit.contain, - ).onPress(() { + locationUtils!.getLocation( + isShowConfirmDialog: true, + onSuccess: (position) { + showCommonBottomSheetWithoutHeight( + context, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Lottie.asset(AppAnimations.ambulance_alert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.contain), + SizedBox(height: 8.h), + "Confirmation".needTranslation.toText28( + color: AppColors.whiteColor, + isBold: true, + ), + SizedBox(height: 8.h), + "Are you sure you want to call Rapid Response Team (RRT)?".needTranslation.toText16(color: AppColors.whiteColor, weight: FontWeight.w500), + SizedBox(height: 24.h), + CustomButton( + text: LocaleKeys.confirm.tr(context: context), + onPressed: () async { Navigator.of(context).pop(); - }), - ], - ), - Lottie.asset(AppAnimations.ambulance_alert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), - SizedBox(height: 8.h), - "Confirmation".needTranslation.toText28(color: AppColors.whiteColor, isBold: true), - SizedBox(height: 8.h), - "Are you sure you want to call Rapid Response Team (RRT)?".needTranslation.toText14(color: AppColors.whiteColor, weight: FontWeight.w500), - SizedBox(height: 24.h), - CustomButton( - text: LocaleKeys.confirm.tr(context: context), - onPressed: () async { - Navigator.of(context).pop(); - showCommonBottomSheetWithoutHeight( - title: "Rapid Response Team (RRT)".needTranslation, - context, - child: RrtRequestTypeSelect(), - isFullScreen: false, - isCloseButtonVisible: true, - hasBottomPadding: false, - backgroundColor: AppColors.bottomSheetBgColor, - callBackFunc: () {}, - ); - }, - backgroundColor: AppColors.whiteColor, - borderColor: AppColors.whiteColor, - textColor: AppColors.primaryRedColor, - icon: AppAssets.checkmark_icon, - iconColor: AppColors.primaryRedColor, - ), - SizedBox(height: 8.h), - ], - ), - ), - ), - isFullScreen: false, - isCloseButtonVisible: false, - hasBottomPadding: false, - backgroundColor: AppColors.primaryRedColor, - callBackFunc: () {}, - ); + showCommonBottomSheetWithoutHeight( + title: "Rapid Response Team (RRT)".needTranslation, + context, + child: RrtRequestTypeSelect(), + isFullScreen: false, + isCloseButtonVisible: true, + hasBottomPadding: false, + isDisablePadding: true, + backgroundColor: AppColors.bottomSheetBgColor, + callBackFunc: () {}, + ); + }, + backgroundColor: AppColors.whiteColor, + borderColor: AppColors.whiteColor, + textColor: AppColors.primaryRedColor, + icon: AppAssets.checkmark_icon, + iconColor: AppColors.primaryRedColor, + ), + SizedBox(height: 20.h), + ], + ), + isFullScreen: false, + isCloseButtonVisible: true, + hasBottomPadding: false, + backgroundColor: AppColors.primaryRedColor, + iconColor: Colors.white, + customCloseIcon: AppAssets.cancel_circle_icon, + callBackFunc: () {}, + ); + }); }), ), ], diff --git a/lib/presentation/my_family/my_family.dart b/lib/presentation/my_family/my_family.dart index 194d5e0..781624a 100644 --- a/lib/presentation/my_family/my_family.dart +++ b/lib/presentation/my_family/my_family.dart @@ -50,7 +50,6 @@ class _FamilyMedicalScreenState extends State { medicalVM?.onFamilyFileTabChange(0); }); } - @override Widget build(BuildContext context) { @@ -69,6 +68,7 @@ class _FamilyMedicalScreenState extends State { text: "Add a new family member".needTranslation, onPressed: () { DialogService dialogService = getIt.get(); + medicalVM!.clearAuthValues(); dialogService.showAddFamilyFileSheet( label: "Add Family Member".needTranslation, message: "Please fill the below field to add a new family member to your profile".needTranslation, diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 1574a0a..fc70d03 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -54,6 +54,7 @@ class CollapsingListView extends StatelessWidget { SliverAppBar( automaticallyImplyLeading: false, pinned: true, + expandedHeight: 100.h, stretch: true, systemOverlayStyle: SystemUiOverlayStyle(statusBarBrightness: Brightness.light), diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 4d0dcf1..7d7bef7 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -105,17 +105,20 @@ class ButtonSheetContent extends StatelessWidget { } void showCommonBottomSheetWithoutHeight( - BuildContext context, { - required Widget child, - required VoidCallback callBackFunc, - String title = "", - bool isCloseButtonVisible = true, - bool isFullScreen = true, - bool isDismissible = true, - Widget? titleWidget, - bool useSafeArea = false, + BuildContext context, { + required Widget child, + required VoidCallback callBackFunc, + String title = "", + bool isCloseButtonVisible = true, + bool isFullScreen = true, + bool isDismissible = true, + Widget? titleWidget, + bool useSafeArea = false, bool hasBottomPadding = true, Color backgroundColor = AppColors.bottomSheetBgColor, + Color iconColor = const Color(0xff2B353E), + String? customCloseIcon, + bool isDisablePadding = false, }) { showModalBottomSheet( sheetAnimationStyle: AnimationStyle( @@ -145,40 +148,32 @@ void showCommonBottomSheetWithoutHeight( physics: ClampingScrollPhysics(), child: isCloseButtonVisible ? Container( - padding: EdgeInsets.only( - left: 24, - top: 24, - right: 24, - bottom: 12, - ), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.bottomSheetBgColor, - borderRadius: 24.h, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - titleWidget ?? - Expanded( - child: title.toText20(weight: FontWeight.w600), - ), - Utils.buildSvgWithAssets( - icon: AppAssets.close_bottom_sheet_icon, - iconColor: Color(0xff2B353E), - ).onPress(() { - Navigator.of(context).pop(); - }), - ], - ), - SizedBox(height: 16.h), - child, - ], - ), - ) + padding: isDisablePadding ? null : EdgeInsets.only(left: 24, top: 24, right: 24, bottom: 12), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: backgroundColor, borderRadius: 24.h), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + titleWidget ?? + Expanded( + child: title.toText20(weight: FontWeight.w600), + ), + Utils.buildSvgWithAssets( + icon: customCloseIcon ?? AppAssets.close_bottom_sheet_icon, + iconColor: iconColor, + ).onPress(() { + Navigator.of(context).pop(); + }), + ], + ).paddingOnly(left: isDisablePadding ? 24 : 0, right: isDisablePadding ? 24 : 0, bottom: isDisablePadding ? 12 : 0, top: isDisablePadding ? 24 : 0), + SizedBox(height: 16.h), + child, + ], + ), + ) : child, ), ), diff --git a/lib/widgets/expandable_bottom_sheet/ExpandableBottomSheet.dart b/lib/widgets/expandable_bottom_sheet/ExpandableBottomSheet.dart index 73a4a47..b18bd58 100644 --- a/lib/widgets/expandable_bottom_sheet/ExpandableBottomSheet.dart +++ b/lib/widgets/expandable_bottom_sheet/ExpandableBottomSheet.dart @@ -10,7 +10,7 @@ class ExpandableBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - print("the currently selected item is ${bottomSheetType}"); + print("the currently selected item is $bottomSheetType"); return AnimatedCrossFade( duration: const Duration(milliseconds: 600), firstChild:children[BottomSheetType.FIXED] ?? SizedBox.shrink(), diff --git a/lib/widgets/radio/custom_radio_button.dart b/lib/widgets/radio/custom_radio_button.dart index 080fcb3..a530102 100644 --- a/lib/widgets/radio/custom_radio_button.dart +++ b/lib/widgets/radio/custom_radio_button.dart @@ -11,14 +11,13 @@ class CustomRadioOption extends StatelessWidget { // final Widget child; // The content of your radio option (e.g., Text, Image) - const CustomRadioOption({ - super.key, - required this.value, - required this.groupValue, - required this.onChanged, - // required this.child, - required this.text, - }); + const CustomRadioOption( + {super.key, + required this.value, + required this.groupValue, + required this.onChanged, + // required this.child, + required this.text}); @override Widget build(BuildContext context) { @@ -31,13 +30,12 @@ class CustomRadioOption extends StatelessWidget { child: Row( children: [ Container( - width: 20.h, - height: 20.h, + width: 18.h, + height: 18.h, decoration: BoxDecoration( - shape: BoxShape.circle, - color: isSelected ? AppColors.primaryRedColor : AppColors.whiteColor, - border: Border.all(color: isSelected ? AppColors.primaryRedColor : AppColors.bottomNAVBorder, width: 2.h), - ), + shape: BoxShape.circle, + color: isSelected ? AppColors.primaryRedColor : AppColors.whiteColor, + border: Border.all(color: isSelected ? AppColors.primaryRedColor : AppColors.bottomNAVBorder, width: 2.h)), ), SizedBox(width: 8.h), text.toText16(weight: FontWeight.w500), // The provided content From 19365375f610de991decc1e205f12a9a3e2dce15 Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Mon, 8 Dec 2025 10:11:13 +0300 Subject: [PATCH 4/5] medical file changes --- .../medical_file/medical_file_page.dart | 223 ++++++++----- .../medical_file/widgets/lab_rad_card.dart | 73 +++-- lib/widgets/expandable_list_widget.dart | 301 ++++++++++++++++++ 3 files changed, 478 insertions(+), 119 deletions(-) create mode 100644 lib/widgets/expandable_list_widget.dart diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 883ca37..e1d4ce7 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -53,6 +53,7 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; +import 'package:hmg_patient_app_new/widgets/expandable_list_widget.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; @@ -148,20 +149,6 @@ class _MedicalFilePageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 16.h), - TextInputWidget( - labelText: LocaleKeys.search.tr(context: context), - hintText: "Type any record".needTranslation, - controller: TextEditingController(), - keyboardType: TextInputType.number, - isEnable: true, - prefix: null, - autoFocus: false, - isBorderAllowed: false, - isAllowLeadingIcon: true, - padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h), - leadingIcon: AppAssets.student_card, - ).paddingSymmetrical(24.w, 0.0), SizedBox(height: 16.h), Container( width: double.infinity, @@ -236,8 +223,7 @@ class _MedicalFilePageState extends State { iconColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, textColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, iconSize: 12.w, - backgroundColor: - insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1), + backgroundColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1), labelPadding: EdgeInsetsDirectional.only(end: 8.w), ); }), @@ -248,27 +234,108 @@ class _MedicalFilePageState extends State { ), ).paddingSymmetrical(24.w, 0.0), SizedBox(height: 16.h), - Consumer(builder: (context, medicalFileVM, child) { - return Column( - children: [ - CustomTabBar( - activeTextColor: AppColors.primaryRedColor, - activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1), - tabs: [ - CustomTabBarModel(AppAssets.myFilesBottom, LocaleKeys.general.tr(context: context).needTranslation), - CustomTabBarModel(AppAssets.insurance, LocaleKeys.insurance.tr(context: context)), - CustomTabBarModel(AppAssets.requests, LocaleKeys.request.tr(context: context).needTranslation), - CustomTabBarModel(AppAssets.more, "More".needTranslation), - ], - onTabChange: (index) { - medicalFileVM.onTabChanged(index); - }, - ).paddingSymmetrical(24.w, 0.0), - SizedBox(height: 24.h), - getSelectedTabData(medicalFileVM.selectedTabIndex), - ], - ); - }), + TextInputWidget( + labelText: LocaleKeys.search.tr(context: context), + hintText: "Type any record".needTranslation, + controller: TextEditingController(), + keyboardType: TextInputType.number, + isEnable: true, + prefix: null, + autoFocus: false, + isBorderAllowed: false, + isAllowLeadingIcon: true, + padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h), + leadingIcon: AppAssets.student_card, + ).paddingSymmetrical(24.w, 0.0), + SizedBox(height: 16.h), + // Using CustomExpandableList + CustomExpandableList( + expansionMode: ExpansionMode.exactlyOne, + dividerColor: Color(0xFF2B353E1A), + + items: [ + ExpandableListItem( + title: "Medical Services".toText20(weight: FontWeight.w500), + children: [ + SizedBox(height: 10.h), + getSelectedTabData(0), + ], + ), + ExpandableListItem( + title: "Medical Reports".toText20( + weight: FontWeight.w500, + ), + children: [ + SizedBox(height: 10.h), + getSelectedTabData(2), + ]), + ExpandableListItem( + title: "Insurance & Payments".toText20(weight: FontWeight.w500), + children: [ + SizedBox(height: 10.h), + getSelectedTabData(1), + ], + ), + ExpandableListItem( + title: "Tracker & Others".toText20(weight: FontWeight.w500), + children: [ + Text("Blood Report"), + SizedBox(height: 8), + Text("X-Ray Report"), + ], + ), + ], + theme: ExpandableListTheme.custom( + defaultTrailingIcon: Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w, iconColor: AppColors.textColor), + ), + ).paddingSymmetrical(16.w, 0.0), + + // ExpansionTileList( + // shrinkWrap: true, + // trailing: Icon(Icons.arrow_drop_down), + // expansionMode: ExpansionMode.exactlyOne, + // children: [ + // ExpansionTile( + // title: "Medical Services".toText20(weight: FontWeight.w600, color: AppColors.textColor), + // iconColor: Color(0xFF2E3039), + // trailing: Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w), + // children: [Text('Child 1')], + // ), + // ExpansionTile( + // title: "Medical Reports".toText20(weight: FontWeight.w600, color: AppColors.textColor), + // children: [Text('Child 2')], + // ), + // ExpansionTile( + // title: "Insurance & Payments".toText20(weight: FontWeight.w600, color: AppColors.textColor), + // children: [Text('Child 3')], + // ), + // ExpansionTile( + // title: "Tracker & Others".toText20(weight: FontWeight.w600, color: AppColors.textColor), + // children: [Text('Child 4')], + // ), + // ], + // ), + // Consumer(builder: (context, medicalFileVM, child) { + // return Column( + // children: [ + // CustomTabBar( + // activeTextColor: AppColors.primaryRedColor, + // activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1), + // tabs: [ + // CustomTabBarModel(AppAssets.myFilesBottom, LocaleKeys.general.tr(context: context).needTranslation), + // CustomTabBarModel(AppAssets.insurance, LocaleKeys.insurance.tr(context: context)), + // CustomTabBarModel(AppAssets.requests, LocaleKeys.request.tr(context: context).needTranslation), + // CustomTabBarModel(AppAssets.more, "More".needTranslation), + // ], + // onTabChange: (index) { + // medicalFileVM.onTabChanged(index); + // }, + // ).paddingSymmetrical(24.w, 0.0), + // SizedBox(height: 24.h), + // getSelectedTabData(medicalFileVM.selectedTabIndex), + // ], + // ); + // }), ], ), ); @@ -324,7 +391,7 @@ class _MedicalFilePageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Appointments & visits".needTranslation.toText18(isBold: true), + "Appointments & visits".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), Row( children: [ LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), @@ -333,7 +400,7 @@ class _MedicalFilePageState extends State { ], ), ], - ).paddingSymmetrical(24.w, 0.h).onPress(() { + ).paddingSymmetrical(0.w, 0.h).onPress(() { Navigator.of(context).push( CustomPageRoute( page: MyAppointmentsPage(), @@ -356,8 +423,7 @@ class _MedicalFilePageState extends State { ? Container( padding: EdgeInsets.all(12.w), width: MediaQuery.of(context).size.width, - decoration: - RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: true), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: true), child: Column( children: [ Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), @@ -415,10 +481,10 @@ class _MedicalFilePageState extends State { }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.h), ), - ).paddingSymmetrical(24.w, 0); + ).paddingSymmetrical(0.w, 0); }), SizedBox(height: 24.h), - "Lab & Radiology".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0.h), + "Lab & Radiology".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), SizedBox(height: 16.h), Row( children: [ @@ -437,11 +503,12 @@ class _MedicalFilePageState extends State { ); }), ), - SizedBox(width: 16.h), + SizedBox(width: 8.w), Expanded( child: LabRadCard( icon: AppAssets.radiology_icon, - labelText: LocaleKeys.radiology.tr(context: context), + labelText: "${LocaleKeys.radiology.tr(context: context)} Results".needTranslation, + // labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar", // labOrderTests: ["Chest X-ray", "Abdominal Ultrasound", "Dental X-ray"], labOrderTests: [], isLoading: false, @@ -454,13 +521,13 @@ class _MedicalFilePageState extends State { }), ), ], - ).paddingSymmetrical(24.w, 0.h), + ).paddingSymmetrical(0.w, 0.h), SizedBox(height: 24.h), - "Active Medications & Prescriptions".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0.h), + "Active Medications & Prescriptions".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), SizedBox(height: 16.h), Consumer(builder: (context, prescriptionVM, child) { return prescriptionVM.isPrescriptionsOrdersLoading - ? const CommonShimmerWidget().paddingSymmetrical(24.w, 0.h) + ? const CommonShimmerWidget().paddingSymmetrical(0.w, 0.h) : prescriptionVM.patientPrescriptionOrders.isNotEmpty ? Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( @@ -503,13 +570,11 @@ class _MedicalFilePageState extends State { spacing: 3.w, runSpacing: 4.w, children: [ - AppCustomChipWidget( - labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), + AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), AppCustomChipWidget( icon: AppAssets.doctor_calendar_icon, labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate( - prescriptionVM.patientPrescriptionOrders[index].appointmentDate), + DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), false, ), ), @@ -522,19 +587,13 @@ class _MedicalFilePageState extends State { 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)), + 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]), + page: PrescriptionDetailPage(isFromAppointments: false, prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]), ), ); }), @@ -607,14 +666,14 @@ class _MedicalFilePageState extends State { width: 62.w, height: 62.h, ), - ).paddingSymmetrical(24.w, 0.h); + ).paddingSymmetrical(0.w, 0.h); }), SizedBox(height: 24.h), //My Doctor Section Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.myDoctor.tr(context: context).toText18(isBold: true), + LocaleKeys.myDoctor.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), Row( children: [ LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), @@ -630,7 +689,7 @@ class _MedicalFilePageState extends State { ); }), ], - ).paddingSymmetrical(24.w, 0.h), + ).paddingSymmetrical(0.w, 0.h), SizedBox(height: 16.h), Consumer(builder: (context, myAppointmentsVM, child) { return myAppointmentsVM.isPatientMyDoctorsLoading @@ -644,10 +703,7 @@ class _MedicalFilePageState extends State { fit: BoxFit.cover, ).circle(100).toShimmer2(isShow: true, radius: 50.r), SizedBox(height: 8.h), - ("Dr. John Smith Smith Smith") - .toString() - .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2) - .toShimmer2(isShow: true), + ("Dr. John Smith Smith Smith").toString().toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2).toShimmer2(isShow: true), ], ) : myAppointmentsVM.patientMyDoctorsList.isEmpty @@ -665,7 +721,7 @@ class _MedicalFilePageState extends State { width: 62.w, height: 62.h, ), - ).paddingSymmetrical(24.w, 0.h) + ).paddingSymmetrical(0.w, 0.h) : SizedBox( height: 100.h, child: ListView.separated( @@ -730,10 +786,10 @@ class _MedicalFilePageState extends State { }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h), ), - ).paddingSymmetrical(24.w, 0); + ).paddingSymmetrical(0.w, 0); }), SizedBox(height: 24.h), - "Others".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0.h), + "Others".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), SizedBox(height: 16.h), GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( @@ -786,7 +842,7 @@ class _MedicalFilePageState extends State { ); }), ], - ).paddingSymmetrical(24.w, 0.0), + ).paddingSymmetrical(0.w, 0.0), SizedBox(height: 24.h), ], ); @@ -801,7 +857,7 @@ class _MedicalFilePageState extends State { labOrder: null, index: index, isLoading: true, - ).paddingSymmetrical(24.w, 0.0) + ).paddingSymmetrical(0.w, 0.0) : insuranceVM.patientInsuranceList.isNotEmpty ? PatientInsuranceCard( insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, @@ -828,14 +884,9 @@ class _MedicalFilePageState extends State { 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); + 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), @@ -847,7 +898,7 @@ class _MedicalFilePageState extends State { height: isFoldable ? 50.h : 40.h, ).paddingOnly(left: 12.w, right: 12.w, bottom: 12.h), ), - ).paddingSymmetrical(24.w, 0.h); + ).paddingSymmetrical(0.w, 0.h); }), SizedBox(height: 10.h), GridView( @@ -902,7 +953,7 @@ class _MedicalFilePageState extends State { iconSize: 36.w, ), ], - ).paddingSymmetrical(24.w, 0.0), + ).paddingSymmetrical(0.w, 0.0), SizedBox(height: 16.h), ], ); @@ -915,12 +966,12 @@ class _MedicalFilePageState extends State { ? PatientSickLeaveCard( patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), isLoading: true, - ).paddingSymmetrical(24.w, 0.0) + ).paddingSymmetrical(0.w, 0.0) : medicalFileVM.patientSickLeaveList.isNotEmpty ? PatientSickLeaveCard( patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first, isLoading: false, - ).paddingSymmetrical(24.w, 0.0) + ).paddingSymmetrical(0.w, 0.0) : Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -934,7 +985,7 @@ class _MedicalFilePageState extends State { width: 62.w, height: 62.h, ), - ).paddingSymmetrical(24.w, 0.h); + ).paddingSymmetrical(0.w, 0.h); }), SizedBox(height: 16.h), GridView( @@ -987,7 +1038,7 @@ class _MedicalFilePageState extends State { ); }), ], - ).paddingSymmetrical(24.w, 0.0), + ).paddingSymmetrical(0.w, 0.0), SizedBox(height: 24.h), ], ); diff --git a/lib/presentation/medical_file/widgets/lab_rad_card.dart b/lib/presentation/medical_file/widgets/lab_rad_card.dart index 1a56baf..eef73eb 100644 --- a/lib/presentation/medical_file/widgets/lab_rad_card.dart +++ b/lib/presentation/medical_file/widgets/lab_rad_card.dart @@ -27,55 +27,62 @@ class LabRadCard extends StatelessWidget { Widget build(BuildContext context) { AppState appState = getIt.get(); return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r, hasShadow: false), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 18.r, hasShadow: false), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + mainAxisAlignment: MainAxisAlignment.start, children: [ Utils.buildSvgWithAssets( icon: icon, width: 40.w, height: 40.h, - fit: BoxFit.contain, + fit: BoxFit.cover, ).toShimmer2(isShow: false, radius: 12.r), SizedBox(width: 8.w), - Flexible(child: labelText.toText14(isBold: true).toShimmer2(isShow: false, radius: 6.r, height: 32.h)), - ], - ), - SizedBox(height: 16.h), - labOrderTests.isNotEmpty - ? ListView.separated( - scrollDirection: Axis.vertical, - padding: EdgeInsets.zero, - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemBuilder: (cxt, index) { - return labOrderTests[index] - .toText12(isBold: true, maxLine: 1) - .toShimmer2(isShow: false, radius: 6.r, height: 24.h, width: 120.w) - .toShimmer2(isShow: isLoading); - }, - separatorBuilder: (cxt, index) => SizedBox(height: 8.h), - itemCount: 3, - ) - : "You don't have any records yet".needTranslation.toText13( - color: AppColors.greyTextColor, isCenter: true), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox.shrink(), + Flexible( + child: labelText.toText12(isBold: true, maxLine: 2), + ), 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) - .toShimmer2(isShow: false, radius: 12.r), + child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon_small, width: 10.w, height: 10.h, fit: BoxFit.contain, iconColor: AppColors.textColor), ), ], - ) + ), + // SizedBox(height: 16.h), + // labOrderTests.isNotEmpty + // ? ListView.separated( + // scrollDirection: Axis.vertical, + // padding: EdgeInsets.zero, + // physics: NeverScrollableScrollPhysics(), + // shrinkWrap: true, + // itemBuilder: (cxt, index) { + // return labOrderTests[index] + // .toText12(isBold: true, maxLine: 1) + // .toShimmer2(isShow: false, radius: 6.r, height: 24.h, width: 120.w) + // .toShimmer2(isShow: isLoading); + // }, + // separatorBuilder: (cxt, index) => SizedBox(height: 8.h), + // itemCount: 3, + // ) + // : "You don't have any records yet".needTranslation.toText13( + // color: AppColors.greyTextColor, isCenter: true), + // SizedBox(height: 16.h), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // SizedBox.shrink(), + // 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) + // .toShimmer2(isShow: false, radius: 12.r), + // ), + // ], + // ) ], - ).paddingAll(16.w), + ).paddingAll(12.w), ); } } diff --git a/lib/widgets/expandable_list_widget.dart b/lib/widgets/expandable_list_widget.dart new file mode 100644 index 0000000..21bbdf6 --- /dev/null +++ b/lib/widgets/expandable_list_widget.dart @@ -0,0 +1,301 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; + +// ==================== MAIN CUSTOM WIDGET ==================== + +class CustomExpandableList extends StatefulWidget { + final List items; + final ExpansionMode expansionMode; + final EdgeInsetsGeometry? itemPadding; + final EdgeInsetsGeometry? contentPadding; + final Color? dividerColor; + final double dividerHeight; + final bool showDividers; + final Duration animationDuration; + final Curve animationCurve; + final ExpandableListTheme? theme; + final Function(int index, bool isExpanded)? onItemToggled; + + const CustomExpandableList({ + Key? key, + required this.items, + this.expansionMode = ExpansionMode.multiple, + this.itemPadding, + this.contentPadding, + this.dividerColor, + this.dividerHeight = 1.0, + this.showDividers = true, + this.animationDuration = const Duration(milliseconds: 300), + this.animationCurve = Curves.easeInOut, + this.theme, + this.onItemToggled, + }) : super(key: key); + + @override + _CustomExpandableListState createState() => _CustomExpandableListState(); +} + +class _CustomExpandableListState extends State { + late List _expandedStates; + + @override + void initState() { + super.initState(); + _expandedStates = List.generate( + widget.items.length, + (index) => widget.items[index].initiallyExpanded, + ); + } + + void _toggleItem(int index) { + setState(() { + if (widget.expansionMode == ExpansionMode.exactlyOne) { + // Close all others, open this one + for (int i = 0; i < _expandedStates.length; i++) { + _expandedStates[i] = (i == index) ? !_expandedStates[i] : false; + } + } else if (widget.expansionMode == ExpansionMode.atMostOne) { + // Toggle this one, close if opening another + bool wasExpanded = _expandedStates[index]; + for (int i = 0; i < _expandedStates.length; i++) { + if (i == index) { + _expandedStates[i] = !wasExpanded; + } else if (!wasExpanded) { + _expandedStates[i] = false; + } + } + } else { + // Multiple - just toggle the clicked item + _expandedStates[index] = !_expandedStates[index]; + } + }); + + widget.onItemToggled?.call(index, _expandedStates[index]); + } + + @override + Widget build(BuildContext context) { + final theme = widget.theme ?? ExpandableListTheme.defaultTheme(context); + + return Column( + children: List.generate(widget.items.length, (index) { + final item = widget.items[index]; + final isExpanded = _expandedStates[index]; + final isLast = index == widget.items.length - 1; + + return Column( + children: [ + _ExpandableListItemWidget( + title: item.title, + isExpanded: isExpanded, + onTap: () => _toggleItem(index), + padding: widget.itemPadding, + contentPadding: widget.contentPadding, + theme: theme, + leading: item.leading, + trailing: item.trailing, + backgroundColor: item.backgroundColor, + expandedBackgroundColor: item.expandedBackgroundColor, + animationDuration: widget.animationDuration, + animationCurve: widget.animationCurve, + children: item.children, + ), + if (widget.showDividers && !isLast) + Divider( + height: widget.dividerHeight, + color: widget.dividerColor ?? theme.dividerColor, + ).paddingSymmetrical(12.h,0), + ], + ); + }), + ); + } +} + +// ==================== SUPPORTING WIDGETS ==================== + +class _ExpandableListItemWidget extends StatelessWidget { + final Widget title; + final List children; + final bool isExpanded; + final VoidCallback onTap; + final EdgeInsetsGeometry? padding; + final EdgeInsetsGeometry? contentPadding; + final ExpandableListTheme theme; + final Widget? leading; + final Widget? trailing; + final Color? backgroundColor; + final Color? expandedBackgroundColor; + final Duration animationDuration; + final Curve animationCurve; + + const _ExpandableListItemWidget({ + super.key, + required this.title, + required this.children, + required this.isExpanded, + required this.onTap, + this.padding, + this.contentPadding, + required this.theme, + this.leading, + this.trailing, + this.backgroundColor, + this.expandedBackgroundColor, + required this.animationDuration, + required this.animationCurve, + }); + + @override + Widget build(BuildContext context) { + return Container( + color: isExpanded + ? (expandedBackgroundColor ?? theme.expandedBackgroundColor) + : (backgroundColor ?? theme.backgroundColor), + child: Column( + children: [ + // Header + InkWell( + onTap: onTap, + child: Padding( + padding: padding ?? theme.itemPadding, + child: Row( + children: [ + if (leading != null) ...[ + leading!, + SizedBox(width: theme.leadingSpacing), + ], + Expanded(child: title), + if (trailing != null) + trailing! + else + AnimatedRotation( + turns: isExpanded ? 0.5 : 0.0, + duration: animationDuration, + curve: animationCurve, + child: theme.defaultTrailingIcon, + ), + ], + ), + ), + ), + + // Content + AnimatedSize( + duration: animationDuration, + curve: animationCurve, + child: Container( + constraints: BoxConstraints( + minHeight: isExpanded ? 0.0 : 0.0, + maxHeight: isExpanded ? double.infinity : 0.0, + ), + child: isExpanded + ? Padding( + padding: contentPadding ?? theme.contentPadding, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: children, + ), + ) + : SizedBox.shrink(), + ), + ), + ], + ), + ); + } +} + +// ==================== DATA MODELS ==================== + +class ExpandableListItem { + final Widget title; + final List children; + final Widget? leading; + final Widget? trailing; + final bool initiallyExpanded; + final Color? backgroundColor; + final Color? expandedBackgroundColor; + + const ExpandableListItem({ + required this.title, + required this.children, + this.leading, + this.trailing, + this.initiallyExpanded = false, + this.backgroundColor, + this.expandedBackgroundColor, + }); +} + +// ==================== THEME ==================== + +class ExpandableListTheme { + final Color backgroundColor; + final Color expandedBackgroundColor; + final Color dividerColor; + final Widget defaultTrailingIcon; + final EdgeInsetsGeometry itemPadding; + final EdgeInsetsGeometry contentPadding; + final double leadingSpacing; + + const ExpandableListTheme({ + required this.backgroundColor, + required this.expandedBackgroundColor, + required this.dividerColor, + required this.defaultTrailingIcon, + required this.itemPadding, + required this.contentPadding, + this.leadingSpacing = 12.0, + }); + + factory ExpandableListTheme.defaultTheme(BuildContext context) { + final textColor = Theme.of(context).textTheme.bodyLarge?.color ?? Colors.black; + + return ExpandableListTheme( + backgroundColor: Colors.transparent, + expandedBackgroundColor: Colors.grey.shade50, + dividerColor: Colors.grey.shade300, + defaultTrailingIcon: Icon( + Icons.keyboard_arrow_down, + color: textColor, + size: 24, + ), + itemPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), + contentPadding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), + ); + } + + factory ExpandableListTheme.custom({ + Color? backgroundColor, + Color? expandedBackgroundColor, + Color? dividerColor, + Widget? defaultTrailingIcon, + EdgeInsetsGeometry? itemPadding, + EdgeInsetsGeometry? contentPadding, + double? leadingSpacing, + }) { + return ExpandableListTheme( + backgroundColor: backgroundColor ?? Colors.transparent, + expandedBackgroundColor: expandedBackgroundColor ?? Colors.grey.shade50, + dividerColor: dividerColor ?? Colors.grey.shade300, + defaultTrailingIcon: defaultTrailingIcon ?? + Icon(Icons.keyboard_arrow_down, color: Colors.black, size: 24), + itemPadding: itemPadding ?? const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), + contentPadding: contentPadding ?? const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), + leadingSpacing: leadingSpacing ?? 12.0, + ); + } +} + +// ==================== ENUMS ==================== + +enum ExpansionMode { + multiple, // Multiple items can be expanded + exactlyOne, // Exactly one item expanded at a time + atMostOne, // Zero or one item expanded at a time +} + + + From d256eec3929ddeee5354c80be95cb96f957bf5a4 Mon Sep 17 00:00:00 2001 From: aamir-csol Date: Mon, 8 Dec 2025 10:50:33 +0300 Subject: [PATCH 5/5] medical file changes --- lib/core/utils/utils.dart | 2 +- lib/extensions/string_extensions.dart | 2 +- .../medical_file/medical_file_page.dart | 22 ++++--- lib/widgets/expandable_list_widget.dart | 2 +- lib/widgets/input_widget.dart | 58 ++++++++++--------- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index e2c11d4..0125f00 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -330,7 +330,7 @@ class Utils { repeat: false, reverse: false, frameRate: FrameRate(60), width: width.h, height: height.h, fit: BoxFit.fill), SizedBox(height: 16.h), (noDataText ?? LocaleKeys.noDataAvailable.tr()) - .toText16(weight: FontWeight.w500, color: AppColors.greyTextColor, isCenter: true) + .toText14(weight: FontWeight.w500, color: AppColors.greyTextColor, isCenter: true) .paddingSymmetrical(64.w, 0.h), SizedBox(height: 16.h), callToActionButton diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 250453d..328ced5 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -263,7 +263,7 @@ extension EmailValidator on String { style: TextStyle(fontSize: 19.f, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, color: color ?? AppColors.blackColor, letterSpacing: -0.4), ); - Widget toText20({Color? color, FontWeight? weight, bool isBold = false}) => Text( + Widget toText20({Color? color, FontWeight? weight, bool isBold = false, }) => Text( this, style: TextStyle( fontSize: 20.f, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, letterSpacing: -0.4), diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index e1d4ce7..538687c 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -245,39 +245,43 @@ class _MedicalFilePageState extends State { isBorderAllowed: false, isAllowLeadingIcon: true, padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h), - leadingIcon: AppAssets.student_card, + leadingIcon: AppAssets.search_icon, + hintColor: AppColors.textColor, ).paddingSymmetrical(24.w, 0.0), SizedBox(height: 16.h), // Using CustomExpandableList CustomExpandableList( expansionMode: ExpansionMode.exactlyOne, dividerColor: Color(0xFF2B353E1A), - + itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h), items: [ ExpandableListItem( - title: "Medical Services".toText20(weight: FontWeight.w500), + title: "Medical Services".toText18(weight: FontWeight.w600), children: [ SizedBox(height: 10.h), getSelectedTabData(0), ], ), ExpandableListItem( - title: "Medical Reports".toText20( - weight: FontWeight.w500, + title: "Medical Reports".toText18( + weight: FontWeight.w600, ), + expandedBackgroundColor: Colors.transparent, children: [ SizedBox(height: 10.h), getSelectedTabData(2), ]), ExpandableListItem( - title: "Insurance & Payments".toText20(weight: FontWeight.w500), + title: "Insurance & Payments".toText18(weight: FontWeight.w600), + expandedBackgroundColor: Colors.transparent, children: [ SizedBox(height: 10.h), getSelectedTabData(1), ], ), ExpandableListItem( - title: "Tracker & Others".toText20(weight: FontWeight.w500), + title: "Tracker & Others".toText18(weight: FontWeight.w600), + expandedBackgroundColor: Colors.transparent, children: [ Text("Blood Report"), SizedBox(height: 8), @@ -481,9 +485,9 @@ class _MedicalFilePageState extends State { }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.h), ), - ).paddingSymmetrical(0.w, 0); + ).paddingSymmetrical(0.w, 0.h); }), - SizedBox(height: 24.h), + SizedBox(height: 10.h), "Lab & Radiology".needTranslation.toText16(weight: FontWeight.w500, letterSpacing: -0.2), SizedBox(height: 16.h), Row( diff --git a/lib/widgets/expandable_list_widget.dart b/lib/widgets/expandable_list_widget.dart index 21bbdf6..b948299 100644 --- a/lib/widgets/expandable_list_widget.dart +++ b/lib/widgets/expandable_list_widget.dart @@ -255,7 +255,7 @@ class ExpandableListTheme { return ExpandableListTheme( backgroundColor: Colors.transparent, - expandedBackgroundColor: Colors.grey.shade50, + expandedBackgroundColor: Colors.transparent, dividerColor: Colors.grey.shade300, defaultTrailingIcon: Icon( Icons.keyboard_arrow_down, diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 4b3f091..c1a38ab 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -47,38 +47,40 @@ class TextInputWidget extends StatelessWidget { final bool isMultiline; final int minLines; final int maxLines; + final Color? hintColor; // final List countryList; // final Function(Country)? onCountryChange; - TextInputWidget( - {super.key, - required this.labelText, - required this.hintText, - this.controller, - this.onChange, - this.onCalendarTypeChanged, - this.prefix, - this.isEnable = true, - this.isBorderAllowed = true, - this.isAllowRadius = true, - this.isReadOnly = false, - this.keyboardType = TextInputType.number, - this.focusNode, - this.autoFocus = false, - this.padding, - this.isAllowLeadingIcon = false, - this.leadingIcon, - this.isCountryDropDown = false, - this.hasError = false, - this.errorMessage, - this.onCountryChange, - this.selectionType, - this.fontSize, - this.isWalletAmountInput = false, - this.suffix, - this.labelColor, + TextInputWidget({ + super.key, + required this.labelText, + required this.hintText, + this.controller, + this.onChange, + this.onCalendarTypeChanged, + this.prefix, + this.isEnable = true, + this.isBorderAllowed = true, + this.isAllowRadius = true, + this.isReadOnly = false, + this.keyboardType = TextInputType.number, + this.focusNode, + this.autoFocus = false, + this.padding, + this.isAllowLeadingIcon = false, + this.leadingIcon, + this.isCountryDropDown = false, + this.hasError = false, + this.errorMessage, + this.onCountryChange, + this.selectionType, + this.fontSize, + this.isWalletAmountInput = false, + this.suffix, + this.labelColor, this.onSubmitted, + this.hintColor, // multiline defaults this.isMultiline = false, this.minLines = 3, @@ -274,7 +276,7 @@ class TextInputWidget extends StatelessWidget { decoration: InputDecoration( isDense: true, hintText: hintText, - hintStyle: TextStyle(fontSize: 14.f, height: 21 / 16, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -0.75), + hintStyle: TextStyle(fontSize: 14.f, height: 21 / 16, fontWeight: FontWeight.w500, color: hintColor != null ? AppColors.textColor : Color(0xff898A8D), letterSpacing: -0.75), prefixIconConstraints: BoxConstraints(minWidth: 30.h), prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, weight: FontWeight.w500), contentPadding: EdgeInsets.zero,