haroon_dev #178

Merged
Haroon6138 merged 3 commits from haroon_dev into master 2 months ago

@ -1496,10 +1496,6 @@
"someRemarksAboutPrescription": "ستجدون هنا بعض الملاحظات حول الوصفة الطبية", "someRemarksAboutPrescription": "ستجدون هنا بعض الملاحظات حول الوصفة الطبية",
"notifyMeBeforeConsumptionTime": "أبلغني قبل وقت الاستهلاك", "notifyMeBeforeConsumptionTime": "أبلغني قبل وقت الاستهلاك",
"noMedicationsToday": "لا أدوية اليوم", "noMedicationsToday": "لا أدوية اليوم",
"route": "Route: {route}",
"frequency": "Frequency: {frequency}",
"instruction": "Instruction: {instruction}",
"duration": "Duration: {days}",
"reminders": "تذكيرات", "reminders": "تذكيرات",
"reminderAddedToCalendar": "تمت إضافة تذكير إلى التقويم ✅", "reminderAddedToCalendar": "تمت إضافة تذكير إلى التقويم ✅",
"errorWhileSettingCalendar": "حدث خطأ أثناء ضبط التقويم:{error}", "errorWhileSettingCalendar": "حدث خطأ أثناء ضبط التقويم:{error}",

@ -1487,10 +1487,8 @@
"someRemarksAboutPrescription": "some remarks about the prescription will be here", "someRemarksAboutPrescription": "some remarks about the prescription will be here",
"notifyMeBeforeConsumptionTime": "Notify me before the consumption time", "notifyMeBeforeConsumptionTime": "Notify me before the consumption time",
"noMedicationsToday": "No medications today", "noMedicationsToday": "No medications today",
"route": "Route: {route}", "route": "Route",
"frequency": "Frequency: {frequency}", "frequency": "Frequency",
"instruction": "Instruction: {instruction}",
"duration": "Duration: {days}",
"reminders": "Reminders", "reminders": "Reminders",
"reminderAddedToCalendar": "Reminder added to calendar ✅", "reminderAddedToCalendar": "Reminder added to calendar ✅",
"errorWhileSettingCalendar": "Error while setting calendar: {error}", "errorWhileSettingCalendar": "Error while setting calendar: {error}",

@ -184,7 +184,6 @@ class ApiClientImp implements ApiClient {
// body['TokenID'] = "@dm!n"; // body['TokenID'] = "@dm!n";
// body['PatientID'] = 4769038; // body['PatientID'] = 4769038;
// body['PatientTypeID'] = 1; // body['PatientTypeID'] = 1;
//
// body['PatientOutSA'] = 0; // body['PatientOutSA'] = 0;
// body['SessionID'] = "45786230487560q"; // body['SessionID'] = "45786230487560q";
} }

@ -605,7 +605,7 @@ class AuthenticationViewModel extends ChangeNotifier {
} }
// _appState.setUserBloodGroup = (activation.patientBlodType ?? ""); // _appState.setUserBloodGroup = (activation.patientBlodType ?? "");
_appState.setAppAuthToken = activation.authenticationTokenId; _appState.setAppAuthToken = activation.authenticationTokenId;
myAppointmentsVM.getActiveAppointmentsCount(); // myAppointmentsVM.getActiveAppointmentsCount();
final request = RequestUtils.getAuthanticatedCommonRequest().toJson(); final request = RequestUtils.getAuthanticatedCommonRequest().toJson();
bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request); bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request);

@ -30,6 +30,8 @@ abstract class BookAppointmentsRepo {
Future<Either<Failure, GenericApiModel<DoctorsProfileResponseModel>>> getDoctorProfile(int clinicID, int projectID, int doctorId, {Function(dynamic)? onSuccess, Function(String)? onError}); Future<Either<Failure, GenericApiModel<DoctorsProfileResponseModel>>> getDoctorProfile(int clinicID, int projectID, int doctorId, {Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorRatingDetails(int doctorId, {Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare, Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare,
{bool continueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}); {bool continueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError});
@ -298,6 +300,52 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
} }
} }
@override
Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorRatingDetails(int doctorId, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"DoctorID": doctorId,
"PatientID": 0,
"License": true,
"IsRegistered": true,
"isDentalAllowedBackend": false,
};
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(
GET_DOCTOR_RATING_DETAILS,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
if (onError != null) {
onError(error);
}
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response,
);
if (onSuccess != null) {
onSuccess(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()));
}
}
//TODO: Implement the logic for Dental & laser clinics //TODO: Implement the logic for Dental & laser clinics
@override @override
Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare, Future<Either<Failure, GenericApiModel<dynamic>>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare,

