From 3185d1e9e7ea22e17c17521e706a7518c9ea232f Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 7 Dec 2025 16:25:52 +0300 Subject: [PATCH] Allergies list implemented --- .../authentication/authentication_repo.dart | 8 +- .../get_allergies_response_model.dart | 37 +++++ .../medical_file/medical_file_repo.dart | 41 ++++++ .../medical_file/medical_file_view_model.dart | 32 ++++ .../allergies/allergies_list_page.dart | 138 ++++++++++++++++++ .../medical_file/medical_file_page.dart | 10 +- 6 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 lib/features/book_appointments/models/resp_models/get_allergies_response_model.dart create mode 100644 lib/presentation/allergies/allergies_list_page.dart diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 6ecf4b1..3194ad7 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -266,10 +266,10 @@ class AuthenticationRepoImp implements AuthenticationRepo { newRequest.forRegisteration = newRequest.isRegister ?? false; newRequest.isRegister = false; //silent login case removed token and login token - if(newRequest.logInTokenID.isEmpty && newRequest.isSilentLogin == true) { - newRequest.logInTokenID = null; - newRequest.deviceToken = null; - } + // if(newRequest.logInTokenID.isEmpty && newRequest.isSilentLogin == true) { + // newRequest.logInTokenID = null; + // newRequest.deviceToken = null; + // } } diff --git a/lib/features/book_appointments/models/resp_models/get_allergies_response_model.dart b/lib/features/book_appointments/models/resp_models/get_allergies_response_model.dart new file mode 100644 index 0000000..cd4802f --- /dev/null +++ b/lib/features/book_appointments/models/resp_models/get_allergies_response_model.dart @@ -0,0 +1,37 @@ +class GetAllergiesResponseModel { + int? patientID; + int? allergyDiseaseType; + int? allergyDiseaseID; + String? description; + String? descriptionN; + String? remarks; + + GetAllergiesResponseModel({ + this.patientID, + this.allergyDiseaseType, + this.allergyDiseaseID, + this.description, + this.descriptionN, + this.remarks, + }); + + GetAllergiesResponseModel.fromJson(Map json) { + patientID = json['PatientID']; + allergyDiseaseType = json['AllergyDiseaseType']; + allergyDiseaseID = json['AllergyDiseaseID']; + description = json['Description']; + descriptionN = json['DescriptionN']; + remarks = json['Remarks']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientID'] = this.patientID; + data['AllergyDiseaseType'] = this.allergyDiseaseType; + data['AllergyDiseaseID'] = this.allergyDiseaseID; + data['Description'] = this.description; + data['DescriptionN'] = this.descriptionN; + data['Remarks'] = this.remarks; + return data; + } +} diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart index ab09ca6..bf10e9e 100644 --- a/lib/features/medical_file/medical_file_repo.dart +++ b/lib/features/medical_file/medical_file_repo.dart @@ -5,6 +5,7 @@ import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_allergies_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart'; @@ -38,6 +39,8 @@ abstract class MedicalFileRepo { Future>> removeFamilyFile({required int? id}); Future>> acceptRejectFamilyFile({required int? id, required int? status}); + + Future>>> getPatientAllergiesList({Function(dynamic)? onSuccess, Function(String)? onError}); } class MedicalFileRepoImp implements MedicalFileRepo { @@ -549,4 +552,42 @@ class MedicalFileRepoImp implements MedicalFileRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>>> getPatientAllergiesList({Function(dynamic)? onSuccess, Function(String)? onError}) async { + Map mapDevice = {"isDentalAllowedBackend": false, "OutSA": 0}; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + GET_PATIENT_ALLERGIES, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final list = response['Patient_Allergies']; + + final vaccinesList = list.map((item) => GetAllergiesResponseModel.fromJson(item as Map)).toList().cast(); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: vaccinesList, + ); + } 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/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index 4b5a14c..9ccc735 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -9,6 +9,7 @@ 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'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; +import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_allergies_response_model.dart'; import 'package:hmg_patient_app_new/features/common/models/family_file_request.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; @@ -27,6 +28,7 @@ class MedicalFileViewModel extends ChangeNotifier { bool isPatientSickLeaveListLoading = false; bool isPatientSickLeavePDFLoading = false; bool isPatientMedicalReportsListLoading = false; + bool isPatientAllergiesListLoading = false; MedicalFileRepo medicalFileRepo; ErrorHandlerService errorHandlerService; @@ -34,6 +36,8 @@ class MedicalFileViewModel extends ChangeNotifier { List patientVaccineList = []; List patientSickLeaveList = []; + List patientAllergiesList = []; + List patientMedicalReportList = []; List patientMedicalReportRequestedList = []; @@ -69,8 +73,10 @@ class MedicalFileViewModel extends ChangeNotifier { initMedicalFileProvider() { patientMedicalReportAppointmentHistoryList.clear(); + patientAllergiesList.clear(); isPatientVaccineListLoading = true; isPatientMedicalReportsListLoading = true; + isPatientAllergiesListLoading = true; notifyListeners(); } @@ -162,6 +168,32 @@ class MedicalFileViewModel extends ChangeNotifier { ); } + Future getPatientAllergiesList({Function(dynamic)? onSuccess, Function(String)? onError}) async { + isPatientAllergiesListLoading = true; + patientAllergiesList.clear(); + notifyListeners(); + final result = await medicalFileRepo.getPatientAllergiesList(); + + result.fold( + (failure) async { + isPatientAllergiesListLoading = false; + notifyListeners(); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + patientAllergiesList = apiResponse.data!; + isPatientAllergiesListLoading = false; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + Future getPatientSickLeaveList({Function(dynamic)? onSuccess, Function(String)? onError}) async { patientSickLeaveList.clear(); final result = await medicalFileRepo.getPatientSickLeavesList(); diff --git a/lib/presentation/allergies/allergies_list_page.dart b/lib/presentation/allergies/allergies_list_page.dart new file mode 100644 index 0000000..efcdd0a --- /dev/null +++ b/lib/presentation/allergies/allergies_list_page.dart @@ -0,0 +1,138 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:hmg_patient_app_new/core/app_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/medical_file/medical_file_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:provider/provider.dart'; + +class AllergiesListPage extends StatelessWidget { + AllergiesListPage({super.key}); + + late MedicalFileViewModel medicalFileViewModel; + + @override + Widget build(BuildContext context) { + medicalFileViewModel = Provider.of(context, listen: false); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.allergies.tr(), + child: SingleChildScrollView( + child: Consumer(builder: (context, medicalFileVM, child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 16.h), + ListView.separated( + scrollDirection: Axis.vertical, + itemCount: medicalFileVM.isPatientAllergiesListLoading + ? 5 + : medicalFileVM.patientAllergiesList.isNotEmpty + ? medicalFileVM.patientAllergiesList.length + : 1, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(left: 24.h, right: 24.h), + itemBuilder: (context, index) { + return medicalFileVM.isPatientAllergiesListLoading + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.allergy_info_icon, width: 36.w, height: 36.h, fit: BoxFit.contain).toShimmer2(isShow: true), + SizedBox(width: 16.h), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Dr John Smith".toText16(isBold: true).toShimmer2(isShow: true), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: 4.h, + children: [ + // AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), + // AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), + ], + ), + ], + ), + ), + ], + ), + ], + ), + ), + ) + : medicalFileVM.patientAllergiesList.isNotEmpty + ? AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.allergy_info_icon, width: 36.w, height: 36.h, fit: BoxFit.contain), + SizedBox(height: 16.h), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (medicalFileVM.patientAllergiesList[index].description).toString().toText16(isBold: true).toShimmer2(isShow: false), + (medicalFileVM.patientAllergiesList[index].remarks).toString().toText12(), + ], + ), + ), + ], + ), + ], + ), + ), + ), + ), + ), + ) + : Utils.getNoDataWidget(context, noDataText: "No allergies data found...".needTranslation); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ), + SizedBox(height: 60.h), + ], + ); + }), + ), + ), + ); + } +} diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 7b5341c..a21e848 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -24,6 +24,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/allergies/allergies_list_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; @@ -801,7 +802,14 @@ class _MedicalFilePageState extends State { svgIcon: AppAssets.allergy_info_icon, isLargeText: true, iconSize: 36.w, - ), + ).onPress(() { + medicalFileViewModel.getPatientAllergiesList(); + Navigator.of(context).push( + CustomPageRoute( + page: AllergiesListPage(), + ), + ); + }), MedicalFileCard( label: "Vaccine Info".needTranslation, textColor: AppColors.blackColor,