import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/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/contact_us/contact_us_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.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/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/eye_measurement_details_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/chip/app_custom_chip_widget.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'; class AppointmentCard extends StatelessWidget { final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel; final MyAppointmentsViewModel myAppointmentsViewModel; final bool isLoading; final bool isFromHomePage; final bool isFromMedicalReport; final bool isForEyeMeasurements; final bool isForFeedback; final MedicalFileViewModel? medicalFileViewModel; final ContactUsViewModel? contactUsViewModel; final BookAppointmentsViewModel bookAppointmentsViewModel; const AppointmentCard({ super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel, required this.bookAppointmentsViewModel, this.isLoading = false, this.isFromHomePage = false, this.isFromMedicalReport = false, this.isForEyeMeasurements = false, this.isForFeedback = false, this.medicalFileViewModel, this.contactUsViewModel, }); @override Widget build(BuildContext context) { final appState = getIt.get(); return InkWell( onTap: () => _goToDetails(context), child: Padding( padding: EdgeInsets.all(14.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildHeader(context, appState), SizedBox(height: 16.h), _buildDoctorRow(context), SizedBox(height: 16.h), _buildActionArea(context, appState), ], ), ), ); } Widget _buildHeader(BuildContext context, AppState appState) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded(child: _buildChips(context, appState)), ], ); } Widget _buildChips(BuildContext context, AppState appState) { final isLiveCare = !isLoading && patientAppointmentHistoryResponseModel.isLiveCareAppointment!; return Wrap( alignment: WrapAlignment.start, direction: Axis.horizontal, spacing: 6.w, runSpacing: 6.h, children: [ AppCustomChipWidget( icon: isLoading ? AppAssets.walkin_appointment_icon : (isLiveCare ? AppAssets.small_livecare_icon : AppAssets.walkin_appointment_icon), iconColor: isLoading ? AppColors.textColor : (isLiveCare ? AppColors.whiteColor : AppColors.textColor), labelText: isLoading ? 'Walk In'.needTranslation : (isLiveCare ? LocaleKeys.livecare.tr(context: context) : 'Walk In'.needTranslation), backgroundColor: isLoading ? AppColors.greyColor : (isLiveCare ? AppColors.successColor : AppColors.greyColor), textColor: isLoading ? AppColors.textColor : (isLiveCare ? AppColors.whiteColor : AppColors.textColor), ).toShimmer2(isShow: isLoading), AppCustomChipWidget( labelText: isLoading ? 'OutPatient'.needTranslation : (appState.isArabic() ? patientAppointmentHistoryResponseModel.isInOutPatientDescriptionN! : patientAppointmentHistoryResponseModel.isInOutPatientDescription!), backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1), textColor: AppColors.primaryRedColor, ).toShimmer2(isShow: isLoading), AppCustomChipWidget( labelText: isLoading ? 'Booked'.needTranslation : AppointmentType.getAppointmentStatusType(patientAppointmentHistoryResponseModel.patientStatusType!), backgroundColor: AppColors.successColor.withValues(alpha: 0.1), textColor: AppColors.successColor, ).toShimmer2(isShow: isLoading), ], ).toShimmer2(isShow: isLoading); } Widget _buildDoctorRow(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( children: [ Image.network( isLoading ? 'https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png' : patientAppointmentHistoryResponseModel.doctorImageURL!, width: 63.h, height: 63.h, fit: BoxFit.cover, ).circle(100).toShimmer2(isShow: isLoading), SizedBox(height: 12.h), AppCustomChipWidget( icon: AppAssets.rating_icon, iconColor: AppColors.ratingColorYellow, labelText: isLoading ? "Rating" : "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}".needTranslation) .toShimmer2(isShow: isLoading), ], ), SizedBox(width: 16.h), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ (isLoading ? 'John Doe' : "${patientAppointmentHistoryResponseModel.doctorTitle} ${patientAppointmentHistoryResponseModel.doctorNameObj!}") .toText16(isBold: true, maxlines: 1) .toShimmer2(isShow: isLoading), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 3.h, runSpacing: 4.h, children: [ AppCustomChipWidget(labelText: isLoading ? 'Cardiology' : patientAppointmentHistoryResponseModel.clinicName!) .toShimmer2(isShow: isLoading), AppCustomChipWidget(labelText: isLoading ? 'Olaya' : patientAppointmentHistoryResponseModel.projectName!) .toShimmer2(isShow: isLoading), AppCustomChipWidget( icon: AppAssets.appointment_calendar_icon, labelText: isLoading ? 'Cardiology' : "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}", ).toShimmer2(isShow: isLoading), // if (!isFromMedicalReport) // AppCustomChipWidget( // icon: AppAssets.appointment_time_icon, // labelText: isLoading // ? 'Cardiology' // : DateUtil.formatDateToTimeLang( // DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false), // ).toShimmer2(isShow: isLoading), // AppCustomChipWidget( // icon: AppAssets.rating_icon, // iconColor: AppColors.ratingColorYellow, // labelText: isLoading ? "Rating" : "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}".needTranslation) // .toShimmer2(isShow: isLoading), ], ), ], ), ), ], ); } Widget _buildActionArea(BuildContext context, AppState appState) { if (isFromMedicalReport) { if (isForEyeMeasurements) { return SizedBox.shrink(); } else { return CustomButton( text: 'Select appointment'.needTranslation, onPressed: () { if (isForFeedback) { contactUsViewModel!.setPatientFeedbackSelectedAppointment(patientAppointmentHistoryResponseModel); } else { medicalFileViewModel!.setSelectedMedicalReportAppointment(patientAppointmentHistoryResponseModel); } Navigator.pop(context, false); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.symmetric(horizontal: 10.w), height: isTablet || isFoldable ? 46.h : 40.h, icon: AppAssets.checkmark_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, ); } } return Row( children: [ Expanded( flex: 6, child: (AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? _getArrivedButton(context) : CustomButton( text: AppointmentType.getNextActionText(patientAppointmentHistoryResponseModel.nextAction), onPressed: () => _goToDetails(context), backgroundColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.15), borderColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01), textColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction), fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.symmetric(horizontal: 10.w), height: isTablet || isFoldable ? 46.h : 40.h, icon: AppointmentType.getNextActionIcon(patientAppointmentHistoryResponseModel.nextAction), iconColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction), iconSize: 15.h, )) .toShimmer2(isShow: isLoading), ), SizedBox(width: 8.h), Expanded( flex: 1, child: Container( height: (isFoldable || isTablet) ? 50.h : 40.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.textColor, borderRadius: 10.h), child: Transform.flip( flipX: appState.isArabic(), child: Utils.buildSvgWithAssets( icon: AppAssets.forward_arrow_icon, iconColor: AppColors.whiteColor, width: 24.w, height: 24.h, fit: BoxFit.contain, ), ), ).toShimmer2(isShow: isLoading).onPress(() { _goToDetails(context); }), ), ], ); } Widget _getArrivedButton(BuildContext context) { final isRecent = DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15; if (isRecent) { return CustomButton( text: LocaleKeys.askDoctor.tr(context: context), onPressed: () async { LoaderBottomSheet.showLoader(loadingText: "Checking doctor availability...".needTranslation); await myAppointmentsViewModel.isDoctorAvailable( projectID: patientAppointmentHistoryResponseModel.projectID, doctorId: patientAppointmentHistoryResponseModel.doctorID, clinicId: patientAppointmentHistoryResponseModel.clinicID, onSuccess: (value) async { if (value) { print("Doctor is available"); await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( context, title: LocaleKeys.askDoctor.tr(context: context), child: AskDoctorRequestTypeSelect( askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList, myAppointmentsViewModel: myAppointmentsViewModel, patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, ), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, ); }); } else { print("Doctor is not available"); } }); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.symmetric(horizontal: 10.w), height: isTablet || isFoldable ? 46.h : 40.h, icon: AppAssets.ask_doctor_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, ); } return CustomButton( text: 'Rebook with same doctor'.needTranslation, onPressed: () => openDoctorScheduleCalendar(context), backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, textColor: AppColors.blackColor, fontSize: 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.symmetric(horizontal: 10.w), height: isTablet || isFoldable ? 46.h : 40.h, icon: AppAssets.rebook_appointment_icon, iconColor: AppColors.blackColor, iconSize: 16.h, ); } void _goToDetails(BuildContext context) { if (isFromMedicalReport) return; if (isForEyeMeasurements) { Navigator.of(context).push( CustomPageRoute( page: EyeMeasurementDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel), ), ); } else { Navigator.of(context) .push( CustomPageRoute( page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel), ), ) .then((_) { myAppointmentsViewModel.initAppointmentsViewModel(); myAppointmentsViewModel.getPatientAppointments(true, false); }); } } void openDoctorScheduleCalendar(BuildContext context) async { final doctor = DoctorsListResponseModel( clinicID: patientAppointmentHistoryResponseModel.clinicID, projectID: patientAppointmentHistoryResponseModel.projectID, doctorID: patientAppointmentHistoryResponseModel.doctorID, doctorImageURL: patientAppointmentHistoryResponseModel.doctorImageURL, doctorTitle: patientAppointmentHistoryResponseModel.doctorTitle, name: patientAppointmentHistoryResponseModel.doctorNameObj, nationalityFlagURL: 'https://hmgwebservices.com/Images/flag/SYR.png', speciality: [], clinicName: patientAppointmentHistoryResponseModel.clinicName, projectName: patientAppointmentHistoryResponseModel.projectName, ); bookAppointmentsViewModel.setSelectedDoctor(doctor); LoaderBottomSheet.showLoader(); await bookAppointmentsViewModel.getDoctorFreeSlots( isBookingForLiveCare: false, onSuccess: (respData) async { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( context, child: AppointmentCalendar(), callBackFunc: () {}, title: 'Pick a Date'.needTranslation, isFullScreen: false, isCloseButtonVisible: true, ); }, onError: (err) { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( context, child: Utils.getErrorWidget(loadingText: err), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, ); }, ); } }