@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/features/book_appointments/models/free_slot.
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/appointment_nearest_gate_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/appointment_nearest_gate_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_rating_details_response_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/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_patient_dental_plan_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_patient_dental_plan_response_model.dart';
@ -92,6 +93,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
late DoctorsProfileResponseModel doctorsProfileResponseModel; late DoctorsProfileResponseModel doctorsProfileResponseModel;
bool isDoctorRatingDetailsLoading = false;
List<DoctorRateDetails> doctorDetailsList = [];
List<FreeSlot> slotsList = []; List<FreeSlot> slotsList = [];
List<TimeSlot> docFreeSlots = []; List<TimeSlot> docFreeSlots = [];
List<TimeSlot> dayEvents = []; List<TimeSlot> dayEvents = [];
@ -340,6 +344,14 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
setIsLiveCareDoctorsListLoading(bool value) {
if (value) {
liveCareDoctorsList.clear();
}
isDoctorsListLoading = value;
notifyListeners();
}
setIsClinicsListLoading(bool value) { setIsClinicsListLoading(bool value) {
if (value) { if (value) {
clinicsList.clear(); clinicsList.clear();
@ -467,10 +479,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
} }
Future<void> getLiveCareDoctorsList({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getLiveCareDoctorsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear(); liveCareDoctorsList.clear();
notifyListeners();
final result = final result =
await bookAppointmentsRepo.getLiveCareDoctorsList(selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!, onError: onError); await bookAppointmentsRepo.getLiveCareDoctorsList(selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!, onError: onError);
result.fold( result.fold(
(failure) async { (failure) async {
onError!(LocaleKeys.noDoctorFound.tr()); onError!(LocaleKeys.noDoctorFound.tr());
@ -614,6 +626,46 @@ class BookAppointmentsViewModel extends ChangeNotifier {
); );
} }
Future<void> getDoctorRatingDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async {
isDoctorRatingDetailsLoading = true;
doctorDetailsList.clear();
notifyListeners();
final result = await bookAppointmentsRepo.getDoctorRatingDetails(selectedDoctor.doctorID ?? 0, onSuccess: onSuccess, onError: onError);
result.fold(
(failure) async {
if (onError != null) {
onError("Failed to load doctor rating details");
}
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
if (onError != null) {
onError(apiResponse.errorMessage ?? "Unknown error occurred");
}
isDoctorRatingDetailsLoading = false;
} else if (apiResponse.messageStatus == 1) {
try {
apiResponse.data['DoctorRatingDetailsList'].forEach((v) {
doctorDetailsList.add(DoctorRateDetails.fromJson(v));
});
isDoctorRatingDetailsLoading = false;
// doctorRatingDetails = DoctorRateDetails.fromJson(apiResponse.data);
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse.data);
}
} catch (e) {
if (onError != null) {
onError("Failed to parse rating details: ${e.toString()}");
}
}
}
},
);
}
Future<void> getDoctorFreeSlots({bool isBookingForLiveCare = false, Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getDoctorFreeSlots({bool isBookingForLiveCare = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
docFreeSlots.clear(); docFreeSlots.clear();
DateTime date; DateTime date;

@ -0,0 +1,36 @@
class DoctorRateDetails {
dynamic doctorID;
dynamic projectID;
dynamic clinicID;
dynamic rate;
dynamic patientNumber;
dynamic ratio;
DoctorRateDetails(
{this.doctorID,
this.projectID,
this.clinicID,
this.rate,
this.patientNumber,
this.ratio});
DoctorRateDetails.fromJson(Map<String, dynamic> json) {
doctorID = json['DoctorID'];
projectID = json['ProjectID'];
clinicID = json['ClinicID'];
rate = json['Rate'];
patientNumber = json['PatientNumber'];
ratio = json['Ratio'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['DoctorID'] = this.doctorID;
data['ProjectID'] = this.projectID;
data['ClinicID'] = this.clinicID;
data['Rate'] = this.rate;
data['PatientNumber'] = this.patientNumber;
data['Ratio'] = this.ratio;
return data;
}
}

@ -41,6 +41,7 @@ class MedicalFileViewModel extends ChangeNotifier {
List<SickLeaveList> patientSickLeavesViewList = []; List<SickLeaveList> patientSickLeavesViewList = [];
bool isSickLeavesSortByClinic = true; bool isSickLeavesSortByClinic = true;
bool isSickLeavesDataNeedsReloading = true;
List<GetAllergiesResponseModel> patientAllergiesList = []; List<GetAllergiesResponseModel> patientAllergiesList = [];
@ -163,15 +164,15 @@ class MedicalFileViewModel extends ChangeNotifier {
} }
setIsPatientSickLeaveListLoading(bool val) { setIsPatientSickLeaveListLoading(bool val) {
if (val) { if (val && isSickLeavesDataNeedsReloading) {
patientSickLeaveList.clear(); patientSickLeaveList.clear();
patientSickLeavesByClinic.clear(); patientSickLeavesByClinic.clear();
patientSickLeavesByHospital.clear(); patientSickLeavesByHospital.clear();
patientSickLeavesViewList.clear(); patientSickLeavesViewList.clear();
patientSickLeavePDFBase64 = ""; patientSickLeavePDFBase64 = "";
isSickLeavesSortByClinic = true; isSickLeavesSortByClinic = true;
}
isPatientSickLeaveListLoading = val; isPatientSickLeaveListLoading = val;
}
notifyListeners(); notifyListeners();
} }
@ -267,6 +268,10 @@ class MedicalFileViewModel extends ChangeNotifier {
} }
Future<void> getPatientSickLeaveList({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientSickLeaveList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isSickLeavesDataNeedsReloading) {
return;
}
patientSickLeaveList.clear(); patientSickLeaveList.clear();
final result = await medicalFileRepo.getPatientSickLeavesList(); final result = await medicalFileRepo.getPatientSickLeavesList();
@ -309,6 +314,7 @@ class MedicalFileViewModel extends ChangeNotifier {
} }
} }
patientSickLeavesViewList = patientSickLeavesByClinic; patientSickLeavesViewList = patientSickLeavesByClinic;
isSickLeavesDataNeedsReloading = false;
notifyListeners(); notifyListeners();
if (onSuccess != null) { if (onSuccess != null) {

@ -47,20 +47,24 @@ class PrescriptionsViewModel extends ChangeNotifier {
late GeocodeResponse locationGeocodeResponse; late GeocodeResponse locationGeocodeResponse;
bool isPrescriptionsDeliveryOrdersLoading = false; bool isPrescriptionsDeliveryOrdersLoading = false;
bool isPrescriptionsDataNeedsReloading = true;
List<PrescriptionDeliveryResponseModel> prescriptionsOrderList = []; List<PrescriptionDeliveryResponseModel> prescriptionsOrderList = [];
PrescriptionsViewModel({required this.prescriptionsRepo, required this.errorHandlerService, required this.navServices}); PrescriptionsViewModel({required this.prescriptionsRepo, required this.errorHandlerService, required this.navServices});
initPrescriptionsViewModel() { initPrescriptionsViewModel() {
if (isPrescriptionsDataNeedsReloading) {
patientPrescriptionOrders.clear(); patientPrescriptionOrders.clear();
patientPrescriptionOrdersByClinic.clear(); patientPrescriptionOrdersByClinic.clear();
patientPrescriptionOrdersByHospital.clear(); patientPrescriptionOrdersByHospital.clear();
patientPrescriptionOrdersViewList.clear(); patientPrescriptionOrdersViewList.clear();
prescriptionsOrderList.clear(); prescriptionsOrderList.clear();
isPrescriptionsOrdersLoading = true; isPrescriptionsOrdersLoading = true;
getPatientPrescriptionOrders();
}
isSortByClinic = true; isSortByClinic = true;
isPrescriptionsDeliveryOrdersLoading = true; isPrescriptionsDeliveryOrdersLoading = true;
getPatientPrescriptionOrders();
notifyListeners(); notifyListeners();
} }
@ -98,6 +102,10 @@ class PrescriptionsViewModel extends ChangeNotifier {
} }
Future<void> getPatientPrescriptionOrders({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientPrescriptionOrders({Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isPrescriptionsDataNeedsReloading) {
return;
}
final result = await prescriptionsRepo.getPatientPrescriptionOrders(patientId: "1231755"); final result = await prescriptionsRepo.getPatientPrescriptionOrders(patientId: "1231755");
result.fold( result.fold(
@ -131,6 +139,7 @@ class PrescriptionsViewModel extends ChangeNotifier {
} }
} }
patientPrescriptionOrdersViewList = patientPrescriptionOrdersByClinic; patientPrescriptionOrdersViewList = patientPrescriptionOrdersByClinic;
isPrescriptionsDataNeedsReloading = false;
notifyListeners(); notifyListeners();
if (onSuccess != null) { if (onSuccess != null) {
onSuccess(apiResponse); onSuccess(apiResponse);

@ -13,17 +13,20 @@ class TodoSectionViewModel extends ChangeNotifier {
String? notificationsCount = "0"; String? notificationsCount = "0";
initializeTodoSectionViewModel() async { initializeTodoSectionViewModel() async {
if (isAncillaryOrdersNeedReloading) {
patientAncillaryOrdersList.clear(); patientAncillaryOrdersList.clear();
isAncillaryOrdersLoading = true; isAncillaryOrdersLoading = true;
isAncillaryDetailsProceduresLoading = true; isAncillaryDetailsProceduresLoading = true;
notificationsCount = "0"; notificationsCount = "0";
getPatientOnlineAncillaryOrderList(); getPatientOnlineAncillaryOrderList();
}
getPatientDashboard(); getPatientDashboard();
} }
bool isAncillaryOrdersLoading = false; bool isAncillaryOrdersLoading = false;
bool isAncillaryDetailsProceduresLoading = false; bool isAncillaryDetailsProceduresLoading = false;
bool isProcessingPayment = false; bool isProcessingPayment = false;
bool isAncillaryOrdersNeedReloading = true;
List<AncillaryOrderItem> patientAncillaryOrdersList = []; List<AncillaryOrderItem> patientAncillaryOrdersList = [];
List<AncillaryOrderProcedureItem> patientAncillaryOrderProceduresList = []; List<AncillaryOrderProcedureItem> patientAncillaryOrderProceduresList = [];
@ -32,6 +35,11 @@ class TodoSectionViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void setIsAncillaryOrdersNeedReloading(bool value) {
isAncillaryOrdersNeedReloading = value;
notifyListeners();
}
Future<void> getPatientDashboard({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientDashboard({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await todoSectionRepo.getPatientDashboard(); final result = await todoSectionRepo.getPatientDashboard();
@ -55,6 +63,10 @@ class TodoSectionViewModel extends ChangeNotifier {
} }
Future<void> getPatientOnlineAncillaryOrderList({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientOnlineAncillaryOrderList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
if (!isAncillaryOrdersNeedReloading) {
return;
}
patientAncillaryOrdersList.clear(); patientAncillaryOrdersList.clear();
isAncillaryOrdersLoading = true; isAncillaryOrdersLoading = true;
notifyListeners(); notifyListeners();
@ -71,6 +83,7 @@ class TodoSectionViewModel extends ChangeNotifier {
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {
patientAncillaryOrdersList = apiResponse.data!; patientAncillaryOrdersList = apiResponse.data!;
isAncillaryOrdersLoading = false; isAncillaryOrdersLoading = false;
isAncillaryOrdersNeedReloading = false;
notifyListeners(); notifyListeners();
if (onSuccess != null) { if (onSuccess != null) {
onSuccess(apiResponse); onSuccess(apiResponse);

@ -15,6 +15,7 @@ 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/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/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/contact_us/contact_us_view_model.dart';
import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/lab_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/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/my_appointments_view_model.dart';
@ -92,6 +93,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
title: LocaleKeys.appointmentDetails.tr(context: context), title: LocaleKeys.appointmentDetails.tr(context: context),
report: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) report: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? () { ? () {
contactUsViewModel.setSelectedFeedbackType(FeedbackType(id: 1, nameEN: "Complaint for appointment", nameAR: 'شكوى على موعد'));
contactUsViewModel.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel); contactUsViewModel.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel);
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
@ -214,11 +216,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
borderRadius: BorderRadius.circular(24.r), borderRadius: BorderRadius.circular(24.r),
// Todo: what is this???? Api Key??? 😲 // Todo: what is this???? Api Key??? 😲
child: Image.network( child: Image.network(
"https://maps.googleapis.com/maps/api/staticmap?center=${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&zoom=14&size=${(MediaQuery.of(context).size.width * 1.5).toInt()}x165&maptype=roadmap&markers=color:red%7C${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&key=${ApiKeyConstants.googleMapsApiKey}", "https://maps.googleapis.com/maps/api/staticmap?center=${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&zoom=14&size=${(MediaQuery.of(context).size.width * 1.5).toInt()}x${(MediaQuery.of(context).size.height * 0.35).toInt()}&maptype=roadmap&markers=color:red%7C${widget.patientAppointmentHistoryResponseModel.latitude},${widget.patientAppointmentHistoryResponseModel.longitude}&key=${ApiKeyConstants.googleMapsApiKey}",
fit: BoxFit.contain, fit: BoxFit.contain,
// errorBuilder: (cxt, child, tr) {
// return SizedBox.shrink();
// },
), ),
), ),
Positioned( Positioned(
@ -756,6 +755,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
], ],
).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h), ).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h),
AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? !widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? CustomButton( ? CustomButton(
text: LocaleKeys.rebookAppointment.tr(context: context), text: LocaleKeys.rebookAppointment.tr(context: context),
onPressed: () { onPressed: () {
@ -773,6 +773,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
iconSize: 18.h, iconSize: 18.h,
).paddingSymmetrical(16.h, 24.h) ).paddingSymmetrical(16.h, 24.h)
: SizedBox.shrink()
: CustomButton( : CustomButton(
text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction),
onPressed: () { onPressed: () {

@ -153,7 +153,7 @@ class AppointmentCard extends StatelessWidget {
SizedBox(height: 2.h), SizedBox(height: 2.h),
(isFoldable || isTablet) (isFoldable || isTablet)
? "${patientAppointmentHistoryResponseModel.decimalDoctorRate}".toText9(isBold: true, color: AppColors.textColor) ? "${patientAppointmentHistoryResponseModel.decimalDoctorRate}".toText9(isBold: true, color: AppColors.textColor)
: "${patientAppointmentHistoryResponseModel.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor), : "${patientAppointmentHistoryResponseModel.decimalDoctorRate ?? "0.0"}".toText11(isBold: true, color: AppColors.textColor),
], ],
), ),
).circle(100).toShimmer2(isShow: isLoading), ).circle(100).toShimmer2(isShow: isLoading),
@ -228,8 +228,16 @@ class AppointmentCard extends StatelessWidget {
Widget _buildActionArea(BuildContext context, AppState appState) { Widget _buildActionArea(BuildContext context, AppState appState) {
if ((patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) && AppointmentType.isArrived(patientAppointmentHistoryResponseModel)) { if ((patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) && AppointmentType.isArrived(patientAppointmentHistoryResponseModel)) {
return CustomButton( return CustomButton(
text: LocaleKeys.viewDetails.tr(context: context), text: isFromMedicalReport ? LocaleKeys.selectAppointment.tr(context: context) : LocaleKeys.viewDetails.tr(context: context),
onPressed: () { onPressed: () {
if (isFromMedicalReport) {
if (isForFeedback) {
contactUsViewModel!.setPatientFeedbackSelectedAppointment(patientAppointmentHistoryResponseModel);
} else {
medicalFileViewModel!.setSelectedMedicalReportAppointment(patientAppointmentHistoryResponseModel);
}
Navigator.pop(context, false);
} else {
Navigator.of(context) Navigator.of(context)
.push( .push(
CustomPageRoute( CustomPageRoute(
@ -240,6 +248,7 @@ class AppointmentCard extends StatelessWidget {
myAppointmentsViewModel.initAppointmentsViewModel(); myAppointmentsViewModel.initAppointmentsViewModel();
myAppointmentsViewModel.getPatientAppointments(true, false); myAppointmentsViewModel.getPatientAppointments(true, false);
}); });
}
}, },
backgroundColor: AppColors.secondaryLightRedColor, backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor,
@ -250,6 +259,9 @@ class AppointmentCard extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 10.w), padding: EdgeInsets.symmetric(horizontal: 10.w),
// height: isTablet || isFoldable ? 46.h : 40.h, // height: isTablet || isFoldable ? 46.h : 40.h,
height: 40.h, height: 40.h,
icon: isFromMedicalReport ? AppAssets.checkmark_icon : null,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
); );
} else { } else {
if (isFromMedicalReport) { if (isFromMedicalReport) {

@ -159,7 +159,8 @@ class AppointmentDoctorCard extends StatelessWidget {
icon: AppAssets.ask_doctor_icon, icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
) )
: CustomButton( : !patientAppointmentHistoryResponseModel.isLiveCareAppointment!
? CustomButton(
text: LocaleKeys.rebookSameDoctor.tr(), text: LocaleKeys.rebookSameDoctor.tr(),
onPressed: () { onPressed: () {
onRescheduleTap(); onRescheduleTap();
@ -175,7 +176,8 @@ class AppointmentDoctorCard extends StatelessWidget {
icon: AppAssets.rebook_appointment_icon, icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
iconSize: 14.h, iconSize: 14.h,
); )
: SizedBox.shrink();
} else { } else {
return patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false return patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false
? CustomButton( ? CustomButton(

@ -11,6 +11,7 @@ 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/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/doctor_rating_details.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@ -108,9 +109,21 @@ class DoctorProfilePage extends StatelessWidget {
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
"Ratings".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), "Ratings".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
bookAppointmentsViewModel.doctorsProfileResponseModel.decimalDoctorRate.toString().toText16(isBold: true, color: AppColors.textColor), bookAppointmentsViewModel.doctorsProfileResponseModel.decimalDoctorRate
.toString()
.toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor),
], ],
), ).onPress(() {
bookAppointmentsViewModel.getDoctorRatingDetails();
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.doctorRating.tr(context: context),
context,
child: DoctorRatingDetails(),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}),
SizedBox(width: 36.w), SizedBox(width: 36.w),
Column( Column(
children: [ children: [
@ -122,15 +135,28 @@ class DoctorProfilePage extends StatelessWidget {
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
"Reviews".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), "Reviews".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
bookAppointmentsViewModel.doctorsProfileResponseModel.noOfPatientsRate.toString().toText16(isBold: true, color: AppColors.textColor), bookAppointmentsViewModel.doctorsProfileResponseModel.noOfPatientsRate
.toString()
.toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor),
], ],
), ).onPress(() {
bookAppointmentsViewModel.getDoctorRatingDetails();
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.doctorRating.tr(context: context),
context,
child: DoctorRatingDetails(),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}),
], ],
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
SizedBox(height: 16.h), SizedBox(height: 16.h),
"Biography".toText14(weight: FontWeight.w600, color: AppColors.textColor), LocaleKeys.docInfo.tr(context: context).toText14(weight: FontWeight.w600, color: AppColors.textColor),
SizedBox(height: 6.h),
bookAppointmentsViewModel.doctorsProfileResponseModel.doctorProfileInfo!.toText12(fontWeight: FontWeight.w600, color: AppColors.greyTextColor), bookAppointmentsViewModel.doctorsProfileResponseModel.doctorProfileInfo!.toText12(fontWeight: FontWeight.w600, color: AppColors.greyTextColor),
], ],
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),

@ -941,7 +941,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
void onLiveCareClinicSelected(GetLiveCareClinicsResponseModel clinic) { void onLiveCareClinicSelected(GetLiveCareClinicsResponseModel clinic) {
bookAppointmentsViewModel.setLiveCareSelectedClinic(clinic); bookAppointmentsViewModel.setLiveCareSelectedClinic(clinic);
bookAppointmentsViewModel.setIsDoctorsListLoading(true); bookAppointmentsViewModel.setIsLiveCareDoctorsListLoading(true);
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: SelectDoctorPage(), page: SelectDoctorPage(),

@ -95,7 +95,57 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h), padding: EdgeInsets.symmetric(horizontal: 24.h),
child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) { child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
return Column( return bookAppointmentsViewModel.isLiveCareSchedule
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
padding: EdgeInsets.only(top: 16.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 : (bookAppointmentsVM.liveCareDoctorsList.isNotEmpty ? bookAppointmentsVM.liveCareDoctorsList.length : 1),
itemBuilder: (context, index) {
// final isExpanded = bookAppointmentsVM.expandedGroupIndex == index;
final isExpanded = true;
return bookAppointmentsVM.isDoctorsListLoading
? DoctorCard(
doctorsListResponseModel: DoctorsListResponseModel(),
isLoading: true,
bookAppointmentsViewModel: bookAppointmentsViewModel,
)
: bookAppointmentsVM.liveCareDoctorsList.isEmpty
? Utils.getNoDataWidget(context, noDataText: LocaleKeys.noDoctorFound.tr())
: 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,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: Padding(
padding: EdgeInsets.all(16.h),
child: DoctorCard(
isLoading: bookAppointmentsVM.isClinicsListLoading,
doctorsListResponseModel: bookAppointmentsVM.liveCareDoctorsList[index],
bookAppointmentsViewModel: bookAppointmentsViewModel,
).onPress(() {
// onLiveCareClinicSelected(bookAppointmentsVM.liveCareClinicsList[index]);
}),
),
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
),
SizedBox(height: 24.h),
],
)
: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox(height: 16.h), SizedBox(height: 16.h),

@ -90,7 +90,7 @@ class DoctorCard extends StatelessWidget {
Row( Row(
children: [ children: [
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width * 0.49, width: MediaQuery.of(context).size.width * 0.55,
child: (isLoading ? "Dr John Smith" : "${doctorsListResponseModel.doctorTitle} ${doctorsListResponseModel.name}") child: (isLoading ? "Dr John Smith" : "${doctorsListResponseModel.doctorTitle} ${doctorsListResponseModel.name}")
.toString() .toString()
.toText16(isBold: true, maxlines: 1), .toText16(isBold: true, maxlines: 1),
@ -99,14 +99,14 @@ class DoctorCard extends StatelessWidget {
), ),
SizedBox(height: 2.h), SizedBox(height: 2.h),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width * 0.45,
child: (isLoading child: (isLoading
? "Consultant Cardiologist" ? "Consultant Cardiologist"
: doctorsListResponseModel.speciality!.isNotEmpty : doctorsListResponseModel.speciality!.isNotEmpty
? doctorsListResponseModel.speciality!.first ? (doctorsListResponseModel.speciality!.first.length > 32
? '${doctorsListResponseModel.speciality!.first.substring(0, 32)}...'
: doctorsListResponseModel.speciality!.first)
: "") : "")
.toString() .toString()
.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, maxLine: 2) .toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, maxLine: 2)
@ -121,16 +121,7 @@ class DoctorCard extends StatelessWidget {
).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
], ],
), ),
], SizedBox(height: 6.h),
),
),
Expanded(
flex: 1,
child: Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown)
.toShimmer2(isShow: isLoading),
),
],
),
Wrap( Wrap(
direction: Axis.horizontal, direction: Axis.horizontal,
spacing: 3.h, spacing: 3.h,
@ -153,6 +144,16 @@ class DoctorCard extends StatelessWidget {
: SizedBox.shrink(), : SizedBox.shrink(),
], ],
), ),
],
),
),
Expanded(
flex: 1,
child: Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown)
.toShimmer2(isShow: isLoading),
),
],
),
SizedBox(height: 12.h), SizedBox(height: 12.h),
CustomButton( CustomButton(
text: LocaleKeys.bookAppo.tr(context: context), text: LocaleKeys.bookAppo.tr(context: context),

@ -0,0 +1,195 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.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/features/book_appointments/book_appointments_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:provider/provider.dart';
class DoctorRatingDetails extends StatelessWidget {
const DoctorRatingDetails({super.key});
@override
Widget build(BuildContext context) {
return Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
return bookAppointmentsVM.isDoctorRatingDetailsLoading
? Utils.getLoadingWidget()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.ceilToDouble().toString().toText44(isBold: true),
SizedBox(height: 4.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${bookAppointmentsVM.doctorsProfileResponseModel.noOfPatientsRate} ${LocaleKeys.reviews.tr(context: context)}"
.toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor),
RatingBar(
initialRating: bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.toDouble(),
direction: Axis.horizontal,
allowHalfRating: true,
itemCount: 5,
itemSize: 20.h,
ignoreGestures: true,
ratingWidget: RatingWidget(
full: Icon(
Icons.star,
color: AppColors.ratingColorYellow,
size: 24.h,
),
half: Icon(
Icons.star_half,
color: AppColors.ratingColorYellow,
),
empty: Icon(
Icons.star,
color: AppColors.ratingColorYellow,
),
),
tapOnlyMode: true,
unratedColor: Colors.grey[500],
itemPadding: EdgeInsets.symmetric(horizontal: 4.0),
onRatingUpdate: (rating) {
print(rating);
},
),
],
),
SizedBox(height: 8.h),
Container(
margin: EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 100.0,
margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0),
child: Text(LocaleKeys.excellent.tr(context: context), style: TextStyle(fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w600))),
getRatingLine(bookAppointmentsVM.doctorDetailsList[0].ratio, Colors.green[700]!),
],
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${getRatingWidth(bookAppointmentsVM.doctorDetailsList[0].ratio).round()}%", style: TextStyle(fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.w600)),
),
],
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 100.0,
margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0),
child: Text(LocaleKeys.vGood.tr(context: context), style: TextStyle(fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w600))),
getRatingLine(bookAppointmentsVM.doctorDetailsList[1].ratio, Color(0xffB7B723)),
],
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[1].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.w600)),
),
],
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 100.0,
margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0),
child: Text(LocaleKeys.good.tr(context: context), style: TextStyle(fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w600))),
getRatingLine(bookAppointmentsVM.doctorDetailsList[2].ratio, Color(0xffEBA727)),
],
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[2].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.w600)),
),
],
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 100.0,
margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0),
child: Text(LocaleKeys.average.tr(context: context), style: TextStyle(fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w600))),
getRatingLine(bookAppointmentsVM.doctorDetailsList[3].ratio, Color(0xffEB7227)),
],
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[3].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.w600)),
),
],
),
),
Container(
margin: EdgeInsets.only(bottom: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 100.0,
margin: EdgeInsets.only(top: 10.0, left: 15.0, right: 15.0),
child: Text(LocaleKeys.average.tr(context: context), style: TextStyle(fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w600))),
getRatingLine(bookAppointmentsVM.doctorDetailsList[4].ratio, Color(0xffE20C0C)),
],
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[4].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: Colors.black, fontWeight: FontWeight.w600)),
),
],
),
),
],
);
});
}
double getRatingWidth(num patientNumber) {
var width = patientNumber;
return width.roundToDouble();
}
Widget getRatingLine(double patientNumber, Color color) {
return Container(
margin: EdgeInsets.only(top: 10.0),
child: Stack(children: [
SizedBox(
width: 150.0,
height: 7.h,
child: Container(
color: Colors.grey[300],
),
),
SizedBox(
width: patientNumber * 1.55,
height: 7.h,
child: Container(
color: color,
),
),
]),
);
}
}

