diff --git a/assets/images/svg/my_child_vaccine.svg b/assets/images/svg/my_child_vaccine.svg new file mode 100644 index 0000000..f671baf --- /dev/null +++ b/assets/images/svg/my_child_vaccine.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 51cf6c5..f715305 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -890,6 +890,10 @@ class ApiConsts { static String getProjectsHaveBDClinics = "Services/OUTPs.svc/REST/BD_getProjectsHaveBDClinics"; static String getClinicsBDFreeSlots = "Services/OUTPs.svc/REST/BD_GetFreeSlots"; + + static String getPatientBloodGroup = "services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails"; + static String getPatientBloodAgreement = "Services/PatientVarification.svc/REST/CheckUserAgreementForBloodDonation"; + // ************ static values for Api **************** static final double appVersionID = 50.3; static final int appChannelId = 3; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index bfe7707..e0a99a7 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -183,6 +183,7 @@ class AppAssets { static const String bulb_icon = '$svgBasePath/bulb_icon.svg'; static const String select_city_icon = '$svgBasePath/select_city_icon.svg'; static const String blood_donation_icon = '$svgBasePath/blood_donation_icon.svg'; + static const String my_child_vaccine_icon = '$svgBasePath/my_child_vaccine.svg'; static const String virtual_tour_icon = '$svgBasePath/virtual_tour_icon.svg'; static const String car_parking_icon = '$svgBasePath/car_parking_icon.svg'; static const String latest_news_icon = '$svgBasePath/latest_news_icon.svg'; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 0c4ba09..f1182e0 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -462,7 +462,7 @@ class AuthenticationViewModel extends ChangeNotifier { if (isSwitchUser && _appState.getSuperUserID == null) { nationalIdController.text = responseID.toString(); - }else if( isSwitchUser && _appState.getSuperUserID != null){ + } else if (isSwitchUser && _appState.getSuperUserID != null) { nationalIdController.text = _appState.getSuperUserID.toString(); } @@ -1078,4 +1078,30 @@ class AuthenticationViewModel extends ChangeNotifier { return null; } } + + Future logout() async { + try { + // Clear user data from AppState + _appState.setAuthenticatedUser(null); + _appState.setAuthenticatedUser(null, isFamily: true); + _appState.setIsAuthenticated = false; + _appState.setAppAuthToken = ""; + _appState.setUserBloodGroup = ""; + _appState.setSuperUserID = null; + _appState.setIsChildLoggedIn = false; + _appState.setFamilyFileTokenID = ""; + _appState.setSelectDeviceByImeiRespModelElement(null); + _appState.setNHICUserData = CheckUserStatusResponseNHIC(); + _appState.setUserRegistrationPayload = RegistrationDataModelPayload(); + // Clear privilege lists + _appState.setPrivilegeModelList([]); + _appState.setVidaPlusProjectList([]); + _appState.setHMCProjectList([]); + _appState.setProjectsDetailList([]); + await clearDefaultInputValues(); + _navigationService.pushAndReplace(AppRoutes.landingScreen); + } catch (e) { + _navigationService.pushAndReplace(AppRoutes.landingScreen); + } + } } diff --git a/lib/features/blood_donation/blood_donation_repo.dart b/lib/features/blood_donation/blood_donation_repo.dart index 5643635..c709b03 100644 --- a/lib/features/blood_donation/blood_donation_repo.dart +++ b/lib/features/blood_donation/blood_donation_repo.dart @@ -23,6 +23,8 @@ abstract class BloodDonationRepo { Future>> getFreeBloodDonationSlots({required Map request}); Future>> addUserAgreementForBloodDonation({required Map request}); + + Future>> getUserAgreementForBloodDonation(); } class BloodDonationRepoImp implements BloodDonationRepo { @@ -76,7 +78,7 @@ class BloodDonationRepoImp implements BloodDonationRepo { GenericApiModel? apiResponse; Failure? failure; await apiClient.post( - GET_BLOOD_REQUEST, + ApiConsts.getPatientBloodGroup, body: mapDevice, isAllowAny: true, onFailure: (error, statusCode, {messageStatus, failureType}) { @@ -287,4 +289,36 @@ class BloodDonationRepoImp implements BloodDonationRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>>> getUserAgreementForBloodDonation() async { + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + ApiConsts.getPatientBloodAgreement, + body: {}, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/blood_donation/blood_donation_view_model.dart b/lib/features/blood_donation/blood_donation_view_model.dart index 8325cf7..8ad5bde 100644 --- a/lib/features/blood_donation/blood_donation_view_model.dart +++ b/lib/features/blood_donation/blood_donation_view_model.dart @@ -4,6 +4,7 @@ import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.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/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.dart'; @@ -233,7 +234,7 @@ class BloodDonationViewModel extends ChangeNotifier { return false; } - if (selectedBloodGroup == null) { + if (selectedGender == null) { await dialogService.showErrorBottomSheet( message: "Please choose Gender", ); @@ -258,29 +259,28 @@ class BloodDonationViewModel extends ChangeNotifier { Future updateBloodGroup() async { LoaderBottomSheet.showLoader(); - // body['City'] = detailsModel.city; - // body['cityCode'] = detailsModel.cityCode; - // body['Gender'] = detailsModel.gender; - // body['BloodGroup'] = detailsModel.bloodGroup; - // body['CellNumber'] = user.mobileNumber; - // body['LanguageID'] = languageID; - // body['NationalID'] = user.nationalityID; - // body['ZipCode'] = user.zipCode ?? "+966"; - // body['isDentalAllowedBackend'] = false; - Map payload = { - "City": selectedCity?.description, - "cityCode": selectedCity?.iD, - "Gender": selectedGender?.value, - "isDentalAllowedBackend": false - // "Gender": selectedGender?.value, - }; + Map payload = {"City": selectedCity?.description, "cityCode": selectedCity?.iD, "Gender": selectedGender?.value, "isDentalAllowedBackend": false}; await bloodDonationRepo.updateBloodGroup(request: payload); await addUserAgreementForBloodDonation(); LoaderBottomSheet.hideLoader(); + dialogService.showSuccessBottomSheetWithoutH(message: "Blood Group Updated Successfully", onOkPressed: () {}); } Future addUserAgreementForBloodDonation() async { Map payload = {"IsAgreed": true}; await bloodDonationRepo.addUserAgreementForBloodDonation(request: payload); } + + Future getUserAgreementForBloodDonation() async { + await bloodDonationRepo.getUserAgreementForBloodDonation(); + } + + Future fetchAllData() async { + LoaderBottomSheet.showLoader(loadingText: "Fetching Data..."); + await getRegionSelectedClinics(); + if (isUserAuthanticated()) { + // await getPatientBloodGroupDetails(); + } + LoaderBottomSheet.hideLoader(); + } } diff --git a/lib/features/blood_donation/widgets/hospital_selection.dart b/lib/features/blood_donation/widgets/hospital_selection.dart index c6065ae..9889410 100644 --- a/lib/features/blood_donation/widgets/hospital_selection.dart +++ b/lib/features/blood_donation/widgets/hospital_selection.dart @@ -15,8 +15,9 @@ import 'package:provider/provider.dart'; class HospitalBottomSheetBodySelection extends StatelessWidget { final Function(BdGetProjectsHaveBdClinic userSelection) onUserHospitalSelection; + final bool isHideTitle; - const HospitalBottomSheetBodySelection({super.key, required this.onUserHospitalSelection(BdGetProjectsHaveBdClinic userSelection)}); + const HospitalBottomSheetBodySelection({super.key, required this.onUserHospitalSelection(BdGetProjectsHaveBdClinic userSelection), this.isHideTitle = false}); @override Widget build(BuildContext context) { @@ -25,7 +26,7 @@ class HospitalBottomSheetBodySelection extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.selectHospital.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.greyTextColor), + if(!isHideTitle) LocaleKeys.selectHospital.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.greyTextColor), SizedBox(height: 16.h), SizedBox( height: MediaQuery.sizeOf(context).height * .4, diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index d67e5de..17cbb94 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -4,6 +4,7 @@ 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/core/enums.dart'; +import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; import 'package:hmg_patient_app_new/core/utils/request_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; @@ -576,9 +577,18 @@ class MedicalFileViewModel extends ChangeNotifier { await RequestUtils.getAddFamilyRequest(nationalIDorFile: authVM.nationalIdController.text, mobileNo: authVM.phoneNumberController.text, countryCode: authVM.selectedCountrySignup.countryCode); final resultEither = await medicalFileRepo.addFamilyFile(request: request.toJson()); - resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) async { + resultEither.fold( + (failure) async => await errorHandlerService.handleError( + failure: failure, + onUnHandledFailure: (failure) { + LoaderBottomSheet.hideLoader(); + _dialogService.showErrorBottomSheet( + message: failure.message!, + onOkPressed: () { + navigationService.pop(); + }); + }), (apiResponse) async { if (apiResponse.messageStatus == 2) { - print("======="); LoaderBottomSheet.hideLoader(); _dialogService.showErrorBottomSheet( message: apiResponse.errorMessage!, diff --git a/lib/presentation/blood_donation/blood_donation_page.dart b/lib/presentation/blood_donation/blood_donation_page.dart index a987220..26da599 100644 --- a/lib/presentation/blood_donation/blood_donation_page.dart +++ b/lib/presentation/blood_donation/blood_donation_page.dart @@ -28,11 +28,22 @@ import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart'; -class BloodDonationPage extends StatelessWidget { +class BloodDonationPage extends StatefulWidget { BloodDonationPage({super.key}); + @override + State createState() => _BloodDonationPageState(); +} + +class _BloodDonationPageState extends State { late AppState appState; + @override + void initState() { + super.initState(); + Future.microtask(() => getIt.get().fetchAllData()); + } + @override Widget build(BuildContext context) { appState = getIt(); @@ -47,70 +58,69 @@ class BloodDonationPage extends StatelessWidget { trailing: CustomButton( text: "Book", onPressed: () { - // if (bloodDonationVM.isUserAuthanticated()) { - bloodDonationVM.fetchHospitalsList().then((value) { - showCommonBottomSheetWithoutHeight(context, title: "Select Hospital", isDismissible: false, child: Consumer(builder: (_, data, __) { - return HospitalBottomSheetBodySelection( - onUserHospitalSelection: (BdGetProjectsHaveBdClinic userChoice) { - print("============User Choice==============="); - - bloodDonationVM.getFreeBloodDonationSlots(request: {"ClinicID": 134, "ProjectID": userChoice.projectId}); - }, - ); - }), callBackFunc: () {}); - }); - // } else { - // return showCommonBottomSheetWithoutHeight( - // context, - // title: LocaleKeys.notice.tr(context: context), - // child: Column( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), - // SizedBox(height: 8.h), - // (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), - // SizedBox(height: 16.h), - // Row( - // children: [ - // Expanded( - // child: CustomButton( - // text: LocaleKeys.cancel.tr(), - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // backgroundColor: AppColors.secondaryLightRedColor, - // borderColor: AppColors.secondaryLightRedColor, - // textColor: AppColors.primaryRedColor, - // icon: AppAssets.cancel, - // iconColor: AppColors.primaryRedColor, - // ), - // ), - // SizedBox(width: 8.h), - // Expanded( - // child: CustomButton( - // text: LocaleKeys.confirm.tr(), - // onPressed: () async { - // Navigator.of(context).pop(); - // // Navigator.pushAndRemoveUntil(context, CustomPageRoute(page: LandingNavigation()), (r) => false); - // await getIt().onLoginPressed(); - // }, - // backgroundColor: AppColors.bgGreenColor, - // borderColor: AppColors.bgGreenColor, - // textColor: Colors.white, - // icon: AppAssets.confirm, - // ), - // ), - // ], - // ), - // SizedBox(height: 16.h), - // ], - // ).center, - // callBackFunc: () {}, - // isFullScreen: false, - // isCloseButtonVisible: true, - // ); - // } + if (bloodDonationVM.isUserAuthanticated()) { + bloodDonationVM.fetchHospitalsList().then((value) { + showCommonBottomSheetWithoutHeight(context, title: "Select Hospital", isDismissible: false, child: Consumer(builder: (_, data, __) { + return HospitalBottomSheetBodySelection( + isHideTitle: true, + onUserHospitalSelection: (BdGetProjectsHaveBdClinic userChoice) { + bloodDonationVM.getFreeBloodDonationSlots(request: {"ClinicID": 134, "ProjectID": userChoice.projectId}); + }, + ); + }), callBackFunc: () {}); + }); + } else { + return showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.notice.tr(context: context), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), + SizedBox(height: 8.h), + (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: CustomButton( + text: LocaleKeys.cancel.tr(), + onPressed: () { + Navigator.of(context).pop(); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + icon: AppAssets.cancel, + iconColor: AppColors.primaryRedColor, + ), + ), + SizedBox(width: 8.h), + Expanded( + child: CustomButton( + text: LocaleKeys.confirm.tr(), + onPressed: () async { + Navigator.of(context).pop(); + // Navigator.pushAndRemoveUntil(context, CustomPageRoute(page: LandingNavigation()), (r) => false); + await getIt().onLoginPressed(); + }, + backgroundColor: AppColors.bgGreenColor, + borderColor: AppColors.bgGreenColor, + textColor: Colors.white, + icon: AppAssets.confirm, + ), + ), + ], + ), + SizedBox(height: 16.h), + ], + ).center, + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } }, backgroundColor: AppColors.bgRedLightColor, borderColor: AppColors.bgRedLightColor, @@ -288,7 +298,60 @@ class BloodDonationPage extends StatelessWidget { onPressed: () async { DialogService dialogService = getIt.get(); if (await bloodDonationVM.validateSelections()) { - bloodDonationVM.updateBloodGroup(); + if (bloodDonationVM.isUserAuthanticated()) { + bloodDonationVM.updateBloodGroup(); + } else { + return showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.notice.tr(context: context), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), + SizedBox(height: 8.h), + (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: CustomButton( + text: LocaleKeys.cancel.tr(), + onPressed: () { + Navigator.of(context).pop(); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + icon: AppAssets.cancel, + iconColor: AppColors.primaryRedColor, + ), + ), + SizedBox(width: 8.h), + Expanded( + child: CustomButton( + text: LocaleKeys.confirm.tr(), + onPressed: () async { + Navigator.of(context).pop(); + // Navigator.pushAndRemoveUntil(context, CustomPageRoute(page: LandingNavigation()), (r) => false); + await getIt().onLoginPressed(); + }, + backgroundColor: AppColors.bgGreenColor, + borderColor: AppColors.bgGreenColor, + textColor: Colors.white, + icon: AppAssets.confirm, + ), + ), + ], + ), + SizedBox(height: 16.h), + ], + ).center, + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } } }, backgroundColor: AppColors.primaryRedColor, diff --git a/lib/presentation/child_vaccine/my_child_vaccine_page.dart b/lib/presentation/child_vaccine/my_child_vaccine_page.dart new file mode 100644 index 0000000..6a226ab --- /dev/null +++ b/lib/presentation/child_vaccine/my_child_vaccine_page.dart @@ -0,0 +1,376 @@ +// 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/app_state.dart'; +// import 'package:hmg_patient_app_new/core/dependencies.dart'; +// import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +// import 'package:hmg_patient_app_new/core/utils/utils.dart'; +// import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +// import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +// import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; +// import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart'; +// import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart'; +// import 'package:hmg_patient_app_new/features/blood_donation/widgets/hospital_selection.dart'; +// import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +// import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_blood_group_widget.dart'; +// import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_city_widget.dart'; +// import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_gender_widget.dart'; +// import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart'; +// import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; +// import 'package:hmg_patient_app_new/services/dialog_service.dart'; +// import 'package:hmg_patient_app_new/theme/colors.dart'; +// import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +// import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +// import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +// import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +// import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +// import 'package:lottie/lottie.dart'; +// import 'package:provider/provider.dart'; +// import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart'; +// +// class MyChildVaccinePage extends StatefulWidget { +// MyChildVaccinePage({super.key}); +// +// @override +// State createState() => _MyChildVaccinePageState(); +// } +// +// class _MyChildVaccinePageState extends State { +// late AppState appState; +// +// @override +// void initState() { +// super.initState(); +// Future.microtask(() => getIt.get().fetchAllData()); +// } +// +// @override +// Widget build(BuildContext context) { +// appState = getIt(); +// return Scaffold( +// backgroundColor: AppColors.bgScaffoldColor, +// body: Consumer(builder: (context, bloodDonationVM, child) { +// return Column( +// children: [ +// Expanded( +// child: CollapsingListView( +// title: "Child Vaccines".needTranslation, +// trailing: CustomButton( +// icon: AppAssets.add_icon, +// text: "Add Child", +// onPressed: () {}, +// backgroundColor: AppColors.bgRedLightColor, +// borderColor: AppColors.bgRedLightColor, +// textColor: AppColors.primaryRedColor, +// iconColor: AppColors.primaryRedColor, +// padding: EdgeInsetsGeometry.symmetric(vertical: 0.h, horizontal: 10.h)), +// child: Padding( +// padding: EdgeInsets.all(24.w), +// child: SingleChildScrollView( +// child: Container( +// decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: false), +// child: Padding( +// padding: EdgeInsets.all(16.h), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Row( +// children: [ +// Utils.buildSvgWithAssets(icon: AppAssets.select_city_icon, width: 40.h, height: 40.h), +// SizedBox(width: 12.w), +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// LocaleKeys.city.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500), +// (appState.isArabic() +// ? (bloodDonationVM.selectedCity?.descriptionN ?? LocaleKeys.select.tr()) +// : bloodDonationVM.selectedCity?.description ?? LocaleKeys.select.tr(context: context)) +// .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), +// ], +// ), +// ], +// ), +// Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), +// ], +// ).onPress(() async { +// showCommonBottomSheetWithoutHeight(context, +// title: LocaleKeys.selectCity.tr(context: context), isDismissible: true, child: SelectCityWidget(bloodDonationViewModel: bloodDonationVM), callBackFunc: () {}); +// }), +// SizedBox(height: 16.h), +// Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), +// SizedBox(height: 16.h), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Row( +// children: [ +// Utils.buildSvgWithAssets(icon: AppAssets.genderInputIcon, width: 40.h, height: 40.h), +// SizedBox(width: 12.w), +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// LocaleKeys.gender.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500), +// (appState.isArabic() +// ? (bloodDonationVM.selectedGender?.typeAr ?? LocaleKeys.select.tr()) +// : bloodDonationVM.selectedGender?.type ?? LocaleKeys.select.tr(context: context)) +// .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), +// ], +// ), +// ], +// ), +// Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), +// ], +// ).onPress(() { +// showCommonBottomSheetWithoutHeight(context, +// title: LocaleKeys.selectGender.tr(context: context), +// isDismissible: true, +// child: SelectGenderWidget(isArabic: appState.isArabic(), bloodDonationViewModel: bloodDonationVM), +// callBackFunc: () {}); +// }), +// SizedBox(height: 16.h), +// Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), +// SizedBox(height: 16.h), +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Row( +// children: [ +// Utils.buildSvgWithAssets(icon: AppAssets.bloodType, width: 40.h, height: 40.h), +// SizedBox(width: 12.w), +// Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// LocaleKeys.bloodType.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500), +// // bloodDonationVM.selectedBloodType?.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), +// (appState.isArabic() +// ? (bloodDonationVM.selectedBloodType ?? LocaleKeys.select.tr()) +// : bloodDonationVM.selectedBloodType ?? LocaleKeys.select.tr(context: context)) +// .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500) +// ], +// ), +// ], +// ), +// Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h), +// ], +// ).onPress(() { +// showCommonBottomSheetWithoutHeight(context, +// title: LocaleKeys.select.tr(context: context), +// isDismissible: true, +// child: SelectBloodGroupWidget(isArabic: appState.isArabic(), bloodDonationViewModel: bloodDonationVM), +// callBackFunc: () {}); +// }), +// ], +// ), +// ), +// ), +// ), +// ), +// ), +// ), +// Container( +// decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), +// child: SizedBox( +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// ], +// ), +// ), +// ), +// ], +// ); +// }), +// ); +// } +// } + + +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/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/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'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; + +class MyChildVaccinePage extends StatefulWidget { + const MyChildVaccinePage({super.key}); + + @override + State createState() => _MyChildVaccinePageState(); +} + +class _MyChildVaccinePageState extends State { + int selectedChildIndex = 0; + + final List> children = [ + {"name": "Faris", "gender": "Son", "image": AppAssets.babyBoyImg}, + {"name": "Zaina", "gender": "Daughter", "image": AppAssets.babyGirlImg}, + {"name": "Ahmed", "gender": "Son", "image": AppAssets.babyBoyImg}, + ]; + + final List> vaccinesData = [ + { + "age": "4 months", + "dueDate": "19 Aug, 2025", + "vaccines": ["IPV", "DTap", "Hepatitis B", "HIB", "Pneumococcal Conjugate (PCV)", "Rota"] + }, + { + "age": "2 months", + "dueDate": "19 June, 2025", + "vaccines": ["IPV", "DTap", "Hepatitis B", "HIB", "Pneumococcal Conjugate (PCV)", "Rota"] + } + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: Column( + children: [ + Expanded( + child: CollapsingListView( + title: "Child Vaccines".needTranslation, + trailing: CustomButton( + icon: AppAssets.add_icon, + text: "Add Child", + onPressed: () {}, + backgroundColor: AppColors.bgRedLightColor, + borderColor: AppColors.bgRedLightColor, + textColor: AppColors.primaryRedColor, + iconColor: AppColors.primaryRedColor, + padding: EdgeInsets.symmetric(vertical: 0.h, horizontal: 10.w), + ), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 16.h), + _buildChildSelector(), + SizedBox(height: 24.h), + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.symmetric(horizontal: 24.w), + itemCount: vaccinesData.length, + separatorBuilder: (context, index) => SizedBox(height: 16.h), + itemBuilder: (context, index) { + return _buildVaccineCard(vaccinesData[index]); + }, + ), + SizedBox(height: 24.h), + ], + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildChildSelector() { + return SizedBox( + height: 50.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + padding: EdgeInsets.symmetric(horizontal: 24.w), + itemCount: children.length, + separatorBuilder: (context, index) => SizedBox(width: 12.w), + itemBuilder: (context, index) { + bool isSelected = selectedChildIndex == index; + return GestureDetector( + onTap: () => setState(() => selectedChildIndex = index), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), + decoration: BoxDecoration( + color: isSelected ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: isSelected ? AppColors.primaryRedColor : AppColors.borderOnlyColor.withValues(alpha: 0.1), + width: 1, + ), + ), + child: Row( + children: [ + Image.asset(children[index]['image'], width: 24.h, height: 24.h), + SizedBox(width: 8.w), + Text( + "${children[index]['name']} (${children[index]['gender']})", + style: TextStyle( + color: isSelected ? AppColors.primaryRedColor : AppColors.textColor, + fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500, + fontSize: 14.f, + ), + ), + ], + ), + ), + ); + }, + ), + ); + } + + Widget _buildVaccineCard(Map data) { + return Container( + padding: EdgeInsets.all(20.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + data['age'].toString().toText18(weight: FontWeight.bold, color: AppColors.textColor), + SizedBox(height: 12.h), + Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h), + decoration: BoxDecoration( + color: AppColors.bgScaffoldColor, + borderRadius: BorderRadius.circular(8.r), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.calendar, width: 16.h, height: 16.h, iconColor: AppColors.textColor), + SizedBox(width: 8.w), + "Due Date : ${data['dueDate']}".toText12(fontWeight: FontWeight.w500, color: AppColors.textColor), + ], + ), + ), + SizedBox(height: 16.h), + ... (data['vaccines'] as List).map((vaccine) => Padding( + padding: EdgeInsets.only(bottom: 12.h), + child: Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.tickIcon, width: 20.h, height: 20.h, iconColor: Colors.green), + SizedBox(width: 12.w), + vaccine.toString().toText14(weight: FontWeight.w500, color: AppColors.textColor), + ], + ), + )), + SizedBox(height: 8.h), + CustomButton( + text: "Send via email", + onPressed: () {}, + backgroundColor: AppColors.bgRedLightColor, + borderColor: Colors.transparent, + textColor: AppColors.primaryRedColor, + icon: AppAssets.email, + iconColor: AppColors.primaryRedColor, + width: double.infinity, + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 80e0f9b..bf4ef3e 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -147,72 +147,66 @@ class ServicesPage extends StatelessWidget { } }), HmgServicesComponentModel( - 3, - LocaleKeys.bloodDonation.tr(), - "", - AppAssets.blood_donation_icon, - bgColor: AppColors.bloodDonationCardColor, - true, - route: null, onTap: () async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.pleaseWait.tr()); - await bloodDonationViewModel.getRegionSelectedClinics(onSuccess: (val) async { - // await bloodDonationViewModel.getPatientBloodGroupDetails(onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - Navigator.of(GetIt.instance().navigatorKey.currentContext!).push( - CustomPageRoute( - page: BloodDonationPage(), - ), - ); - // }, onError: (err) { - // LoaderBottomSheet.hideLoader(); - // }); - }, onError: (err) { - LoaderBottomSheet.hideLoader(); - }); - }), - // HmgServicesComponentModel( - // 11, - // "Covid 19 Test".needTranslation, - // "".needTranslation, - // AppAssets.covid19icon, - // bgColor: AppColors.covid29Color, - // true, - // route: AppRoutes.covid19Test, - // ), + 3, + "Blood Donation".needTranslation, + "".needTranslation, + AppAssets.blood_donation_icon, + bgColor: AppColors.bloodDonationCardColor, + true, + route: AppRoutes.bloodDonationPage, + ), + HmgServicesComponentModel( + 3, + "My Child Vaccine".needTranslation, + "".needTranslation, + AppAssets.my_child_vaccine_icon, + bgColor: AppColors.myChildVaccineCardColor, + true, + route: AppRoutes.myChildVaccine, + ), +// HmgServicesComponentModel( +// 11, +// "Covid 19 Test".needTranslation, +// "".needTranslation, +// AppAssets.covid19icon, +// bgColor: AppColors.covid29Color, +// true, +// route: AppRoutes.covid19Test, +// ), - // HmgServicesComponentModel( - // 11, - // "Vital Sign".needTranslation, - // "".needTranslation, - // AppAssets.covid19icon, - // bgColor: AppColors.covid29Color, - // true, - // route: AppRoutes.vitalSign, - // ) +// HmgServicesComponentModel( +// 11, +// "Vital Sign".needTranslation, +// "".needTranslation, +// AppAssets.covid19icon, +// bgColor: AppColors.covid29Color, +// true, +// route: AppRoutes.vitalSign, +// ) - // HmgServicesComponentModel( - // 3, - // "Home Health Care".needTranslation, - // "".needTranslation, - // AppAssets.homeBottom, - // bgColor: AppColors.primaryRedColor, - // true, - // route: AppRoutes.homeHealthCarePage, - // ), - // HmgServicesComponentModel( - // 11, - // "Virtual Tour".needTranslation, - // "".needTranslation, - // AppAssets.my_address, - // bgColor: AppColors.quickLoginColor, - // true, - // route: null, - // onTap:(){ - // Utils.openWebView( - // url: 'https://hmgwebservices.com/vt_mobile/html/index.html', - // ); - // }, - // ) +// HmgServicesComponentModel( +// 3, +// "Home Health Care".needTranslation, +// "".needTranslation, +// AppAssets.homeBottom, +// bgColor: AppColors.primaryRedColor, +// true, +// route: AppRoutes.homeHealthCarePage, +// ), +// HmgServicesComponentModel( +// 11, +// "Virtual Tour".needTranslation, +// "".needTranslation, +// AppAssets.my_address, +// bgColor: AppColors.quickLoginColor, +// true, +// route: null, +// onTap:(){ +// Utils.openWebView( +// url: 'https://hmgwebservices.com/vt_mobile/html/index.html', +// ); +// }, +// ) ]; late final List hmgHealthToolServices = [ diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 8cc2103..88dfb13 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -13,6 +13,7 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/int_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/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/medical_file/medical_file_view_model.dart'; @@ -84,7 +85,9 @@ class ProfileSettingsState extends State { Widget build(BuildContext context) { return CollapsingListView( title: LocaleKeys.profileAndSettings.tr(context: context), - logout: () {}, + logout: () { + context.read().logout(); + }, isClose: true, child: SingleChildScrollView( padding: EdgeInsets.only(top: 24.h, bottom: 24.h), @@ -183,8 +186,7 @@ class ProfileSettingsState extends State { ), ], ), - LocaleKeys.quickActions.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) - .paddingOnly(left: 24.w, right: 24.w), + LocaleKeys.quickActions.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h), @@ -279,8 +281,7 @@ class ProfileSettingsState extends State { children: [ Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.greyTextColor), label.toText14(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).expanded, - if (trailingLabel.isNotEmpty) - trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1), + if (trailingLabel.isNotEmpty) trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1), switchValue != null ? Switch( value: switchValue, diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 018af1c..702b37e 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -5,6 +5,7 @@ import 'package:hmg_patient_app_new/presentation/authentication/register.dart'; import 'package:hmg_patient_app_new/presentation/authentication/register_step2.dart'; import 'package:hmg_patient_app_new/presentation/blood_donation/blood_donation_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; +import 'package:hmg_patient_app_new/presentation/child_vaccine/my_child_vaccine_page.dart'; import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/comprehensive_checkup_page.dart'; import 'package:hmg_patient_app_new/presentation/covid19test/covid19_landing_page.dart'; import 'package:hmg_patient_app_new/presentation/e_referral/new_e_referral.dart'; @@ -54,6 +55,7 @@ class AppRoutes { static const String homeHealthCarePage = '/homeHealthCarePage'; static const String zoomCallPage = '/zoomCallPage'; static const String bloodDonationPage = '/bloodDonationPage'; + static const String myChildVaccine = '/myChildVaccine'; static const String smartWatches = '/smartWatches'; static const String huaweiHealthExample = '/huaweiHealthExample'; static const String covid19Test = '/covid19Test'; @@ -104,6 +106,7 @@ class AppRoutes { possibleConditionsPage: (context) => PossibleConditionsPage(), triagePage: (context) => TriagePage(), bloodDonationPage: (context) => BloodDonationPage(), + myChildVaccine: (context) => MyChildVaccinePage(), bookAppointmentPage: (context) => BookAppointmentPage(), userInfoSelection: (context) => UserInfoSelectionPage(), userInfoFlowManager: (context) => UserInfoFlowManager(), diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index 79cc3a9..b8d480e 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -2,6 +2,7 @@ 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/route_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; @@ -23,6 +24,9 @@ abstract class DialogService { Future showCommonBottomSheetWithoutH({String? label, required String message, required Function() onOkPressed, Function()? onCancelPressed}); + + Future showSuccessBottomSheetWithoutH({String? label, required String message, required Function() onOkPressed, Function()? onCancelPressed}); + Future showFamilyBottomSheetWithoutH( {String? label, required String message, @@ -122,6 +126,20 @@ class DialogServiceImp implements DialogService { ); } + + @override + Future showSuccessBottomSheetWithoutH( + {String? label, required String message, required Function() onOkPressed, Function()? onCancelPressed}) async { + final context = navigationService.navigatorKey.currentContext; + if (context == null) return; + showCommonBottomSheetWithoutHeight( + context, + title: label ?? "", + child: Utils.getSuccessWidget(loadingText: message.needTranslation), + callBackFunc: () {}, + ); + } + @override Future showFamilyBottomSheetWithoutH( {String? label, @@ -256,6 +274,8 @@ Widget exceptionBottomSheetWidget( ); } + + Widget showPhoneNumberPickerWidget( {required BuildContext context, String? message, required Function() onSMSPress, required Function() onWhatsappPress}) { return StatefulBuilder(builder: (BuildContext context, StateSetter setModalState) { diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index ee48c60..d56178b 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -99,6 +99,7 @@ class AppColors { // Services Page Colors static const Color eReferralCardColor = Color(0xFFFF8012); // #FF8012 static const Color bloodDonationCardColor = Color(0xFFFF5662); // #FF5662 + static const Color myChildVaccineCardColor = Color(0xFFFF2D78); // #FF5662 static const Color bookAppointment = Color(0xFF415364); // #415364 // Water Monitor