diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index e643c5d..7a7450a 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -443,6 +443,7 @@ class AuthenticationViewModel extends ChangeNotifier { int? patientID, }) async { bool isForRegister = (_appState.getUserRegistrationPayload.healthId != null || _appState.getUserRegistrationPayload.patientOutSa == true || _appState.getUserRegistrationPayload.patientOutSa == 1); + MyAppointmentsViewModel myAppointmentsVM = getIt(); final request = RequestUtils.getCommonRequestWelcome( phoneNumber: phoneNumberController.text, @@ -573,6 +574,7 @@ class AuthenticationViewModel extends ChangeNotifier { } // _appState.setUserBloodGroup = (activation.patientBlodType ?? ""); _appState.setAppAuthToken = activation.authenticationTokenId; + myAppointmentsVM.getActiveAppointmentsCount(); final request = await RequestUtils.getAuthanticatedCommonRequest().toJson(); bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request); @@ -593,7 +595,6 @@ class AuthenticationViewModel extends ChangeNotifier { if (isUserAgreedBefore) { navigateToHomeScreen(); } else { - MyAppointmentsViewModel myAppointmentsVM = getIt(); myAppointmentsVM.setIsAppointmentDataToBeLoaded(true); navigateToHomeScreen(); //Agreement page not designed yet so we are navigating to home screen directly diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index 363ad28..8460bd4 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_card_history.dart'; @@ -14,9 +15,10 @@ class InsuranceViewModel extends ChangeNotifier { bool isInsuranceUpdateDetailsLoading = false; bool isInsuranceDataToBeLoaded = true; - bool isInsuranceApprovalsLoading = false; + bool isInsuranceExpired = false; + InsuranceRepo insuranceRepo; ErrorHandlerService errorHandlerService; @@ -85,6 +87,11 @@ class InsuranceViewModel extends ChangeNotifier { patientInsuranceList = apiResponse.data!; isInsuranceLoading = false; isInsuranceDataToBeLoaded = false; + + isInsuranceExpired = DateTime.now().isAfter( + DateUtil.convertStringToDate(patientInsuranceList.first.cardValidTo), + ); + notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart index b94f004..87451c2 100644 --- a/lib/features/my_appointments/my_appointments_repo.dart +++ b/lib/features/my_appointments/my_appointments_repo.dart @@ -47,6 +47,8 @@ abstract class MyAppointmentsRepo { Future>> insertLiveCareVIDARequest({required clientRequestID, required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); Future>> getTamaraInstallmentsDetails(); + + Future>> getActiveAppointmentsCount(); } class MyAppointmentsRepoImp implements MyAppointmentsRepo { @@ -476,9 +478,6 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { final list = response['PatientDoctorAppointmentResultList']; - // if (list == null || list.isEmpty) { - // throw Exception("Appointments list is empty"); - // } final appointmentsList = list.map((item) => PatientAppointmentHistoryResponseModel.fromJson(item as Map)).toList().cast(); @@ -583,4 +582,40 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future> getActiveAppointmentsCount() async { + Map mapDevice = {}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + GET_ACTIVE_APPOINTMENTS_LIST_URL, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final appointmentCount = response['AppointmentActiveNumber']; + + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: appointmentCount, + ); + } 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 60fbff2..0da9b7a 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -17,6 +17,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { ErrorHandlerService errorHandlerService; AppState appState; + int activeAppointmentsCount = 0; + bool isMyAppointmentsLoading = false; bool isAppointmentPatientShareLoading = false; bool isTimeLineAppointmentsLoading = false; @@ -64,7 +66,6 @@ class MyAppointmentsViewModel extends ChangeNotifier { isMyAppointmentsLoading = true; isTimeLineAppointmentsLoading = true; patientMyDoctorsList.clear(); - isPatientMyDoctorsLoading = true; } isTamaraDetailsLoading = true; isAppointmentPatientShareLoading = true; @@ -121,10 +122,12 @@ class MyAppointmentsViewModel extends ChangeNotifier { patientArrivedAppointmentsHistoryList.clear(); notifyListeners(); - final result = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments); - final resultArrived = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: false, isArrivedAppointments: true); + final results = await Future.wait([ + myAppointmentsRepo.getPatientAppointments(isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments), + myAppointmentsRepo.getPatientAppointments(isActiveAppointment: false, isArrivedAppointments: true), + ]); - result.fold( + results[0].fold( (failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) { if (apiResponse.messageStatus == 2) { @@ -141,7 +144,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { }, ); - resultArrived.fold( + results[1].fold( (failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) { if (apiResponse.messageStatus == 2) { @@ -149,6 +152,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } else if (apiResponse.messageStatus == 1) { patientArrivedAppointmentsHistoryList = apiResponse.data!; isMyAppointmentsLoading = false; + isAppointmentDataToBeLoaded = false; notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); @@ -363,6 +367,9 @@ class MyAppointmentsViewModel extends ChangeNotifier { Future getPatientMyDoctors({Function(dynamic)? onSuccess, Function(String)? onError}) async { if (!isAppointmentDataToBeLoaded) return; + isPatientMyDoctorsLoading = true; + notifyListeners(); + final result = await myAppointmentsRepo.getPatientDoctorsList(); result.fold( @@ -527,17 +534,26 @@ class MyAppointmentsViewModel extends ChangeNotifier { if (onSuccess != null) { onSuccess(apiResponse); } + }, + ); + } - // if (apiResponse.messageStatus == 2) { - // onError!(apiResponse.errorMessage!); - // // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); - // } else if (apiResponse.messageStatus == 1) { - // getTamaraInstallmentsDetailsResponseModel = apiResponse.data!; - // notifyListeners(); - // if (onSuccess != null) { - // onSuccess(apiResponse); - // } - // } + Future getActiveAppointmentsCount({Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.getActiveAppointmentsCount(); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + onError!(apiResponse.errorMessage!); + activeAppointmentsCount = 0; + } else if (apiResponse.messageStatus == 1) { + activeAppointmentsCount = apiResponse.data ?? 0; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } }, ); } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index c87039c..fe93ec3 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -86,30 +86,25 @@ class _AppointmentDetailsPageState extends State { onAskDoctorTap: () {}, onCancelTap: () async { myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); - showCommonBottomSheet(context, - child: Utils.getLoadingWidget(), - callBackFunc: (str) {}, - title: "", - height: ResponsiveExtension.screenHeight * 0.3, - isCloseButtonVisible: false, - isDismissible: false, - isFullScreen: false); + LoaderBottomSheet.showLoader(loadingText: "Cancelling Appointment, Please Wait...".needTranslation); await myAppointmentsViewModel.cancelAppointment( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, onSuccess: (apiResponse) { - Navigator.of(context).pop(); - showCommonBottomSheet(context, - child: Utils.getSuccessWidget(loadingText: "Appointment Cancelled Successfully".needTranslation), - callBackFunc: (str) {}, - title: "", - height: ResponsiveExtension.screenHeight * 0.3, - isCloseButtonVisible: false, - isDismissible: false, - isFullScreen: false, - isSuccessDialog: true); + LoaderBottomSheet.hideLoader(); + myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + myAppointmentsViewModel.getPatientAppointments(true, false); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getSuccessWidget(loadingText: "Appointment Cancelled Successfully".needTranslation), + callBackFunc: () { + Navigator.of(context).pop(); + }, + title: "", + isCloseButtonVisible: true, + isDismissible: false, + isFullScreen: false, + ); }); - Navigator.of(context).pop(); - Navigator.of(context).pop(); }, onRescheduleTap: () async { openDoctorScheduleCalendar(); @@ -510,7 +505,7 @@ class _AppointmentDetailsPageState extends State { projectName: widget.patientAppointmentHistoryResponseModel.projectName, ); bookAppointmentsViewModel.setSelectedDoctor(doctor); - LoaderBottomSheet.showLoader(); + LoaderBottomSheet.showLoader(loadingText: "Fetching Doctor Schedule, Please Wait...".needTranslation); await bookAppointmentsViewModel.getDoctorFreeSlots( isBookingForLiveCare: false, onSuccess: (dynamic respData) async { @@ -541,24 +536,19 @@ class _AppointmentDetailsPageState extends State { case 0: break; case 10: - showCommonBottomSheet(context, - child: Utils.getLoadingWidget(), callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.3, isCloseButtonVisible: false, isDismissible: false, isFullScreen: false); + LoaderBottomSheet.showLoader(loadingText: "Confirming Appointment, Please Wait...".needTranslation); 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, + LoaderBottomSheet.hideLoader(); + myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + myAppointmentsViewModel.getPatientAppointments(true, false); + showCommonBottomSheet(context, child: Utils.getSuccessWidget(loadingText: "Appointment Confirmed Successfully".needTranslation), callBackFunc: (str) { + Navigator.of(context).pop(); + }, title: "", height: ResponsiveExtension.screenHeight * 0.3, isCloseButtonVisible: true, isDismissible: false, isFullScreen: false, isSuccessDialog: true); }); - Navigator.of(context).pop(); - Navigator.of(context).pop(); + // LoaderBottomSheet.hideLoader(); case 15: break; case 20: diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index 06257c7..51e9703 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -8,10 +8,16 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import '../../widgets/chip/app_custom_chip_widget.dart'; @@ -20,11 +26,13 @@ class MyDoctorsPage extends StatelessWidget { MyDoctorsPage({super.key}); late MyAppointmentsViewModel myAppointmentsViewModel; + late BookAppointmentsViewModel bookAppointmentsViewModel; @override Widget build(BuildContext context) { AppState appState = getIt.get(); myAppointmentsViewModel = Provider.of(context, listen: false); + bookAppointmentsViewModel = Provider.of(context, listen: false); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( @@ -141,13 +149,38 @@ class MyDoctorsPage extends StatelessWidget { "".toText16(), Transform.flip( flipX: appState.isArabic(), - child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), + child: + Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon_small, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), ], ), ], ), ), - ), + ).onPress(() async { + bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( + clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, + projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, + doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, + )); + LoaderBottomSheet.showLoader(); + await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage(), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }), ), ), ); diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index aa67a76..1451bcb 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -117,26 +117,26 @@ class _AppointmentCardState extends State { ).toShimmer2(isShow: widget.isLoading), ), // TODO: Implement the logic to enable/disable the switch based on reminder status - AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) - ? SizedBox().toShimmer2(isShow: widget.isLoading) - : 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.isLoading ? false : widget.patientAppointmentHistoryResponseModel.hasReminder!, - onChanged: (newValue) { - setState(() { - widget.myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); - }); - }, - ).toShimmer2(isShow: widget.isLoading), + // AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) + // ? SizedBox().toShimmer2(isShow: widget.isLoading) + // : 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.isLoading ? false : widget.patientAppointmentHistoryResponseModel.hasReminder!, + // onChanged: (newValue) { + // setState(() { + // widget.myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel); + // }); + // }, + // ).toShimmer2(isShow: widget.isLoading), ], ), SizedBox(height: 16.h), @@ -155,7 +155,7 @@ class _AppointmentCardState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ (widget.isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : widget.patientAppointmentHistoryResponseModel.doctorNameObj!) - .toText16(isBold: true) + .toText16(isBold: true, maxlines: 1) .toShimmer2(isShow: widget.isLoading), SizedBox(height: 8.h), Wrap( diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index b89d3e8..5190e5b 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -43,6 +43,7 @@ class PatientInsuranceCard extends StatelessWidget { children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -51,20 +52,14 @@ class PatientInsuranceCard extends StatelessWidget { "Policy: ${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor), ], ), - CustomButton( + AppCustomChipWidget( icon: isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon, + labelText: isInsuranceExpired ? "Insurance Expired".needTranslation : "Insurance Active".needTranslation, iconColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, - iconSize: 13.h, - text: isInsuranceExpired ? "Insurance Expired".needTranslation : "Insurance Active".needTranslation, - onPressed: () {}, - backgroundColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.15) : AppColors.successColor.withOpacity(0.15), - borderColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.01) : AppColors.successColor.withOpacity(0.01), textColor: isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, + iconSize: 12, + backgroundColor: isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1), + labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h), ), ], ), @@ -79,8 +74,10 @@ class PatientInsuranceCard extends StatelessWidget { children: [ 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}"), + labelText: "${LocaleKeys.expiryDate.tr(context: context)} ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(insuranceCardDetailsModel.cardValidTo), false)}", + labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h), + ), + AppCustomChipWidget(labelText: "Patient Card ID: ${insuranceCardDetailsModel.patientCardID}".needTranslation), ], ), 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 1eff927..7fc7115 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -26,6 +26,7 @@ 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/appointments/my_doctors_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; +import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_approvals_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; @@ -200,9 +201,21 @@ class _MedicalFilePageState extends State { ), AppCustomChipWidget( icon: AppAssets.blood_icon, - labelText: "${LocaleKeys.bloodType.tr(context: context)}: ${appState.getUserBloodGroup}", + labelText: "Blood: ${appState.getUserBloodGroup}", iconColor: AppColors.primaryRedColor, + labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h), ), + Consumer(builder: (context, insuranceVM, child) { + return AppCustomChipWidget( + icon: insuranceVM.isInsuranceExpired ? AppAssets.cancel_circle_icon : AppAssets.insurance_active_icon, + labelText: insuranceVM.isInsuranceExpired ? "Insurance Expired".needTranslation : "Insurance Active".needTranslation, + iconColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, + textColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor : AppColors.successColor, + iconSize: 12, + backgroundColor: insuranceVM.isInsuranceExpired ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.successColor.withOpacity(0.1), + labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h), + ); + }), ], ), ], @@ -515,7 +528,7 @@ class _MedicalFilePageState extends State { backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, - fontSize: 12.3, + fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 12.h, height: 40.h, @@ -532,7 +545,7 @@ class _MedicalFilePageState extends State { backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, - fontSize: 13, + fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 12.h, height: 40.h, @@ -569,7 +582,6 @@ class _MedicalFilePageState extends State { Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], ).onPress(() { - myAppointmentsViewModel.setIsPatientMyDoctorsLoading(true); myAppointmentsViewModel.getPatientMyDoctors(); Navigator.of(context).push( CustomPageRoute( @@ -639,7 +651,31 @@ class _MedicalFilePageState extends State { ), ], ), - ), + ).onPress(() async { + bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( + clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, + projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, + doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, + )); + LoaderBottomSheet.showLoader(); + await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage(), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }), ), ), ) diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index 9f6d55b..9328401 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -59,6 +59,7 @@ class _PrescriptionDetailPageState extends State { Expanded( child: CollapsingListView( title: LocaleKeys.prescriptions.tr(context: context), + instructions: () {}, child: SingleChildScrollView( child: Consumer(builder: (context, prescriptionVM, child) { return Column( diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart index 8357033..acf03f5 100644 --- a/lib/presentation/prescriptions/prescription_item_view.dart +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -209,21 +209,7 @@ class PrescriptionItemView extends StatelessWidget { height: 40.h, ).toShimmer2(isShow: isLoading), ), - SizedBox(width: 16.h), - Expanded( - child: CustomButton( - text: LocaleKeys.readInstructions.tr(context: context), - onPressed: () {}, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: AppColors.whiteColor, - fontSize: 13, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ).toShimmer2(isShow: isLoading), - ), + // SizedBox(width: 16.h), ], ).paddingSymmetrical(16.h, 16.h), ], diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 2687944..e889346 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -21,12 +21,14 @@ class CollapsingListView extends StatelessWidget { VoidCallback? report; VoidCallback? logout; VoidCallback? history; + VoidCallback? instructions; Widget? bottomChild; Widget? trailing; bool isClose; bool isLeading; - CollapsingListView({required this.title, this.child, this.search, this.isClose = false, this.bottomChild, this.report, this.logout, this.history, this.isLeading = true, this.trailing}); + CollapsingListView( + {required this.title, this.child, this.search, this.isClose = false, this.bottomChild, this.report, this.logout, this.history, this.instructions, this.isLeading = true, this.trailing}); @override Widget build(BuildContext context) { @@ -98,6 +100,7 @@ class CollapsingListView extends StatelessWidget { if (logout != null) actionButton(context, t, title: "Logout".needTranslation, icon: AppAssets.logout).onPress(logout!), if (report != null) actionButton(context, t, title: "Report".needTranslation, icon: AppAssets.report_icon).onPress(report!), if (history != null) actionButton(context, t, title: "History".needTranslation, icon: AppAssets.insurance_history_icon).onPress(history!), + if (instructions != null) actionButton(context, t, title: "Instructions".needTranslation, icon: AppAssets.requests).onPress(instructions!), if (search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(search!).paddingOnly(right: 24), if (trailing != null) trailing!, ], diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart index 2cfd5ce..8facd92 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 { color: Colors.transparent, // Crucially, set color to transparent style: BorderStyle.none, ), - borderRadius: BorderRadius.circular(8.0), // Apply a border radius of 16.0 + borderRadius: BorderRadius.circular(8.h), // Apply a border radius of 16.0 ), ), child: icon.isNotEmpty