@ -159,6 +159,15 @@ class ErOnlineCheckinHome extends StatelessWidget {
await vm.getPatientERPaymentInformation(onSuccess: (response) { await vm.getPatientERPaymentInformation(onSuccess: (response) {
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
vm.navigateToEROnlineCheckInPaymentPage(); vm.navigateToEROnlineCheckInPaymentPage();
}, onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err.toString()),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}); });
}, },
onHospitalSearch: (value) { onHospitalSearch: (value) {

@ -204,7 +204,7 @@ class _HealthCalculatorsPageState extends State<HealthCalculatorsPage> {
crossAxisCount: 3, // 4 icons per row crossAxisCount: 3, // 4 icons per row
crossAxisSpacing: 16.w, crossAxisSpacing: 16.w,
mainAxisSpacing: 16.w, mainAxisSpacing: 16.w,
childAspectRatio: 0.80), childAspectRatio: 0.85),
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: type == HealthCalculatorEnum.general ? generalHealthServices.length : womenHealthServices.length, itemCount: type == HealthCalculatorEnum.general ? generalHealthServices.length : womenHealthServices.length,
@ -214,6 +214,7 @@ class _HealthCalculatorsPageState extends State<HealthCalculatorsPage> {
icon: type == HealthCalculatorEnum.general ? generalHealthServices[index].icon : womenHealthServices[index].icon, icon: type == HealthCalculatorEnum.general ? generalHealthServices[index].icon : womenHealthServices[index].icon,
labelText: type == HealthCalculatorEnum.general ? generalHealthServices[index].title : womenHealthServices[index].title, labelText: type == HealthCalculatorEnum.general ? generalHealthServices[index].title : womenHealthServices[index].title,
onTap: () { onTap: () {
Navigator.pop(context);
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: HealthCalculatorDetailedPage( page: HealthCalculatorDetailedPage(

@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.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/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:open_filex/open_filex.dart'; import 'package:open_filex/open_filex.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -197,49 +198,23 @@ class _PatientSickleavesListPageState extends State<PatientSickleavesListPage> {
], ],
), ),
SizedBox(height: 8.h), SizedBox(height: 8.h),
Row( Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [ children: [
CustomButton( AppCustomChipWidget(
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(sickLeave.appointmentDate), false), labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(sickLeave.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: 24.h,
), ),
SizedBox(width: 8.h), AppCustomChipWidget(
CustomButton( labelText: model.isSickLeavesSortByClinic ? sickLeave.projectName! : sickLeave.clinicName!,
text: model.isSickLeavesSortByClinic ? sickLeave.projectName! : sickLeave.clinicName!,
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: 24.h,
), ),
SizedBox(width: 8.h), AppCustomChipWidget(
CustomButton( labelText: "${sickLeave.sickLeaveDays} Days",
text: "${sickLeave.sickLeaveDays} Days",
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: 24.h,
), ),
], ],
), ),
SizedBox(height: 8.h), SizedBox(height: 12.h),
Row( Row(
children: [ children: [
Expanded( Expanded(

@ -80,7 +80,10 @@ class MonthlyReport extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
"${appState.getAuthenticatedUser()!.emailAddress}".toText16(color: AppColors.textColor, weight: FontWeight.w500), SizedBox(
width: MediaQuery.of(context).size.width * 0.7,
child: "${appState.getAuthenticatedUser()!.emailAddress}".toText16(color: AppColors.textColor, weight: FontWeight.w500, maxlines: 2),
),
], ],
), ),
], ],

@ -148,7 +148,7 @@ class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
text: LocaleKeys.downloadPrescription.tr(context: context), text: LocaleKeys.downloadPrescription.tr(context: context),
onPressed: () async { onPressed: () async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionPDFPleaseWait.tr(context: context)); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionPDFPleaseWait.tr(context: context));
await prescriptionVM.getPrescriptionPDFBase64(widget.prescriptionsResponseModel).then((val) async { await prescriptionVM.getPrescriptionPDFBase64(widget.prescriptionsResponseModel, onSuccess: (value) async {
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
if (prescriptionVM.prescriptionPDFBase64Data.isNotEmpty) { if (prescriptionVM.prescriptionPDFBase64Data.isNotEmpty) {
String path = await Utils.createFileFromString(prescriptionVM.prescriptionPDFBase64Data, "pdf"); String path = await Utils.createFileFromString(prescriptionVM.prescriptionPDFBase64Data, "pdf");
@ -164,6 +164,15 @@ class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
); );
} }
} }
}, onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}); });
}, },
backgroundColor: AppColors.successColor.withValues(alpha: 0.15), backgroundColor: AppColors.successColor.withValues(alpha: 0.15),

