diff --git a/assets/images/svg/cross_circle.svg b/assets/images/svg/cross_circle.svg
new file mode 100644
index 0000000..bcf9f90
--- /dev/null
+++ b/assets/images/svg/cross_circle.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/filters.svg b/assets/images/svg/filters.svg
new file mode 100644
index 0000000..521f6fa
--- /dev/null
+++ b/assets/images/svg/filters.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/images/svg/ic_close.svg b/assets/images/svg/ic_close.svg
new file mode 100644
index 0000000..615b42d
--- /dev/null
+++ b/assets/images/svg/ic_close.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json
index 8945fee..b08e783 100644
--- a/assets/langs/ar-SA.json
+++ b/assets/langs/ar-SA.json
@@ -856,5 +856,13 @@
"onboardingHeading1": "حجز المواعيد لم يكن أسهل من قبل",
"onboardingBody1": "ببضع نقرات فقط يمكنك استشارة الطبيب الذي تختاره.",
"onboardingHeading2": "الوصول إلى السجل الطبي بين يديك",
- "onboardingBody2": "تتبع تاريخك الطبي بما في ذلك الفحوصات المخبرية، الوصفات الطبية، التأمين، وغيرها."
+ "onboardingBody2": "تتبع تاريخك الطبي بما في ذلك الفحوصات المخبرية، الوصفات الطبية، التأمين، وغيرها.",
+ "hmgHospitals": "مستشفيات HMG",
+ "hmcMedicalClinic": "مراكز HMC الطبية",
+ "applyFilter": "تطبيق الفلتر",
+ "facilityAndLocation": "المرفق والموقع",
+ "regionAndLocation": "المنطقة والمواقع",
+ "clearAllFilters": "مسح جميع الفلاتر",
+ "filters": "فلاتر",
+ "searchClinic": "بحث عن عيادة"
}
\ No newline at end of file
diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json
index 843daf8..adab1d5 100644
--- a/assets/langs/en-US.json
+++ b/assets/langs/en-US.json
@@ -852,5 +852,13 @@
"onboardingHeading1": "Booking appointment has never been easy",
"onboardingBody1": "In few clicks find yourself having consultation with the doctor of your choice.",
"onboardingHeading2": "Access the medical history on finger tips",
- "onboardingBody2": "Keep track on your medical history including labs, prescription, insurance, etc"
+ "onboardingBody2": "Keep track on your medical history including labs, prescription, insurance, etc",
+ "hmgHospitals": "HMG Hospitals",
+ "hmcMedicalClinic": "HMC Medical Centers",
+ "applyFilter": "AppLy Filter",
+ "facilityAndLocation": "Facility and Location",
+ "regionAndLocation": "Region And Locations",
+ "clearAllFilters": "Clear all filters",
+ "filters": "Filters",
+ "searchClinic": "Search Clinic"
}
\ No newline at end of file
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index 31b4f32..716448d 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -145,6 +145,9 @@ class AppAssets {
static const String ic_normal_result = '$svgBasePath/normal_result.svg';
static const String ic_low_result = '$svgBasePath/low_result.svg';
static const String ic_critical_low_result = '$svgBasePath/critical_low_result.svg';
+ static const String ic_filters = '$svgBasePath/filters.svg';
+ static const String ic_close = '$svgBasePath/ic_close.svg';
+ static const String ic_cross_circle = '$svgBasePath/cross_circle.svg';
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';
diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart
index 5ef653a..bd292ec 100644
--- a/lib/features/book_appointments/book_appointments_view_model.dart
+++ b/lib/features/book_appointments/book_appointments_view_model.dart
@@ -53,6 +53,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
List get filteredClinicsList => _filteredClinicsList;
List doctorsList = [];
+ List filteredDoctorList = [];
List liveCareDoctorsList = [];
@@ -87,6 +88,19 @@ class BookAppointmentsViewModel extends ChangeNotifier {
bool shouldLoadSpecificClinic = false;
String? currentlySelectedHospitalFromRegionFlow;
+ ///variables for doctor filter
+ List searchedRegionList = [];
+ List facilityList = ["hmgHospitals", "hmcMedicalClinic"];
+ List searchedHospitalList = [];
+ List
+ searchedPatientDoctorAppointmentHospitalsList = [];
+ List searchedClinicList = [];
+
+ PatientDoctorAppointmentList? selectedHospitalForFilters;
+ List? selectedFacilityForFilters = [], selectedRegionForFilters = [];
+ String? selectedClinicForFilters;
+ bool applyFilters = false;
+
BookAppointmentsViewModel(
{required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils}) {
;
@@ -279,8 +293,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
doctorsList = apiResponse.data!;
+ filteredDoctorList = doctorsList;
isDoctorsListLoading = false;
initializeFilteredList();
+ clearSearchFilters();
+ getFiltersFromDoctorList();
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
@@ -757,4 +774,134 @@ class BookAppointmentsViewModel extends ChangeNotifier {
void getLocation() {
locationUtils.getLocation();
}
+
+ void clearSearchFilters() {
+ searchedRegionList.clear();
+ searchedHospitalList.clear();
+ searchedPatientDoctorAppointmentHospitalsList.clear();
+ searchedClinicList.clear();
+ notifyListeners();
+ }
+
+ void clearSelection() {
+ selectedFacilityForFilters = [];
+ selectedClinicForFilters = null;
+ selectedHospitalForFilters = null;
+ selectedRegionForFilters = [];
+ applyFilters = false;
+ notifyListeners();
+ }
+
+ void setSelections(
+ List? selectedFacilityForFilters,
+ List? selectedRegionForFilters,
+ String? selectedClinicForFilters,
+ PatientDoctorAppointmentList? selectedHospitalForFilters,
+ bool applyFilters) {
+ this.selectedFacilityForFilters = selectedFacilityForFilters;
+ this.selectedClinicForFilters = selectedClinicForFilters;
+ this.selectedHospitalForFilters = selectedHospitalForFilters;
+ this.selectedRegionForFilters = selectedRegionForFilters;
+ this.applyFilters = applyFilters;
+ notifyListeners();
+ }
+
+ void getFiltersFromDoctorList() {
+ doctorsList.forEach((element) {
+ if (!searchedRegionList
+ .contains(element.getRegionName(_appState.isArabic()))) {
+ searchedRegionList
+ .add(element.getRegionName(_appState.isArabic()) ?? "");
+ }
+ if (!searchedHospitalList.contains(element.projectName)) {
+ searchedPatientDoctorAppointmentHospitalsList
+ .add(PatientDoctorAppointmentList()
+ ..filterName = element.projectName
+ ..isHMC = element.isHMC
+ ..distanceInKMs = "0");
+ searchedHospitalList.add(element.projectName ?? "");
+ }
+ if (!searchedClinicList.contains(element.clinicName)) {
+ searchedClinicList.add(element.clinicName ?? "");
+ }
+ });
+ }
+
+ void updateApplyFilters(bool applyFilters) {
+ this.applyFilters = applyFilters;
+ notifyListeners();
+ }
+
+ void setSelectedRegion(String region) {
+ if (selectedRegionForFilters?.contains(region) == true) {
+ selectedRegionForFilters?.remove(region);
+ } else {
+ selectedRegionForFilters?.add(region);
+ }
+ notifyListeners();
+ }
+
+ void setSelectedHospital(PatientDoctorAppointmentList? hospital) {
+ selectedHospitalForFilters = hospital;
+ notifyListeners();
+ }
+
+ void setSelectedFacilityForFilter(String facility) {
+ if (selectedFacilityForFilters?.contains(facility) == true) {
+ selectedFacilityForFilters?.remove(facility);
+ } else {
+ selectedFacilityForFilters?.add(facility);
+ }
+
+ notifyListeners();
+ }
+
+ void setSelectedClinicForFilter(String? clinic) {
+ selectedClinicForFilters = clinic;
+ notifyListeners();
+ }
+
+ bool isArabic() {
+ return _appState.isArabic();
+ }
+
+ List getDoctorListAsPerSelection() {
+ if (!applyFilters) return doctorsList;
+
+ if ((selectedRegionForFilters?.isEmpty == true) &&
+ (selectedFacilityForFilters?.isEmpty == true) &&
+ selectedClinicForFilters == null &&
+ selectedHospitalForFilters == null) {
+ return doctorsList;
+ }
+ var list = doctorsList.where((element) {
+ var isInSelectedRegion = (selectedRegionForFilters?.isEmpty == true)
+ ? true
+ : selectedRegionForFilters
+ ?.any((region) => region == element.getRegionName(isArabic()));
+ var shouldApplyFacilityFilter =
+ (selectedFacilityForFilters?.isEmpty == true) ? false : true;
+ var isHMC = (selectedFacilityForFilters?.isEmpty == true)
+ ? true
+ : selectedFacilityForFilters?.any((item) => item.contains("hmc"));
+ var isInSelectedClinic = (selectedClinicForFilters == null)
+ ? true
+ : selectedClinicForFilters == element.clinicName;
+ var isInSelectedHospital = (selectedHospitalForFilters == null)
+ ? true
+ : element.projectName == selectedHospitalForFilters?.filterName;
+ var facilityFilter = ((shouldApplyFacilityFilter == true) ? isHMC : true);
+
+ return (isInSelectedRegion ?? true) &&
+ (facilityFilter ?? true) &&
+ isInSelectedClinic &&
+ isInSelectedHospital;
+ }).toList();
+ return list;
+ }
+
+ void updateList() {
+ filteredDoctorList = getDoctorListAsPerSelection();
+ notifyListeners();
+ }
}
diff --git a/lib/features/doctor_filter/doctor_filter_view_model.dart b/lib/features/doctor_filter/doctor_filter_view_model.dart
new file mode 100644
index 0000000..889ab5a
--- /dev/null
+++ b/lib/features/doctor_filter/doctor_filter_view_model.dart
@@ -0,0 +1,110 @@
+import 'package:flutter/material.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/features/book_appointments/models/resp_models/doctors_list_response_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart' show PatientDoctorAppointmentList;
+
+class DoctorFilterViewModel extends ChangeNotifier{
+
+ late AppState appState;
+ DoctorFilterViewModel(){
+ appState = getIt();
+ }
+ List searchedRegionList = [];
+ List facilityList = ["hmgHospitals", "hmcMedicalClinic"];
+ List searchedHospitalList = [];
+ List
+ searchedPatientDoctorAppointmentHospitalsList = [];
+ List searchedClinicList = [];
+
+ PatientDoctorAppointmentList? selectedHospitalForFilters;
+ List? selectedFacilityForFilters = [] , selectedRegionForFilters = [];
+ String? selectedClinicForFilters;
+ bool applyFilters = false;
+
+ void clearSearchFilters() {
+ searchedRegionList.clear();
+ searchedHospitalList.clear();
+ searchedPatientDoctorAppointmentHospitalsList.clear();
+ searchedClinicList.clear();
+ notifyListeners();
+ }
+
+ void clearSelection() {
+ selectedFacilityForFilters = [];
+ selectedClinicForFilters = null;
+ selectedHospitalForFilters = null;
+ selectedRegionForFilters = [];
+ applyFilters = false;
+ notifyListeners();
+ }
+
+ void getFiltersFromDoctorList(List doctorsList) {
+ doctorsList.forEach((element) {
+ if (!searchedRegionList
+ .contains(element.getRegionName(appState.isArabic()))) {
+ searchedRegionList
+ .add(element.getRegionName(appState.isArabic()) ?? "");
+ }
+ if (!searchedHospitalList.contains(element.projectName)) {
+ searchedPatientDoctorAppointmentHospitalsList
+ .add(PatientDoctorAppointmentList()
+ ..filterName = element.projectName
+ ..isHMC = element.isHMC
+ ..distanceInKMs = "0");
+ searchedHospitalList.add(element.projectName ?? "");
+ }
+ if (!searchedClinicList.contains(element.clinicName)) {
+ searchedClinicList.add(element.clinicName ?? "");
+ }
+ });
+ }
+
+ void updateApplyFilters(bool applyFilters) {
+ this.applyFilters = applyFilters;
+ notifyListeners();
+ }
+
+ void setSelectedRegion(String region) {
+ if (selectedRegionForFilters?.contains(region) == true) {
+ selectedRegionForFilters?.remove(region);
+ } else {
+ selectedRegionForFilters?.add(region);
+ }
+ notifyListeners();
+ }
+
+ void setSelectedHospital(PatientDoctorAppointmentList? hospital) {
+ selectedHospitalForFilters = hospital;
+ notifyListeners();
+ }
+
+ void setSelectedFacilityForFilter(String facility) {
+ if (selectedFacilityForFilters?.contains(facility) == true) {
+ selectedFacilityForFilters?.remove(facility);
+ } else {
+ selectedFacilityForFilters?.add(facility);
+ }
+
+ notifyListeners();
+ }
+
+ void setSelectedClinicForFilter(String? clinic) {
+ selectedClinicForFilters = clinic;
+ notifyListeners();
+ }
+
+ void setSelections(
+ List? selectedFacilityForFilters,
+ List? selectedRegionForFilters,
+ String? selectedClinicForFilters,
+ PatientDoctorAppointmentList? selectedHospitalForFilters,
+ bool applyFilters) {
+ this.selectedFacilityForFilters = selectedFacilityForFilters;
+ this.selectedClinicForFilters = selectedClinicForFilters;
+ this.selectedHospitalForFilters = selectedHospitalForFilters;
+ this.selectedRegionForFilters = selectedRegionForFilters;
+ this.applyFilters = applyFilters;
+ notifyListeners();
+ }
+}
\ No newline at end of file
diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart
index 3d12e5b..9447bd1 100644
--- a/lib/generated/locale_keys.g.dart
+++ b/lib/generated/locale_keys.g.dart
@@ -849,5 +849,19 @@ abstract class LocaleKeys {
static const selectCountry = 'selectCountry';
static const forLoginVerification = 'forLoginVerification';
static const searchHospital = 'searchHospital';
+ static const skip = 'skip';
+ static const getStarted = 'getStarted';
+ static const onboardingHeading1 = 'onboardingHeading1';
+ static const onboardingBody1 = 'onboardingBody1';
+ static const onboardingHeading2 = 'onboardingHeading2';
+ static const onboardingBody2 = 'onboardingBody2';
+ static const hmgHospitals = 'hmgHospitals';
+ static const hmcMedicalClinic = 'hmcMedicalClinic';
+ static const applyFilter = 'applyFilter';
+ static const facilityAndLocation = 'facilityAndLocation';
+ static const regionAndLocation = 'regionAndLocation';
+ static const clearAllFilters = 'clearAllFilters';
+ static const filters = 'filters';
+ static const searchClinic = 'searchClinic';
}
diff --git a/lib/main.dart b/lib/main.dart
index 3690c72..4dfba4b 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -10,6 +10,7 @@ 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/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/lab/history/lab_history_viewmodel.dart';
@@ -154,7 +155,9 @@ void main() async {
ChangeNotifierProvider(
create: (_) => LabHistoryViewModel()),
ChangeNotifierProvider(
- create: (_) => LabRangeViewModel())
+ create: (_) => LabRangeViewModel()) ,
+ ChangeNotifierProvider(
+ create: (_) => DoctorFilterViewModel())
], child: MyApp()),
),
);
diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart
new file mode 100644
index 0000000..58a0d00
--- /dev/null
+++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart
@@ -0,0 +1,66 @@
+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/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.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/widgets/appbar/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 HospitalBottomSheetBodyForDoctorFilter extends StatelessWidget {
+ late BookAppointmentsViewModel appointmentsViewModel;
+ late AppointmentViaRegionViewmodel regionalViewModel;
+ final TextEditingController searchText = TextEditingController();
+
+ HospitalBottomSheetBodyForDoctorFilter({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,
+ ),
+ ),
+ SizedBox(height: 24.h),
+ SizedBox(
+ height: MediaQuery.sizeOf(context).height * .4,
+ child: ListView.separated(
+ itemBuilder: (_, index)
+ {
+ var hospital = appointmentsViewModel.searchedPatientDoctorAppointmentHospitalsList[index];
+ return HospitalListItem(
+ hospitalData: hospital,
+ isLocationEnabled: appointmentsViewModel.isLocationEnabled(),
+ ).onPress(() {
+ regionalViewModel.setHospitalModel(hospital);
+ context.read().setSelectedHospital(hospital);
+ Navigator.pop(context);
+ });},
+ separatorBuilder: (_, __) => SizedBox(
+ height: 16.h,
+ ),
+ itemCount: appointmentsViewModel.searchedPatientDoctorAppointmentHospitalsList?.length ?? 0),
+ )
+ ],
+ );
+ }
+}
diff --git a/lib/presentation/book_appointment/doctor_filter/RegionChips.dart b/lib/presentation/book_appointment/doctor_filter/RegionChips.dart
new file mode 100644
index 0000000..c81e548
--- /dev/null
+++ b/lib/presentation/book_appointment/doctor_filter/RegionChips.dart
@@ -0,0 +1,60 @@
+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';
+import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'
+ show BookAppointmentsViewModel;
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_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';
+
+class RegionChips extends StatelessWidget {
+ const RegionChips({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Selector>(
+ selector: (_, model) => model.searchedRegionList,
+ builder: (__, data, ___) =>
+ Selector?>(
+ selector: (_, model) => model.selectedRegionForFilters,
+ builder: (context, selectRegion, ___) => Row(
+ children: [
+ Expanded(
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ itemCount: data.length,
+ separatorBuilder: (_, __)=>SizedBox(width: 8.h,),
+
+ itemBuilder: (_, index) => AppCustomChipWidget(
+ labelText: data[index],
+ textColor: selectRegion?.any((selectedRegion)=>data[index] == selectedRegion) == true
+ ? AppColors.primaryRedColor
+
+ : AppColors.textColor,
+ backgroundColor:
+ selectRegion?.any((selectedRegion)=>data[index] == selectedRegion) == true
+ ? AppColors.primaryRedColor
+ .withOpacity(0.1)
+ : AppColors.whiteColor,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: selectRegion?.any((selectedRegion)=>data[index] == selectedRegion) == true
+ ? AppColors
+ .primaryRedBorderColor
+ : AppColors
+ .chipBorderColorOpacity20,
+ width: 1,
+ ),
+ borderRadius:
+ BorderRadius.circular(10)))
+ .onPress(() {
+ context
+ .read()
+ .setSelectedRegion(data[index]);
+ })))
+ ],
+ ),
+ ));
+ }
+}
diff --git a/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart b/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart
new file mode 100644
index 0000000..155d8e3
--- /dev/null
+++ b/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart
@@ -0,0 +1,85 @@
+import 'package:easy_localization/easy_localization.dart'
+ show tr, StringTranslateExtension;
+import 'package:flutter/material.dart';
+import 'package:flutter_staggered_animations/flutter_staggered_animations.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/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.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/book_appointment/doctor_filter/clinic_item.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic_card.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/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';
+
+import '../../../features/book_appointments/models/resp_models/get_clinic_list_response_model.dart' show GetClinicsListResponseModel;
+
+class ClinicBottomSheet extends StatelessWidget {
+ late BookAppointmentsViewModel appointmentsViewModel;
+ late AppointmentViaRegionViewmodel regionalViewModel;
+ final TextEditingController searchText = TextEditingController();
+
+ ClinicBottomSheet({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ appointmentsViewModel = Provider.of(context);
+ regionalViewModel = Provider.of(context);
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ LocaleKeys.selectClinic.tr(),
+ style: TextStyle(
+ fontSize: 21,
+ fontWeight: FontWeight.w600,
+ color: AppColors.blackColor,
+ ),
+ ),
+ SizedBox(height: 24.h),
+ SizedBox(
+ height: MediaQuery.sizeOf(context).height * .4,
+ child: ListView.separated(
+ itemBuilder: (_, index)
+ {
+ return AnimationConfiguration.staggeredList(
+ position: index,
+ duration: const Duration(milliseconds: 500),
+ child: SlideAnimation(
+ verticalOffset: 100.0,
+ child: FadeInAnimation(
+ child: AnimatedContainer(
+ duration: Duration(milliseconds: 300),
+ curve: Curves.easeInOut,
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
+ child: ClinicItem(
+ isArabic: appointmentsViewModel.isArabic(),
+ clinicName: appointmentsViewModel.searchedClinicList[index],
+ ),
+ ),
+ ),
+ ),
+
+ ).onPress(() {
+ context.read()
+ .setSelectedClinicForFilter(appointmentsViewModel.searchedClinicList[index]);
+ Navigator.pop(context);
+ });},
+ separatorBuilder: (_, __) => SizedBox(
+ height: 16.h,
+ ),
+ itemCount: appointmentsViewModel.searchedClinicList.length ?? 0),
+ )
+ ],
+ );
+ }
+}
diff --git a/lib/presentation/book_appointment/doctor_filter/clinic_item.dart b/lib/presentation/book_appointment/doctor_filter/clinic_item.dart
new file mode 100644
index 0000000..0d5ba76
--- /dev/null
+++ b/lib/presentation/book_appointment/doctor_filter/clinic_item.dart
@@ -0,0 +1,52 @@
+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;
+
+class ClinicItem extends StatelessWidget {
+ final String clinicName;
+ final bool isArabic;
+
+ ClinicItem({super.key, required this.clinicName, required this.isArabic});
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.all(16.h),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.h,
+ hasShadow: false,
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Utils.buildSvgWithAssets(
+ icon: AppAssets.generic_clinic_icon,
+ width: 24.h,
+ height: 24.h,
+ fit: BoxFit.contain),
+ SizedBox(height: 16.h),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(child: clinicName.toText16(isBold: true)),
+ Transform.flip(
+ flipX: isArabic,
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.forward_arrow_icon,
+ width: 15.h,
+ height: 15.h,
+ fit: BoxFit.contain,
+ iconColor: AppColors.textColor),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart b/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart
new file mode 100644
index 0000000..1a772f7
--- /dev/null
+++ b/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart
@@ -0,0 +1,249 @@
+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/features/book_appointments/book_appointments_view_model.dart';
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.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_bottom_sheet_body.dart';
+import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/RegionChips.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/facility_Chips.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
+import 'package:hmg_patient_app_new/widgets/input_widget.dart';
+import 'package:provider/provider.dart';
+
+import '../../../widgets/buttons/custom_button.dart';
+
+class DoctorsFilters extends StatelessWidget{
+
+
+ TextEditingController hospitalController = TextEditingController();
+ TextEditingController clinicController = TextEditingController();
+ DoctorsFilters({super.key,});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ appBar: AppBar(
+ backgroundColor: AppColors.bgScaffoldColor,
+
+ automaticallyImplyLeading: false,
+ centerTitle: false,
+ title: Utils.buildSvgWithAssets(icon: AppAssets.ic_close, height: 32.h, width: 32.h).onPress((){
+ context.read()
+ .clearSelection()
+ ;
+ Navigator.pop(context);
+ })
+
+
+
+ ),
+
+ body: Column(
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ LocaleKeys.filters.tr(),
+ style:TextStyle(
+ fontFamily: 'Poppins',
+ fontWeight: FontWeight.w600,
+ fontSize: 27.fSize,
+ color: AppColors.textColor,
+ letterSpacing: -1
+ )
+ ),
+ Text(
+ LocaleKeys.clearAllFilters.tr(),
+ style:TextStyle(
+ fontFamily: 'Poppins',
+ fontWeight: FontWeight.w500,
+ fontSize: 14.fSize,
+ color: AppColors.errorColor
+ )
+ ).onPress((){
+ context.read().clearSelection();
+ context.read().updateApplyFilters(false);
+ // context.read().setSelections(
+ // context.read().selectedFacilityForFilters,
+ // context.read().selectedRegionForFilters,
+ // context.read().selectedClinicForFilters,
+ // context.read().selectedHospitalForFilters,
+ // context.read().applyFilters);
+ context.read().updateList();
+ })
+ ],
+ ),
+ titleWidget(LocaleKeys.regionAndLocation.tr()),
+ SizedBox(
+ height: 42.h,
+ child: RegionChips()),
+ titleWidget(LocaleKeys.facilityAndLocation.tr()),
+ SizedBox(
+ height: 42.h,
+ child: FacilityChip()),
+ titleWidget(LocaleKeys.hospital.tr()),
+ TextInputWidget(
+ controller: TextEditingController()..text =context.watch().selectedHospitalForFilters?.filterName??'',
+ labelText: LocaleKeys.hospital.tr(context: context),
+ hintText: LocaleKeys.searchHospital.tr(context: context),
+ isEnable: false,
+ prefix: null,
+ autoFocus: false,
+ isBorderAllowed: false,
+ keyboardType: TextInputType.text,
+ suffix:context.watch().selectedHospitalForFilters != null
+ ? GestureDetector(
+ onTap: () {
+ context.read().setSelectedHospital(null);
+ },
+ child: Utils.buildSvgWithAssets(icon: AppAssets.ic_cross_circle, width: 24.h, height: 24.h, fit: BoxFit.scaleDown),
+ )
+ : null,
+ onChange: (value) {
+ // DoctorFilterViewModel.filterClinics(value!);
+ },
+ padding: EdgeInsets.symmetric(
+ vertical: ResponsiveExtension(8).h,
+ horizontal: ResponsiveExtension(10).h,
+ ),
+ ).onPress((){
+ openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
+ }),
+
+ titleWidget(LocaleKeys.clinic.tr()),
+ TextInputWidget(
+ controller: TextEditingController()..text =context.watch().selectedClinicForFilters ??'',
+ labelText: LocaleKeys.clinicName.tr(context: context),
+ hintText: LocaleKeys.searchClinic.tr().needTranslation,
+ isEnable: false,
+ prefix: null,
+ autoFocus: false,
+ isBorderAllowed: false,
+ keyboardType: TextInputType.text,
+ suffix:context.read().selectedClinicForFilters?.isNotEmpty == true
+ ? GestureDetector(
+ onTap: () {
+ context.read().setSelectedClinicForFilter(null);
+ },
+ child: Utils.buildSvgWithAssets(icon: AppAssets.ic_cross_circle, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
+ )
+ : null,
+ onChange: (value) {
+ // DoctorFilterViewModel.filterClinics(value!);
+ },
+ padding: EdgeInsets.symmetric(
+ vertical: 8.h,
+ horizontal: 10.h,
+ ),
+ ).onPress((){
+ openClinicListBottomSheet(context,);
+ }),
+
+
+ ],
+ ).paddingSymmetrical(24.h, 0.h),
+ Spacer(),
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: Colors.white,
+ customBorder: BorderRadius.only(topLeft: Radius.circular(24.h), topRight: Radius.circular(24.h)) ,
+
+ ),
+ child: CustomButton(
+ text: LocaleKeys.applyFilter.tr(),
+ onPressed: () {
+ context.read().updateApplyFilters(true);
+ context.read().setSelections(
+ context.read().selectedFacilityForFilters?.toList()??[],
+ context.read().selectedRegionForFilters?.toList()??[],
+ context.read().selectedClinicForFilters,
+ context.read().selectedHospitalForFilters,
+ context.read().applyFilters);
+ context.read().updateList();
+ Navigator.pop(context);
+ },
+ backgroundColor: AppColors.primaryRedColor,
+ borderColor: AppColors.primaryRedColor,
+ textColor: Colors.white,
+ fontSize: 16,
+ padding: EdgeInsets.zero,
+ fontWeight: FontWeight.w500,
+ borderRadius: 12,
+ icon: AppAssets.add_icon,
+ iconColor: AppColors.primaryRedColor,
+ ).paddingAll(24.h),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget titleWidget(String title){
+ return Column(
+ children: [
+ SizedBox(height: 24.h,),
+ Text(
+ title,
+ style:TextStyle(
+ fontFamily: 'Poppins',
+ fontWeight: FontWeight.w600,
+ fontSize: 16.fSize,
+ color: AppColors.textColor,
+ letterSpacing:-1
+ )
+ ),
+ SizedBox(height: 8.h,),
+ ],
+ );
+ }
+
+ void openRegionListBottomSheet(BuildContext context, RegionBottomSheetType type) {
+ context.read().flush();
+ context.read().setBottomSheetType(type);
+ context.read().setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION);
+ // AppointmentViaRegionViewmodel? viewmodel = null;
+ showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer(builder: (_, data, __) => getTitle(data)), isDismissible: false,
+ child: Consumer(builder: (_, data, __) {
+ return getRegionalSelectionWidget(data);
+ }), callBackFunc: () {});
+ }
+
+ Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data) {
+
+ if (data.bottomSheetState == AppointmentViaRegionState.HOSPITAL_SELECTION) {
+ return HospitalBottomSheetBodyForDoctorFilter();
+ }
+ if (data.bottomSheetState == AppointmentViaRegionState.CLINIC_SELECTION) {
+ } else {
+ SizedBox.shrink();
+ }
+ return SizedBox.shrink();
+ }
+
+ getTitle(AppointmentViaRegionViewmodel data) {
+ return SizedBox.shrink();
+ }
+
+ void openClinicListBottomSheet(BuildContext context) {
+ showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer(builder: (_, data, __) => getTitle(data)), isDismissible: false,
+ child: Consumer(builder: (_, data, __) {
+ return ClinicBottomSheet();
+ }), callBackFunc: () {});
+ }
+
+}
\ No newline at end of file
diff --git a/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart b/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart
new file mode 100644
index 0000000..f416ed4
--- /dev/null
+++ b/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart
@@ -0,0 +1,65 @@
+
+import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension;
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
+import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'
+ show BookAppointmentsViewModel;
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_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';
+
+class FacilityChip extends StatelessWidget {
+ const FacilityChip({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Selector>(
+ selector: (_, model) => model.facilityList,
+ builder: (__, data, ___) =>
+ Selector?>(
+ selector: (_, model) => model.selectedFacilityForFilters,
+ builder: (context, selectRegion, ___) => Row(
+ children: [
+ Expanded(
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+
+ itemCount: data.length,
+ separatorBuilder: (_, __)=>SizedBox(width: 8.h,),
+ itemBuilder: (_, index) => AppCustomChipWidget(
+ icon: data[index].contains("hmg")?AppAssets.hmg: AppAssets.hmc,
+ iconHasColor: false,
+ iconSize: 18,
+ labelText: data[index].tr(),
+ textColor: selectRegion?.any((selectedRegion)=>data[index] == selectedRegion) == true
+ ? AppColors.primaryRedColor
+ : AppColors.textColor,
+ backgroundColor:
+ data[index] == selectRegion
+ ? AppColors.primaryRedColor
+ .withOpacity(0.1)
+ : AppColors.whiteColor,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: selectRegion?.any((selectedRegion)=>data[index] == selectedRegion) == true
+ ? AppColors
+ .primaryRedBorderColor
+ : AppColors
+ .chipBorderColorOpacity20,
+ width: 1,
+ ),
+ borderRadius:
+ BorderRadius.circular(10)))
+ .onPress(() {
+ context
+ .read()
+ .setSelectedFacilityForFilter(data[index]);
+ })))
+ ],
+ ),
+ ));
+ }
+}
diff --git a/lib/presentation/book_appointment/search_doctor_by_name.dart b/lib/presentation/book_appointment/search_doctor_by_name.dart
index 8f611dc..5949ef5 100644
--- a/lib/presentation/book_appointment/search_doctor_by_name.dart
+++ b/lib/presentation/book_appointment/search_doctor_by_name.dart
@@ -9,7 +9,9 @@ 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/book_appointments/book_appointments_view_model.dart';
+import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/doctors_filter.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/doctor_card.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
@@ -33,16 +35,12 @@ class SearchDoctorByName extends StatefulWidget {
class _SearchDoctorByNameState extends State {
TextEditingController searchEditingController = TextEditingController();
-
FocusNode textFocusNode = FocusNode();
-
- late AppState appState;
late BookAppointmentsViewModel bookAppointmentsViewModel;
@override
Widget build(BuildContext context) {
bookAppointmentsViewModel = Provider.of(context, listen: false);
- appState = getIt.get();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Column(
@@ -56,33 +54,85 @@ class _SearchDoctorByNameState extends State {
child: Column(
children: [
SizedBox(height: 16.h),
- TextInputWidget(
- labelText: LocaleKeys.search.tr(context: context),
- hintText: LocaleKeys.doctorName.tr(context: context),
- controller: searchEditingController,
- isEnable: true,
- prefix: null,
- autoFocus: false,
- isBorderAllowed: false,
- keyboardType: TextInputType.text,
- focusNode: textFocusNode,
- suffix: searchEditingController.text.isNotEmpty
- ? GestureDetector(
- onTap: () {
- searchEditingController.clear();
- // bookAppointmentsViewModel.filterClinics("");
- textFocusNode.unfocus();
- },
- child: Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
- )
- : null,
- onChange: (value) {
- // bookAppointmentsViewModel.filterClinics(value!);
- },
- padding: EdgeInsets.symmetric(
- vertical: ResponsiveExtension(10).h,
- horizontal: ResponsiveExtension(15).h,
- ),
+ Row(
+ spacing: 8.h,
+ children: [
+ Expanded(
+ child: TextInputWidget(
+ labelText: LocaleKeys.search.tr(context: context),
+ hintText: LocaleKeys.doctorName.tr(context: context),
+ controller: searchEditingController,
+ isEnable: true,
+ prefix: null,
+ autoFocus: false,
+ isBorderAllowed: false,
+ keyboardType: TextInputType.text,
+ focusNode: textFocusNode,
+ suffix: searchEditingController.text.isNotEmpty
+ ? GestureDetector(
+ onTap: () {
+ searchEditingController.clear();
+ // bookAppointmentsViewModel.filterClinics("");
+ textFocusNode.unfocus();
+ },
+ child: Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
+ )
+ : null,
+ onChange: (value) {
+ // bookAppointmentsViewModel.filterClinics(value!);
+ },
+ padding: EdgeInsets.symmetric(
+ vertical: ResponsiveExtension(10).h,
+ horizontal: ResponsiveExtension(15).h,
+ ),
+ ),
+ ),
+ Visibility(
+ visible: context.watch().doctorsList.isNotEmpty,
+ child: SizedBox(
+ height: 56.h,
+ width: 56.h,
+ child: DecoratedBox(decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 10.h,
+ hasShadow: false,
+ ),
+ child: Utils.buildSvgWithAssets(icon: AppAssets.ic_filters,
+ height: 24.h,
+ width: 24.h, ).paddingAll(16.h).onPress((){
+ context.read()
+ ..clearSelection()
+ ..clearSearchFilters()
+ ..getFiltersFromDoctorList(
+ bookAppointmentsViewModel.doctorsList
+ )..setSelections(
+ bookAppointmentsViewModel.selectedFacilityForFilters?.toList(),
+ bookAppointmentsViewModel.selectedRegionForFilters?.toList(),
+ bookAppointmentsViewModel.selectedClinicForFilters,
+ bookAppointmentsViewModel.selectedHospitalForFilters,
+ bookAppointmentsViewModel.applyFilters) ;
+ Navigator.of(context).push(
+ PageRouteBuilder(
+ pageBuilder: (context, animation, secondaryAnimation) => DoctorsFilters(), // Replace YourNewPage with your actual page widget
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
+ const begin = Offset(0.0, 1.0); // Start from the bottom (y=1.0)
+ const end = Offset.zero; // End at the original position (y=0.0)
+ final tween = Tween(begin: begin, end: end);
+ final offsetAnimation = animation.drive(tween);
+
+ return SlideTransition(
+ position: offsetAnimation,
+ child: child,
+ );
+ },
+ transitionDuration: Duration(milliseconds: 200), // Adjust duration as needed
+ ),
+ );
+ }),
+ ),
+ ),
+ )
+ ],
),
SizedBox(height: 16.h),
Consumer(builder: (context, bookAppointmentsVM, child) {
@@ -94,7 +144,7 @@ class _SearchDoctorByNameState extends State {
padding: EdgeInsets.only(top: 24.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
- itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 : bookAppointmentsVM.doctorsList.length,
+ itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 : bookAppointmentsVM.filteredDoctorList.length,
itemBuilder: (context, index) {
return bookAppointmentsVM.isDoctorsListLoading
? DoctorCard(
@@ -113,11 +163,11 @@ class _SearchDoctorByNameState extends State {
curve: Curves.easeInOut,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: DoctorCard(
- doctorsListResponseModel: bookAppointmentsVM.doctorsList[index],
+ doctorsListResponseModel: bookAppointmentsVM.filteredDoctorList[index],
isLoading: false,
bookAppointmentsViewModel: bookAppointmentsViewModel,
).onPress(() async {
- bookAppointmentsVM.setSelectedDoctor(bookAppointmentsVM.doctorsList[index]);
+ bookAppointmentsVM.setSelectedDoctor(bookAppointmentsVM.filteredDoctorList[index]);
// bookAppointmentsVM.setSelectedDoctor(DoctorsListResponseModel());
LoaderBottomSheet.showLoader();
await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) {
@@ -166,7 +216,11 @@ class _SearchDoctorByNameState extends State {
text: LocaleKeys.search.tr(context: context),
onPressed: () async {
textFocusNode.unfocus();
+ print("the value is empty ${searchEditingController.text.isNotEmpty}");
if (searchEditingController.text.isNotEmpty) {
+ bookAppointmentsViewModel.updateApplyFilters(false);
+ bookAppointmentsViewModel.clearSelection();
+ bookAppointmentsViewModel.updateList();
bookAppointmentsViewModel.setIsDoctorSearchByNameStarted(true);
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
// LoaderBottomSheet.showLoader();
@@ -210,4 +264,9 @@ class _SearchDoctorByNameState extends State {
),
);
}
+ @override
+ void dispose() {
+ bookAppointmentsViewModel.doctorsList.clear();
+ super.dispose();
+ }
}
diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart
index fd6e691..5975631 100644
--- a/lib/presentation/book_appointment/select_doctor_page.dart
+++ b/lib/presentation/book_appointment/select_doctor_page.dart
@@ -68,33 +68,44 @@ class _SelectDoctorPageState extends State {
children: [
// TODO: Implement doctor filter functionality
SizedBox(height: 16.h),
- TextInputWidget(
- labelText: LocaleKeys.search.tr(context: context),
- hintText: LocaleKeys.doctorName.tr(context: context),
- controller: searchEditingController,
- isEnable: true,
- prefix: null,
- autoFocus: false,
- isBorderAllowed: false,
- keyboardType: TextInputType.text,
- focusNode: textFocusNode,
- suffix: searchEditingController.text.isNotEmpty
- ? GestureDetector(
- onTap: () {
- searchEditingController.clear();
- bookAppointmentsViewModel.filterClinics("");
- textFocusNode.unfocus();
- },
- child: Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
- )
- : null,
- onChange: (value) {
- bookAppointmentsViewModel.filterClinics(value!);
- },
- padding: EdgeInsets.symmetric(
- vertical: ResponsiveExtension(10).h,
- horizontal: ResponsiveExtension(15).h,
- ),
+ Row(
+ spacing: 8.h,
+ children: [
+ Expanded(
+ child: TextInputWidget(
+ labelText: LocaleKeys.search.tr(context: context),
+ hintText: LocaleKeys.doctorName.tr(context: context),
+ controller: searchEditingController,
+ isEnable: true,
+ prefix: null,
+ autoFocus: false,
+ isBorderAllowed: false,
+ keyboardType: TextInputType.text,
+ focusNode: textFocusNode,
+ suffix: searchEditingController.text.isNotEmpty
+ ? GestureDetector(
+ onTap: () {
+ searchEditingController.clear();
+ bookAppointmentsViewModel.filterClinics("");
+ textFocusNode.unfocus();
+ },
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.close_bottom_sheet_icon,
+ width: 20.h,
+ height: 20.h,
+ fit: BoxFit.scaleDown),
+ )
+ : null,
+ onChange: (value) {
+ bookAppointmentsViewModel.filterClinics(value!);
+ },
+ padding: EdgeInsets.symmetric(
+ vertical: ResponsiveExtension(10).h,
+ horizontal: ResponsiveExtension(15).h,
+ ),
+ ),
+ ),
+ ],
),
ListView.separated(
padding: EdgeInsets.only(top: 24.h),
diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart
index a4db172..084f85b 100644
--- a/lib/widgets/chip/app_custom_chip_widget.dart
+++ b/lib/widgets/chip/app_custom_chip_widget.dart
@@ -62,7 +62,7 @@ class AppCustomChipWidget extends StatelessWidget {
// padding: EdgeInsets.all(0.0),
padding: padding,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
- labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: deleteIcon?.isNotEmpty == true ? 2.h : 8.h),
+ labelPadding: EdgeInsetsDirectional.only(start: 0.h, end: deleteIcon?.isNotEmpty == true ? 2.h : 8.h),
backgroundColor: backgroundColor,
shape: shape ??
SmoothRectangleBorder(
diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart
index 4a2322c..4b06096 100644
--- a/lib/widgets/input_widget.dart
+++ b/lib/widgets/input_widget.dart
@@ -114,6 +114,7 @@ class TextInputWidget extends StatelessWidget {
children: [
Container(
padding: padding,
+ height: 58.h,
alignment: Alignment.center,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: Colors.white,
@@ -134,12 +135,23 @@ class TextInputWidget extends StatelessWidget {
// textField: _buildTextField(context),
)
: Expanded(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
+ child: Row(
children: [
- _buildLabelText(labelColor).paddingOnly(right: (appState.getLanguageCode() == "ar" ? 10 : 0)),
- _buildTextField(context),
+ Expanded(
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ _buildLabelText(labelColor).paddingOnly(right: (appState.getLanguageCode() == "ar" ? 10 : 0)),
+ Row(
+ children: [
+ Expanded(child: _buildTextField(context)),
+ ],
+ ),
+ ],
+ ),
+ ),
+ (suffix!= null )?suffix!:SizedBox.shrink()
],
),
),
@@ -218,7 +230,6 @@ class TextInputWidget extends StatelessWidget {
fontWeight: FontWeight.w500,
color: labelColor ?? AppColors.inputLabelTextColor,
letterSpacing: -0.2,
- height: 18 / 12,
),
);
}