medical report implementation contd.

pull/30/head
Haroon Amjad 2 months ago
parent de717edfe8
commit 14725616c6

@ -3,6 +3,7 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart';
@ -15,6 +16,8 @@ abstract class MedicalFileRepo {
Future<Either<Failure, GenericApiModel<List<PatientSickLeavesResponseModel>>>> getPatientSickLeavesList(); Future<Either<Failure, GenericApiModel<List<PatientSickLeavesResponseModel>>>> getPatientSickLeavesList();
Future<Either<Failure, GenericApiModel<dynamic>>> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser); Future<Either<Failure, GenericApiModel<dynamic>>> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser);
Future<Either<Failure, GenericApiModel<List<PatientMedicalReportResponseModel>>>> getPatientMedicalReportsList();
} }
class MedicalFileRepoImp implements MedicalFileRepo { class MedicalFileRepoImp implements MedicalFileRepo {
@ -157,4 +160,49 @@ class MedicalFileRepoImp implements MedicalFileRepo {
return Left(UnknownFailure(e.toString())); return Left(UnknownFailure(e.toString()));
} }
} }
@override
Future<Either<Failure, GenericApiModel<List<PatientMedicalReportResponseModel>>>> getPatientMedicalReportsList() async {
Map<String, dynamic> mapDevice = {
"IsReport": true,
"EncounterType": 1,
"RequestType": 1,
};
try {
GenericApiModel<List<PatientMedicalReportResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
REPORTS,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['GetPatientMedicalStatus'];
// if (list == null || list.isEmpty) {
// throw Exception("lab list is empty");
// }
final vaccinesList = list.map((item) => PatientMedicalReportResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientMedicalReportResponseModel>();
apiResponse = GenericApiModel<List<PatientMedicalReportResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: vaccinesList,
);
} 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()));
}
}
} }

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart';
@ -10,6 +11,7 @@ class MedicalFileViewModel extends ChangeNotifier {
bool isPatientVaccineListLoading = false; bool isPatientVaccineListLoading = false;
bool isPatientSickLeaveListLoading = false; bool isPatientSickLeaveListLoading = false;
bool isPatientSickLeavePDFLoading = false; bool isPatientSickLeavePDFLoading = false;
bool isPatientMedicalReportsListLoading = false;
MedicalFileRepo medicalFileRepo; MedicalFileRepo medicalFileRepo;
ErrorHandlerService errorHandlerService; ErrorHandlerService errorHandlerService;
@ -17,12 +19,33 @@ class MedicalFileViewModel extends ChangeNotifier {
List<PatientVaccineResponseModel> patientVaccineList = []; List<PatientVaccineResponseModel> patientVaccineList = [];
List<PatientSickLeavesResponseModel> patientSickLeaveList = []; List<PatientSickLeavesResponseModel> patientSickLeaveList = [];
List<PatientMedicalReportResponseModel> patientMedicalReportList = [];
List<PatientMedicalReportResponseModel> patientMedicalReportRequestedList = [];
List<PatientMedicalReportResponseModel> patientMedicalReportReadyList = [];
List<PatientMedicalReportResponseModel> patientMedicalReportCancelledList = [];
String patientSickLeavePDFBase64 = ""; String patientSickLeavePDFBase64 = "";
int selectedMedicalReportsTabIndex = 0;
MedicalFileViewModel({required this.medicalFileRepo, required this.errorHandlerService}); MedicalFileViewModel({required this.medicalFileRepo, required this.errorHandlerService});
initMedicalFileProvider() { initMedicalFileProvider() {
isPatientVaccineListLoading = true; isPatientVaccineListLoading = true;
isPatientMedicalReportsListLoading = true;
notifyListeners();
}
void onMedicalReportTabChange(int index) {
selectedMedicalReportsTabIndex = index;
if (index == 0) {
patientMedicalReportList = patientMedicalReportRequestedList;
} else if (index == 1) {
patientMedicalReportList = patientMedicalReportReadyList;
} else if (index == 2) {
patientMedicalReportList = patientMedicalReportCancelledList;
}
notifyListeners(); notifyListeners();
} }
@ -44,6 +67,14 @@ class MedicalFileViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
setIsPatientMedicalReportsLoading(bool val) {
if (val) {
patientMedicalReportList.clear();
}
isPatientMedicalReportsListLoading = val;
notifyListeners();
}
void onTabChanged(int index) { void onTabChanged(int index) {
selectedTabIndex = index; selectedTabIndex = index;
notifyListeners(); notifyListeners();
@ -101,7 +132,8 @@ class MedicalFileViewModel extends ChangeNotifier {
); );
} }
Future<void> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser,{Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientSickLeavePDF(PatientSickLeavesResponseModel patientSickLeavesResponseModel, AuthenticatedUser authenticatedUser,
{Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await medicalFileRepo.getPatientSickLeavePDF(patientSickLeavesResponseModel, authenticatedUser); final result = await medicalFileRepo.getPatientSickLeavePDF(patientSickLeavesResponseModel, authenticatedUser);
result.fold( result.fold(
@ -125,4 +157,35 @@ class MedicalFileViewModel extends ChangeNotifier {
}, },
); );
} }
Future<void> getPatientMedicalReportList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
patientMedicalReportList.clear();
final result = await medicalFileRepo.getPatientMedicalReportsList();
result.fold(
(failure) async => await errorHandlerService.handleError(
failure: failure,
onOkPressed: () {
onError!(failure.message);
},
),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
patientMedicalReportList = apiResponse.data!;
if (patientMedicalReportList.isNotEmpty) {
patientMedicalReportRequestedList = patientMedicalReportList.where((element) => element.status == 1).toList();
patientMedicalReportReadyList = patientMedicalReportList.where((element) => element.status == 2).toList();
patientMedicalReportCancelledList = patientMedicalReportList.where((element) => element.status == 4).toList();
}
isPatientMedicalReportsListLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
} }