@ -10,6 +10,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/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.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/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/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
@ -56,75 +57,19 @@ class PrescriptionItemView extends StatelessWidget {
spacing: 6.h, spacing: 6.h,
runSpacing: 6.h, runSpacing: 6.h,
children: [ children: [
Row( AppCustomChipWidget(
mainAxisSize: MainAxisSize.min, labelText: "${LocaleKeys.route.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].route}",
children: [
CustomButton(
text: "${LocaleKeys.route.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].route}",
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,
).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
], AppCustomChipWidget(
), labelText: "${LocaleKeys.frequency.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].frequency}",
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.frequency.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].frequency}",
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,
).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
], AppCustomChipWidget(
), labelText: "${LocaleKeys.dailyDoses.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}",
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.dailyDoses.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}",
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,
).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
], AppCustomChipWidget(
), labelText: "${LocaleKeys.days.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].days}",
Row(
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: "${LocaleKeys.days.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].days}",
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,
).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
], ],
),
],
).paddingSymmetrical(16.h, 0.h), ).paddingSymmetrical(16.h, 0.h),
SizedBox(height: 8.h), SizedBox(height: 8.h),
if (!isLoading) if (!isLoading)

@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart';
import 'package:hmg_patient_app_new/theme/colors.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -207,32 +208,16 @@ class _PrescriptionsListPageState extends State<PrescriptionsListPage> {
], ],
), ),
SizedBox(height: 8.h), SizedBox(height: 8.h),
Row( Wrap(
direction: Axis.horizontal,
spacing: 6.h,
runSpacing: 6.h,
children: [ children: [
CustomButton( AppCustomChipWidget(
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false), labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.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: 24.h,
), ),
SizedBox(width: 8.h), AppCustomChipWidget(
CustomButton( labelText: model.isSortByClinic ? prescription.name! : prescription.clinicDescription!,
text: model.isSortByClinic ? prescription.name! : prescription.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: 24.h,
), ),
], ],
), ),

