From 9c2dd721b4a239c5f83fa05509ce87d9d31646d9 Mon Sep 17 00:00:00 2001 From: "taha.alam" Date: Wed, 17 Sep 2025 14:20:16 +0300 Subject: [PATCH] bottom sheets added of region facitlity and hospital. --- .../models/facility_selection.dart | 8 ++ .../facility_selection_item.dart | 88 ++++++++++++++ .../facility_type_selection_widget.dart | 79 ++++++++++++ .../hospital_bottom_sheet_body.dart | 109 +++++++++++++++++ .../hospital_list_items.dart | 113 +++++++++++++++++ .../type_selection_widget.dart | 93 ++++++++++++++ .../region_bottomsheet/region_list_item.dart | 114 ++++++++++++++++++ .../region_list_widget.dart | 86 +++++++++++++ lib/widgets/chip/app_custom_chip_widget.dart | 74 ++++++++++-- lib/widgets/input_widget.dart | 13 ++ 10 files changed, 766 insertions(+), 11 deletions(-) create mode 100644 lib/features/my_appointments/models/facility_selection.dart create mode 100644 lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart create mode 100644 lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart create mode 100644 lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart create mode 100644 lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart create mode 100644 lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart create mode 100644 lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart create mode 100644 lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart diff --git a/lib/features/my_appointments/models/facility_selection.dart b/lib/features/my_appointments/models/facility_selection.dart new file mode 100644 index 0000000..b1f12de --- /dev/null +++ b/lib/features/my_appointments/models/facility_selection.dart @@ -0,0 +1,8 @@ +enum FacilitySelection{ +ALL('ALL'), +HMG('hmg'), +HMC('hmc'); + +final String value; +const FacilitySelection(this.value); +} \ No newline at end of file diff --git a/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart b/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart new file mode 100644 index 0000000..1660146 --- /dev/null +++ b/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/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/theme/colors.dart' show AppColors; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; + +class FacilitySelectionItem extends StatelessWidget { + final String svgPath; + final String title; + final String subTitle; + + const FacilitySelectionItem( + {super.key, + required this.svgPath, + required this.subTitle, + required this.title}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Utils.buildSvgWithAssets( + icon: svgPath, + width: 32, + height: 32, + fit: BoxFit.contain, + ), + SizedBox(height: 16,), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + info, + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18, + height: 13, + fit: BoxFit.contain, + ), + ], + ) + ], + ).paddingAll(16.h), + ); + } + + + Widget get info => Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + title, + style: TextStyle( + fontSize: 16.h, + fontWeight: FontWeight.w600, + color: AppColors.blackColor, + ), + ), + ), + Align( + alignment: Alignment.centerLeft, + child: Text( + subTitle, + style: TextStyle( + fontSize: 12.h, + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + ), + ), + ], + ); +} diff --git a/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart b/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart new file mode 100644 index 0000000..64af81e --- /dev/null +++ b/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart @@ -0,0 +1,79 @@ +import 'package:easy_localization/easy_localization.dart' + show tr, StringTranslateExtension; +import 'package:flutter/cupertino.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart' + show MyAppointmentsViewModel; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:provider/provider.dart' show Provider; + +class FacilityTypeSelectionWidget extends StatelessWidget { + late MyAppointmentsViewModel myAppointmentsViewModel; + late AppointmentViaRegionViewmodel regionalViewModel; + final String selectedRegion; + + FacilityTypeSelectionWidget({super.key, required this.selectedRegion}); + + @override + Widget build(BuildContext context) { + myAppointmentsViewModel = Provider.of(context); + regionalViewModel = Provider.of(context); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + LocaleKeys.selectFacility.tr(), + style: TextStyle( + fontSize: 21, + fontWeight: FontWeight.w600, + color: AppColors.blackColor, + ), + ), + Text( + LocaleKeys.selectFacilitiesSubTitle, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + ), + SizedBox(height: 24.h), + FacilitySelectionItem( + svgPath: AppAssets.hmg, + title: "HMG".needTranslation, + subTitle: LocaleKeys.hospitalsWithCount.tr(namedArgs: { + 'count': + "${myAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmgSize ?? 0}" + }), + ).onPress( + () { + regionalViewModel.setFacility(FacilitySelection.HMG.name); + regionalViewModel.setBottomSheetState( + AppointmentViaRegionState.HOSPITAL_SELECTION); + }, + ), + SizedBox(height: 16.h), + FacilitySelectionItem( + svgPath: AppAssets.hmc, + title: "HMC".needTranslation, + subTitle: LocaleKeys.medicalCentersWithCount.tr(namedArgs: { + 'count': + "${myAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmcSize ?? 0}" + })).onPress( + () { + regionalViewModel.setFacility(FacilitySelection.HMC.name); + regionalViewModel.setBottomSheetState( + AppointmentViaRegionState.HOSPITAL_SELECTION); + }, + ), + ], + ); + } +} diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart new file mode 100644 index 0000000..803d75c --- /dev/null +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart @@ -0,0 +1,109 @@ +import 'package:easy_localization/easy_localization.dart' + show tr, StringTranslateExtension; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/enums.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart'; +import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:provider/provider.dart'; + +class HospitalBottomSheetBody extends StatelessWidget { + late MyAppointmentsViewModel appointmentsViewModel; + late AppointmentViaRegionViewmodel regionalViewModel; + final TextEditingController searchText = TextEditingController(); + + HospitalBottomSheetBody({super.key}); + + @override + Widget build(BuildContext context) { + appointmentsViewModel = Provider.of(context); + regionalViewModel = Provider.of(context); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + LocaleKeys.selectHospital.tr(), + style: TextStyle( + fontSize: 21, + fontWeight: FontWeight.w600, + color: AppColors.blackColor, + ), + ), + Text( + LocaleKeys.selectHospitalSubTitle.tr(), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + ), + SizedBox(height: 16.h), + TextInputWidget( + labelText: LocaleKeys.search.tr(), + hintText: "Search Hospital".tr(), + controller: searchText, + onChange: (value) { + appointmentsViewModel.filterHospitalListByString(value, regionalViewModel.selectedRegionId , regionalViewModel.selectedFacilityType == + FacilitySelection.HMG.name); + }, + isEnable: true, + prefix: null, + autoFocus: false, + isBorderAllowed: false, + keyboardType: TextInputType.text, + isAllowLeadingIcon: true, + selectionType: SelectionTypeEnum.search, + padding: EdgeInsets.symmetric( + vertical: ResponsiveExtension(10).h, + horizontal: ResponsiveExtension(15).h, + ), + ), + SizedBox(height: 24.h), + // TypeSelectionWidget( + // hmcCount: "0", + // hmgCount: "0", + // ), + // SizedBox(height: 21.h), + SizedBox( + height: MediaQuery.sizeOf(context).height * .4, + child: ListView.separated( + itemBuilder: (_, index) => HospitalListItem( + hospitalData: regionalViewModel.selectedFacilityType == + FacilitySelection.HMG.name + ? appointmentsViewModel + .filteredHospitalList! + .registeredDoctorMap![ + regionalViewModel.selectedRegionId!]! + .hmgDoctorList![index] + : appointmentsViewModel + .filteredHospitalList + ?.registeredDoctorMap?[ + regionalViewModel.selectedRegionId!] + ?.hmcDoctorList?[index], + isLocationEnabled: appointmentsViewModel.getLocationStatus(), + ), + separatorBuilder: (_, __) => SizedBox( + height: 16.h, + ), + itemCount: (regionalViewModel.selectedFacilityType == + FacilitySelection.HMG.name + ? (appointmentsViewModel.filteredHospitalList?.registeredDoctorMap?[ + regionalViewModel.selectedRegionId]?.hmgDoctorList) + : (appointmentsViewModel + .filteredHospitalList + ?.registeredDoctorMap?[ + regionalViewModel.selectedRegionId]?.hmcDoctorList))?.length ?? + 0), + ) + ], + ); + } +} diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart new file mode 100644 index 0000000..41fb924 --- /dev/null +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart @@ -0,0 +1,113 @@ +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/app_state.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/my_appointments/models/resp_models/doctor_list_api_response.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; + +class HospitalListItem extends StatelessWidget { + final PatientDoctorAppointmentList? hospitalData; + final bool isLocationEnabled; + + late AppState appState; + + HospitalListItem( + {super.key, required this.hospitalData, required this.isLocationEnabled}); + + @override + Widget build(BuildContext context) { + appState = getIt.get(); + return DecoratedBox( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8.h, + children: [hospitalName, distanceInfo], + ), + ), + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18, + height: 13, + fit: BoxFit.contain, + ), + ], + ).paddingSymmetrical(16.h, 16.h), + ); + } + + Widget get hospitalName => Row( + children: [ + Utils.buildSvgWithAssets( + icon: (hospitalData?.isHMC == true) ? AppAssets.hmc : AppAssets.hmg, + ).paddingOnly(right: 10), + Expanded( + child: Text( + hospitalData?.filterName ?? "", + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 16, + color: AppColors.blackColor, + ), + ), + ) + ], + ); + + Widget get distanceInfo => Row( + + children: [ + Visibility( + visible: (hospitalData?.distanceInKMs != "0"), + child: + + + AppCustomChipWidget( + labelText: + "${hospitalData?.distanceInKMs ?? ""} km".needTranslation, + deleteIcon: AppAssets.location_red, + deleteIconSize: Size(9, 12), + backgroundColor: AppColors.secondaryLightRedColor, + textColor: AppColors.errorColor, + ), + + + ), + Visibility( + visible: (hospitalData?.distanceInKMs == "0"), + child: Row( + children: [ + AppCustomChipWidget( + labelText: "Distance not available".needTranslation, + textColor: AppColors.blackColor, + ), + SizedBox(width: 8.h,) + + ], + )), + Visibility( + visible: !isLocationEnabled, + child: AppCustomChipWidget( + labelText: "Location turned off".needTranslation, + deleteIcon: AppAssets.location_unavailable, + deleteIconSize: Size(9, 12), + textColor: AppColors.blackColor, + )), + ], + ); +} diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart new file mode 100644 index 0000000..8f09e1a --- /dev/null +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.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/my_appointments/models/facility_selection.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:provider/provider.dart' show Consumer; + +class TypeSelectionWidget extends StatelessWidget { + final String hmcCount; + final String hmgCount; + + const TypeSelectionWidget( + {super.key, required this.hmcCount, required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (_, data, __) => Row( + spacing: 8, + mainAxisSize: MainAxisSize.max, + children: [ + AppCustomChipWidget( + labelText: "All Facilities".needTranslation, + shape: RoundedRectangleBorder( + side: BorderSide( + color: data.currentlySelectedFacility == FacilitySelection.ALL + ? AppColors.errorColor + : AppColors.chipBorderColorOpacity20, + width: 1, + ), + borderRadius: BorderRadius.circular(10)), + backgroundColor: + data.currentlySelectedFacility == FacilitySelection.ALL + ? AppColors.secondaryLightRedColor + : AppColors.whiteColor, + textColor: data.currentlySelectedFacility == FacilitySelection.ALL + ? AppColors.errorColor + : AppColors.blackColor, + ).onPress((){ + data.setSelectedFacility(FacilitySelection.ALL); + }), + AppCustomChipWidget( + icon: AppAssets.hmg, + iconHasColor: false, + labelText: "Hospitals".needTranslation, + shape: RoundedRectangleBorder( + side: BorderSide( + color: data.currentlySelectedFacility == FacilitySelection.HMG + ? AppColors.errorColor + : AppColors.chipBorderColorOpacity20, + width: 1, + ), + borderRadius: BorderRadius.circular(10)), + backgroundColor: + data.currentlySelectedFacility == FacilitySelection.HMG + ? AppColors.secondaryLightRedColor + : AppColors.whiteColor, + textColor: data.currentlySelectedFacility == FacilitySelection.HMG + ? AppColors.errorColor + : AppColors.blackColor, + ).onPress((){ + data.setSelectedFacility(FacilitySelection.HMG); + }), + AppCustomChipWidget( + icon: AppAssets.hmc, + iconHasColor: false, + labelText: "Medical Centers".needTranslation, + shape: RoundedRectangleBorder( + side: BorderSide( + color: data.currentlySelectedFacility == FacilitySelection.HMC + ? AppColors.errorColor + : AppColors.chipBorderColorOpacity20, + width: 1, + ), + borderRadius: BorderRadius.circular(10)), + backgroundColor: + data.currentlySelectedFacility == FacilitySelection.HMC + ? AppColors.secondaryLightRedColor + : AppColors.whiteColor, + textColor: data.currentlySelectedFacility == FacilitySelection.HMC + ? AppColors.errorColor + : AppColors.blackColor, + ).onPress((){ + data.setSelectedFacility(FacilitySelection.HMC); + }), + ], + ), + ); + } +} diff --git a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart new file mode 100644 index 0000000..ab8e21f --- /dev/null +++ b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart @@ -0,0 +1,114 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; + +class RegionListItem extends StatelessWidget { + final String title; + final String hmcCount; + final String hmgCount; + final String subTitle; + + const RegionListItem( + {super.key, + required this.title, + required this.subTitle, + required this.hmcCount, + required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + header, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + spacing: 8.h, + children: [ + placesCountItem( + AppAssets.hmg, hmgCount, " ${LocaleKeys.hospital.tr()}"), + placesCountItem(AppAssets.hmc, hmcCount, + " ${LocaleKeys.medicalCenters.tr()}"), + ], + ), + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18, + height: 13, + fit: BoxFit.contain, + ), + ], + ) + ], + ).paddingAll(16.h), + ); + } + + Widget placesCountItem(String svgPath, String count, String title) { + return AppCustomChipWidget( + iconSize: 14, + icon: svgPath, + iconHasColor: false, + richText: RichText( + text: TextSpan( + text: count, + style: TextStyle( + fontSize: 12.h, + fontWeight: FontWeight.w700, + color: AppColors.blackColor), + children: [ + TextSpan( + text: title, + style: TextStyle( + fontSize: 12.h, + fontWeight: FontWeight.w500, + color: AppColors.blackColor)) + ])), + ); + } + + Widget get header => Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + title, + style: TextStyle( + fontSize: 16.h, + fontWeight: FontWeight.w600, + color: AppColors.blackColor, + ), + ), + ), + Align( + alignment: Alignment.centerLeft, + child: Text( + subTitle, + style: TextStyle( + fontSize: 12.h, + fontWeight: FontWeight.w500, + color: AppColors.greyTextColor, + ), + ), + ), + ], + ); +} diff --git a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart new file mode 100644 index 0000000..d68637b --- /dev/null +++ b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart @@ -0,0 +1,86 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart' + show MyAppointmentsViewModel; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart' + show RegionListItem; +import 'package:provider/provider.dart'; + +class RegionBottomSheetBody extends StatefulWidget { + + const RegionBottomSheetBody({super.key}); + + @override + State createState() => _RegionBottomSheetBodyState(); +} + +class _RegionBottomSheetBodyState extends State { + late MyAppointmentsViewModel myAppointmentsViewModel; + late AppointmentViaRegionViewmodel regionalViewModel; + + @override + void initState() { + scheduleMicrotask(() { + myAppointmentsViewModel.getRegionMappedProjectList(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + myAppointmentsViewModel = Provider.of(context); + regionalViewModel = Provider.of(context); + return Consumer( + builder: (context, myAppointmentsVM, child) { + if (myAppointmentsVM.isRegionListLoading) { + return Container( + height: MediaQuery.of(context).size.height * 0.3, + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), + ), + child: Center( + child: Utils.getLoadingWidget(), + ), + ); + } else { + return SizedBox( + height: MediaQuery.of(context).size.height * 0.5, + child: ListView.separated( + itemCount: + myAppointmentsVM.hospitalList?.registeredDoctorMap?.length ?? + 0, + separatorBuilder: (_, __) { + return SizedBox( + height: 16.h, + ); + }, + itemBuilder: (_, index) { + String key = myAppointmentsVM + .hospitalList?.registeredDoctorMap?.keys + .toList()[index] ?? + ''; + return RegionListItem( + title: key, + subTitle: "", + hmcCount: + "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmcSize ?? 0}", + hmgCount: + "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmgSize ?? 0}", + ).onPress(() { + regionalViewModel.setSelectedRegionId(key); + regionalViewModel.setBottomSheetState(AppointmentViaRegionState.TYPE_SELECTION); + }); + }, + ), + ); + } + }, + ); + } +} diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart index 203cb86..3ece752 100644 --- a/lib/widgets/chip/app_custom_chip_widget.dart +++ b/lib/widgets/chip/app_custom_chip_widget.dart @@ -10,23 +10,38 @@ import 'package:smooth_corner/smooth_corner.dart'; class AppCustomChipWidget extends StatelessWidget { AppCustomChipWidget({ super.key, - required this.labelText, + this.labelText, this.textColor = AppColors.textColor, this.backgroundColor = AppColors.greyColor, this.iconSize = 12, this.icon = "", this.iconColor = AppColors.textColor, + this.richText, + this.iconHasColor = true, + this.shape, + this.deleteIcon, + this.deleteIconSize = const Size(12, 12), + this.deleteIconColor = AppColors.textColor, + this.deleteIconHasColor = false, }); - String? labelText; - Color? textColor; - Color? backgroundColor; - num iconSize; - String icon; - Color iconColor; + final String? labelText; + final Widget? richText; + final Color? textColor; + final Color? backgroundColor; + final num iconSize; + final String icon; + final String? deleteIcon; + final Size? deleteIconSize; + final Color iconColor; + final Color? deleteIconColor; + final bool iconHasColor; + final bool deleteIconHasColor; + final OutlinedBorder? shape; @override Widget build(BuildContext context) { + print("detected icon: $deleteIcon"); return ChipTheme( data: ChipThemeData( padding: EdgeInsets.all(0.0), @@ -41,18 +56,55 @@ class AppCustomChipWidget extends StatelessWidget { ), child: icon.isNotEmpty ? Chip( - avatar: icon.isNotEmpty ? Utils.buildSvgWithAssets(icon: icon, width: iconSize.h, height: iconSize.h, iconColor: iconColor) : SizedBox.shrink(), - label: labelText!.toText10(weight: FontWeight.w500, letterSpacing: -0.64, color: textColor), + avatar: icon.isNotEmpty + ? Utils.buildSvgWithAssets( + icon: icon, + width: iconSize.h, + height: iconSize.h, + iconColor: iconHasColor ? iconColor : null) + : SizedBox.shrink(), + label: richText ?? + labelText!.toText10( + weight: FontWeight.w500, + letterSpacing: -0.64, + color: textColor), padding: EdgeInsets.all(0.0), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - labelPadding: EdgeInsets.only(left: -4.h, right: 8.h), + labelPadding: EdgeInsets.only( + left: -4.h, + right: deleteIcon?.isNotEmpty == true ? 2.h : 8.h), backgroundColor: backgroundColor, + shape: shape, + deleteIcon: deleteIcon?.isNotEmpty == true + ? Utils.buildSvgWithAssets( + icon: deleteIcon!, + width: deleteIconSize!.width!.h, + height: deleteIconSize!.height.h, + iconColor: deleteIconHasColor ? deleteIconColor : null) + : null, + onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null, ) : Chip( materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - label: labelText!.toText10(weight: FontWeight.w500, letterSpacing: -0.64, color: textColor), + label: richText ?? + labelText!.toText10( + weight: FontWeight.w500, + letterSpacing: -0.64, + color: textColor), padding: EdgeInsets.all(0.0), backgroundColor: backgroundColor, + shape: shape, + labelPadding: EdgeInsets.only( + left: 8.h, + right: deleteIcon?.isNotEmpty == true ? -2.h : 8.h), + deleteIcon: deleteIcon?.isNotEmpty == true + ? Utils.buildSvgWithAssets( + icon: deleteIcon!, + width: deleteIconSize!.width.h, + height: deleteIconSize!.height.h, + iconColor: deleteIconHasColor ? deleteIconColor : null) + : null, + onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null, ), ); } diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 66c3877..8feb0f9 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -139,6 +139,7 @@ class TextInputWidget extends StatelessWidget { ), ), if (selectionType == SelectionTypeEnum.calendar) _buildTrailingIcon(context), + if (selectionType == SelectionTypeEnum.search) _buildTrailingIconForSearch(context), ], ), ), @@ -256,4 +257,16 @@ class TextInputWidget extends StatelessWidget { ), ); } + + _buildTrailingIconForSearch(BuildContext context) { + final AppState appState = getIt.get(); + return Container( + height: 40.h, + width: 40.h, + margin: EdgeInsets.zero, + padding: EdgeInsets.all(8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 10.h, color: AppColors.whiteColor), + child: Utils.buildSvgWithAssets(icon: AppAssets.search_icon), + ); + } }