@ -0,0 +1,192 @@
class PatientMedicalReportResponseModel {
int? status;
String? encounterDate;
int? projectID;
int? invoiceNo;
int? encounterNo;
String? procedureId;
int? requestType;
String? setupId;
int? patientID;
int? doctorID;
int? clinicID;
String? requestDate;
bool? isRead;
dynamic isReadOn;
num? actualDoctorRate;
String? admissionDate;
int? admissionNumber;
String? appointmentDate;
int? appointmentNO;
String? appointmentTime;
String? clinicDescription;
dynamic clinicDescriptionN;
num? decimalDoctorRate;
String? docName;
dynamic docNameN;
String? doctorImageURL;
String? doctorName;
dynamic doctorNameN;
num? doctorRate;
num? doctorStarsRate;
int? invoiceNoVP;
dynamic invoiceType;
bool? isDoctorAllowVedioCall;
bool? isExecludeDoctor;
bool? isInOutPatient;
String? isInOutPatientDescription;
String? isInOutPatientDescriptionN;
int? noOfPatientsRate;
String? projectName;
dynamic projectNameN;
int? sourceID;
dynamic sourceName;
dynamic sourceNameN;
String? statusDesc;
dynamic strAppointmentDate;
PatientMedicalReportResponseModel(
{this.status,
this.encounterDate,
this.projectID,
this.invoiceNo,
this.encounterNo,
this.procedureId,
this.requestType,
this.setupId,
this.patientID,
this.doctorID,
this.clinicID,
this.requestDate,
this.isRead,
this.isReadOn,
this.actualDoctorRate,
this.admissionDate,
this.admissionNumber,
this.appointmentDate,
this.appointmentNO,
this.appointmentTime,
this.clinicDescription,
this.clinicDescriptionN,
this.decimalDoctorRate,
this.docName,
this.docNameN,
this.doctorImageURL,
this.doctorName,
this.doctorNameN,
this.doctorRate,
this.doctorStarsRate,
this.invoiceNoVP,
this.invoiceType,
this.isDoctorAllowVedioCall,
this.isExecludeDoctor,
this.isInOutPatient,
this.isInOutPatientDescription,
this.isInOutPatientDescriptionN,
this.noOfPatientsRate,
this.projectName,
this.projectNameN,
this.sourceID,
this.sourceName,
this.sourceNameN,
this.statusDesc,
this.strAppointmentDate});
PatientMedicalReportResponseModel.fromJson(Map<String, dynamic> json) {
status = json['Status'];
encounterDate = json['EncounterDate'];
projectID = json['ProjectID'];
invoiceNo = json['InvoiceNo'];
encounterNo = json['EncounterNo'];
procedureId = json['ProcedureId'];
requestType = json['RequestType'];
setupId = json['SetupId'];
patientID = json['PatientID'];
doctorID = json['DoctorID'];
clinicID = json['ClinicID'];
requestDate = json['RequestDate'];
isRead = json['IsRead'];
isReadOn = json['IsReadOn'];
actualDoctorRate = json['ActualDoctorRate'];
admissionDate = json['AdmissionDate'];
admissionNumber = json['AdmissionNumber'];
appointmentDate = json['AppointmentDate'];
appointmentNO = json['AppointmentNO'];
appointmentTime = json['AppointmentTime'];
clinicDescription = json['ClinicDescription'];
clinicDescriptionN = json['ClinicDescriptionN'];
decimalDoctorRate = json['DecimalDoctorRate'];
docName = json['DocName'];
docNameN = json['DocNameN'];
doctorImageURL = json['DoctorImageURL'];
doctorName = json['DoctorName'];
doctorNameN = json['DoctorNameN'];
doctorRate = json['DoctorRate'];
doctorStarsRate = json['DoctorStarsRate'];
invoiceNoVP = json['InvoiceNo_VP'];
invoiceType = json['InvoiceType'];
isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall'];
isExecludeDoctor = json['IsExecludeDoctor'];
isInOutPatient = json['IsInOutPatient'];
isInOutPatientDescription = json['IsInOutPatientDescription'];
isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN'];
noOfPatientsRate = json['NoOfPatientsRate'];
projectName = json['ProjectName'];
projectNameN = json['ProjectNameN'];
sourceID = json['SourceID'];
sourceName = json['SourceName'];
sourceNameN = json['SourceNameN'];
statusDesc = json['StatusDesc'];
strAppointmentDate = json['StrAppointmentDate'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Status'] = this.status;
data['EncounterDate'] = this.encounterDate;
data['ProjectID'] = this.projectID;
data['InvoiceNo'] = this.invoiceNo;
data['EncounterNo'] = this.encounterNo;
data['ProcedureId'] = this.procedureId;
data['RequestType'] = this.requestType;
data['SetupId'] = this.setupId;
data['PatientID'] = this.patientID;
data['DoctorID'] = this.doctorID;
data['ClinicID'] = this.clinicID;
data['RequestDate'] = this.requestDate;
data['IsRead'] = this.isRead;
data['IsReadOn'] = this.isReadOn;
data['ActualDoctorRate'] = this.actualDoctorRate;
data['AdmissionDate'] = this.admissionDate;
data['AdmissionNumber'] = this.admissionNumber;
data['AppointmentDate'] = this.appointmentDate;
data['AppointmentNO'] = this.appointmentNO;
data['AppointmentTime'] = this.appointmentTime;
data['ClinicDescription'] = this.clinicDescription;
data['ClinicDescriptionN'] = this.clinicDescriptionN;
data['DecimalDoctorRate'] = this.decimalDoctorRate;
data['DocName'] = this.docName;
data['DocNameN'] = this.docNameN;
data['DoctorImageURL'] = this.doctorImageURL;
data['DoctorName'] = this.doctorName;
data['DoctorNameN'] = this.doctorNameN;
data['DoctorRate'] = this.doctorRate;
data['DoctorStarsRate'] = this.doctorStarsRate;
data['InvoiceNo_VP'] = this.invoiceNoVP;
data['InvoiceType'] = this.invoiceType;
data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall;
data['IsExecludeDoctor'] = this.isExecludeDoctor;
data['IsInOutPatient'] = this.isInOutPatient;
data['IsInOutPatientDescription'] = this.isInOutPatientDescription;
data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN;
data['NoOfPatientsRate'] = this.noOfPatientsRate;
data['ProjectName'] = this.projectName;
data['ProjectNameN'] = this.projectNameN;
data['SourceID'] = this.sourceID;
data['SourceName'] = this.sourceName;
data['SourceNameN'] = this.sourceNameN;
data['StatusDesc'] = this.statusDesc;
data['StrAppointmentDate'] = this.strAppointmentDate;
return data;
}
}

@ -23,6 +23,7 @@ import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.da
import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart';
import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_reports_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/vaccine_list_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/vaccine_list_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart';
@ -601,16 +602,41 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
padding: EdgeInsets.only(top: 12), padding: EdgeInsets.only(top: 12),
shrinkWrap: true, shrinkWrap: true,
children: [ children: [
MedicalFileCard(label: "Update Insurance".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon).onPress(() { MedicalFileCard(
label: "Update Insurance".needTranslation,
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.eye_result_icon,
isLargeText: false,
iconSize: 36.h)
.onPress(() {
Navigator.of(context).push( Navigator.of(context).push(
FadePage( FadePage(
page: InsuranceHomePage(), page: InsuranceHomePage(),
), ),
); );
}), }),
MedicalFileCard(label: "Insurance Approvals".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), MedicalFileCard(
MedicalFileCard(label: "My Invoices List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), label: "Insurance Approvals".needTranslation,
MedicalFileCard(label: "Ancillary Orders List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.eye_result_icon,
isLargeText: false,
iconSize: 36.h),
MedicalFileCard(
label: "My Invoices List".needTranslation,
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.eye_result_icon,
isLargeText: false,
iconSize: 36.h),
MedicalFileCard(
label: "Ancillary Orders List".needTranslation,
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.eye_result_icon,
isLargeText: false,
iconSize: 36.h),
], ],
).paddingSymmetrical(24.h, 0.0), ).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -626,31 +652,61 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), patientSickLeavesResponseModel: PatientSickLeavesResponseModel(),
isLoading: true, isLoading: true,
).paddingSymmetrical(24.h, 0.0) ).paddingSymmetrical(24.h, 0.0)
: medicalFileVM.patientSickLeaveList.isNotEmpty ? PatientSickLeaveCard( : medicalFileVM.patientSickLeaveList.isNotEmpty
patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first, ? PatientSickLeaveCard(
isLoading: false, patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first,
).paddingSymmetrical(24.h, 0.0) : SizedBox.shrink(); isLoading: false,
).paddingSymmetrical(24.h, 0.0)
: SizedBox.shrink();
}), }),
SizedBox(height: 10.h), SizedBox(height: 16.h),
// GridView( GridView(
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 13), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 13, mainAxisSpacing: 13),
// physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
// padding: EdgeInsets.only(top: 12), padding: EdgeInsets.zero,
// shrinkWrap: true, shrinkWrap: true,
// children: [ children: [
// MedicalFileCard(label: "Update Insurance".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon).onPress(() { MedicalFileCard(
// Navigator.of(context).push( label: LocaleKeys.monthlyReports.tr(context: context),
// FadePage( textColor: AppColors.blackColor,
// page: InsuranceHomePage(), backgroundColor: AppColors.whiteColor,
// ), svgIcon: AppAssets.eye_result_icon,
// ); isLargeText: false,
// }), iconSize: 40.h,
// MedicalFileCard(label: "Insurance Approvals".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), ),
// MedicalFileCard(label: "My Invoices List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), MedicalFileCard(
// MedicalFileCard(label: "Ancillary Orders List".needTranslation, textColor: AppColors.blackColor, backgroundColor: AppColors.whiteColor, svgIcon: AppAssets.eye_result_icon), label: "Medical Reports".needTranslation,
// ], textColor: AppColors.blackColor,
// ).paddingSymmetrical(24.h, 0.0), backgroundColor: AppColors.whiteColor,
// SizedBox(height: 16.h), svgIcon: AppAssets.allergy_info_icon,
isLargeText: false,
iconSize: 40.h,
).onPress(() {
medicalFileViewModel.setIsPatientMedicalReportsLoading(true);
medicalFileViewModel.getPatientMedicalReportList();
Navigator.of(context).push(
FadePage(
page: MedicalReportsPage(),
),
);
}),
MedicalFileCard(
label: "Sick Leave Report".needTranslation,
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.vaccine_info_icon,
isLargeText: false,
iconSize: 40.h,
).onPress(() {
Navigator.of(context).push(
FadePage(
page: VaccineListPage(),
),
);
}),
],
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 24.h),
], ],
); );
case 3: case 3:

@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/utils/size_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/medical_file/medical_file_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_medical_report_card.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:provider/provider.dart';
class MedicalReportsPage extends StatefulWidget {
const MedicalReportsPage({super.key});
@override
State<MedicalReportsPage> createState() => _MedicalReportsPageState();
}
class _MedicalReportsPageState extends State<MedicalReportsPage> {
late MedicalFileViewModel medicalFileViewModel;
@override
Widget build(BuildContext context) {
medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: "Medical Reports".needTranslation,
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 16.h),
CustomTabBar(
activeTextColor: Color(0xffED1C2B),
activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
tabs: [
CustomTabBarModel(null, "Requested".needTranslation),
CustomTabBarModel(null, "Ready".needTranslation),
CustomTabBarModel(null, "Cancelled".needTranslation),
],
onTabChange: (index) {
medicalFileViewModel.onMedicalReportTabChange(index);
},
).paddingSymmetrical(24.h, 0.h),
Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) {
return ListView.separated(
padding: EdgeInsets.only(top: 24.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: medicalFileViewModel.isPatientMedicalReportsListLoading ? 3 : medicalFileViewModel.patientMedicalReportList.length,
// medicalFileViewModel.patientMedicalReportList.isNotEmpty
// ? medicalFileViewModel.patientMedicalReportList.length
// : 1,
itemBuilder: (context, index) {
return medicalFileViewModel.isPatientMedicalReportsListLoading
? PatientMedicalReportCard(
patientMedicalReportResponseModel: PatientMedicalReportResponseModel(),
isLoading: true,
).paddingSymmetrical(24.h, 0.h)
: 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: PatientMedicalReportCard(
patientMedicalReportResponseModel: medicalFileVM.patientMedicalReportList[index],
isLoading: false,
),
).paddingSymmetrical(24.h, 0.h),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
);
}),
SizedBox(height: 24.h),
],
),
),
),
);
}
}

