From 093e645f6009184af50315aec3259fa03f1a9264 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 30 Sep 2025 11:57:37 +0300 Subject: [PATCH] request medical report implementation completed. --- lib/core/api/api_client.dart | 2 +- lib/core/api_consts.dart | 2 +- .../medical_file/medical_file_repo.dart | 55 ++++++- .../medical_file/medical_file_view_model.dart | 23 ++- .../widgets/appointment_card.dart | 8 +- .../medical_file/medical_file_page.dart | 134 +++++++++++------- .../widgets/medical_file_card.dart | 4 +- .../widgets/patient_sick_leave_card.dart | 8 +- .../medical_report_request_page.dart | 1 + .../medical_report/medical_reports_page.dart | 110 +++++++++++--- lib/theme/colors.dart | 2 +- lib/widgets/buttons/custom_button.dart | 2 +- lib/widgets/chip/app_custom_chip_widget.dart | 4 +- lib/widgets/input_widget.dart | 4 +- 14 files changed, 263 insertions(+), 96 deletions(-) diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 29b41fd..5d4da2b 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -177,7 +177,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 1018977; + // body['PatientID'] = 4770714; } body.removeWhere((key, value) => value == null); diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index fa02b2e..1c6cec1 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -119,7 +119,7 @@ var GET_STATUS_FOR_COCO = 'Services/COCWS.svc/REST/GetStatusforCOC'; // var GET_PATIENT_AppointmentHistory = 'Services' // '/Doctors.svc/REST/PateintHasAppoimentHistory'; -var GET_PATIENT_AppointmentHistory = 'Services' +var GET_PATIENT_APPOINTMENT_HISTORY_ASYNC = 'Services' '/Doctors.svc/REST/PateintHasAppoimentHistory_Async'; ///VITAL SIGN diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart index 658d045..7077fd0 100644 --- a/lib/features/medical_file/medical_file_repo.dart +++ b/lib/features/medical_file/medical_file_repo.dart @@ -30,6 +30,8 @@ abstract class MedicalFileRepo { Future>>> addFamilyFile({required dynamic request}); Future>>> getPatientAppointmentsForMedicalReport(); + + Future>> insertRequestForMedicalReport({required PatientAppointmentHistoryResponseModel appointmentHistoryResponseModel}); } class MedicalFileRepoImp implements MedicalFileRepo { @@ -366,7 +368,7 @@ class MedicalFileRepoImp implements MedicalFileRepo { GenericApiModel>? apiResponse; Failure? failure; await apiClient.post( - GET_PATIENT_APPOINTMENT_HISTORY, + GET_PATIENT_APPOINTMENT_HISTORY_ASYNC, body: mapDevice, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; @@ -374,9 +376,6 @@ class MedicalFileRepoImp implements MedicalFileRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { final list = response['AppoimentAllHistoryResultList']; - // if (list == null || list.isEmpty) { - // throw Exception("Appointments list is empty"); - // } final appointmentsList = list.map((item) => PatientAppointmentHistoryResponseModel.fromJson(item as Map)).toList().cast(); @@ -398,4 +397,52 @@ class MedicalFileRepoImp implements MedicalFileRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future>> insertRequestForMedicalReport({required PatientAppointmentHistoryResponseModel appointmentHistoryResponseModel}) async { + Map mapDevice = { + "ClinicID": appointmentHistoryResponseModel.clinicID, + "DoctorID": appointmentHistoryResponseModel.doctorID, + "SetupID": appointmentHistoryResponseModel.setupID, + "EncounterNo": appointmentHistoryResponseModel.appointmentNo, + "EncounterType": 1, + "IsActive": appointmentHistoryResponseModel.isActiveDoctor, + "ProjectID": appointmentHistoryResponseModel.projectID, + "Remarks": "", + "ProcedureId": "", + "RequestType": 1, + "Source": 2, + "Status": 1, + "CreatedBy": 102 + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + INSERT_REQUEST_FOR_MEDICAL_REPORT, + body: mapDevice, + 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/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index 061392e..95c5d63 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -1,7 +1,6 @@ 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/utils/request_utils.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.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'; @@ -54,6 +53,7 @@ class MedicalFileViewModel extends ChangeNotifier { void onMedicalReportTabChange(int index) { selectedMedicalReportsTabIndex = index; + print("Selected Medical Report Tab Index: $selectedMedicalReportsTabIndex"); if (index == 0) { patientMedicalReportList = patientMedicalReportRequestedList; } else if (index == 1) { @@ -85,6 +85,7 @@ class MedicalFileViewModel extends ChangeNotifier { setIsPatientMedicalReportsLoading(bool val) { if (val) { + onMedicalReportTabChange(0); patientMedicalReportList.clear(); patientMedicalReportPDFBase64 = ""; } @@ -327,6 +328,26 @@ class MedicalFileViewModel extends ChangeNotifier { ); } + Future insertRequestForMedicalReport({Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await medicalFileRepo.insertRequestForMedicalReport(appointmentHistoryResponseModel: patientMedicalReportSelectedAppointment!); + + result.fold( + (failure) async { + onError!(failure.message); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + Future addFamilyFile() async { final resultEither = await medicalFileRepo.addFamilyFile(request: {}); resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) async {}); diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index d287795..6d157a5 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -167,9 +167,11 @@ class _AppointmentCardState extends State { labelText: widget.isLoading ? "Cardiology" : DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)) .toShimmer2(isShow: widget.isLoading), - AppCustomChipWidget( - icon: AppAssets.appointment_time_icon, - labelText: widget.isLoading + widget.isFromMedicalReport + ? SizedBox.shrink() + : AppCustomChipWidget( + icon: AppAssets.appointment_time_icon, + labelText: widget.isLoading ? "Cardiology" : DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)) .toShimmer2(isShow: widget.isLoading), diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 2a9fcfe..7fd9138 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -38,8 +38,6 @@ import 'package:hmg_patient_app_new/presentation/medical_file/vaccine_list_page. import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.dart'; -import 'package:hmg_patient_app_new/presentation/my_family/my_Family.dart'; -import 'package:hmg_patient_app_new/presentation/my_family/widget/my_family_sheet.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -51,7 +49,6 @@ import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; import '../prescriptions/prescription_detail_page.dart'; @@ -502,7 +499,14 @@ class _MedicalFilePageState extends State { ), ), ).paddingSymmetrical(24.h, 0.h) - : Utils.getNoDataWidget(context, noDataText: "You don't have any prescriptions yet.".needTranslation, isSmallWidget: true, width: 62, height: 62).paddingSymmetrical(24.h, 0.h); + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Utils.getNoDataWidget(context, noDataText: "You don't have any prescriptions yet.".needTranslation, isSmallWidget: true, width: 62, height: 62)) + .paddingSymmetrical(24.h, 0.h); }), SizedBox(height: 24.h), //My Doctor Section @@ -551,7 +555,7 @@ class _MedicalFilePageState extends State { "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 64.h, height: 64.h, - fit: BoxFit.fill, + fit: BoxFit.cover, ).circle(100).toShimmer2(isShow: true, radius: 50.h), SizedBox(height: 8.h), Expanded( @@ -591,8 +595,14 @@ class _MedicalFilePageState extends State { ), ), ) - : Utils.getNoDataWidget(context, noDataText: "You don't have any completed visits yet.".needTranslation, isSmallWidget: true, width: 62, height: 62) - .paddingSymmetrical(24.h, 0.h); + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Utils.getNoDataWidget(context, noDataText: "You don't have any completed visits yet.".needTranslation, isSmallWidget: true, width: 62, height: 62), + ).paddingSymmetrical(24.h, 0.h); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h), ), @@ -602,7 +612,12 @@ class _MedicalFilePageState extends State { "Others".needTranslation.toText18(isBold: true).paddingSymmetrical(24.h, 0.h), SizedBox(height: 16.h), GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 13), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 16, + mainAxisSpacing: 16, + mainAxisExtent: 130, + ), physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, shrinkWrap: true, @@ -613,15 +628,15 @@ class _MedicalFilePageState extends State { backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon, isLargeText: true, - iconSize: 40.h, + iconSize: 36.h, ), MedicalFileCard( - label: "Allergy Info".needTranslation, + label: "Allergy Info".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.allergy_info_icon, isLargeText: true, - iconSize: 40.h, + iconSize: 36.h, ), MedicalFileCard( label: "Vaccine Info".needTranslation, @@ -629,7 +644,7 @@ class _MedicalFilePageState extends State { backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.vaccine_info_icon, isLargeText: true, - iconSize: 40.h, + iconSize: 36.h, ).onPress(() { Navigator.of(context).push( CustomPageRoute( @@ -661,37 +676,49 @@ class _MedicalFilePageState extends State { DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo), ), ) - : Utils.getNoDataWidget( - context, - noDataText: "You don't have insurance registered with HMG.".needTranslation, - isSmallWidget: true, - width: 62, - height: 62, - callToActionButton: CustomButton( - icon: AppAssets.update_insurance_card_icon, - iconColor: AppColors.successColor, - iconSize: 15.h, - text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", - onPressed: () { - insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); - insuranceViewModel.getPatientInsuranceDetailsForUpdate( - appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); - showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); - }, - backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - borderColor: AppColors.bgGreenColor.withOpacity(0.0), - textColor: AppColors.bgGreenColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ).paddingSymmetrical(64.h, 0.h), - ); + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Utils.getNoDataWidget( + context, + noDataText: "You don't have insurance registered with HMG.".needTranslation, + isSmallWidget: true, + width: 62, + height: 62, + callToActionButton: CustomButton( + icon: AppAssets.update_insurance_card_icon, + iconColor: AppColors.successColor, + iconSize: 15.h, + text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", + onPressed: () { + insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); + insuranceViewModel.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + }, + backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), + borderColor: AppColors.bgGreenColor.withOpacity(0.0), + textColor: AppColors.bgGreenColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ).paddingOnly(left: 12.h, right: 12.h, bottom: 12.h), + ), + ).paddingSymmetrical(24.h, 0.h); }), SizedBox(height: 10.h), GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 13), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 16, + mainAxisSpacing: 16, + mainAxisExtent: 140, + ), physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.only(top: 12), shrinkWrap: true, @@ -701,7 +728,7 @@ class _MedicalFilePageState extends State { textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon, - isLargeText: false, + isLargeText: true, iconSize: 36.h) .onPress(() { Navigator.of(context).push( @@ -715,21 +742,21 @@ class _MedicalFilePageState extends State { textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon, - isLargeText: false, + isLargeText: true, iconSize: 36.h), MedicalFileCard( label: "My Invoices List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon, - isLargeText: false, + isLargeText: true, iconSize: 36.h), MedicalFileCard( label: "Ancillary Orders List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon, - isLargeText: false, + isLargeText: true, iconSize: 36.h), ], ).paddingSymmetrical(24.h, 0.0), @@ -761,7 +788,12 @@ class _MedicalFilePageState extends State { }), SizedBox(height: 16.h), GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 6.5, mainAxisSpacing: 6.5), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 16, + mainAxisSpacing: 16, + mainAxisExtent: 140, + ), physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, shrinkWrap: true, @@ -771,16 +803,16 @@ class _MedicalFilePageState extends State { textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon, - isLargeText: false, - iconSize: 40.h, + isLargeText: true, + iconSize: 36.h, ), MedicalFileCard( label: "Medical Reports".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.allergy_info_icon, - isLargeText: false, - iconSize: 40.h, + isLargeText: true, + iconSize: 36.h, ).onPress(() { medicalFileViewModel.setIsPatientMedicalReportsLoading(true); medicalFileViewModel.getPatientMedicalReportList(); @@ -795,8 +827,8 @@ class _MedicalFilePageState extends State { textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.vaccine_info_icon, - isLargeText: false, - iconSize: 40.h, + isLargeText: true, + iconSize: 36.h, ).onPress(() { Navigator.of(context).push( CustomPageRoute( diff --git a/lib/presentation/medical_file/widgets/medical_file_card.dart b/lib/presentation/medical_file/widgets/medical_file_card.dart index c4980d9..e8cff72 100644 --- a/lib/presentation/medical_file/widgets/medical_file_card.dart +++ b/lib/presentation/medical_file/widgets/medical_file_card.dart @@ -29,14 +29,14 @@ class MedicalFileCard extends StatelessWidget { borderRadius: 20, ), child: Padding( - padding: EdgeInsets.all(8.h), + padding: EdgeInsets.all(12.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Utils.buildSvgWithAssets(icon: svgIcon, width: iconSize.h, height: iconSize.h, fit: BoxFit.contain), SizedBox(height: 12.h), - isLargeText ? label.toText14(color: textColor, isBold: true, maxlines: 1) : label.toText11(color: textColor, isBold: true, maxLine: 2), + isLargeText ? label.toText13(color: textColor, isBold: true, maxLine: 2) : label.toText11(color: textColor, isBold: true, maxLine: 2), ], ), ), diff --git a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart index 5cd2547..fed7d15 100644 --- a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart +++ b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart @@ -59,7 +59,7 @@ class PatientSickLeaveCard extends StatelessWidget { isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : patientSickLeavesResponseModel.doctorImageURL!, width: 30.h, height: 30.h, - fit: BoxFit.fill, + fit: BoxFit.cover, ).circle(100).toShimmer2(isShow: isLoading), SizedBox(width: 16.h), Expanded( @@ -182,11 +182,11 @@ class PatientSickLeaveCard extends StatelessWidget { Color getStatusColor() { Color statusColor = Colors.white; if (patientSickLeavesResponseModel.status == 1) { - statusColor = Color(0xffCC9B14); + statusColor = Color(0xffCC9B14); // TODO change color as per In Queue design } else if (patientSickLeavesResponseModel.status == 2) { - statusColor = Color(0xff359846); + statusColor = AppColors.successColor; } else if (patientSickLeavesResponseModel.status == 3) { - statusColor = Color(0xffD02127); + statusColor = AppColors.primaryRedColor; } else { statusColor = Colors.white; } diff --git a/lib/presentation/medical_report/medical_report_request_page.dart b/lib/presentation/medical_report/medical_report_request_page.dart index 8f891e2..9d1bcb1 100644 --- a/lib/presentation/medical_report/medical_report_request_page.dart +++ b/lib/presentation/medical_report/medical_report_request_page.dart @@ -54,6 +54,7 @@ class MedicalReportRequestPage extends StatelessWidget { }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), ), + SizedBox(height: 24.h), ], ), ); diff --git a/lib/presentation/medical_report/medical_reports_page.dart b/lib/presentation/medical_report/medical_reports_page.dart index c08c750..71abcb7 100644 --- a/lib/presentation/medical_report/medical_reports_page.dart +++ b/lib/presentation/medical_report/medical_reports_page.dart @@ -41,23 +41,71 @@ class _MedicalReportsPageState extends State { child: CollapsingListView( title: "Medical Reports".needTranslation, child: SingleChildScrollView( - child: Column( - children: [ - SizedBox(height: 16.h), - CustomTabBar( - activeTextColor: Color(0xffED1C2B), - activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), - tabs: [ - CustomTabBarModel(null, "Requested".needTranslation), - CustomTabBarModel(null, "Ready".needTranslation), - CustomTabBarModel(null, "Cancelled".needTranslation), - ], - onTabChange: (index) { - medicalFileViewModel.onMedicalReportTabChange(index); - }, - ).paddingSymmetrical(24.h, 0.h), - Consumer(builder: (context, medicalFileVM, child) { - return ListView.separated( + child: Consumer(builder: (context, medicalFileVM, child) { + return Column( + children: [ + SizedBox(height: 16.h), + Row( + children: [ + CustomButton( + text: "Requested".needTranslation, + onPressed: () { + medicalFileViewModel.onMedicalReportTabChange(0); + }, + backgroundColor: medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + textColor: medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.ready.tr(context: context), + onPressed: () { + medicalFileViewModel.onMedicalReportTabChange(1); + }, + backgroundColor: medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + textColor: medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.cancelled.tr(context: context), + onPressed: () { + medicalFileViewModel.onMedicalReportTabChange(2); + }, + backgroundColor: medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + textColor: medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ).paddingSymmetrical(24.h, 0.h), + // CustomTabBar( + // activeTextColor: Color(0xffED1C2B), + // activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), + // tabs: [ + // CustomTabBarModel(null, "Requested".needTranslation), + // CustomTabBarModel(null, "Ready".needTranslation), + // CustomTabBarModel(null, "Cancelled".needTranslation), + // ], + // onTabChange: (index) { + // medicalFileViewModel.onMedicalReportTabChange(index); + // }, + // ).paddingSymmetrical(24.h, 0.h), + ListView.separated( padding: EdgeInsets.only(top: 24.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), @@ -93,14 +141,14 @@ class _MedicalReportsPageState extends State { ), ), ) - : Utils.getNoDataWidget(context, noDataText: "You don't have any medical reports yet.".needTranslation).paddingSymmetrical(24.h, 0.h); + : Utils.getNoDataWidget(context, noDataText: "You don't have any medical reports yet.".needTranslation).paddingSymmetrical(24.h, 24.h); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ); - }), - SizedBox(height: 24.h), - ], - ), + ), + SizedBox(height: 24.h), + ], + ); + }), ), ), ), @@ -167,6 +215,22 @@ class _MedicalReportsPageState extends State { }, onConfirmTap: () async { Navigator.pop(context); + LoaderBottomSheet.showLoader(); + await medicalFileViewModel.insertRequestForMedicalReport(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, child: Utils.getSuccessWidget(loadingText: "Your medical report request has been successfully submitted.".needTranslation), callBackFunc: () { + medicalFileViewModel.setIsPatientMedicalReportsLoading(true); + medicalFileViewModel.onMedicalReportTabChange(0); + medicalFileViewModel.getPatientMedicalReportList(); + }); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, child: Utils.getErrorWidget(loadingText: err), callBackFunc: () { + medicalFileViewModel.setIsPatientMedicalReportsLoading(true); + medicalFileViewModel.onMedicalReportTabChange(0); + medicalFileViewModel.getPatientMedicalReportList(); + }); + }); }), callBackFunc: () {}, isFullScreen: false, diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 4015249..291f81d 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -32,7 +32,7 @@ class AppColors { static const Color textColorLight = Color(0xFF5E5E5E); static const Color borderOnlyColor = Color(0xFF2E3039); static const Color chipBorderColorOpacity20 = Color(0x332E3039); - static const Color dividerColor = Color(0xFFD2D2D2); + static const Color dividerColor = Color(0x40D2D2D2); static const Color warningColorYellow = Color(0xFFF4A308); static const Color blackBgColor = Color(0xFF2E3039); static const blackColor = textColor; diff --git a/lib/widgets/buttons/custom_button.dart b/lib/widgets/buttons/custom_button.dart index 2f8a9ec..a4bec4c 100644 --- a/lib/widgets/buttons/custom_button.dart +++ b/lib/widgets/buttons/custom_button.dart @@ -78,7 +78,7 @@ class CustomButton extends StatelessWidget { style: context.dynamicTextStyle( fontSize: fontSize.fSize, color: isDisabled ? textColor.withOpacity(0.5) : textColor, - letterSpacing: -0.4, + letterSpacing: 0, fontWeight: fontWeight, ), ), diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart index a4db172..16db798 100644 --- a/lib/widgets/chip/app_custom_chip_widget.dart +++ b/lib/widgets/chip/app_custom_chip_widget.dart @@ -58,7 +58,7 @@ class AppCustomChipWidget extends StatelessWidget { child: icon.isNotEmpty ? Chip( avatar: icon.isNotEmpty ? Utils.buildSvgWithAssets(icon: icon, width: iconSize.h, height: iconSize.h, iconColor: iconHasColor ? iconColor : null) : SizedBox.shrink(), - label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: -0.64, color: textColor), + label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor), // padding: EdgeInsets.all(0.0), padding: padding, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, @@ -77,7 +77,7 @@ class AppCustomChipWidget extends StatelessWidget { ) : Chip( materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: -0.64, color: textColor), + label: richText ?? labelText!.toText10(weight: FontWeight.w500, letterSpacing: 0, color: textColor), padding: EdgeInsets.all(0.0), backgroundColor: backgroundColor, shape: shape ?? SmoothRectangleBorder( diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 4a2322c..38e5829 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -217,7 +217,7 @@ class TextInputWidget extends StatelessWidget { fontSize: 12.fSize, fontWeight: FontWeight.w500, color: labelColor ?? AppColors.inputLabelTextColor, - letterSpacing: -0.2, + letterSpacing: -0, height: 18 / 12, ), ); @@ -246,7 +246,7 @@ class TextInputWidget extends StatelessWidget { decoration: InputDecoration( isDense: true, hintText: hintText, - hintStyle: TextStyle(fontSize: 14.fSize, height: 21 / 16, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -1), + hintStyle: TextStyle(fontSize: 14.fSize, height: 21 / 16, fontWeight: FontWeight.w500, color: Color(0xff898A8D), letterSpacing: -0.75), prefixIconConstraints: BoxConstraints(minWidth: 30.h), prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, weight: FontWeight.w500), contentPadding: EdgeInsets.zero,