@ -658,6 +658,7 @@ class _AncillaryOrderDetailsListState extends State<AncillaryOrderDetailsList> {
text: LocaleKeys.proceedToPayment.tr(context: context), text: LocaleKeys.proceedToPayment.tr(context: context),
onPressed: () { onPressed: () {
// Navigate to payment page with selected procedures // Navigate to payment page with selected procedures
todoSectionViewModel.setIsAncillaryOrdersNeedReloading(true);
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
page: AncillaryOrderPaymentPage( page: AncillaryOrderPaymentPage(

@ -71,12 +71,6 @@ class AncillaryOrdersList extends StatelessWidget {
return Center( return Center(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 40.h), padding: EdgeInsets.symmetric(vertical: 40.h),
child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 12.r,
hasShadow: false,
),
child: Utils.getNoDataWidget( child: Utils.getNoDataWidget(
context, context,
noDataText: LocaleKeys.youDontHaveAnyAncillaryOrdersYet.tr(context: context), noDataText: LocaleKeys.youDontHaveAnyAncillaryOrdersYet.tr(context: context),
@ -85,7 +79,6 @@ class AncillaryOrdersList extends StatelessWidget {
height: 62.h, height: 62.h,
), ),
), ),
),
); );
} }
} }

Loading…
Cancel
Save