@ -0,0 +1,120 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
class PatientMedicalReportCard extends StatelessWidget {
PatientMedicalReportCard({super.key, required this.patientMedicalReportResponseModel, this.isLoading = false});
PatientMedicalReportResponseModel patientMedicalReportResponseModel;
bool isLoading = true;
@override
Widget build(BuildContext context) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.network(
isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : patientMedicalReportResponseModel.doctorImageURL!,
width: 63.h,
height: 63.h,
fit: BoxFit.fill,
).circle(100).toShimmer2(isShow: isLoading),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(isLoading ? "" : patientMedicalReportResponseModel.doctorName!).toText16(isBold: true).toShimmer2(isShow: isLoading),
SizedBox(height: 4.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(labelText: isLoading ? "" : patientMedicalReportResponseModel.clinicDescription!).toShimmer2(isShow: isLoading),
AppCustomChipWidget(labelText: isLoading ? "" : patientMedicalReportResponseModel.projectName!).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: isLoading
? ""
: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientMedicalReportResponseModel.requestDate), false)}, ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientMedicalReportResponseModel.requestDate), false)}")
.toShimmer2(isShow: isLoading),
AppCustomChipWidget(
icon: AppAssets.rating_icon, iconColor: AppColors.ratingColorYellow, labelText: isLoading ? "" : "Rating: ${patientMedicalReportResponseModel.decimalDoctorRate}")
.toShimmer2(isShow: isLoading),
],
),
],
),
),
],
),
patientMedicalReportResponseModel.status == 2
? Padding(
padding: EdgeInsets.only(top: 16.h),
child: Row(
children: [
Expanded(
child: CustomButton(
text: "Share",
onPressed: () {},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
height: 40.h,
icon: AppAssets.download_1,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
).toShimmer2(isShow: isLoading),
),
SizedBox(width: 16.h),
Expanded(
child: CustomButton(
text: "Download",
onPressed: () {},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
height: 40.h,
icon: AppAssets.download_1,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
).toShimmer2(isShow: isLoading),
),
],
),
)
: SizedBox.shrink()
],
),
),
);
}
}
Loading…
Cancel
Save