From e37eb78f815e8cf410b265fbbd1b9f0b3861ee04 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 9 Sep 2025 15:40:14 +0300 Subject: [PATCH] my appointments changes implementation contd. --- assets/images/svg/lab_result_icon.svg | 7 +- assets/images/svg/prescription_item_icon.svg | 6 + assets/images/svg/radiology_icon.svg | 4 + assets/images/svg/rebook_appointment_icon.svg | 4 + assets/images/svg/report_icon.svg | 3 + lib/core/app_assets.dart | 4 + .../authentication/authentication_repo.dart | 2 +- .../authentication_view_model.dart | 4 +- lib/features/insurance/insurance_repo.dart | 2 +- .../my_appointments/my_appointments_repo.dart | 48 +- .../my_appointments_view_model.dart | 51 +- .../utils/appointment_type.dart | 19 + .../prescriptions/prescriptions_repo.dart | 41 +- .../prescriptions_view_model.dart | 1 - .../appointment_details_page.dart | 501 ++++++++++++++---- .../appointment_payment_page.dart | 32 +- .../appointments/my_appointments_page.dart | 177 +++++-- .../widgets/appointment_card.dart | 142 +++-- .../widgets/appointment_doctor_card.dart | 50 +- .../insurance_update_details_card.dart | 41 +- .../widgets/patient_insurance_card.dart | 44 +- .../medical_file/medical_file_page.dart | 42 +- .../widgets/medical_file_card.dart | 11 +- .../prescription_detail_page.dart | 87 +-- 24 files changed, 883 insertions(+), 440 deletions(-) create mode 100644 assets/images/svg/prescription_item_icon.svg create mode 100644 assets/images/svg/radiology_icon.svg create mode 100644 assets/images/svg/rebook_appointment_icon.svg create mode 100644 assets/images/svg/report_icon.svg diff --git a/assets/images/svg/lab_result_icon.svg b/assets/images/svg/lab_result_icon.svg index 245048d..a8c442d 100644 --- a/assets/images/svg/lab_result_icon.svg +++ b/assets/images/svg/lab_result_icon.svg @@ -1,4 +1,5 @@ - - - + + + + diff --git a/assets/images/svg/prescription_item_icon.svg b/assets/images/svg/prescription_item_icon.svg new file mode 100644 index 0000000..6aba05f --- /dev/null +++ b/assets/images/svg/prescription_item_icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/svg/radiology_icon.svg b/assets/images/svg/radiology_icon.svg new file mode 100644 index 0000000..e1ae996 --- /dev/null +++ b/assets/images/svg/radiology_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/rebook_appointment_icon.svg b/assets/images/svg/rebook_appointment_icon.svg new file mode 100644 index 0000000..da4533a --- /dev/null +++ b/assets/images/svg/rebook_appointment_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/svg/report_icon.svg b/assets/images/svg/report_icon.svg new file mode 100644 index 0000000..97b6db8 --- /dev/null +++ b/assets/images/svg/report_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index eff2ccc..eec83ba 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -85,6 +85,10 @@ class AppAssets { static const String directions_icon = '$svgBasePath/directions_icon.svg'; static const String apple_pay_button = '$svgBasePath/pay_with_apple_pay.svg'; static const String bell = '$svgBasePath/bell.svg'; + static const String rebook_appointment_icon = '$svgBasePath/rebook_appointment_icon.svg'; + static const String report_icon = '$svgBasePath/report_icon.svg'; + static const String radiology_icon = '$svgBasePath/radiology_icon.svg'; + static const String prescription_item_icon = '$svgBasePath/prescription_item_icon.svg'; //bottom navigation// diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 21061dc..21415df 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -38,7 +38,7 @@ class AuthenticationRepoImp implements AuthenticationRepo { @override Future>> selectDeviceByImei({required String firebaseToken}) async { - final mapDevice = {"IMEI": firebaseToken}; + Map mapDevice = {"IMEI": firebaseToken}; try { GenericApiModel? apiResponse; Failure? failure; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index c451c40..d324a71 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -167,8 +167,8 @@ class AuthenticationViewModel extends ChangeNotifier { Future selectDeviceImei({required Function(dynamic data) onSuccess, Function(String)? onError}) async { // LoadingUtils.showFullScreenLoading(); // String firebaseToken = _appState.deviceToken; - // String firebaseToken = await Utils.getStringFromPrefs(CacheConst.pushToken); - String firebaseToken = "fY1fq_cITMmUCztA3UKKL9:APA91bEb2ZcdCPQPq3QsA0NW6a6btFvN-JjB1Pn3ZCoCzBMmVUhhh1ZQMtRn9tYPQ5G-jHDLiEpVAlBuRCVMkLDxa-zijsqbIui-4A-ynwclDWGFT4bUHTc"; + String firebaseToken = await Utils.getStringFromPrefs(CacheConst.pushToken); + // String firebaseToken = "fY1fq_cITMmUCztA3UKKL9:APA91bEb2ZcdCPQPq3QsA0NW6a6btFvN-JjB1Pn3ZCoCzBMmVUhhh1ZQMtRn9tYPQ5G-jHDLiEpVAlBuRCVMkLDxa-zijsqbIui-4A-ynwclDWGFT4bUHTc"; // == "" // ? "dOGRRszQQMGe_9wA5Hx3kO:APA91bFV5IcIJXvcCXXk0tc2ddtZgWwCPq7sGSuPr-YW7iiJpQZKgFGN9GAzCVOWL8MfheaP1slE8MdxB7lczdPBGdONQ7WbMmhgHcsUCUktq-hsapGXXqc" // : _appState.deviceToken; diff --git a/lib/features/insurance/insurance_repo.dart b/lib/features/insurance/insurance_repo.dart index 68b53e4..874cc28 100644 --- a/lib/features/insurance/insurance_repo.dart +++ b/lib/features/insurance/insurance_repo.dart @@ -106,7 +106,7 @@ class InsuranceRepoImp implements InsuranceRepo { @override Future>> getPatientInsuranceDetailsForUpdate({required String patientId, required String identificationNo}) async { - final mapDevice = {"SetupID": "010266", "ProjectID": 15, "PatientIdentificationID": identificationNo, "IsFamily": false, "ParentID": 0}; + Map mapDevice = {"SetupID": "010266", "ProjectID": 15, "PatientIdentificationID": identificationNo, "IsFamily": false, "ParentID": 0}; try { GenericApiModel? apiResponse; diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart index 0815b94..8fc477c 100644 --- a/lib/features/my_appointments/my_appointments_repo.dart +++ b/lib/features/my_appointments/my_appointments_repo.dart @@ -8,8 +8,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class MyAppointmentsRepo { - Future>>> getPatientAppointments( - {required bool isActiveAppointment, required bool isArrivedAppointments}); + Future>>> getPatientAppointments({required bool isActiveAppointment, required bool isArrivedAppointments}); Future>> getPatientShareAppointment({required int projectID, required int clinicID, required String appointmentNo}); @@ -28,6 +27,8 @@ abstract class MyAppointmentsRepo { Future>> generateAppointmentQR({required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp}); Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); + + Future>> confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); } class MyAppointmentsRepoImp implements MyAppointmentsRepo { @@ -37,8 +38,7 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { MyAppointmentsRepoImp({required this.loggerService, required this.apiClient}); @override - Future>>> getPatientAppointments( - {required bool isActiveAppointment, required bool isArrivedAppointments}) async { + Future>>> getPatientAppointments({required bool isActiveAppointment, required bool isArrivedAppointments}) async { Map mapDevice = { "IsActiveAppointment": isActiveAppointment, "isDentalAllowedBackend": false, @@ -310,4 +310,44 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future> confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}) async { + Map requestBody = { + "AppointmentNumber": patientAppointmentHistoryResponseModel.appointmentNo, + "IsLiveCareAppointment": patientAppointmentHistoryResponseModel.isLiveCareAppointment, + "ClinicID": patientAppointmentHistoryResponseModel.clinicID, + "ProjectID": patientAppointmentHistoryResponseModel.projectID, + "ConfirmationBy": 102, + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + CONFIRM_APPOINTMENT, + body: requestBody, + 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/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index 5c952e9..2815977 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -14,6 +14,10 @@ class MyAppointmentsViewModel extends ChangeNotifier { bool isAppointmentPatientShareLoading = false; List patientAppointmentsHistoryList = []; + + List patientUpcomingAppointmentsHistoryList = []; + List patientArrivedAppointmentsHistoryList = []; + PatientAppointmentShareResponseModel? patientAppointmentShareResponseModel; MyAppointmentsViewModel({required this.myAppointmentsRepo, required this.errorHandlerService}); @@ -25,6 +29,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { initAppointmentsViewModel() { patientAppointmentsHistoryList.clear(); + patientUpcomingAppointmentsHistoryList.clear(); + patientArrivedAppointmentsHistoryList.clear(); isMyAppointmentsLoading = true; isAppointmentPatientShareLoading = true; notifyListeners(); @@ -50,6 +56,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { Future getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async { final result = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments); + final resultArrived = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: false, isArrivedAppointments: true); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -57,7 +64,23 @@ class MyAppointmentsViewModel extends ChangeNotifier { if (apiResponse.messageStatus == 2) { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); } else if (apiResponse.messageStatus == 1) { - patientAppointmentsHistoryList = apiResponse.data!; + patientUpcomingAppointmentsHistoryList = apiResponse.data!; + isMyAppointmentsLoading = false; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + + resultArrived.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + patientArrivedAppointmentsHistoryList = apiResponse.data!; isMyAppointmentsLoading = false; notifyListeners(); if (onSuccess != null) { @@ -66,6 +89,13 @@ class MyAppointmentsViewModel extends ChangeNotifier { } }, ); + + patientAppointmentsHistoryList.addAll(patientUpcomingAppointmentsHistoryList); + patientAppointmentsHistoryList.addAll(patientArrivedAppointmentsHistoryList); + + print('Upcoming Appointments: ${patientUpcomingAppointmentsHistoryList.length}'); + print('Arrived Appointments: ${patientArrivedAppointmentsHistoryList.length}'); + print('All Appointments: ${patientAppointmentsHistoryList.length}'); } Future getPatientShareAppointment(int projectID, int clinicID, String appointmentNo, {Function(dynamic)? onSuccess, Function(String)? onError}) async { @@ -145,6 +175,25 @@ class MyAppointmentsViewModel extends ChangeNotifier { ); } + Future confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.confirmAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + onError!(apiResponse.errorMessage!); + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + Future createAdvancePayment( {required String paymentMethodName, required int projectID, diff --git a/lib/features/my_appointments/utils/appointment_type.dart b/lib/features/my_appointments/utils/appointment_type.dart index cd8bb56..abc23dc 100644 --- a/lib/features/my_appointments/utils/appointment_type.dart +++ b/lib/features/my_appointments/utils/appointment_type.dart @@ -43,6 +43,25 @@ class AppointmentType { } } + static Color getNextActionTextColor(nextAction) { + switch (nextAction) { + case 0: + return AppColors.successColor; + case 10: + return AppColors.successColor; + case 15: + return AppColors.textColor; + case 20: + return AppColors.infoColor; + case 50: + return AppColors.successColor; + case 90: + return AppColors.alertColor; + default: + return AppColors.successColor; + } + } + static Color getNextActionButtonColor(nextAction) { switch (nextAction) { case 0: diff --git a/lib/features/prescriptions/prescriptions_repo.dart b/lib/features/prescriptions/prescriptions_repo.dart index f584f7b..5f2db30 100644 --- a/lib/features/prescriptions/prescriptions_repo.dart +++ b/lib/features/prescriptions/prescriptions_repo.dart @@ -21,23 +21,7 @@ class PrescriptionsRepoImp implements PrescriptionsRepo { @override Future>>> getPatientPrescriptionOrders({required String patientId}) async { - final mapDevice = { - "isDentalAllowedBackend": false, - "VersionID": 50.0, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 1, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientID": "1018977", - "PatientOutSA": "0", - "SessionID": "03478TYC02N80874CTYN04883475!?" - }; + Map mapDevice = {}; try { GenericApiModel>? apiResponse; @@ -52,7 +36,7 @@ class PrescriptionsRepoImp implements PrescriptionsRepo { try { final list = response['PatientPrescriptionList']; if (list == null || list.isEmpty) { - throw Exception("lab list is empty"); + // throw Exception("lab list is empty"); } final prescriptionOrders = list.map((item) => PatientPrescriptionsResponseModel.fromJson(item as Map)).toList().cast(); @@ -78,28 +62,13 @@ class PrescriptionsRepoImp implements PrescriptionsRepo { @override Future>>> getPatientPrescriptionDetails({required PatientPrescriptionsResponseModel prescriptionsResponseModel}) async { - final mapDevice = { + Map mapDevice = { "AppointmentNo": prescriptionsResponseModel.appointmentNo.toString(), "SetupID": prescriptionsResponseModel.setupID, "EpisodeID": prescriptionsResponseModel.episodeID.toString(), "ClinicID": prescriptionsResponseModel.clinicID.toString(), "ProjectID": prescriptionsResponseModel.projectID.toString(), - "DischargeNo": prescriptionsResponseModel.dischargeNo.toString(), - "isDentalAllowedBackend": false, - "VersionID": 50.0, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 1, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientID": "1018977", - "PatientOutSA": "0", - "SessionID": "03478TYC02N80874CTYN04883475!?" + "DischargeNo": prescriptionsResponseModel.dischargeNo.toString() }; try { @@ -115,7 +84,7 @@ class PrescriptionsRepoImp implements PrescriptionsRepo { try { final list = prescriptionsResponseModel.isInOutPatient! ? response['ListPRM'] : response['INP_GetPrescriptionReport_List']; if (list == null || list.isEmpty) { - throw Exception("prescription list is empty"); + // throw Exception("prescription list is empty"); } final prescriptionOrders = list.map((item) => PrescriptionDetailResponseModel.fromJson(item as Map)).toList().cast(); diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index ff93f84..d57b17e 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -31,7 +31,6 @@ class PrescriptionsViewModel extends ChangeNotifier { patientPrescriptionOrdersByHospital.clear(); patientPrescriptionOrdersViewList.clear(); isPrescriptionsOrdersLoading = true; - isPrescriptionsDetailsLoading = true; isSortByClinic = true; getPatientPrescriptionOrders(); notifyListeners(); diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 4255c71..91a15a4 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -1,6 +1,9 @@ +import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.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/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; @@ -11,16 +14,23 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart'; +import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_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/appointments/appointment_payment_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart'; +import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart'; +import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart'; import 'package:hmg_patient_app_new/theme/colors.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/shimmer/movies_shimmer_widget.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; +import '../medical_file/widgets/medical_file_card.dart'; + class AppointmentDetailsPage extends StatefulWidget { AppointmentDetailsPage({super.key, required this.patientAppointmentHistoryResponseModel}); @@ -32,10 +42,23 @@ class AppointmentDetailsPage extends StatefulWidget { class _AppointmentDetailsPageState extends State { late MyAppointmentsViewModel myAppointmentsViewModel; + late PrescriptionsViewModel prescriptionsViewModel; + + @override + void initState() { + scheduleMicrotask(() { + if (AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) { + prescriptionsViewModel.setPrescriptionsDetailsLoading(); + prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel()); + } + }); + super.initState(); + } @override Widget build(BuildContext context) { myAppointmentsViewModel = Provider.of(context); + prescriptionsViewModel = Provider.of(context); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, appBar: AppBar( @@ -52,7 +75,23 @@ class _AppointmentDetailsPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Appointment Details".needTranslation.toText24(isBold: true), + "Appointment Details".needTranslation.toText20(isBold: true), + if (AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) + CustomButton( + text: "Report".needTranslation, + onPressed: () {}, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + iconSize: 16.h, + icon: AppAssets.report_icon, + iconColor: AppColors.primaryRedColor, + ) ], ), SizedBox(height: 24.h), @@ -74,8 +113,7 @@ class _AppointmentDetailsPageState extends State { Navigator.of(context).pop(); showCommonBottomSheet(context, child: Utils.getSuccessWidget(loadingText: "Appointment Cancelled Successfully".needTranslation), - callBackFunc: (str) { - }, + callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.3, isCloseButtonVisible: false, @@ -89,106 +127,266 @@ class _AppointmentDetailsPageState extends State { onRescheduleTap: () {}, ), SizedBox(height: 16.h), - if (!AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) - Column( - children: [ - 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: [ - Row( - children: [ - "Appointment Status".needTranslation.toText16(isBold: true), - ], - ), - SizedBox(height: 4.h), - (!AppointmentType.isConfirmed(widget.patientAppointmentHistoryResponseModel) - ? "Not Confirmed".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500) - : "Confirmed".needTranslation.toText12(color: AppColors.successColor, fontWeight: FontWeight.w500)), - SizedBox(height: 16.h), - Stack( + !AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) + ? Column( + children: [ + 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: [ - ClipRRect( - clipBehavior: Clip.hardEdge, - borderRadius: BorderRadius.circular(24), - child: Image.network( - "https://maps.googleapis.com/maps/api/staticmap?center=${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&zoom=14&size=350x165&maptype=roadmap&markers=color:red%7C${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&key=AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng", - fit: BoxFit.contain, - ), + Row( + children: [ + "Appointment Status".needTranslation.toText16(isBold: true), + ], ), - Positioned( - bottom: 0, - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.785, - child: CustomButton( - text: "Get Directions".needTranslation, - onPressed: () { - MapsLauncher.launchCoordinates(double.parse(widget.patientAppointmentHistoryResponseModel.latitude!), - double.parse(widget.patientAppointmentHistoryResponseModel.longitude!), widget.patientAppointmentHistoryResponseModel.projectName); - }, - backgroundColor: AppColors.textColor.withOpacity(0.8), - borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), - textColor: AppColors.whiteColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12.h, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - icon: AppAssets.directions_icon, - iconColor: AppColors.whiteColor, - iconSize: 13.h, - ).paddingAll(12.h), - ), + SizedBox(height: 4.h), + (!AppointmentType.isConfirmed(widget.patientAppointmentHistoryResponseModel) + ? "Not Confirmed".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500) + : "Confirmed".needTranslation.toText12(color: AppColors.successColor, fontWeight: FontWeight.w500)), + SizedBox(height: 16.h), + Stack( + children: [ + ClipRRect( + clipBehavior: Clip.hardEdge, + borderRadius: BorderRadius.circular(24), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&zoom=14&size=350x165&maptype=roadmap&markers=color:red%7C${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&key=AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng", + fit: BoxFit.contain, + ), + ), + Positioned( + bottom: 0, + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.785, + child: CustomButton( + text: "Get Directions".needTranslation, + onPressed: () { + MapsLauncher.launchCoordinates(double.parse(widget.patientAppointmentHistoryResponseModel.latitude!), + double.parse(widget.patientAppointmentHistoryResponseModel.longitude!), widget.patientAppointmentHistoryResponseModel.projectName); + }, + backgroundColor: AppColors.textColor.withOpacity(0.8), + borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), + textColor: AppColors.whiteColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12.h, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.directions_icon, + iconColor: AppColors.whiteColor, + iconSize: 13.h, + ).paddingAll(12.h), + ), + ), + ], ), ], ), - ], + ), ), - ), - ), - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: false, - ), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + ), + child: Row( + mainAxisSize: MainAxisSize.max, children: [ - LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), - "Notify me before the appointment".needTranslation.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), + "Notify me before the appointment".needTranslation.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + ], + ), + const Spacer(), + Switch( + activeColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + value: widget.patientAppointmentHistoryResponseModel.hasReminder!, + onChanged: (newValue) { + setState(() { + myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); + }); + }, + ), ], - ), - const Spacer(), - Switch( - activeColor: AppColors.successColor, - activeTrackColor: AppColors.successColor.withValues(alpha: .15), - value: widget.patientAppointmentHistoryResponseModel.hasReminder!, - onChanged: (newValue) { - setState(() { - myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - }); - }, - ), - ], - ).paddingSymmetrical(16.h, 16.h), + ).paddingSymmetrical(16.h, 16.h), + ), + SizedBox(height: 16.h), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Lab & Radiology".needTranslation.toText18(isBold: true), + SizedBox(height: 16.h), + GridView( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13.h, mainAxisSpacing: 13.h, childAspectRatio: 7 / 6), + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + children: [ + MedicalFileCard( + label: LocaleKeys.labResults.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.lab_result_icon, + iconSize: 40, + isLargeText: true, + ), + MedicalFileCard( + label: LocaleKeys.radiology.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.radiology_icon, + iconSize: 40, + isLargeText: true, + ), + ], + ), + LocaleKeys.prescriptions.tr().toText18(isBold: true), + SizedBox(height: 16.h), + Consumer(builder: (context, prescriptionVM, child) { + return prescriptionVM.isPrescriptionsDetailsLoading + ? const MoviesShimmerWidget() + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: Colors.white, + borderRadius: 20.h, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + children: [ + ListView.separated( + itemCount: prescriptionVM.prescriptionDetailsList.length, + shrinkWrap: true, + padding: const EdgeInsets.only(left: 0, right: 8), + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: Row( + children: [ + Utils.buildSvgWithAssets( + icon: AppAssets.prescription_item_icon, + width: 40.h, + height: 40.h, + ), + SizedBox(width: 8.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Column( + children: [ + SizedBox(width: 150.h, child: prescriptionVM.prescriptionDetailsList[index].itemDescription!.toText12(isBold: true, maxLine: 1)), + SizedBox( + width: 150.h, + child: + "Prescribed By: ${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}" + .needTranslation + .toText10(weight: FontWeight.w500, color: AppColors.greyTextColor, letterSpacing: -0.4), + ), + ], + ), + SizedBox(width: 68.h), + Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon, + iconColor: AppColors.blackColor, + width: 18.h, + height: 13.h, + fit: BoxFit.contain, + ), + ], + ), + ], + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ).onPress(() { + prescriptionVM.setPrescriptionsDetailsLoading(); + Navigator.of(context).push( + FadePage( + page: PrescriptionDetailPage(prescriptionsResponseModel: getPrescriptionRequestModel()), + ), + ); + }), + SizedBox(height: 16.h), + const Divider(color: AppColors.dividerColor), + SizedBox(height: 16.h), + Row( + children: [ + // Expanded( + // child: CustomButton( + // text: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? LocaleKeys.resendOrder.tr(context: context) : LocaleKeys.prescriptionDeliveryError.tr(context: context), + // onPressed: () {}, + // backgroundColor: AppColors.secondaryLightRedColor, + // borderColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.primaryRedColor, + // fontSize: 14, + // fontWeight: FontWeight.w500, + // borderRadius: 12.h, + // height: 40.h, + // icon: AppAssets.appointment_calendar_icon, + // iconColor: AppColors.primaryRedColor, + // iconSize: 16.h, + // ), + // ), + // SizedBox(width: 16.h), + Expanded( + child: CustomButton( + text: "All Prescriptions".needTranslation, + onPressed: () { + Navigator.of(context) + .push( + FadePage( + page: PrescriptionsListPage(), + ), + ) + .then((val) { + prescriptionsViewModel.setPrescriptionsDetailsLoading(); + prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel()); + }); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12.h, + height: 40.h, + icon: AppAssets.requests, + iconColor: AppColors.primaryRedColor, + iconSize: 16.h, + ), + ), + ], + ), + ], + ), + ), + ); + }), + ], ), - SizedBox(height: 16.h), - ], - ), ], ).paddingSymmetrical(24.h, 24.h), ), @@ -242,28 +440,39 @@ class _AppointmentDetailsPageState extends State { ) ], ).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h), - CustomButton( - text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), - onPressed: () { - myAppointmentsViewModel.setIsPatientAppointmentShareLoading(true); - Navigator.of(context).push( - FadePage( - page: AppointmentPaymentPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), - ), - ); - }, - backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction), - borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), - textColor: AppColors.whiteColor, - fontSize: 16, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 50.h, - icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ).paddingSymmetrical(16.h, 24.h), + AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) + ? CustomButton( + text: "Re-book Appointment".needTranslation, + onPressed: () {}, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50.h, + icon: AppAssets.add_icon, + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ).paddingSymmetrical(16.h, 24.h) + : CustomButton( + text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), + onPressed: () { + handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction); + }, + backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction), + borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), + textColor: widget.patientAppointmentHistoryResponseModel.nextAction == 15 ? AppColors.textColor : AppColors.whiteColor, + fontSize: 16, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50.h, + icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ).paddingSymmetrical(16.h, 24.h), ], ), ), @@ -272,4 +481,64 @@ class _AppointmentDetailsPageState extends State { ), ); } + + Future handleAppointmentNextAction(nextAction) async { + switch (nextAction) { + case 0: + break; + case 10: + showCommonBottomSheet(context, + child: Utils.getLoadingWidget(), callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.3, isCloseButtonVisible: false, isDismissible: false, isFullScreen: false); + await myAppointmentsViewModel.confirmAppointment( + patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, + onSuccess: (apiResponse) { + Navigator.of(context).pop(); + showCommonBottomSheet(context, + child: Utils.getSuccessWidget(loadingText: "Appointment Confirmed Successfully".needTranslation), + callBackFunc: (str) {}, + title: "", + height: ResponsiveExtension.screenHeight * 0.3, + isCloseButtonVisible: false, + isDismissible: false, + isFullScreen: false, + isSuccessDialog: true); + }); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + case 15: + break; + case 20: + myAppointmentsViewModel.setIsPatientAppointmentShareLoading(true); + Navigator.of(context).push( + FadePage( + page: AppointmentPaymentPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), + ), + ); + case 50: + // return LocaleKeys.confirmLiveCare.tr(); + case 90: + // return LocaleKeys.checkinOption.tr(); + default: + // return "No Action".needTranslation; + } + } + + PatientPrescriptionsResponseModel getPrescriptionRequestModel() { + return PatientPrescriptionsResponseModel( + appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo, + setupID: widget.patientAppointmentHistoryResponseModel.setupID, + episodeID: widget.patientAppointmentHistoryResponseModel.episodeID, + clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, + projectID: widget.patientAppointmentHistoryResponseModel.projectID, + dischargeNo: 0, + isInOutPatient: widget.patientAppointmentHistoryResponseModel.isInOutPatient, + isHomeMedicineDeliverySupported: false, + doctorImageURL: widget.patientAppointmentHistoryResponseModel.doctorImageURL, + doctorName: "${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}", + appointmentDate: widget.patientAppointmentHistoryResponseModel.appointmentDate, + clinicDescription: widget.patientAppointmentHistoryResponseModel.clinicName, + decimalDoctorRate: widget.patientAppointmentHistoryResponseModel.decimalDoctorRate, + name: widget.patientAppointmentHistoryResponseModel.projectName, + ); + } } diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index 861d5b9..7f2ea9d 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -19,12 +19,16 @@ 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/payfort/payfort_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; +import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/theme/colors.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/in_app_browser/InAppBrowser.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 'package:smooth_corner/smooth_corner.dart'; @@ -220,7 +224,13 @@ class _AppointmentPaymentPageState extends State { "Insurance expired or inactive".needTranslation.toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500).paddingSymmetrical(24.h, 0.h), CustomButton( text: LocaleKeys.updateInsurance.tr(context: context), - onPressed: () {}, + onPressed: () { + Navigator.of(context).push( + FadePage( + page: InsuranceHomePage(), + ), + ); + }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.secondaryLightRedBorderColor, textColor: AppColors.whiteColor, @@ -366,14 +376,24 @@ class _AppointmentPaymentPageState extends State { clinicID: widget.patientAppointmentHistoryResponseModel.clinicID, projectID: widget.patientAppointmentHistoryResponseModel.projectID, appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), - isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!); + isFollowUp: myAppointmentsViewModel.patientAppointmentShareResponseModel!.isFollowup!, + onSuccess: (apiResponse) { + Future.delayed(Duration(milliseconds: 500), () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingNavigation(), + ), + (r) => false); + Navigator.of(context).push( + FadePage(page: MyAppointmentsPage()), + ); + }); + }); } }); }); - Future.delayed(Duration(milliseconds: 500), () { - Navigator.of(context).pop(); - print(payfortViewModel.payfortCheckPaymentStatusResponseModel!.responseMessage!); - }); } else {} }); // checkPaymentStatus(appo); diff --git a/lib/presentation/appointments/my_appointments_page.dart b/lib/presentation/appointments/my_appointments_page.dart index 0850641..4a3a46e 100644 --- a/lib/presentation/appointments/my_appointments_page.dart +++ b/lib/presentation/appointments/my_appointments_page.dart @@ -64,49 +64,154 @@ class _MyAppointmentsPageState extends State { ], onTabChange: (index) { print(index); + myAppointmentsViewModel.onTabChange(index); }, ).paddingSymmetrical(24.h, 0.h), Consumer(builder: (context, myAppointmentsVM, child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 24.h), - // Expandable list - ListView.separated( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 5 : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? myAppointmentsVM.patientAppointmentsHistoryList.length : 1, - itemBuilder: (context, index) { - return myAppointmentsVM.isMyAppointmentsLoading - ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h) - : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? 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, - margin: EdgeInsets.symmetric(vertical: 8.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - ), - ).paddingSymmetrical(24.h, 0.h), - ), - ), - ) : Utils.getNoDataWidget(context); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ), - ], - ); + return getSelectedTabData(myAppointmentsVM.selectedTabIndex, myAppointmentsVM); }), ], ), ), ); } + + Widget getSelectedTabData(int index, MyAppointmentsViewModel myAppointmentsVM) { + switch (index) { + case 0: + //All Appointments Tab Data + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24.h), + // Expandable list + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: myAppointmentsVM.isMyAppointmentsLoading + ? 5 + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty + ? myAppointmentsVM.patientAppointmentsHistoryList.length + : 1, + itemBuilder: (context, index) { + return myAppointmentsVM.isMyAppointmentsLoading + ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h) + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty + ? 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, + margin: EdgeInsets.symmetric(vertical: 8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + ), + ).paddingSymmetrical(24.h, 0.h), + ), + ), + ) + : Utils.getNoDataWidget(context); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ), + ], + ); + case 1: + //Upcoming Appointments Tab Data + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24.h), + // Expandable list + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: myAppointmentsVM.isMyAppointmentsLoading + ? 5 + : myAppointmentsVM.patientUpcomingAppointmentsHistoryList.isNotEmpty + ? myAppointmentsVM.patientUpcomingAppointmentsHistoryList.length + : 1, + itemBuilder: (context, index) { + return myAppointmentsVM.isMyAppointmentsLoading + ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h) + : myAppointmentsVM.patientUpcomingAppointmentsHistoryList.isNotEmpty + ? 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, + margin: EdgeInsets.symmetric(vertical: 8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientUpcomingAppointmentsHistoryList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + ), + ).paddingSymmetrical(24.h, 0.h), + ), + ), + ) + : Utils.getNoDataWidget(context); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ), + ], + ); + case 2: + //Completed Appointments Tab Data + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 24.h), + // Expandable list + ListView.separated( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: myAppointmentsVM.isMyAppointmentsLoading + ? 5 + : myAppointmentsVM.patientArrivedAppointmentsHistoryList.isNotEmpty + ? myAppointmentsVM.patientArrivedAppointmentsHistoryList.length + : 1, + itemBuilder: (context, index) { + return myAppointmentsVM.isMyAppointmentsLoading + ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h) + : myAppointmentsVM.patientArrivedAppointmentsHistoryList.isNotEmpty + ? 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, + margin: EdgeInsets.symmetric(vertical: 8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientArrivedAppointmentsHistoryList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + ), + ).paddingSymmetrical(24.h, 0.h), + ), + ), + ) + : Utils.getNoDataWidget(context); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), + ), + ], + ); + default: + return Container(); + } + } } diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 51af492..e9babeb 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -1,3 +1,4 @@ +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'; @@ -10,6 +11,7 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/appointments/appointment_details_page.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; @@ -33,11 +35,16 @@ class _AppointmentCardState extends State { AppState appState = getIt.get(); return InkWell( onTap: () { - Navigator.of(context).push( + Navigator.of(context) + .push( FadePage( page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), ), - ); + ) + .then((val) { + widget.myAppointmentsViewModel.initAppointmentsViewModel(); + widget.myAppointmentsViewModel.getPatientAppointments(true, false); + }); }, child: Padding( padding: EdgeInsets.all(14.h), @@ -94,24 +101,26 @@ class _AppointmentCardState extends State { ), ), // TODO: Implement the logic to enable/disable the switch based on reminder status - Switch( - activeColor: AppColors.successColor, - activeTrackColor: AppColors.successColor.withValues(alpha: .15), - thumbIcon: WidgetStateProperty.resolveWith( - (Set states) { - if (states.contains(WidgetState.selected)) { - return const Icon(Icons.check); // Icon when switch is ON - } - return const Icon(Icons.close); // Icon when switch is OFF - }, - ), - value: widget.patientAppointmentHistoryResponseModel.hasReminder!, - onChanged: (newValue) { - setState(() { - widget.myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - }); - }, - ), + AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) + ? SizedBox() + : Switch( + activeColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + thumbIcon: WidgetStateProperty.resolveWith( + (Set states) { + if (states.contains(WidgetState.selected)) { + return const Icon(Icons.check); // Icon when switch is ON + } + return const Icon(Icons.close); // Icon when switch is OFF + }, + ), + value: widget.patientAppointmentHistoryResponseModel.hasReminder!, + onChanged: (newValue) { + setState(() { + widget.myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); + }); + }, + ), ], ), SizedBox(height: 16.h), @@ -155,30 +164,32 @@ class _AppointmentCardState extends State { children: [ Expanded( flex: 6, - child: CustomButton( - text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), - onPressed: () { - Navigator.of(context) - .push(FadePage( - page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), - )) - .then((val) { - widget.myAppointmentsViewModel.initAppointmentsViewModel(); - widget.myAppointmentsViewModel.getPatientAppointments(true, false); - }); - }, - backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.1), - borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), - textColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction), - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), - iconColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction), - iconSize: 14.h, - ), + child: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) + ? getArrivedAppointmentButton() + : CustomButton( + text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), + onPressed: () { + Navigator.of(context) + .push(FadePage( + page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), + )) + .then((val) { + widget.myAppointmentsViewModel.initAppointmentsViewModel(); + widget.myAppointmentsViewModel.getPatientAppointments(true, false); + }); + }, + backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.15), + borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), + textColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction), + iconColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction), + iconSize: 14.h, + ), ), SizedBox(width: 8.h), Expanded( @@ -200,11 +211,16 @@ class _AppointmentCardState extends State { ), ), ).onPress(() { - Navigator.of(context).push( + Navigator.of(context) + .push( FadePage( page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), ), - ); + ) + .then((val) { + widget.myAppointmentsViewModel.initAppointmentsViewModel(); + widget.myAppointmentsViewModel.getPatientAppointments(true, false); + }); }), ), ], @@ -215,5 +231,39 @@ class _AppointmentCardState extends State { ); } + Widget getArrivedAppointmentButton() { + return DateTime.now().difference(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15 + ? CustomButton( + text: LocaleKeys.askDoctor.tr(context: context), + onPressed: () {}, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.ask_doctor_icon, + iconColor: AppColors.primaryRedColor, + iconSize: 16.h, + ) + : CustomButton( + text: "Rebook with same doctor".needTranslation, + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.rebook_appointment_icon, + iconColor: AppColors.blackColor, + iconSize: 16.h, + ); + } + void performAppointmentNextAction(nextAction) {} } diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 801fdca..e6d7338 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -59,10 +59,7 @@ class AppointmentDoctorCard extends StatelessWidget { icon: AppAssets.doctor_calendar_icon, labelText: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}, ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}"), - AppCustomChipWidget( - icon: AppAssets.rating_icon, - iconColor: AppColors.ratingColorYellow, - labelText: "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}"), + AppCustomChipWidget(icon: AppAssets.rating_icon, iconColor: AppColors.ratingColorYellow, labelText: "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}"), ], ), ], @@ -82,20 +79,37 @@ class AppointmentDoctorCard extends StatelessWidget { Widget getAppointmentActionButtons(bool isAppointmentArrived) { if (isAppointmentArrived) { - return CustomButton( - text: LocaleKeys.askDoctor.tr(), - onPressed: () {}, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - icon: AppAssets.ask_doctor_icon, - iconColor: AppColors.primaryRedColor, - ); + return DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15 + ? CustomButton( + text: LocaleKeys.askDoctor.tr(), + onPressed: () {}, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + iconSize: 16.h, + icon: AppAssets.ask_doctor_icon, + iconColor: AppColors.primaryRedColor, + ) + : CustomButton( + text: "Rebook with same doctor".needTranslation, + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.rebook_appointment_icon, + iconColor: AppColors.blackColor, + iconSize: 16.h, + ); } else { return Row( children: [ diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index 51afdc4..b6a38b2 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -10,6 +10,7 @@ import 'package:hmg_patient_app_new/features/insurance/insurance_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/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -68,42 +69,14 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { Wrap( direction: Axis.horizontal, spacing: 4.h, - runSpacing: 4.h, + runSpacing: -8.h, children: [ - Row( - children: [ - CustomButton( - icon: AppAssets.doctor_calendar_icon, - iconColor: AppColors.blackColor, - iconSize: 13.h, - text: "${LocaleKeys.expiryOn.tr(context: context)} ${insuranceViewModel.patientInsuranceUpdateResponseModel!.effectiveTo}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], + AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: "${LocaleKeys.expiryOn.tr(context: context)} ${insuranceViewModel.patientInsuranceUpdateResponseModel!.effectiveTo}", ), - Row( - children: [ - CustomButton( - text: "Member ID: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.memberID!}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], + AppCustomChipWidget( + labelText: "Member ID: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.memberID!}", ), ], ), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 899016e..720c452 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -13,6 +13,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:provider/provider.dart'; @@ -73,44 +74,13 @@ class PatientInsuranceCard extends StatelessWidget { SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, - spacing: 6.h, - runSpacing: 6.h, + spacing: 4.h, + runSpacing: -8.h, children: [ - Row( - children: [ - CustomButton( - icon: AppAssets.doctor_calendar_icon, - iconColor: AppColors.blackColor, - iconSize: 13.h, - text: "${LocaleKeys.expiryDate.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceCardDetailsModel.cardValidTo), false)}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - Row( - children: [ - CustomButton( - text: "Patient Card ID: ${insuranceCardDetailsModel.patientCardID}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), + AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: "${LocaleKeys.expiryDate.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceCardDetailsModel.cardValidTo), false)}"), + AppCustomChipWidget(labelText: "Patient Card ID: ${insuranceCardDetailsModel.patientCardID}"), ], ), SizedBox(height: 10.h), diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index d6cbd14..47951c4 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -167,22 +167,22 @@ class _MedicalFilePageState extends State { padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 30.h, ), - SizedBox(width: 4.h), - CustomButton( - icon: AppAssets.insurance_active_icon, - iconColor: AppColors.successColor, - iconSize: 13.h, - text: "Insurance Active", - onPressed: () {}, - backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - borderColor: AppColors.bgGreenColor.withOpacity(0.0), - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.normal, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), + // SizedBox(width: 4.h), + // CustomButton( + // icon: AppAssets.insurance_active_icon, + // iconColor: AppColors.successColor, + // iconSize: 13.h, + // text: "Insurance Active", + // onPressed: () {}, + // backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), + // borderColor: AppColors.bgGreenColor.withOpacity(0.0), + // textColor: AppColors.blackColor, + // fontSize: 10, + // fontWeight: FontWeight.normal, + // borderRadius: 12, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // height: 30.h, + // ), ], ), SizedBox(height: 8.h), @@ -255,7 +255,7 @@ class _MedicalFilePageState extends State { ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.0) : PatientInsuranceCard( insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, - isInsuranceExpired: DateTime.now().isBefore(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))); + isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))); }), SizedBox(height: 10.h), GridView( @@ -264,10 +264,10 @@ class _MedicalFilePageState extends State { padding: EdgeInsets.only(top: 12), shrinkWrap: true, children: [ - MedicalFileCard(label: "Update Insurance", textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), - MedicalFileCard(label: "Insurance Approvals", textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), - MedicalFileCard(label: "My Invoices List", textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), - MedicalFileCard(label: "Ancillary Orders List", textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), + MedicalFileCard(label: "Update Insurance".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), + MedicalFileCard(label: "Insurance Approvals".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), + MedicalFileCard(label: "My Invoices List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), + MedicalFileCard(label: "Ancillary Orders List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), ], ).paddingSymmetrical(24.h, 0.0), SizedBox(height: 16.h), diff --git a/lib/presentation/medical_file/widgets/medical_file_card.dart b/lib/presentation/medical_file/widgets/medical_file_card.dart index 92bb4ee..82f38ec 100644 --- a/lib/presentation/medical_file/widgets/medical_file_card.dart +++ b/lib/presentation/medical_file/widgets/medical_file_card.dart @@ -6,18 +6,19 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; class MedicalFileCard extends StatelessWidget { final String label; - - // final Color svgColor; final Color textColor; final Color backgroundColor; final String svgIcon; + final num iconSize; + bool isLargeText; MedicalFileCard({ required this.label, - // required this.svgColor, required this.textColor, required this.backgroundColor, this.svgIcon = "", + this.iconSize = 30, + this.isLargeText = false }); @override @@ -33,9 +34,9 @@ class MedicalFileCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Utils.buildSvgWithAssets(icon: svgIcon, width: 30.h, height: 30.h, fit: BoxFit.contain), + Utils.buildSvgWithAssets(icon: svgIcon, width: iconSize.h, height: iconSize.h, fit: BoxFit.contain), SizedBox(height: 12.h), - label.toText11(color: textColor, isBold: true), + isLargeText ? label.toText14(color: textColor, isBold: true) : label.toText11(color: textColor, isBold: true), ], ), ), diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index 1f8e0a2..3bd9273 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -14,6 +14,7 @@ import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_mo 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/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart'; import 'package:provider/provider.dart'; @@ -34,6 +35,7 @@ class _PrescriptionDetailPageState extends State { @override void initState() { scheduleMicrotask(() { + prescriptionsViewModel.setPrescriptionsDetailsLoading(); prescriptionsViewModel.getPrescriptionDetails(widget.prescriptionsResponseModel); }); super.initState(); @@ -85,82 +87,23 @@ class _PrescriptionDetailPageState extends State { SizedBox(height: 16.h), Wrap( direction: Axis.horizontal, - spacing: 6.h, - runSpacing: 6.h, + spacing: 4.h, + runSpacing: -8.h, children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - icon: AppAssets.doctor_calendar_icon, - iconColor: AppColors.textColor, - iconSize: 13.h, - text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false), - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], + AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false), ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - text: widget.prescriptionsResponseModel.clinicDescription!, - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], + AppCustomChipWidget( + labelText: widget.prescriptionsResponseModel.clinicDescription!, ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - icon: AppAssets.rating_icon, - iconColor: AppColors.ratingColorYellow, - iconSize: 13.h, - text: "Rating: ${widget.prescriptionsResponseModel.decimalDoctorRate}", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], + AppCustomChipWidget( + icon: AppAssets.rating_icon, + iconColor: AppColors.ratingColorYellow, + labelText: "Rating: ${widget.prescriptionsResponseModel.decimalDoctorRate}".needTranslation, ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - CustomButton( - text: widget.prescriptionsResponseModel.name!, - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], + AppCustomChipWidget( + labelText: widget.prescriptionsResponseModel.name!, ), ], ),