diff --git a/assets/images/svg/doctor_calendar_icon.svg b/assets/images/svg/doctor_calendar_icon.svg
new file mode 100644
index 0000000..f76c49f
--- /dev/null
+++ b/assets/images/svg/doctor_calendar_icon.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/images/svg/prescription_remarks_icon.svg b/assets/images/svg/prescription_remarks_icon.svg
new file mode 100644
index 0000000..a8d7adb
--- /dev/null
+++ b/assets/images/svg/prescription_remarks_icon.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/svg/rating_icon.svg b/assets/images/svg/rating_icon.svg
new file mode 100644
index 0000000..dee25d4
--- /dev/null
+++ b/assets/images/svg/rating_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index a43406e..bd3e541 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -64,6 +64,9 @@ class AppAssets {
static const String view_report_icon = '$svgBasePath/view_report_icon.svg';
static const String forward_arrow_icon = '$svgBasePath/forward_arrow_icon.svg';
static const String prescription_refill_icon = '$svgBasePath/prescription_refill_icon.svg';
+ static const String rating_icon = '$svgBasePath/rating_icon.svg';
+ static const String doctor_calendar_icon = '$svgBasePath/doctor_calendar_icon.svg';
+ static const String prescription_remarks_icon = '$svgBasePath/prescription_remarks_icon.svg';
//bottom navigation//
diff --git a/lib/features/prescriptions/models/resp_models/prescription_detail_response_model.dart b/lib/features/prescriptions/models/resp_models/prescription_detail_response_model.dart
new file mode 100644
index 0000000..3ca8396
--- /dev/null
+++ b/lib/features/prescriptions/models/resp_models/prescription_detail_response_model.dart
@@ -0,0 +1,144 @@
+class PrescriptionDetailResponseModel {
+ String? address;
+ num? appointmentNo;
+ String? clinic;
+ dynamic companyName;
+ num? days;
+ String? doctorName;
+ num? doseDailyQuantity;
+ String? frequency;
+ num? frequencyNumber;
+ dynamic image;
+ dynamic imageExtension;
+ String? imageSRCUrl;
+ dynamic imageString;
+ String? imageThumbUrl;
+ String? isCovered;
+ String? itemDescription;
+ num? itemID;
+ String? orderDate;
+ num? patientID;
+ String? patientName;
+ String? phoneOffice1;
+ dynamic prescriptionQR;
+ num? prescriptionTimes;
+ dynamic productImage;
+ dynamic productImageBase64;
+ String? productImageString;
+ num? projectID;
+ String? projectName;
+ String? remarks;
+ String? route;
+ String? sKU;
+ num? scaleOffset;
+ String? startDate;
+
+ PrescriptionDetailResponseModel(
+ {this.address,
+ this.appointmentNo,
+ this.clinic,
+ this.companyName,
+ this.days,
+ this.doctorName,
+ this.doseDailyQuantity,
+ this.frequency,
+ this.frequencyNumber,
+ this.image,
+ this.imageExtension,
+ this.imageSRCUrl,
+ this.imageString,
+ this.imageThumbUrl,
+ this.isCovered,
+ this.itemDescription,
+ this.itemID,
+ this.orderDate,
+ this.patientID,
+ this.patientName,
+ this.phoneOffice1,
+ this.prescriptionQR,
+ this.prescriptionTimes,
+ this.productImage,
+ this.productImageBase64,
+ this.productImageString,
+ this.projectID,
+ this.projectName,
+ this.remarks,
+ this.route,
+ this.sKU,
+ this.scaleOffset,
+ this.startDate});
+
+ PrescriptionDetailResponseModel.fromJson(Map json) {
+ address = json['Address'];
+ appointmentNo = json['AppointmentNo'];
+ clinic = json['Clinic'];
+ companyName = json['CompanyName'];
+ days = json['Days'];
+ doctorName = json['DoctorName'];
+ doseDailyQuantity = json['DoseDailyQuantity'];
+ frequency = json['Frequency'];
+ frequencyNumber = json['FrequencyNumber'];
+ image = json['Image'];
+ imageExtension = json['ImageExtension'];
+ imageSRCUrl = json['ImageSRCUrl'];
+ imageString = json['ImageString'];
+ imageThumbUrl = json['ImageThumbUrl'];
+ isCovered = json['IsCovered'];
+ itemDescription = json['ItemDescription'];
+ itemID = json['ItemID'];
+ orderDate = json['OrderDate'];
+ patientID = json['PatientID'];
+ patientName = json['PatientName'];
+ phoneOffice1 = json['PhoneOffice1'];
+ prescriptionQR = json['PrescriptionQR'];
+ prescriptionTimes = json['PrescriptionTimes'];
+ productImage = json['ProductImage'];
+ productImageBase64 = json['ProductImageBase64'];
+ productImageString = json['ProductImageString'];
+ projectID = json['ProjectID'];
+ projectName = json['ProjectName'];
+ remarks = json['Remarks'];
+ route = json['Route'];
+ sKU = json['SKU'];
+ scaleOffset = json['ScaleOffset'];
+ startDate = json['StartDate'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['Address'] = address;
+ data['AppointmentNo'] = appointmentNo;
+ data['Clinic'] = clinic;
+ data['CompanyName'] = companyName;
+ data['Days'] = days;
+ data['DoctorName'] = doctorName;
+ data['DoseDailyQuantity'] = doseDailyQuantity;
+ data['Frequency'] = frequency;
+ data['FrequencyNumber'] = frequencyNumber;
+ data['Image'] = image;
+ data['ImageExtension'] = imageExtension;
+ data['ImageSRCUrl'] = imageSRCUrl;
+ data['ImageString'] = imageString;
+ data['ImageThumbUrl'] = imageThumbUrl;
+ data['IsCovered'] = isCovered;
+ data['ItemDescription'] = itemDescription;
+ data['ItemID'] = itemID;
+ data['OrderDate'] = orderDate;
+ data['PatientID'] = patientID;
+ data['PatientName'] = patientName;
+ data['PhoneOffice1'] = phoneOffice1;
+ data['PrescriptionQR'] = prescriptionQR;
+ data['PrescriptionTimes'] = prescriptionTimes;
+ data['ProductImage'] = productImage;
+ data['ProductImageBase64'] = productImageBase64;
+ data['ProductImageString'] = productImageString;
+ data['ProjectID'] = projectID;
+ data['ProjectName'] = projectName;
+ data['Remarks'] = remarks;
+ data['Route'] = route;
+ data['SKU'] = sKU;
+ data['ScaleOffset'] = scaleOffset;
+ data['StartDate'] = startDate;
+ return data;
+ }
+}
diff --git a/lib/features/prescriptions/prescriptions_repo.dart b/lib/features/prescriptions/prescriptions_repo.dart
index 53cf827..de7bc4b 100644
--- a/lib/features/prescriptions/prescriptions_repo.dart
+++ b/lib/features/prescriptions/prescriptions_repo.dart
@@ -4,10 +4,13 @@ import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:dartz/dartz.dart';
import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_model.dart';
+import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/prescription_detail_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class PrescriptionsRepo {
Future>>> getPatientPrescriptionOrders({required String patientId});
+
+ Future>>> getPatientPrescriptionDetails({required PatientPrescriptionsResponseModel prescriptionsResponseModel});
}
class PrescriptionsRepoImp implements PrescriptionsRepo {
@@ -72,4 +75,67 @@ class PrescriptionsRepoImp implements PrescriptionsRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>>> getPatientPrescriptionDetails({required PatientPrescriptionsResponseModel prescriptionsResponseModel}) async {
+ final mapDevice = {
+ "AppointmentNo": prescriptionsResponseModel.appointmentNo.toString(),
+ "SetupID": prescriptionsResponseModel.setupID,
+ "EpisodeID": prescriptionsResponseModel.episodeID.toString(),
+ "ClinicID": prescriptionsResponseModel.clinicID.toString(),
+ "ProjectID": prescriptionsResponseModel.projectID.toString(),
+ "DischargeNo": prescriptionsResponseModel.dischargeNo.toString(),
+ "isDentalAllowedBackend": false,
+ "VersionID": 50.0,
+ "Channel": 3,
+ "LanguageID": 2,
+ "IPAdress": "10.20.10.20",
+ "generalid": "Cs2020@2016\$2958",
+ "Latitude": 0.0,
+ "Longitude": 0.0,
+ "DeviceTypeID": 1,
+ "PatientType": 1,
+ "PatientTypeID": 1,
+ "TokenID": "@dm!n",
+ "PatientID": "1018977",
+ "PatientOutSA": "0",
+ "SessionID": "03478TYC02N80874CTYN04883475!?"
+ };
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ prescriptionsResponseModel.isInOutPatient! ? GET_PRESCRIPTION_REPORT_ENH : GET_PRESCRIPTION_REPORT,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus}) {
+ try {
+ final list = prescriptionsResponseModel.isInOutPatient! ? response['ListPRM'] : response['INP_GetPrescriptionReport_List'];
+ if (list == null || list.isEmpty) {
+ throw Exception("prescription list is empty");
+ }
+
+ final prescriptionOrders = list.map((item) => PrescriptionDetailResponseModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: prescriptionOrders,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
}
diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart
index 031b26e..23a818e 100644
--- a/lib/features/prescriptions/prescriptions_view_model.dart
+++ b/lib/features/prescriptions/prescriptions_view_model.dart
@@ -1,21 +1,26 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_model.dart';
+import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/prescription_detail_response_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_repo.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
class PrescriptionsViewModel extends ChangeNotifier {
bool isPrescriptionsOrdersLoading = false;
+ bool isPrescriptionsDetailsLoading = false;
PrescriptionsRepo prescriptionsRepo;
ErrorHandlerService errorHandlerService;
+ // Prescription Orders Lists
List patientPrescriptionOrders = [];
List patientPrescriptionOrdersByClinic = [];
List patientPrescriptionOrdersByHospital = [];
-
List patientPrescriptionOrdersViewList = [];
+ // Prescription Details List
+ List prescriptionDetailsList = [];
+
bool isSortByClinic = true;
PrescriptionsViewModel({required this.prescriptionsRepo, required this.errorHandlerService});
@@ -26,11 +31,18 @@ class PrescriptionsViewModel extends ChangeNotifier {
patientPrescriptionOrdersByHospital.clear();
patientPrescriptionOrdersViewList.clear();
isPrescriptionsOrdersLoading = true;
+ isPrescriptionsDetailsLoading = true;
isSortByClinic = true;
getPatientPrescriptionOrders();
notifyListeners();
}
+ setPrescriptionsDetailsLoading() {
+ isPrescriptionsDetailsLoading = true;
+ prescriptionDetailsList.clear();
+ notifyListeners();
+ }
+
setIsSortByClinic(bool value) {
isSortByClinic = value;
if (isSortByClinic) {
@@ -79,4 +91,24 @@ class PrescriptionsViewModel extends ChangeNotifier {
},
);
}
+
+ Future getPrescriptionDetails(PatientPrescriptionsResponseModel prescriptionsResponseModel, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ final result = await prescriptionsRepo.getPatientPrescriptionDetails(prescriptionsResponseModel: prescriptionsResponseModel);
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) {
+ if (apiResponse.messageStatus == 2) {
+ // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
+ } else if (apiResponse.messageStatus == 1) {
+ prescriptionDetailsList = apiResponse.data!;
+ isPrescriptionsDetailsLoading = false;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
}
diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart
new file mode 100644
index 0000000..0231c67
--- /dev/null
+++ b/lib/presentation/prescriptions/prescription_detail_page.dart
@@ -0,0 +1,313 @@
+import 'dart:async';
+
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/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/prescriptions/models/resp_models/patient_prescriptions_response_model.dart';
+import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
+import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:provider/provider.dart';
+
+class PrescriptionDetailPage extends StatefulWidget {
+ PrescriptionDetailPage({super.key, required this.prescriptionsResponseModel});
+
+ PatientPrescriptionsResponseModel prescriptionsResponseModel;
+
+ @override
+ State createState() => _PrescriptionDetailPageState();
+}
+
+class _PrescriptionDetailPageState extends State {
+ late PrescriptionsViewModel prescriptionsViewModel;
+
+ @override
+ void initState() {
+ scheduleMicrotask(() {
+ prescriptionsViewModel.getPrescriptionDetails(widget.prescriptionsResponseModel);
+ });
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ prescriptionsViewModel = Provider.of(context, listen: false);
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ appBar: AppBar(
+ title: LocaleKeys.prescriptions.tr(context: context).toText18(),
+ backgroundColor: AppColors.bgScaffoldColor,
+ ),
+ body: SingleChildScrollView(
+ child: Consumer(builder: (context, prescriptionVM, child) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ LocaleKeys.prescriptions.tr(context: context).toText24(isBold: true).paddingSymmetrical(24.h, 0.h),
+ SizedBox(height: 24.h),
+ 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(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Image.network(
+ widget.prescriptionsResponseModel.doctorImageURL!,
+ width: 24.h,
+ height: 24.h,
+ fit: BoxFit.fill,
+ ).circle(100),
+ SizedBox(width: 8.h),
+ Expanded(child: widget.prescriptionsResponseModel.doctorName!.toText16(isBold: true)),
+ ],
+ ),
+ SizedBox(height: 16.h),
+ Wrap(
+ direction: Axis.horizontal,
+ spacing: 6.h,
+ runSpacing: 6.h,
+ children: [
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ icon: AppAssets.doctor_calendar_icon,
+ iconColor: AppColors.textColor,
+ iconSize: 13.h,
+ text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false),
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ text: widget.prescriptionsResponseModel.clinicDescription!,
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ icon: AppAssets.rating_icon,
+ iconColor: AppColors.ratingColorYellow,
+ iconSize: 13.h,
+ text: "Rating: ${widget.prescriptionsResponseModel.decimalDoctorRate}",
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ text: widget.prescriptionsResponseModel.name!,
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ).paddingSymmetrical(24.h, 0.h),
+ SizedBox(height: 16.h),
+ ListView.builder(
+ shrinkWrap: true,
+ physics: NeverScrollableScrollPhysics(),
+ itemCount: prescriptionVM.isPrescriptionsDetailsLoading ? 5 : prescriptionVM.prescriptionDetailsList.length,
+ itemBuilder: (context, index) {
+ return prescriptionVM.isPrescriptionsDetailsLoading
+ ? const MoviesShimmerWidget()
+ : AnimationConfiguration.staggeredList(
+ position: index,
+ duration: const Duration(milliseconds: 500),
+ child: SlideAnimation(
+ verticalOffset: 100.0,
+ child: FadeInAnimation(
+ child: AnimatedContainer(
+ duration: Duration(milliseconds: 300),
+ curve: Curves.easeInOut,
+ margin: EdgeInsets.symmetric(vertical: 8.h),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: EdgeInsets.all(16.h),
+ child: Container(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Image.network(
+ prescriptionVM.prescriptionDetailsList[index].imageSRCUrl!,
+ width: 60.h,
+ height: 60.h,
+ fit: BoxFit.fill,
+ ).circle(100),
+ SizedBox(width: 8.h),
+ Expanded(
+ child: prescriptionVM.prescriptionDetailsList[index].itemDescription!.toText16(isBold: true, maxlines: 2),
+ ),
+ ],
+ ),
+ SizedBox(height: 16.h),
+ Wrap(
+ direction: Axis.horizontal,
+ spacing: 6.h,
+ runSpacing: 6.h,
+ children: [
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ text: "${LocaleKeys.route.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].route}",
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ text: "${LocaleKeys.frequency.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].frequency}",
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ text: "${LocaleKeys.dailyDoses.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].doseDailyQuantity}",
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ CustomButton(
+ text: "${LocaleKeys.days.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].days}",
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 30.h,
+ ),
+ ],
+ ),
+ ],
+ ),
+ SizedBox(height: 8.h),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.h, height: 18.h),
+ SizedBox(width: 9.h),
+ Expanded(child: "${LocaleKeys.remarks.tr(context: context)}: ${prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true)),
+ ],
+ )
+ ],
+ ),
+ ),
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ ).paddingSymmetrical(24.h, 0.h),
+ ],
+ );
+ }),
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart
index c678a8e..4aa1a1b 100644
--- a/lib/presentation/prescriptions/prescriptions_list_page.dart
+++ b/lib/presentation/prescriptions/prescriptions_list_page.dart
@@ -11,9 +11,11 @@ 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/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.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/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
class PrescriptionsListPage extends StatefulWidget {
@@ -45,248 +47,252 @@ class _PrescriptionsListPageState extends State {
title: LocaleKeys.prescriptions.tr(context: context).toText18(),
backgroundColor: AppColors.bgScaffoldColor,
),
- body: Padding(
- padding: EdgeInsets.all(24.h),
- child: SingleChildScrollView(
- child: Consumer(builder: (context, model, child) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- LocaleKeys.prescriptions.tr(context: context).toText24(isBold: true),
- SizedBox(height: 16.h),
- // Build Tab Bar
- SizedBox(height: 16.h),
- // Clinic & Hospital Sort
- Row(
- children: [
- CustomButton(
- text: LocaleKeys.byClinic.tr(context: context),
- onPressed: () {
- model.setIsSortByClinic(true);
- },
- backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
- borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
- textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
- fontSize: 12,
- fontWeight: FontWeight.w500,
- borderRadius: 10,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 40.h,
- ),
- SizedBox(width: 8.h),
- CustomButton(
- text: LocaleKeys.byHospital.tr(context: context),
- onPressed: () {
- model.setIsSortByClinic(false);
- },
- backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
- borderColor: model.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
- textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
- fontSize: 12,
- fontWeight: FontWeight.w500,
- borderRadius: 10,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 40.h,
- ),
- ],
- ),
- SizedBox(height: 20.h),
- // Expandable list
- ListView.builder(
- itemCount: model.isPrescriptionsOrdersLoading ? 4 : model.patientPrescriptionOrdersViewList.length,
- physics: NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- padding: const EdgeInsets.only(left: 0, right: 8),
- itemBuilder: (context, index) {
- final isExpanded = expandedIndex == index;
- return model.isPrescriptionsOrdersLoading
- ? const MoviesShimmerWidget()
- : AnimationConfiguration.staggeredList(
- position: index,
- duration: const Duration(milliseconds: 500),
- child: SlideAnimation(
- verticalOffset: 100.0,
- child: FadeInAnimation(
- child: AnimatedContainer(
- duration: Duration(milliseconds: 300),
- curve: Curves.easeInOut,
- margin: EdgeInsets.symmetric(vertical: 8.h),
- decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
- child: InkWell(
- onTap: () {
- setState(() {
- expandedIndex = isExpanded ? null : index;
- });
- },
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Padding(
- padding: EdgeInsets.all(16.h),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- CustomButton(
- text: "${model.patientPrescriptionOrdersViewList[index].prescriptionsList!.length} Prescriptions Available",
- 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,
- ),
- Icon(isExpanded ? Icons.expand_less : Icons.expand_more),
- ],
- ),
- SizedBox(height: 8.h),
- model.patientPrescriptionOrdersViewList[index].filterName!.toText16(isBold: true)
- ],
- ),
+ body: SingleChildScrollView(
+ child: Consumer(builder: (context, model, child) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ LocaleKeys.prescriptions.tr(context: context).toText24(isBold: true).paddingSymmetrical(24.h, 0.h),
+ SizedBox(height: 16.h),
+ // Build Tab Bar
+ SizedBox(height: 16.h),
+ // Clinic & Hospital Sort
+ Row(
+ children: [
+ CustomButton(
+ text: LocaleKeys.byClinic.tr(context: context),
+ onPressed: () {
+ model.setIsSortByClinic(true);
+ },
+ backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
+ borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
+ textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 10,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 40.h,
+ ),
+ SizedBox(width: 8.h),
+ CustomButton(
+ text: LocaleKeys.byHospital.tr(context: context),
+ onPressed: () {
+ model.setIsSortByClinic(false);
+ },
+ backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
+ borderColor: model.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
+ textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 10,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 40.h,
+ ),
+ ],
+ ).paddingSymmetrical(24.h, 0.h),
+ SizedBox(height: 20.h),
+ // Expandable list
+ ListView.builder(
+ itemCount: model.isPrescriptionsOrdersLoading ? 4 : model.patientPrescriptionOrdersViewList.length,
+ physics: NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ padding: const EdgeInsets.only(left: 0, right: 8),
+ itemBuilder: (context, index) {
+ final isExpanded = expandedIndex == index;
+ return model.isPrescriptionsOrdersLoading
+ ? const MoviesShimmerWidget()
+ : AnimationConfiguration.staggeredList(
+ position: index,
+ duration: const Duration(milliseconds: 500),
+ child: SlideAnimation(
+ verticalOffset: 100.0,
+ child: FadeInAnimation(
+ child: AnimatedContainer(
+ duration: Duration(milliseconds: 300),
+ curve: Curves.easeInOut,
+ margin: EdgeInsets.symmetric(vertical: 8.h),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
+ child: InkWell(
+ onTap: () {
+ setState(() {
+ expandedIndex = isExpanded ? null : index;
+ });
+ },
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: EdgeInsets.all(16.h),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ CustomButton(
+ text: "${model.patientPrescriptionOrdersViewList[index].prescriptionsList!.length} Prescriptions Available",
+ 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,
+ ),
+ Icon(isExpanded ? Icons.expand_less : Icons.expand_more),
+ ],
+ ),
+ SizedBox(height: 8.h),
+ model.patientPrescriptionOrdersViewList[index].filterName!.toText16(isBold: true)
+ ],
),
- AnimatedSwitcher(
- duration: Duration(milliseconds: 500),
- switchInCurve: Curves.easeIn,
- switchOutCurve: Curves.easeOut,
- transitionBuilder: (Widget child, Animation animation) {
- return FadeTransition(
- opacity: animation,
- child: SizeTransition(
- sizeFactor: animation,
- axisAlignment: 0.0,
- child: child,
- ),
- );
- },
- child: isExpanded
- ? Container(
- key: ValueKey(index),
- padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- ...model.patientPrescriptionOrdersViewList[index].prescriptionsList!.map((prescription) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Image.network(
- prescription.doctorImageURL!,
- width: 24.h,
- height: 24.h,
- fit: BoxFit.fill,
- ).circle(100),
- SizedBox(width: 8.h),
- Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)),
- ],
- ),
- SizedBox(height: 8.h),
- Row(
- children: [
- CustomButton(
- text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false),
+ ),
+ AnimatedSwitcher(
+ duration: Duration(milliseconds: 500),
+ switchInCurve: Curves.easeIn,
+ switchOutCurve: Curves.easeOut,
+ transitionBuilder: (Widget child, Animation animation) {
+ return FadeTransition(
+ opacity: animation,
+ child: SizeTransition(
+ sizeFactor: animation,
+ axisAlignment: 0.0,
+ child: child,
+ ),
+ );
+ },
+ child: isExpanded
+ ? Container(
+ key: ValueKey(index),
+ padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ ...model.patientPrescriptionOrdersViewList[index].prescriptionsList!.map((prescription) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Image.network(
+ prescription.doctorImageURL!,
+ width: 24.h,
+ height: 24.h,
+ fit: BoxFit.fill,
+ ).circle(100),
+ SizedBox(width: 8.h),
+ Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)),
+ ],
+ ),
+ SizedBox(height: 8.h),
+ Row(
+ children: [
+ CustomButton(
+ text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false),
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 24.h,
+ ),
+ SizedBox(width: 8.h),
+ CustomButton(
+ text: model.isSortByClinic ? prescription.name! : prescription.clinicDescription!,
+ onPressed: () {},
+ backgroundColor: AppColors.greyColor,
+ borderColor: AppColors.greyColor,
+ textColor: AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 8,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 24.h,
+ ),
+ ],
+ ),
+ SizedBox(height: 8.h),
+ Row(
+ children: [
+ Expanded(
+ flex: 6,
+ child: CustomButton(
+ text: prescription.isHomeMedicineDeliverySupported!
+ ? LocaleKeys.resendOrder.tr(context: context)
+ : LocaleKeys.prescriptionDeliveryError.tr(context: context),
onPressed: () {},
- backgroundColor: AppColors.greyColor,
- borderColor: AppColors.greyColor,
- textColor: AppColors.blackColor,
- fontSize: 12,
+ backgroundColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor.withOpacity(0.15) : AppColors.greyF7Color,
+ borderColor: AppColors.successColor.withOpacity(0.01),
+ textColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35),
+ fontSize: prescription.isHomeMedicineDeliverySupported! ? 14 : 12,
fontWeight: FontWeight.w500,
- borderRadius: 8,
+ borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 24.h,
+ height: 40.h,
+ icon: AppAssets.prescription_refill_icon,
+ iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35),
+ iconSize: 14.h,
),
- SizedBox(width: 8.h),
- CustomButton(
- text: model.isSortByClinic ? prescription.name! : prescription.clinicDescription!,
- onPressed: () {},
- backgroundColor: AppColors.greyColor,
- borderColor: AppColors.greyColor,
- textColor: AppColors.blackColor,
- fontSize: 12,
- fontWeight: FontWeight.w500,
- borderRadius: 8,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 24.h,
- ),
- ],
- ),
- SizedBox(height: 8.h),
- Row(
- children: [
- Expanded(
- flex: 6,
- child: CustomButton(
- text: prescription.isHomeMedicineDeliverySupported!
- ? LocaleKeys.resendOrder.tr(context: context)
- : LocaleKeys.prescriptionDeliveryError.tr(context: context),
- onPressed: () {},
- backgroundColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor.withOpacity(0.15) : AppColors.greyF7Color,
- borderColor: AppColors.successColor.withOpacity(0.01),
- textColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35),
- fontSize: prescription.isHomeMedicineDeliverySupported! ? 14 : 12,
- fontWeight: FontWeight.w500,
- borderRadius: 12,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 40.h,
- icon: AppAssets.prescription_refill_icon,
- iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35),
- iconSize: 14.h,
+ ),
+ SizedBox(width: 8.h),
+ Expanded(
+ flex: 1,
+ child: Container(
+ height: 40.h,
+ width: 40.h,
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.textColor,
+ borderRadius: 10.h,
),
- ),
- SizedBox(width: 8.h),
- Expanded(
- flex: 1,
- child: Container(
- height: 40.h,
- width: 40.h,
- decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
- color: AppColors.textColor,
- borderRadius: 10.h,
- ),
- child: Padding(
- padding: EdgeInsets.all(8.h),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon,
- width: 10.h,
- height: 10.h,
- fit: BoxFit.contain,
- ),
+ child: Padding(
+ padding: EdgeInsets.all(8.h),
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.forward_arrow_icon,
+ width: 10.h,
+ height: 10.h,
+ fit: BoxFit.contain,
),
),
- ),
- ],
- ),
- SizedBox(height: 12.h),
- Divider(color: AppColors.borderOnlyColor.withOpacity(0.05), height: 1.h),
- SizedBox(height: 12.h),
- ],
- );
- }).toList(),
- ],
- ),
- )
- : SizedBox.shrink(),
- ),
- ],
- ),
+ ).onPress(() {
+ model.setPrescriptionsDetailsLoading();
+ Navigator.of(context).push(
+ FadePage(
+ page: PrescriptionDetailPage(prescriptionsResponseModel: prescription),
+ ),
+ );
+ }),
+ ),
+ ],
+ ),
+ SizedBox(height: 12.h),
+ Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h),
+ SizedBox(height: 12.h),
+ ],
+ );
+ }).toList(),
+ ],
+ ),
+ )
+ : SizedBox.shrink(),
+ ),
+ ],
),
),
),
),
- );
- },
- ),
- ],
- );
- }),
- ),
+ ),
+ );
+ },
+ ).paddingSymmetrical(24.h, 0.h),
+ ],
+ );
+ }),
),
);
}
diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart
index d9cf167..018727c 100644
--- a/lib/theme/colors.dart
+++ b/lib/theme/colors.dart
@@ -32,6 +32,7 @@ class AppColors {
static const Color borderOnlyColor = Color(0xFF2E3039);
static const Color dividerColor = Color(0xFFD2D2D2);
static const Color warningColorYellow = Color(0xFFF4A308);
+ static const Color ratingColorYellow = Color(0xFFFFAF15);
//Chips
static const Color successColor = Color(0xff18C273);