diff --git a/assets/images/png/cc_ar.png b/assets/images/png/cc_ar.png
new file mode 100644
index 0000000..e4388ba
Binary files /dev/null and b/assets/images/png/cc_ar.png differ
diff --git a/assets/images/png/cc_en.png b/assets/images/png/cc_en.png
new file mode 100644
index 0000000..c11cf5e
Binary files /dev/null and b/assets/images/png/cc_en.png differ
diff --git a/assets/images/svg/comprehensive_checkup.svg b/assets/images/svg/comprehensive_checkup.svg
new file mode 100644
index 0000000..885d9a7
--- /dev/null
+++ b/assets/images/svg/comprehensive_checkup.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/images/svg/e-referral.svg b/assets/images/svg/e-referral.svg
new file mode 100644
index 0000000..3262779
--- /dev/null
+++ b/assets/images/svg/e-referral.svg
@@ -0,0 +1,7 @@
+
diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart
index 162f0fd..28475ea 100644
--- a/lib/core/api/api_client.dart
+++ b/lib/core/api/api_client.dart
@@ -103,7 +103,7 @@ class ApiClientImp implements ApiClient {
url = endPoint;
} else {
if (isRCService) {
- url = RC_BASE_URL + endPoint;
+ url = ApiConsts.rcBaseUrl + endPoint;
} else {
url = ApiConsts.baseUrl + endPoint;
}
@@ -161,11 +161,10 @@ class ApiClientImp implements ApiClient {
// body['VersionID'] = ApiConsts.appVersionID.toString();
if (!isExternal) {
- body['VersionID'] = "50.0";
- body['Channel'] = ApiConsts.appChannelId.toString();
+ body['VersionID'] = ApiConsts.appVersionID;
+ body['Channel'] = ApiConsts.appChannelId;
body['IPAdress'] = ApiConsts.appIpAddress;
body['generalid'] = ApiConsts.appGeneralId;
-
body['LanguageID'] = _appState.getLanguageID().toString();
body['Latitude'] = _appState.userLat.toString();
body['Longitude'] = _appState.userLong.toString();
@@ -184,9 +183,6 @@ class ApiClientImp implements ApiClient {
}
body.removeWhere((key, value) => value == null);
- log("uri: ${Uri.parse(url.trim())}");
-
- log("body: ${json.encode(body)}");
final bool networkStatus = await Utils.checkConnection(bypassConnectionCheck: bypassConnectionCheck);
@@ -202,6 +198,8 @@ class ApiClientImp implements ApiClient {
final response = await http.post(Uri.parse(url.trim()), body: json.encode(body), headers: headers);
final int statusCode = response.statusCode;
+ log("uri: ${Uri.parse(url.trim())}");
+ log("body: ${json.encode(body)}");
log("response.body: ${response.body}");
if (statusCode < 200 || statusCode >= 400) {
onFailure('Error While Fetching data', statusCode, failureType: StatusCodeFailure("Error While Fetching data"));
@@ -213,13 +211,14 @@ class ApiClientImp implements ApiClient {
onSuccess(parsed, statusCode, messageStatus: 1, errorMessage: "");
} else {
onSuccess(parsed, statusCode,
- messageStatus: parsed.contains('MessageStatus') ? parsed['MessageStatus'] : 1,
- errorMessage: parsed.contains('ErrorEndUserMessage') ? parsed['ErrorEndUserMessage'] : "");
+ messageStatus: (parsed is Map && parsed.containsKey('MessageStatus')) ? parsed['MessageStatus'] : 1,
+ errorMessage: (parsed is Map && parsed.containsKey('ErrorEndUserMessage')) ? parsed['ErrorEndUserMessage'] : "");
}
} else {
if (parsed['Response_Message'] != null) {
onSuccess(parsed, statusCode,
- messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']);
+ messageStatus: (parsed is Map && parsed.containsKey('MessageStatus')) ? parsed['MessageStatus'] : 1,
+ errorMessage: (parsed is Map && parsed.containsKey('ErrorEndUserMessage')) ? parsed['ErrorEndUserMessage'] : "");
} else {
if (parsed['ErrorType'] == 4) {
//TODO : handle app update
@@ -352,9 +351,9 @@ class ApiClientImp implements ApiClient {
url = endPoint;
} else {
if (isRCService) {
- url = RC_BASE_URL + endPoint;
+ url = ApiConsts.rcBaseUrl + endPoint;
} else {
- url = BASE_URL + endPoint;
+ url = ApiConsts.baseUrl + endPoint;
}
}
if (queryParams != null) {
diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart
index b21d329..3faef34 100644
--- a/lib/core/api_consts.dart
+++ b/lib/core/api_consts.dart
@@ -14,7 +14,7 @@ var PACKAGES_ORDERS = '/api/orders';
var PACKAGES_ORDER_HISTORY = '/api/orders/items';
var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara';
// var BASE_URL = 'http://10.50.100.198:2018/';
-var BASE_URL = 'https://uat.hmgwebservices.com/';
+var BASE_URL = 'https://uat.hmgwebservices.com/';
// var BASE_URL = 'https://hmgwebservices.com/';
// var BASE_URL = 'http://10.201.204.103/';
// var BASE_URL = 'https://orash.cloudsolutions.com.sa/';
@@ -46,8 +46,6 @@ var PHARMACY_REDIRECT_URL = 'https://bit.ly/AlhabibPharmacy';
// RC API URL
// var RC_BASE_URL = 'https://rc.hmg.com/';
-var RC_BASE_URL = 'https://rc.hmg.com/uat/';
-
// var RC_BASE_URL = 'https://ms.hmg.com/rc/';
var PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity';
@@ -521,12 +519,6 @@ var ADD_HHC_ORDER_RC = "api/HHC/add";
var GET_ALL_HHC_ORDERS_RC = 'api/hhc/list';
var UPDATE_HHC_ORDER_RC = 'api/hhc/update';
-// CMC RC SERVICES
-var GET_ALL_CMC_SERVICES_RC = 'api/cmc/getallcmc';
-var ADD_CMC_ORDER_RC = 'api/cmc/add';
-var GET_ALL_CMC_ORDERS_RC = 'api/cmc/list';
-var UPDATE_CMC_ORDER_RC = 'api/cmc/update';
-
// RRT RC SERVICES
var ADD_RRT_ORDER_RC = "api/rrt/add";
var GET_ALL_RRT_ORDERS_RC = "api/rrt/list";
@@ -725,7 +717,7 @@ class ApiConsts {
static String baseUrl = 'https://hmgwebservices.com/'; // HIS API URL PROD
- static String RCBaseUrl = 'https://rc.hmg.com/'; // RC API URL PROD
+ static String rcBaseUrl = 'https://rc.hmg.com/'; // RC API URL PROD
static var payFortEnvironment = FortEnvironment.production;
static var applePayMerchantId = "merchant.com.hmgwebservices";
@@ -752,7 +744,7 @@ class ApiConsts {
TAMARA_URL = "https://mdlaboratories.com/tamaralive/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://mdlaboratories.com/tamaralive/Home/GetInstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://mdlaboratories.com/tamaralive/api/OnlineTamara/order_status?orderid=';
- RCBaseUrl = 'https://rc.hmg.com/';
+ rcBaseUrl = 'https://rc.hmg.com/';
break;
case AppEnvironmentTypeEnum.dev:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -762,7 +754,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
- RCBaseUrl = 'https://rc.hmg.com/test/';
+ rcBaseUrl = 'https://rc.hmg.com/';
break;
case AppEnvironmentTypeEnum.uat:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -772,7 +764,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
- RCBaseUrl = 'https://rc.hmg.com/test/';
+ rcBaseUrl = 'https://rc.hmg.com/';
break;
case AppEnvironmentTypeEnum.preProd:
baseUrl = "https://webservices.hmg.com/";
@@ -782,7 +774,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
- RCBaseUrl = 'https://rc.hmg.com/';
+ rcBaseUrl = 'https://rc.hmg.com/';
break;
case AppEnvironmentTypeEnum.qa:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -792,7 +784,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
- RCBaseUrl = 'https://rc.hmg.com/test/';
+ rcBaseUrl = 'https://rc.hmg.com/';
break;
case AppEnvironmentTypeEnum.staging:
baseUrl = "https://uat.hmgwebservices.com/";
@@ -802,7 +794,7 @@ class ApiConsts {
TAMARA_URL = "https://epharmacy.hmg.com/tamara/Home/Checkout";
GET_TAMARA_INSTALLMENTS_URL = "https://epharmacy.hmg.com/tamara/Home/getinstallments";
GET_TAMARA_PAYMENT_STATUS = 'https://epharmacy.hmg.com/tamara/api/OnlineTamara/order_status?orderid=';
- RCBaseUrl = 'https://rc.hmg.com/test/';
+ rcBaseUrl = 'https://rc.hmg.com/';
break;
}
}
@@ -846,8 +838,19 @@ class ApiConsts {
static final String createAdvancePayments = 'Services/Patients.svc/REST/HIS_CreateAdvancePayment';
static final String addAdvanceNumberRequest = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest';
+ // RC CMC ServIces
+ static final String allCMCOrdersRc = 'api/cmc/list';
+ static final String allCMCServicesRc = 'api/cmc/getallcmc';
+ static final String updateCMCOrder = 'api/cmc/update';
+
+ // CMC RC SERVICES
+ var GET_ALL_CMC_SERVICES_RC = 'api/cmc/getallcmc';
+ var ADD_CMC_ORDER_RC = 'api/cmc/add';
+ var GET_ALL_CMC_ORDERS_RC = 'api/cmc/list';
+ var UPDATE_CMC_ORDER_RC = 'api/cmc/update';
+
// ************ static values for Api ****************
- static final double appVersionID = 18.7;
+ static final double appVersionID = 20.0;
static final int appChannelId = 3;
static final String appIpAddress = "10.20.10.20";
static final String appGeneralId = "Cs2020@2016\$2958";
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index e8215ba..3f524be 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -171,7 +171,8 @@ class AppAssets {
static const String to_arrow = '$svgBasePath/to_arrow.svg';
static const String dual_arrow = '$svgBasePath/to_arrow.svg';
static const String forward_arrow_medium = '$svgBasePath/forward_arrow_medium.svg';
-
+ static const String eReferral = '$svgBasePath/e-referral.svg';
+ static const String comprehensiveCheckup = '$svgBasePath/comprehensive_checkup.svg';
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';
@@ -200,6 +201,8 @@ class AppAssets {
static const String visa = '$pngBasePath/visa.png';
static const String lockIcon = '$pngBasePath/lock-icon.png';
static const String dummy_user = '$pngBasePath/dummy_user.png';
+ static const String comprehensiveCheckupEn = '$pngBasePath/cc_en.png';
+ static const String comprehensiveCheckupAr = '$pngBasePath/cc_er.png';
}
class AppAnimations {
diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart
index 37d0cc4..835e9bf 100644
--- a/lib/core/dependencies.dart
+++ b/lib/core/dependencies.dart
@@ -15,6 +15,8 @@ import 'package:hmg_patient_app_new/features/emergency_services/emergency_servic
import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_view_model.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_repo.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_repo.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart';
@@ -104,47 +106,30 @@ class AppDependencies {
getIt.registerLazySingleton(() => InsuranceRepoImp(loggerService: getIt(), apiClient: getIt()));
getIt.registerLazySingleton(() => PayfortRepoImp(loggerService: getIt(), apiClient: getIt()));
getIt.registerLazySingleton(
- () => LocalAuthService(loggerService: getIt(), localAuth: getIt()));
+ () => LocalAuthService(loggerService: getIt(), localAuth: getIt()),
+ );
getIt.registerLazySingleton(() => HabibWalletRepoImp(loggerService: getIt(), apiClient: getIt()));
getIt.registerLazySingleton(() => MedicalFileRepoImp(loggerService: getIt(), apiClient: getIt()));
getIt.registerLazySingleton(() => ImmediateLiveCareRepoImp(loggerService: getIt(), apiClient: getIt()));
getIt.registerLazySingleton(() => EmergencyServicesRepoImp(loggerService: getIt(), apiClient: getIt()));
getIt.registerLazySingleton(() => TodoSectionRepoImp(loggerService: getIt(), apiClient: getIt()));
- getIt.registerLazySingleton(
- () => LocationRepoImpl(apiClient: getIt()));
+ getIt.registerLazySingleton(() => LocationRepoImpl(apiClient: getIt()));
getIt.registerLazySingleton(() => ContactUsRepoImp(loggerService: getIt(), apiClient: getIt()));
+ getIt.registerLazySingleton(() => HmgServicesRepoImp(loggerService: getIt(), apiClient: getIt()));
// ViewModels
// Global/shared VMs → LazySingleton
- getIt.registerLazySingleton(
- () => LabViewModel(labRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()),
- );
+ getIt.registerLazySingleton(() => LabViewModel(labRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()));
- getIt.registerLazySingleton(
- () => RadiologyViewModel(
- radiologyRepo: getIt(),
- errorHandlerService: getIt(),
- ),
- );
+ getIt.registerLazySingleton(() => RadiologyViewModel(radiologyRepo: getIt(), errorHandlerService: getIt()));
- getIt.registerLazySingleton(
- () => PrescriptionsViewModel(
- prescriptionsRepo: getIt(),
- errorHandlerService: getIt(),
- ),
- );
+ getIt.registerLazySingleton(() => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt()));
- getIt.registerLazySingleton(
- () => InsuranceViewModel(
- insuranceRepo: getIt(),
- errorHandlerService: getIt(),
- ),
- );
+ getIt.registerLazySingleton(() => InsuranceViewModel(insuranceRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton(
- () => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()),
- );
+ () => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton(
() => PayfortViewModel(
@@ -198,53 +183,39 @@ class AppDependencies {
);
getIt.registerLazySingleton(() => ProfileSettingsViewModel());
- getIt.registerLazySingleton(
- () => DateRangeSelectorRangeViewModel(),
- );
+ getIt.registerLazySingleton(() => DateRangeSelectorRangeViewModel());
- getIt.registerLazySingleton(
- () => DoctorFilterViewModel(),
- );
+ getIt.registerLazySingleton(() => DoctorFilterViewModel());
getIt.registerLazySingleton(
- () => AppointmentViaRegionViewmodel(
- navigationService: getIt(),
- appState: getIt(),
- ),
+ () => AppointmentViaRegionViewmodel(navigationService: getIt(), appState: getIt()),
);
getIt.registerLazySingleton(
() => EmergencyServicesViewModel(
- locationUtils: getIt(),
- navServices: getIt(),
- emergencyServicesRepo: getIt(),
- appState: getIt(),
- errorHandlerService: getIt(),
- appointmentRepo: getIt(),
- dialogService: getIt()
- ),
+ locationUtils: getIt(),
+ navServices: getIt(),
+ emergencyServicesRepo: getIt(),
+ appState: getIt(),
+ errorHandlerService: getIt(),
+ appointmentRepo: getIt(),
+ dialogService: getIt()),
);
getIt.registerLazySingleton(
- () => LocationViewModel(
- locationRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ () => LocationViewModel(locationRepo: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton(
- () => ContactUsViewModel(
- contactUsRepo: getIt(),
- appState: getIt(),
- errorHandlerService: getIt(),
- ),
+ () => ContactUsViewModel(contactUsRepo: getIt(), appState: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton(
- () => TodoSectionViewModel(
- todoSectionRepo: getIt(),
- errorHandlerService: getIt(),
- ),
+ () => TodoSectionViewModel(todoSectionRepo: getIt(), errorHandlerService: getIt()),
+ );
+
+ getIt.registerLazySingleton(
+ () => HmgServicesViewModel(hmgServicesRepo: getIt(), errorHandlerService: getIt()),
);
// Screen-specific VMs → Factory
diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart
index d58aef6..82b9909 100644
--- a/lib/core/utils/date_util.dart
+++ b/lib/core/utils/date_util.dart
@@ -6,19 +6,17 @@ class DateUtil {
/// convert String To Date function
/// [date] String we want to convert
static DateTime convertStringToDate(String? date) {
- print("the date is $date");
-
if (date == null) return DateTime.now();
if (date.isEmpty) return DateTime.now();
- const start = "/Date(";
- const end = "+0300)";
- final startIndex = date.indexOf(start);
- final endIndex = date.indexOf(end, startIndex + start.length);
- return DateTime.fromMillisecondsSinceEpoch(int.parse(
- date.substring(startIndex + start.length, endIndex),
- ));
-
+ const start = "/Date(";
+ const end = "+0300)";
+ final startIndex = date.indexOf(start);
+ final endIndex = date.indexOf(end, startIndex + start.length);
+ return DateTime.fromMillisecondsSinceEpoch(int.parse(
+ date.substring(startIndex + start.length, endIndex),
+ ))
+ ;
}
static DateTime convertStringToDateSaudiTimezone(String date, int projectId) {
@@ -36,10 +34,10 @@ class DateUtil {
// .add(Duration(hours: 4));
// } else {
return DateTime.fromMillisecondsSinceEpoch(
- int.parse(
- date.substring(startIndex + start.length, endIndex),
- ),
- isUtc: true)
+ int.parse(
+ date.substring(startIndex + start.length, endIndex),
+ ),
+ isUtc: true)
.add(Duration(hours: 3));
// }
} else {
@@ -156,7 +154,13 @@ class DateUtil {
static String getDateFormatted(String date) {
DateTime dateObj = DateUtil.convertStringToDate(date);
- return DateUtil.getWeekDay(dateObj.weekday) + ", " + dateObj.day.toString() + " " + DateUtil.getMonth(dateObj.month) + " " + dateObj.year.toString();
+ return DateUtil.getWeekDay(dateObj.weekday) +
+ ", " +
+ dateObj.day.toString() +
+ " " +
+ DateUtil.getMonth(dateObj.month) +
+ " " +
+ dateObj.year.toString();
}
static String getISODateFormat(DateTime dateTime) {
@@ -352,7 +356,13 @@ class DateUtil {
if (dateTime != null) {
return lang == 'en'
? getWeekDayEnglish(dateTime.weekday) + ", " + getMonth(dateTime.month) + " " + dateTime.day.toString() + " " + dateTime.year.toString()
- : getWeekDayArabic(dateTime.weekday) + ", " + dateTime.day.toString() + " " + getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
+ : getWeekDayArabic(dateTime.weekday) +
+ ", " +
+ dateTime.day.toString() +
+ " " +
+ getMonthArabic(dateTime.month) +
+ " " +
+ dateTime.year.toString();
} else {
return "";
}
@@ -381,7 +391,9 @@ class DateUtil {
static String getMonthYearLangDateFormatted(DateTime dateTime, String lang) {
if (dateTime != null) {
- return lang == 'en' ? getMonth(dateTime.month) + " " + dateTime.year.toString() : getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
+ return lang == 'en'
+ ? getMonth(dateTime.month) + " " + dateTime.year.toString()
+ : getMonthArabic(dateTime.month) + " " + dateTime.year.toString();
} else {
return "";
}
@@ -488,10 +500,8 @@ class DateUtil {
}
}
-
-extension OnlyDate on DateTime{
-
- DateTime provideDateOnly(){
+extension OnlyDate on DateTime {
+ DateTime provideDateOnly() {
return DateTime(this.year, month, day);
}
-}
\ No newline at end of file
+}
diff --git a/lib/features/emergency_services/emergency_services_repo.dart b/lib/features/emergency_services/emergency_services_repo.dart
index c54c3d1..ccfc210 100644
--- a/lib/features/emergency_services/emergency_services_repo.dart
+++ b/lib/features/emergency_services/emergency_services_repo.dart
@@ -44,13 +44,11 @@ abstract class EmergencyServicesRepo {
Future>>> getTransportationMethods({int? id});
-
Future>> submitAmbulanceRequest(PatientER_RC request);
Future>>> getTransportationOrders({int? id});
- Future>> cancelOrder(int? iD, int patientId);
-
+ Future>> cancelOrder(int? iD, int patientId);
}
class EmergencyServicesRepoImp implements EmergencyServicesRepo {
@@ -150,7 +148,10 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['response']['transportationservices'];
- final proceduresList = list.map((item) => PatientERTransportationMethod.fromJson(item as Map)).toList().cast();
+ final proceduresList = list
+ .map((item) => PatientERTransportationMethod.fromJson(item as Map))
+ .toList()
+ .cast();
apiResponse = GenericApiModel>(
messageStatus: messageStatus,
@@ -249,7 +250,7 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
Failure? failure;
await apiClient.post(
body: {},
- "$GET_ALL_TRANSPORTATIONS_ORDERS?patientID=$id",
+ "$GET_ALL_TRANSPORTATIONS_ORDERS?patientID=$id",
isRCService: true,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
@@ -257,7 +258,8 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['response'];
- final proceduresList = list.map((item) => AmbulanceRequestOrdersModel.fromJson(item as Map)).toList().cast();
+ final proceduresList =
+ list.map((item) => AmbulanceRequestOrdersModel.fromJson(item as Map)).toList().cast();
apiResponse = GenericApiModel>(
messageStatus: messageStatus,
@@ -327,13 +329,11 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
await apiClient.post(
CHECK_PATIENT_ER_ADVANCE_BALANCE,
body: mapDevice,
- onFailure: (error, statusCode, {messageStatus, failureType}) {
- failure = failureType;
- },
+ onFailure: (error, statusCode, {messageStatus, failureType}) => failure = failureType,
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final bool patientHasERBalance = response['BalanceAmount'] > 0;
- print(patientHasERBalance);
+ log(patientHasERBalance.toString());
apiResponse = GenericApiModel(
messageStatus: messageStatus,
statusCode: statusCode,
@@ -353,7 +353,6 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
}
}
-
@override
Future>> checkPatientERPaymentInformation({int? projectID}) async {
Map mapDevice = {"ClinicID": 10, "ProjectID": projectID ?? 0};
diff --git a/lib/features/hmg_services/hmg_services_repo.dart b/lib/features/hmg_services/hmg_services_repo.dart
new file mode 100644
index 0000000..39a6142
--- /dev/null
+++ b/lib/features/hmg_services/hmg_services_repo.dart
@@ -0,0 +1,178 @@
+import 'dart:developer';
+
+import 'package:dartz/dartz.dart';
+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/common_models/generic_api_model.dart';
+import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
+import 'package:hmg_patient_app_new/services/logger_service.dart';
+
+abstract class HmgServicesRepo {
+ Future>>> getAllCmcOrders();
+
+ Future>> updateCmcPresOrder(OrderUpdateRequestModel requestModel);
+
+ Future>>> getAllCmcServices({required int patientID});
+}
+
+class HmgServicesRepoImp implements HmgServicesRepo {
+ final ApiClient apiClient;
+ final LoggerService loggerService;
+
+ HmgServicesRepoImp({required this.apiClient, required this.loggerService});
+
+ @override
+ Future>>> getAllCmcOrders() async {
+ Map requestBody = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ ApiConsts.allCMCOrdersRc,
+ isRCService: true,
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("CMC Orders API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ List cmcOrdersList = [];
+ // Log the full response for debugging
+ // Extract MessageStatus and ErrorEndUserMessage from root level
+ final apiErrorMessage = response['ErrorEndUserMessage'] as String?;
+ // Parse the response array
+ if (response['response'] != null && response['response'] is List) {
+ final ordersList = response['response'] as List;
+
+ for (var orderJson in ordersList) {
+ if (orderJson is Map) {
+ try {
+ cmcOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(orderJson));
+ } catch (e) {
+ loggerService.logError("Error parsing individual order: ${e.toString()}");
+ }
+ }
+ }
+ }
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: apiErrorMessage ?? errorMessage,
+ data: cmcOrdersList,
+ );
+ } catch (e) {
+ loggerService.logError("Error parsing CMC orders: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in getAllCmcOrders: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> getAllCmcServices({required int patientID}) async {
+ Map requestBody = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ '${ApiConsts.allCMCServicesRc}?patientID=$patientID',
+ isRCService: true,
+ isAllowAny: true,
+ body: requestBody,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("CMC Services API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ List cmcServicesList = [];
+
+ if (response['response'] != null && response['response'] is List) {
+ final servicesList = response['response'] as List;
+
+ for (var serviceJson in servicesList) {
+ if (serviceJson is Map) {
+ cmcServicesList.add(GetCMCServicesResponseModel.fromJson(serviceJson));
+ }
+ }
+ }
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: cmcServicesList,
+ );
+ } catch (e) {
+ loggerService.logError("Error parsing CMC services: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ log("Unknown error in getAllCmcServices: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>> updateCmcPresOrder(OrderUpdateRequestModel requestModel) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+
+ await apiClient.post(
+ ApiConsts.updateCMCOrder,
+ isRCService: true,
+ body: requestModel.toJson(),
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ loggerService.logError("Update CMC Order API Failed: $error, Status: $statusCode");
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: errorMessage,
+ data: true,
+ );
+
+ loggerService.logInfo("CMC Order updated successfully: PresOrderID=${requestModel.presOrderID}");
+ } catch (e) {
+ loggerService.logError("Error processing update CMC order response: ${e.toString()}");
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ loggerService.logError("Unknown error in updateCmcPresOrder: ${e.toString()}");
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+}
diff --git a/lib/features/hmg_services/hmg_services_view_model.dart b/lib/features/hmg_services/hmg_services_view_model.dart
new file mode 100644
index 0000000..84e3bb4
--- /dev/null
+++ b/lib/features/hmg_services/hmg_services_view_model.dart
@@ -0,0 +1,137 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_repo.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
+import 'package:hmg_patient_app_new/services/error_handler_service.dart';
+
+class HmgServicesViewModel extends ChangeNotifier {
+ final HmgServicesRepo hmgServicesRepo;
+ final ErrorHandlerService errorHandlerService;
+
+ HmgServicesViewModel({required this.hmgServicesRepo, required this.errorHandlerService});
+
+ bool isCmcOrdersLoading = false;
+ bool isCmcServicesLoading = false;
+ bool isUpdatingOrder = false;
+
+ List cmcOrdersList = [];
+ List cmcServicesList = [];
+
+ Future getOrdersList() async {
+ cmcOrdersList.clear();
+ isCmcOrdersLoading = true;
+ notifyListeners();
+ await getAllCmcOrders();
+ }
+
+ Future getAllCmcOrders({
+ Function(dynamic)? onSuccess,
+ Function(String)? onError,
+ }) async {
+ isCmcOrdersLoading = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.getAllCmcOrders();
+
+ result.fold(
+ (failure) async {
+ isCmcOrdersLoading = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isCmcOrdersLoading = false;
+ if (apiResponse.messageStatus == 1) {
+ cmcOrdersList = apiResponse.data ?? [];
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+ }
+
+ Future getAllCmcServices({required int patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ isCmcServicesLoading = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.getAllCmcServices(patientID: patientID);
+
+ result.fold(
+ (failure) async {
+ isCmcServicesLoading = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isCmcServicesLoading = false;
+ if (apiResponse.messageStatus == 1) {
+ cmcServicesList = apiResponse.data ?? [];
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+ }
+
+ Future updateCmcPresOrder({
+ required OrderUpdateRequestModel requestModel,
+ Function(dynamic)? onSuccess,
+ Function(String)? onError,
+ }) async {
+ isUpdatingOrder = true;
+ notifyListeners();
+
+ final result = await hmgServicesRepo.updateCmcPresOrder(requestModel);
+
+ bool success = false;
+
+ result.fold(
+ (failure) async {
+ isUpdatingOrder = false;
+ notifyListeners();
+ await errorHandlerService.handleError(failure: failure);
+ if (onError != null) {
+ onError(failure.toString());
+ }
+ },
+ (apiResponse) {
+ isUpdatingOrder = false;
+ if (apiResponse.messageStatus == 1) {
+ success = true;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ } else {
+ notifyListeners();
+ if (onError != null) {
+ onError(apiResponse.errorMessage ?? 'Unknown error');
+ }
+ }
+ },
+ );
+
+ return success;
+ }
+}
diff --git a/lib/features/hmg_services/models/hmg_services.dart b/lib/features/hmg_services/models/hmg_services.dart
deleted file mode 100644
index 2c33381..0000000
--- a/lib/features/hmg_services/models/hmg_services.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'dart:ui';
-
-import 'package:flutter/material.dart';
-
-class HmgServices {
- int action;
- String title;
- String subTitle;
- String icon;
- bool isLogin;
- bool isLocked;
- Color bgColor;
- Color textColor;
- String route;
- HmgServices(this.action, this.title, this.subTitle, this.icon, this.isLogin, {this.isLocked = false, this.bgColor = Colors.white, this.textColor = Colors.black, this.route=''});
-}
diff --git a/lib/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart b/lib/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart
new file mode 100644
index 0000000..a1fcc4b
--- /dev/null
+++ b/lib/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart
@@ -0,0 +1,131 @@
+class CMCInsertPresOrderRequestModel {
+ double? versionID;
+ int? channel;
+ int? languageID;
+ String? iPAdress;
+ String? generalid;
+ int? patientOutSA;
+ String? sessionID;
+ bool? isDentalAllowedBackend;
+ int? deviceTypeID;
+ int? patientID;
+ String? tokenID;
+ int? patientTypeID;
+ int? patientType;
+ double? latitude;
+ double? longitude;
+ int? createdBy;
+ int? orderServiceID;
+ int? projectID;
+ List? patientERCMCInsertServicesList;
+
+ CMCInsertPresOrderRequestModel(
+ {this.versionID,
+ this.channel,
+ this.languageID,
+ this.iPAdress,
+ this.generalid,
+ this.patientOutSA,
+ this.sessionID,
+ this.isDentalAllowedBackend,
+ this.deviceTypeID,
+ this.patientID,
+ this.tokenID,
+ this.patientTypeID,
+ this.patientType,
+ this.latitude,
+ this.longitude,
+ this.createdBy,
+ this.orderServiceID,
+ this.projectID,
+ this.patientERCMCInsertServicesList});
+
+ CMCInsertPresOrderRequestModel.fromJson(Map json) {
+ versionID = json['VersionID'];
+ channel = json['Channel'];
+ languageID = json['LanguageID'];
+ iPAdress = json['IPAdress'];
+ generalid = json['generalid'];
+ patientOutSA = json['PatientOutSA'];
+ sessionID = json['SessionID'];
+ isDentalAllowedBackend = json['isDentalAllowedBackend'];
+ deviceTypeID = json['DeviceTypeID'];
+ patientID = json['PatientID'];
+ tokenID = json['TokenID'];
+ patientTypeID = json['PatientTypeID'];
+ patientType = json['PatientType'];
+ latitude = json['Latitude'];
+ longitude = json['Longitude'];
+ createdBy = json['CreatedBy'];
+ orderServiceID = json['OrderServiceID'];
+ projectID = json['ProjectId'];
+ if (json['PatientER_CMC_InsertServicesList'] != null) {
+ patientERCMCInsertServicesList = [];
+ json['PatientER_CMC_InsertServicesList'].forEach((v) {
+ patientERCMCInsertServicesList!.add(
+ new PatientERCMCInsertServicesList.fromJson(v),
+ );
+ });
+ }
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['VersionID'] = this.versionID;
+ data['Channel'] = this.channel;
+ data['LanguageID'] = this.languageID;
+ data['IPAdress'] = this.iPAdress;
+ data['generalid'] = this.generalid;
+ data['isOutPatient'] = this.patientOutSA == 0 ? false : true;
+ data['SessionID'] = this.sessionID;
+ data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
+ data['DeviceTypeID'] = this.deviceTypeID;
+ data['TokenID'] = this.tokenID;
+ data['PatientTypeID'] = this.patientTypeID;
+ data['PatientType'] = this.patientType;
+ data['latitude'] = this.latitude;
+ data['longitude'] = this.longitude;
+ // data['CreatedBy'] = this.createdBy;
+ data['OrderServiceID'] = this.orderServiceID;
+ data['ProjectID'] = this.projectID;
+ if (this.patientERCMCInsertServicesList != null) {
+ data['procedures'] = this.patientERCMCInsertServicesList!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class PatientERCMCInsertServicesList {
+ int? recordID;
+ String? serviceID;
+ String? selectedServiceName;
+ String? selectedServiceNameAR;
+ dynamic price;
+ dynamic vAT;
+ dynamic totalPrice;
+
+ PatientERCMCInsertServicesList(
+ {this.recordID, this.serviceID, this.selectedServiceName, this.selectedServiceNameAR, this.price, this.vAT, this.totalPrice});
+
+ PatientERCMCInsertServicesList.fromJson(Map json) {
+ recordID = json['RecordID'];
+ serviceID = json['ServiceID'];
+ selectedServiceName = json['selectedServiceName'];
+ selectedServiceNameAR = json['selectedServiceNameAR'];
+ price = json['Price'];
+ vAT = json['VAT'];
+ totalPrice = json['TotalPrice'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['RecordID'] = this.recordID;
+ data['ServiceID'] = this.serviceID;
+ data['selectedServiceName'] = this.selectedServiceName;
+ data['selectedServiceNameAR'] = this.selectedServiceNameAR;
+ data['Price'] = this.price;
+ data['VAT'] = this.vAT;
+ data['TotalPrice'] = this.totalPrice;
+ return data;
+ }
+}
diff --git a/lib/features/hmg_services/models/req_models/order_update_req_model.dart b/lib/features/hmg_services/models/req_models/order_update_req_model.dart
new file mode 100644
index 0000000..0f9964f
--- /dev/null
+++ b/lib/features/hmg_services/models/req_models/order_update_req_model.dart
@@ -0,0 +1,82 @@
+class OrderUpdateRequestModel {
+ double? versionID;
+ int? channel;
+ int? languageID;
+ String? iPAdress;
+ String? generalid;
+ int? patientOutSA;
+ String? sessionID;
+ bool? isDentalAllowedBackend;
+ int? deviceTypeID;
+ int? patientID;
+ String? tokenID;
+ int? patientTypeID;
+ int? patientType;
+ int? presOrderID;
+ int? presOrderStatus;
+ int? editedBy;
+ String? rejectionReason;
+
+ OrderUpdateRequestModel({
+ this.versionID,
+ this.channel,
+ this.languageID,
+ this.iPAdress,
+ this.generalid,
+ this.patientOutSA,
+ this.sessionID,
+ this.isDentalAllowedBackend,
+ this.deviceTypeID,
+ this.patientID,
+ this.tokenID,
+ this.patientTypeID,
+ this.patientType,
+ this.presOrderID,
+ this.presOrderStatus,
+ this.editedBy,
+ this.rejectionReason,
+ });
+
+ OrderUpdateRequestModel.fromJson(Map json) {
+ versionID = json['VersionID'];
+ channel = json['Channel'];
+ languageID = json['LanguageID'];
+ iPAdress = json['IPAdress'];
+ generalid = json['generalid'];
+ patientOutSA = json['PatientOutSA'];
+ sessionID = json['SessionID'];
+ isDentalAllowedBackend = json['isDentalAllowedBackend'];
+ deviceTypeID = json['DeviceTypeID'];
+ patientID = json['PatientID'];
+ tokenID = json['TokenID'];
+ patientTypeID = json['PatientTypeID'];
+ patientType = json['PatientType'];
+ presOrderID = json['PresOrderID'];
+ presOrderStatus = json['PresOrderStatus'];
+ editedBy = json['EditedBy'];
+ rejectionReason = json['RejectionReason'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['VersionID'] = versionID;
+ data['Channel'] = channel;
+ data['LanguageID'] = languageID;
+ data['IPAdress'] = iPAdress;
+ data['generalid'] = generalid;
+ data['PatientOutSA'] = patientOutSA;
+ data['SessionID'] = sessionID;
+ data['isDentalAllowedBackend'] = isDentalAllowedBackend;
+ data['DeviceTypeID'] = deviceTypeID;
+ data['PatientID'] = patientID;
+ data['TokenID'] = tokenID;
+ data['PatientTypeID'] = patientTypeID;
+ data['PatientType'] = patientType;
+ data['Id'] = presOrderID;
+ data['ClickButton'] = 14;
+ data['PresOrderStatus'] = presOrderStatus;
+ data['EditedBy'] = editedBy;
+ data['RejectionReason'] = rejectionReason;
+ return data;
+ }
+}
diff --git a/lib/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart b/lib/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart
new file mode 100644
index 0000000..ddd91f4
--- /dev/null
+++ b/lib/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart
@@ -0,0 +1,344 @@
+import 'dart:developer';
+
+class GetCMCAllOrdersResponseModel {
+ int? iD;
+ int? patientId;
+ int? patientOutSa;
+ bool? isOutPatient;
+ int? projectId;
+ int? nearestProjectId;
+ dynamic longitude;
+ dynamic latitude;
+ dynamic appointmentNo;
+ dynamic dischargeId;
+ int? statusId;
+ int? serviceId;
+ int? channel;
+ Orderpayment? orderpayment;
+ dynamic orderselectedservice;
+ dynamic wforder;
+ dynamic orderapprovalobj;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+ String? statusText;
+ int? paymentStatus;
+ dynamic clientRequestid;
+ dynamic paymentStatusText;
+ String? projectName;
+ String? nearestProjectName;
+ dynamic paymentAmount;
+ WFOrder? wFOrder;
+ String? serviceText;
+ bool? isSentForApproval;
+ int? exaCartOrderId;
+ bool? isTimer;
+ int? timeSeconds;
+ int? totalPendingSeconds;
+ int? timeMinute;
+ int? timeHour;
+ int? timeTotalSeconds;
+ int? timeTotalMinute;
+ int? timeTotalHour;
+ dynamic approvalStatus;
+ bool? isActive;
+ int? clickButton;
+ List? procedures;
+ dynamic pickupLocation;
+ dynamic dropOffLocation;
+ dynamic clinicName;
+ dynamic doctorName;
+ dynamic branch;
+ dynamic time;
+ dynamic notes;
+
+ GetCMCAllOrdersResponseModel(
+ {this.iD,
+ this.patientId,
+ this.patientOutSa,
+ this.isOutPatient,
+ this.projectId,
+ this.nearestProjectId,
+ this.longitude,
+ this.latitude,
+ this.appointmentNo,
+ this.dischargeId,
+ this.statusId,
+ this.serviceId,
+ this.channel,
+ this.orderpayment,
+ this.orderselectedservice,
+ this.wforder,
+ this.orderapprovalobj,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted,
+ this.statusText,
+ this.paymentStatus,
+ this.clientRequestid,
+ this.paymentStatusText,
+ this.projectName,
+ this.nearestProjectName,
+ this.paymentAmount,
+ this.wFOrder,
+ this.serviceText,
+ this.isSentForApproval,
+ this.exaCartOrderId,
+ this.isTimer,
+ this.timeSeconds,
+ this.totalPendingSeconds,
+ this.timeMinute,
+ this.timeHour,
+ this.timeTotalSeconds,
+ this.timeTotalMinute,
+ this.timeTotalHour,
+ this.approvalStatus,
+ this.isActive,
+ this.clickButton,
+ this.procedures,
+ this.pickupLocation,
+ this.dropOffLocation,
+ this.clinicName,
+ this.doctorName,
+ this.branch,
+ this.time,
+ this.notes});
+
+ GetCMCAllOrdersResponseModel.fromJson(Map json) {
+ log("responseJson: $json");
+ iD = json['ID'];
+ patientId = json['PatientId'];
+ patientOutSa = json['PatientOutSa'];
+ isOutPatient = json['IsOutPatient'];
+ projectId = json['ProjectId'];
+ nearestProjectId = json['NearestProjectId'];
+ longitude = json['Longitude'];
+ latitude = json['Latitude'];
+ appointmentNo = json['AppointmentNo'];
+ dischargeId = json['DischargeId'];
+ statusId = json['StatusId'];
+ serviceId = json['ServiceId'];
+ channel = json['Channel'];
+ orderpayment = json['orderpayment'] != null ? Orderpayment.fromJson(json['orderpayment']) : null;
+ orderselectedservice = json['orderselectedservice'];
+ wforder = json['wforder'];
+ orderapprovalobj = json['orderapprovalobj'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ statusText = json['StatusText'];
+ paymentStatus = json['PaymentStatus'];
+ clientRequestid = json['ClientRequestid'];
+ paymentStatusText = json['PaymentStatusText'];
+ projectName = json['ProjectName'];
+ nearestProjectName = json['NearestProjectName'];
+ paymentAmount = json['PaymentAmount'];
+ wFOrder = json['WF_order'] != null ? WFOrder.fromJson(json['WF_order']) : null;
+ serviceText = json['ServiceText'];
+ isSentForApproval = json['isSentForApproval'];
+ exaCartOrderId = json['ExaCart_OrderId'];
+ isTimer = json['isTimer'];
+ timeSeconds = json['TimeSeconds'];
+ totalPendingSeconds = json['TotalPendingSeconds'];
+ timeMinute = json['TimeMinute'];
+ timeHour = json['TimeHour'];
+ timeTotalSeconds = json['TimeTotalSeconds'];
+ timeTotalMinute = json['TimeTotalMinute'];
+ timeTotalHour = json['TimeTotalHour'];
+ approvalStatus = json['ApprovalStatus'];
+ isActive = json['isActive'];
+ clickButton = json['ClickButton'];
+ pickupLocation = json['PickupLocation'];
+ dropOffLocation = json['DropOffLocation'];
+ clinicName = json['clinicName'];
+ doctorName = json['DoctorName'];
+ branch = json['Branch'];
+ time = json['Time'];
+ notes = json['Notes'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['ID'] = iD;
+ data['PatientId'] = patientId;
+ data['PatientOutSa'] = patientOutSa;
+ data['IsOutPatient'] = isOutPatient;
+ data['ProjectId'] = projectId;
+ data['NearestProjectId'] = nearestProjectId;
+ data['Longitude'] = longitude;
+ data['Latitude'] = latitude;
+ data['AppointmentNo'] = appointmentNo;
+ data['DischargeId'] = dischargeId;
+ data['StatusId'] = statusId;
+ data['ServiceId'] = serviceId;
+ data['Channel'] = channel;
+ if (orderpayment != null) {
+ data['orderpayment'] = orderpayment!.toJson();
+ }
+ data['orderselectedservice'] = orderselectedservice;
+
+ data['wforder'] = wforder;
+ data['orderapprovalobj'] = orderapprovalobj;
+ data['Created'] = created;
+ data['CreatedBy'] = createdBy;
+ data['Modified'] = modified;
+ data['ModifiedBy'] = modifiedBy;
+ data['IsDeleted'] = isDeleted;
+ data['StatusText'] = statusText;
+ data['PaymentStatus'] = paymentStatus;
+ data['ClientRequestid'] = clientRequestid;
+ data['PaymentStatusText'] = paymentStatusText;
+ data['ProjectName'] = projectName;
+ data['NearestProjectName'] = nearestProjectName;
+ data['PaymentAmount'] = paymentAmount;
+ if (wFOrder != null) {
+ data['WF_order'] = wFOrder!.toJson();
+ }
+ data['ServiceText'] = serviceText;
+ data['isSentForApproval'] = isSentForApproval;
+ data['ExaCart_OrderId'] = exaCartOrderId;
+ data['isTimer'] = isTimer;
+ data['TimeSeconds'] = timeSeconds;
+ data['TotalPendingSeconds'] = totalPendingSeconds;
+ data['TimeMinute'] = timeMinute;
+ data['TimeHour'] = timeHour;
+ data['TimeTotalSeconds'] = timeTotalSeconds;
+ data['TimeTotalMinute'] = timeTotalMinute;
+ data['TimeTotalHour'] = timeTotalHour;
+ data['ApprovalStatus'] = approvalStatus;
+ data['isActive'] = isActive;
+ data['ClickButton'] = clickButton;
+ data['PickupLocation'] = pickupLocation;
+ data['DropOffLocation'] = dropOffLocation;
+ data['clinicName'] = clinicName;
+ data['DoctorName'] = doctorName;
+ data['Branch'] = branch;
+ data['Time'] = time;
+ data['Notes'] = notes;
+ return data;
+ }
+}
+
+class Orderpayment {
+ int? iD;
+ int? orderId;
+ dynamic clientRequestId;
+ dynamic totalAmount;
+ int? paymentStatus;
+ dynamic order;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+
+ Orderpayment(
+ {this.iD,
+ this.orderId,
+ this.clientRequestId,
+ this.totalAmount,
+ this.paymentStatus,
+ this.order,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted});
+
+ Orderpayment.fromJson(Map json) {
+ iD = json['ID'];
+ orderId = json['OrderId'];
+ clientRequestId = json['ClientRequestId'];
+ totalAmount = json['TotalAmount'];
+ paymentStatus = json['PaymentStatus'];
+ order = json['Order'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['ID'] = iD;
+ data['OrderId'] = orderId;
+ data['ClientRequestId'] = clientRequestId;
+ data['TotalAmount'] = totalAmount;
+ data['PaymentStatus'] = paymentStatus;
+ data['Order'] = order;
+ data['Created'] = created;
+ data['CreatedBy'] = createdBy;
+ data['Modified'] = modified;
+ data['ModifiedBy'] = modifiedBy;
+ data['IsDeleted'] = isDeleted;
+ return data;
+ }
+}
+
+class WFOrder {
+ dynamic wfButtonsDTO;
+ int? iD;
+ int? orderId;
+ int? previousStep;
+ int? nextStep;
+ int? serviceId;
+ dynamic order;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+
+ WFOrder(
+ {this.wfButtonsDTO,
+ this.iD,
+ this.orderId,
+ this.previousStep,
+ this.nextStep,
+ this.serviceId,
+ this.order,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted});
+
+ WFOrder.fromJson(Map json) {
+ wfButtonsDTO = json['wf_ButtonsDTO'];
+ iD = json['ID'];
+ orderId = json['OrderId'];
+ previousStep = json['PreviousStep'];
+ nextStep = json['NextStep'];
+ serviceId = json['ServiceId'];
+ order = json['Order'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['wf_ButtonsDTO'] = wfButtonsDTO;
+ data['ID'] = iD;
+ data['OrderId'] = orderId;
+ data['PreviousStep'] = previousStep;
+ data['NextStep'] = nextStep;
+ data['ServiceId'] = serviceId;
+ data['Order'] = order;
+ data['Created'] = created;
+ data['CreatedBy'] = createdBy;
+ data['Modified'] = modified;
+ data['ModifiedBy'] = modifiedBy;
+ data['IsDeleted'] = isDeleted;
+ return data;
+ }
+}
diff --git a/lib/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart b/lib/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart
new file mode 100644
index 0000000..670a582
--- /dev/null
+++ b/lib/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart
@@ -0,0 +1,57 @@
+class GetCMCServicesResponseModel {
+ int? iD;
+ String? serviceID;
+ int? orderServiceID;
+ String? text;
+ String? textN;
+ dynamic price;
+ dynamic priceVAT;
+ dynamic priceTotal;
+ bool? isEnabled;
+ int? orderId;
+ int? quantity;
+
+ GetCMCServicesResponseModel({
+ this.iD,
+ this.serviceID,
+ this.orderServiceID,
+ this.text,
+ this.textN,
+ this.price,
+ this.priceVAT,
+ this.priceTotal,
+ this.isEnabled,
+ this.orderId,
+ this.quantity,
+ });
+
+ GetCMCServicesResponseModel.fromJson(Map json) {
+ iD = json['ID'];
+ serviceID = json['ServiceID'];
+ orderServiceID = json['OrderServiceID'];
+ text = json['Text'];
+ textN = json['TextN'];
+ price = json['Price'];
+ priceVAT = json['PriceVAT'];
+ priceTotal = json['PriceTotal'];
+ isEnabled = json['IsEnabled'];
+ orderId = json['OrderId'];
+ quantity = json['Quantity'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['ID'] = this.iD;
+ data['ServiceID'] = this.serviceID;
+ data['OrderServiceID'] = this.orderServiceID;
+ data['Text'] = this.text;
+ data['TextN'] = this.textN;
+ data['Price'] = this.price;
+ data['PriceVAT'] = this.priceVAT;
+ data['PriceTotal'] = this.priceTotal;
+ data['IsEnabled'] = this.isEnabled;
+ data['OrderId'] = this.orderId;
+ data['Quantity'] = this.quantity;
+ return data;
+ }
+}
diff --git a/lib/features/hmg_services/models/ui_models/hmg_services_component_model.dart b/lib/features/hmg_services/models/ui_models/hmg_services_component_model.dart
new file mode 100644
index 0000000..d5180ae
--- /dev/null
+++ b/lib/features/hmg_services/models/ui_models/hmg_services_component_model.dart
@@ -0,0 +1,25 @@
+import 'package:flutter/material.dart';
+
+class HmgServicesComponentModel {
+ int action;
+ String title;
+ String subTitle;
+ String icon;
+ bool isLogin;
+ bool isLocked;
+ Color bgColor;
+ Color textColor;
+ String route;
+
+ HmgServicesComponentModel(
+ this.action,
+ this.title,
+ this.subTitle,
+ this.icon,
+ this.isLogin, {
+ this.isLocked = false,
+ this.bgColor = Colors.white,
+ this.textColor = Colors.black,
+ this.route = '',
+ });
+}
diff --git a/lib/main.dart b/lib/main.dart
index 20c4ece..1af80b6 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -14,6 +14,7 @@ import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.da
import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_view_model.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/lab/history/lab_history_viewmodel.dart';
@@ -132,7 +133,8 @@ void main() async {
),
ChangeNotifierProvider(
create: (_) => getIt.get(),
- ),ChangeNotifierProvider(
+ ),
+ ChangeNotifierProvider(
create: (_) => getIt.get(),
),
ChangeNotifierProvider(
@@ -140,6 +142,9 @@ void main() async {
),
ChangeNotifierProvider(
create: (_) => getIt.get(),
+ ),
+ ChangeNotifierProvider(
+ create: (_) => getIt.get(),
)
], child: MyApp()),
),
diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart
index 79084c9..12f3589 100644
--- a/lib/presentation/appointments/appointment_details_page.dart
+++ b/lib/presentation/appointments/appointment_details_page.dart
@@ -30,7 +30,7 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
-import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:maps_launcher/maps_launcher.dart';
import 'package:provider/provider.dart';
@@ -317,7 +317,7 @@ class _AppointmentDetailsPageState extends State {
SizedBox(height: 16.h),
Consumer(builder: (context, prescriptionVM, child) {
return prescriptionVM.isPrescriptionsDetailsLoading
- ? const MoviesShimmerWidget()
+ ? const CommonShimmerWidget()
: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: Colors.white,
diff --git a/lib/presentation/comprehensive_checkup/cmc_order_detail_page.dart b/lib/presentation/comprehensive_checkup/cmc_order_detail_page.dart
new file mode 100644
index 0000000..97e5e6d
--- /dev/null
+++ b/lib/presentation/comprehensive_checkup/cmc_order_detail_page.dart
@@ -0,0 +1,344 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:fluttertoast/fluttertoast.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/features/hmg_services/hmg_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
+import 'package:hmg_patient_app_new/services/dialog_service.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+import 'package:intl/intl.dart';
+import 'package:provider/provider.dart';
+import 'package:shimmer/shimmer.dart';
+
+class CmcOrderDetailPage extends StatefulWidget {
+ const CmcOrderDetailPage({super.key});
+
+ @override
+ State createState() => _CmcOrderDetailPageState();
+}
+
+class _CmcOrderDetailPageState extends State {
+ bool _isLoading = false;
+
+ @override
+ void initState() {
+ super.initState();
+ final hmgServicesViewModel = context.read();
+ scheduleMicrotask(() async {
+ await hmgServicesViewModel.getOrdersList();
+ });
+ }
+
+ Color _getStatusColor(int? statusId) {
+ switch (statusId) {
+ case 1: // Pending
+ return const Color(0xffCC9B14);
+ case 2: // Processing
+ return const Color(0xff2E303A);
+ case 3: // Completed
+ return const Color(0xff359846);
+ case 4: // Cancelled
+ case 6: // Rejected
+ case 7: // Rejected
+ return const Color(0xffD02127);
+ default:
+ return AppColors.greyColor;
+ }
+ }
+
+ String _formatDate(String? dateString) {
+ if (dateString == null) return '';
+ try {
+ final date = DateTime.parse(dateString);
+ return DateFormat('dd MMM yyyy').format(date);
+ } catch (e) {
+ return dateString;
+ }
+ }
+
+ Future _showCancelConfirmationDialog({
+ required BuildContext context,
+ required HmgServicesViewModel viewModel,
+ required GetCMCAllOrdersResponseModel order,
+ }) async {
+ final dialogService = context.read();
+
+ await dialogService.showCommonBottomSheetWithoutH(
+ label: "Confirm Cancellation".needTranslation,
+ message: "Are you sure you want to cancel this order?".needTranslation,
+ onOkPressed: () async {
+ Navigator.of(context).pop();
+
+ // Show loading state
+ setState(() {
+ _isLoading = true;
+ });
+
+ final requestModel = OrderUpdateRequestModel(
+ presOrderID: order.iD,
+ rejectionReason: "",
+ presOrderStatus: 4, // Cancelled status
+ editedBy: 3,
+ );
+
+ final success = await viewModel.updateCmcPresOrder(
+ requestModel: requestModel,
+ onSuccess: (_) async {
+ setState(() {
+ _isLoading = false;
+ });
+ Fluttertoast.showToast(
+ msg: "Order cancelled successfully".needTranslation,
+ toastLength: Toast.LENGTH_SHORT,
+ gravity: ToastGravity.BOTTOM,
+ backgroundColor: Colors.green,
+ textColor: Colors.white,
+ );
+ await viewModel.getAllCmcOrders();
+ },
+ onError: (error) {
+ setState(() {
+ _isLoading = false;
+ });
+ Fluttertoast.showToast(
+ msg: error,
+ toastLength: Toast.LENGTH_SHORT,
+ gravity: ToastGravity.BOTTOM,
+ backgroundColor: Colors.red,
+ textColor: Colors.white,
+ );
+ },
+ );
+
+ if (!success) {
+ setState(() {
+ _isLoading = false;
+ });
+ }
+ },
+ onCancelPressed: () {
+ Navigator.of(context).pop();
+ },
+ );
+ }
+
+ Widget _buildLoadingShimmer() {
+ return ListView.separated(
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ padding: EdgeInsets.all(21.w),
+ itemCount: 3,
+ separatorBuilder: (_, __) => SizedBox(height: 12.h),
+ itemBuilder: (context, index) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300]!,
+ highlightColor: Colors.grey[100]!,
+ child: Container(
+ height: 120.h,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(10.r),
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ Widget _buildOrderCard(GetCMCAllOrdersResponseModel order) {
+ final statusColor = _getStatusColor(order.statusId);
+ final canCancel = order.statusId == 1 || order.statusId == 2;
+
+ return Container(
+ decoration: BoxDecoration(
+ color: statusColor,
+ borderRadius: BorderRadius.circular(10.r),
+ boxShadow: [
+ BoxShadow(
+ color: const Color(0xff000000).withValues(alpha: 0.05),
+ blurRadius: 27,
+ offset: const Offset(0, -3),
+ ),
+ ],
+ ),
+ child: Container(
+ margin: EdgeInsets.only(left: 6.w),
+ padding: EdgeInsets.symmetric(vertical: 14.h, horizontal: 12.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.white, width: 1),
+ borderRadius: BorderRadius.only(
+ bottomRight: Radius.circular(10.r),
+ topRight: Radius.circular(10.r),
+ ),
+ ),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ order.statusText ?? '',
+ style: TextStyle(
+ fontSize: 12.f,
+ fontWeight: FontWeight.w600,
+ color: statusColor,
+ letterSpacing: -0.4,
+ height: 16 / 10,
+ ),
+ ),
+ SizedBox(height: 6.h),
+ Text(
+ '${"Request ID".needTranslation}: ${order.iD}',
+ style: TextStyle(
+ fontSize: 16.f,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2E303A),
+ letterSpacing: -0.64,
+ height: 25 / 16,
+ ),
+ ),
+ SizedBox(height: 4.h),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "${"Hospital".needTranslation}: ",
+ style: TextStyle(
+ fontSize: 12.f,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff575757),
+ letterSpacing: -0.4,
+ height: 16 / 10,
+ ),
+ ),
+ Expanded(
+ child: Text(
+ order.projectName?.trim() ?? '',
+ style: TextStyle(
+ fontSize: 14.f,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2B353E),
+ letterSpacing: -0.56,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Text(
+ _formatDate(order.created),
+ style: TextStyle(
+ fontSize: 12.f,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2B353E),
+ letterSpacing: -0.4,
+ height: 16 / 10,
+ ),
+ ),
+ if (canCancel) ...[
+ SizedBox(height: 12.h),
+ InkWell(
+ onTap: _isLoading
+ ? null
+ : () {
+ _showCancelConfirmationDialog(
+ context: context,
+ viewModel: context.read(),
+ order: order,
+ );
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 14.w),
+ decoration: BoxDecoration(
+ color: _isLoading ? Colors.grey : const Color(0xffD02127),
+ border: Border.all(color: Colors.white, width: 1),
+ borderRadius: BorderRadius.circular(10.r),
+ ),
+ child: Text(
+ "Cancel".needTranslation,
+ style: TextStyle(
+ fontSize: 12.f,
+ fontWeight: FontWeight.w600,
+ color: Colors.white,
+ letterSpacing: -0.4,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget _buildEmptyState() {
+ return Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(Icons.inbox_outlined, size: 80.w, color: AppColors.greyColor),
+ SizedBox(height: 16.h),
+ Text(
+ "No orders found".needTranslation,
+ style: TextStyle(
+ fontSize: 16.f,
+ color: AppColors.greyTextColor,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return CollapsingListView(
+ title: "CMC Orders".needTranslation,
+ isLeading: true,
+ child: Consumer(
+ builder: (context, viewModel, child) {
+ if (viewModel.isCmcOrdersLoading) {
+ return _buildLoadingShimmer();
+ }
+
+ if (viewModel.cmcOrdersList.isEmpty) {
+ return SizedBox(
+ height: MediaQuery.of(context).size.height * 0.6,
+ child: _buildEmptyState(),
+ );
+ }
+
+ return ListView.separated(
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ padding: EdgeInsets.all(21.w),
+ itemCount: viewModel.cmcOrdersList.length,
+ separatorBuilder: (_, __) => SizedBox(height: 12.h),
+ itemBuilder: (context, index) {
+ final order = viewModel.cmcOrdersList.reversed.toList()[index];
+ return _buildOrderCard(order);
+ },
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/comprehensive_checkup/comprehensive_checkup_page.dart b/lib/presentation/comprehensive_checkup/comprehensive_checkup_page.dart
new file mode 100644
index 0000000..d242e55
--- /dev/null
+++ b/lib/presentation/comprehensive_checkup/comprehensive_checkup_page.dart
@@ -0,0 +1,378 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/app_state.dart';
+import 'package:hmg_patient_app_new/core/dependencies.dart';
+import 'package:hmg_patient_app_new/core/utils/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/hmg_services/hmg_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
+import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/cmc_order_detail_page.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+import 'package:hmg_patient_app_new/widgets/media_viewer/full_screen_image_viewer.dart';
+import 'package:hmg_patient_app_new/widgets/radio_list_tile_widget.dart';
+import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
+import 'package:provider/provider.dart';
+import 'package:shimmer/shimmer.dart';
+
+class ComprehensiveCheckupPage extends StatefulWidget {
+ const ComprehensiveCheckupPage({super.key});
+
+ @override
+ State createState() => _ComprehensiveCheckupPageState();
+}
+
+class _ComprehensiveCheckupPageState extends State {
+ int? _selectedServiceId;
+ GetCMCServicesResponseModel? _selectedService;
+
+ @override
+ void initState() {
+ super.initState();
+ final HmgServicesViewModel hmgServicesViewModel = context.read();
+ final AppState appState = getIt.get();
+
+ scheduleMicrotask(() async {
+ final user = appState.getAuthenticatedUser();
+ if (user != null) {
+ await hmgServicesViewModel.getAllCmcOrders();
+ await hmgServicesViewModel.getAllCmcServices(patientID: user.patientId ?? 0);
+ }
+ });
+ }
+
+ GetCMCAllOrdersResponseModel? _getPendingOrder(List orders) {
+ if (orders.isEmpty) return null;
+
+ // Find pending or processing orders (status 1 or 2)
+ for (var order in orders) {
+ if (order.statusId == 1 || order.statusId == 2) {
+ return order;
+ }
+ }
+
+ return null;
+ }
+
+ Widget _buildPendingOrderCard(GetCMCAllOrdersResponseModel order) {
+ int status = order.statusId ?? 0;
+ String statusDisp = order.statusText ?? "";
+ Color statusColor;
+
+ if (status == 1) {
+ // pending
+ statusColor = const Color(0xffCC9B14);
+ } else if (status == 2) {
+ // processing
+ statusColor = const Color(0xff2E303A);
+ } else if (status == 3) {
+ // completed
+ statusColor = const Color(0xff359846);
+ } else {
+ // cancel / rejected
+ statusColor = const Color(0xffD02127);
+ }
+
+ return Container(
+ width: double.infinity,
+ margin: EdgeInsets.all(16.h),
+ decoration: BoxDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: BorderRadius.circular(12.h),
+ boxShadow: [
+ BoxShadow(
+ color: Color.fromARGB(13, 0, 0, 0),
+ blurRadius: 4,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ ),
+ child: Container(
+ padding: EdgeInsets.all(14.h),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ statusDisp,
+ style: TextStyle(
+ fontSize: 12.h,
+ fontWeight: FontWeight.w600,
+ color: statusColor,
+ letterSpacing: -0.4,
+ ),
+ ),
+ SizedBox(height: 6.h),
+ Text(
+ '${"Request ID".needTranslation}: ${order.iD}',
+ style: TextStyle(
+ fontSize: 16.h,
+ fontWeight: FontWeight.w600,
+ color: AppColors.blackColor,
+ letterSpacing: -0.64,
+ ),
+ ),
+ SizedBox(height: 4.h),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "${"Hospital".needTranslation}: ",
+ style: TextStyle(
+ fontSize: 12.h,
+ fontWeight: FontWeight.w600,
+ color: AppColors.greyTextColor,
+ letterSpacing: -0.4,
+ ),
+ ),
+ Expanded(
+ child: Text(
+ order.projectName ?? "",
+ style: TextStyle(
+ fontSize: 14.h,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2B353E),
+ letterSpacing: -0.56,
+ ),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 4.h),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "${"Service Name".needTranslation}: ",
+ style: TextStyle(
+ fontSize: 12.h,
+ fontWeight: FontWeight.w600,
+ color: AppColors.greyTextColor,
+ letterSpacing: -0.4,
+ ),
+ ),
+ Expanded(
+ child: Text(
+ order.serviceText ?? "",
+ style: TextStyle(
+ fontSize: 14.h,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xff2B353E),
+ letterSpacing: -0.56,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget _buildServiceSelectionList(List services) {
+ if (services.isEmpty) {
+ return Center(
+ child: Padding(
+ padding: EdgeInsets.all(24.h),
+ child: Text(
+ 'No services available'.needTranslation,
+ style: TextStyle(
+ fontSize: 16.h,
+ color: AppColors.greyTextColor,
+ ),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 16.h),
+ Text(
+ 'Select a Service'.needTranslation,
+ style: TextStyle(
+ fontSize: 20.h,
+ fontWeight: FontWeight.w700,
+ color: AppColors.blackColor,
+ letterSpacing: -0.8,
+ ),
+ ).paddingOnly(left: 16.w, right: 16.w),
+ ListView.builder(
+ padding: EdgeInsets.zero,
+ itemCount: services.length,
+ shrinkWrap: true,
+ physics: NeverScrollableScrollPhysics(),
+ itemBuilder: (context, index) {
+ final service = services[index];
+ final serviceName = service.text ?? service.textN ?? '';
+ final price = service.priceTotal ?? 0.0;
+ return RadioListTileWidget(
+ value: service.iD ?? 0,
+ groupValue: _selectedServiceId,
+ title: serviceName,
+ subtitleWidget: Utils.getPaymentAmountWithSymbol(
+ isExpanded: false,
+ price.toString().toText14(),
+ AppColors.blackColor,
+ 14,
+ isSaudiCurrency: true,
+ ),
+ onChanged: (value) {
+ setState(() {
+ _selectedServiceId = value;
+ _selectedService = service;
+ });
+ },
+ );
+ },
+ ),
+ // Illustration image below the services list similar to the old implementation
+ SizedBox(height: 12.h),
+ Builder(builder: (context) {
+ final appStateLocal = getIt.get();
+ final String imagePath = appStateLocal.isArabic() ? AppAssets.comprehensiveCheckupAr : AppAssets.comprehensiveCheckupEn;
+ return Stack(
+ children: [
+ Image.asset(
+ imagePath,
+ width: double.infinity,
+ fit: BoxFit.cover,
+ ).paddingAll(16.w),
+ Align(
+ alignment: Alignment.topRight,
+ child: Container(
+ decoration: BoxDecoration(
+ color: Color.fromARGB(51, 0, 0, 0),
+ borderRadius: BorderRadius.circular(1000.r),
+ ),
+ margin: EdgeInsets.all(12.h),
+ child: IconButton(
+ icon: Icon(Icons.zoom_in, color: Colors.white),
+ padding: EdgeInsets.all(12.h),
+ onPressed: () => _showFullScreenImage(context, imagePath, isSvg: false),
+ ),
+ ),
+ ),
+ ],
+ );
+ }),
+ ],
+ );
+ }
+
+ void _proceedWithSelectedService() {
+ if (_selectedService != null) {
+ // TODO: Navigate to next step or create order
+ // This will be implemented based on your flow
+ // For now, just show a message
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Selected: ${_selectedService!.text}'),
+ ),
+ );
+ }
+ }
+
+ Widget _buildLoadingShimmer() {
+ return ListView.separated(
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ padding: EdgeInsets.all(21.w),
+ itemCount: 3,
+ separatorBuilder: (_, __) => SizedBox(height: 12.h),
+ itemBuilder: (context, index) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300]!,
+ highlightColor: Colors.grey[100]!,
+ child: Container(
+ height: 120.h,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(10.r),
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return CollapsingListView(
+ title: "Comprehensive Checkup".needTranslation,
+ requests: () {
+ Navigator.of(context).push(CustomPageRoute(page: CmcOrderDetailPage(), direction: AxisDirection.up));
+ },
+ // bottomChild sticks to the bottom of the scaffold; make it reactive using Consumer
+ bottomChild: Consumer(
+ builder: (context, hmgServicesViewModel, child) {
+ // if still loading, don't show the bottom button
+ if (hmgServicesViewModel.isCmcOrdersLoading || hmgServicesViewModel.isCmcServicesLoading) return SizedBox.shrink();
+
+ final pendingOrder = _getPendingOrder(hmgServicesViewModel.cmcOrdersList);
+
+ // show button only when there is no pending order and a service is selected
+ if (pendingOrder == null && _selectedServiceId != null) {
+ return SafeArea(
+ top: false,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
+ child: CustomButton(
+ borderWidth: 0,
+ text: "Next".needTranslation,
+ onPressed: _proceedWithSelectedService,
+ textColor: AppColors.whiteColor,
+ borderRadius: 12.r,
+ borderColor: Colors.transparent,
+ padding: EdgeInsets.symmetric(vertical: 14.h),
+ ),
+ ),
+ );
+ }
+
+ return SizedBox.shrink();
+ },
+ ),
+ child: Consumer(
+ builder: (context, hmgServicesViewModel, child) {
+ if (hmgServicesViewModel.isCmcOrdersLoading || hmgServicesViewModel.isCmcServicesLoading) {
+ return _buildLoadingShimmer();
+ }
+
+ final pendingOrder = _getPendingOrder(hmgServicesViewModel.cmcOrdersList);
+
+ if (pendingOrder != null) {
+ // Return the pending order card directly. The outer CollapsingListView's
+ // CustomScrollView/SliverList will provide proper scroll constraints.
+ return _buildPendingOrderCard(pendingOrder);
+ } else {
+ return _buildServiceSelectionList(hmgServicesViewModel.cmcServicesList);
+ }
+ },
+ ),
+ );
+ }
+
+ void _showFullScreenImage(BuildContext context, String path, {bool isSvg = false}) {
+ Navigator.of(context).push(MaterialPageRoute(builder: (_) => FullScreenImageViewer(isSvg: isSvg, path: path)));
+ }
+}
diff --git a/lib/presentation/comprehensive_checkup/old_cmc_page.dart b/lib/presentation/comprehensive_checkup/old_cmc_page.dart
new file mode 100644
index 0000000..042eab0
--- /dev/null
+++ b/lib/presentation/comprehensive_checkup/old_cmc_page.dart
@@ -0,0 +1,195 @@
+// import 'package:hmg_patient_app/core/enum/viewstate.dart';
+// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart';
+// import 'package:hmg_patient_app/core/viewModels/AlHabibMedicalService/cmc_view_model.dart';
+// import 'package:hmg_patient_app/core/viewModels/project_view_model.dart';
+// import 'package:hmg_patient_app/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart';
+// import 'package:hmg_patient_app/uitl/translations_delegate_base.dart';
+// import 'package:hmg_patient_app/uitl/utils.dart';
+// import 'package:hmg_patient_app/uitl/utils_new.dart';
+// import 'package:hmg_patient_app/widgets/buttons/defaultButton.dart';
+// import 'package:hmg_patient_app/widgets/dragable_sheet.dart';
+// import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart';
+// import 'package:hmg_patient_app/widgets/photo_view_page.dart';
+// import 'package:flutter/cupertino.dart';
+// import 'package:flutter/material.dart';
+// import 'package:flutter_svg/svg.dart';
+// import 'package:provider/provider.dart';
+//
+// import 'new_cmc_step_tow_page.dart';
+//
+// class NewCMCStepOnePage extends StatefulWidget {
+// final CMCInsertPresOrderRequestModel cMCInsertPresOrderRequestModel;
+// final Function changePageViewIndex;
+// final CMCViewModel model;
+//
+// final double latitude;
+// final double longitude;
+//
+// const NewCMCStepOnePage({Key? key, required this.cMCInsertPresOrderRequestModel, required this.model, required this.changePageViewIndex, required this.latitude, required this.longitude})
+// : super(key: key);
+//
+// @override
+// _NewCMCStepOnePageState createState() => _NewCMCStepOnePageState();
+// }
+//
+// class _NewCMCStepOnePageState extends State {
+// int selectedItem = 0;
+//
+// @override
+// void initState() {
+// super.initState();
+// }
+//
+// @override
+// Widget build(BuildContext context) {
+// ProjectViewModel projectViewModel = Provider.of(context);
+//
+// return AppScaffold(
+// isShowAppBar: false,
+// baseViewModel: widget.model,
+// body: Column(
+// children: [
+// Expanded(
+// child: SingleChildScrollView(
+// physics: BouncingScrollPhysics(),
+// padding: EdgeInsets.all(21),
+// child: Column(
+// children: [
+// ListView.separated(
+// physics: NeverScrollableScrollPhysics(),
+// shrinkWrap: true,
+// itemBuilder: (context, index) {
+// return Row(
+// children: [
+// Radio(
+// value: num.tryParse(widget.model.cmcAllServicesList[index].serviceID!),
+// activeColor: Colors.red[800],
+// onChanged: (newValue) async {
+// selectedItem = index;
+// PatientERCMCInsertServicesList patientERCMCInsertServicesList = PatientERCMCInsertServicesList(
+// price: widget.model.cmcAllServicesList[index].price,
+// serviceID: widget.model.cmcAllServicesList[index].serviceID,
+// selectedServiceName: widget.model.cmcAllServicesList[index].text,
+// selectedServiceNameAR: widget.model.cmcAllServicesList[index].textN,
+// recordID: 1,
+// totalPrice: widget.model.cmcAllServicesList[index].priceTotal,
+// vAT: widget.model.cmcAllServicesList[index].priceVAT);
+// setState(() {
+// widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList = [patientERCMCInsertServicesList];
+// });
+// // CMCGetItemsRequestModel cMCGetItemsRequestModel = new CMCGetItemsRequestModel(checkupType: newValue);
+// // await widget.model.getCheckupItems(cMCGetItemsRequestModel: cMCGetItemsRequestModel);
+// },
+// groupValue: widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList!.length > 0
+// ? int.parse(widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList![0].serviceID!)
+// : 1),
+// Expanded(
+// child: Padding(
+// padding: const EdgeInsets.only(
+// left: 10,
+// right: 10,
+// top: 20,
+// bottom: 20,
+// ),
+// child: Text(
+// projectViewModel.isArabic ? widget.model.cmcAllServicesList[index].textN! : widget.model.cmcAllServicesList[index].text!,
+// style: TextStyle(
+// fontSize: 14,
+// fontWeight: FontWeight.w600,
+// letterSpacing: -0.45,
+// ),
+// ),
+// ),
+// ),
+// ],
+// );
+// },
+// separatorBuilder: (context, index) {
+// return mDivider(Colors.grey);
+// },
+// itemCount: widget.model.cmcAllServicesList.length),
+// Stack(
+// children: [
+// Image.asset(
+// projectViewModel.isArabic ? "assets/images/cc_ar.png" : "assets/images/cc_en.png",
+// width: double.infinity,
+// ),
+// Align(
+// alignment: Alignment.topRight,
+// child: Container(
+// decoration: containerColorRadiusBorder(
+// Colors.black.withOpacity(0.2),
+// 1000,
+// Colors.white,
+// ),
+// margin: EdgeInsets.all(12),
+// child: IconButton(
+// icon: SvgPicture.asset(
+// "assets/images/new/ic_zoom.svg",
+// color: Colors.white,
+// ),
+// padding: EdgeInsets.all(12),
+// onPressed: () {
+// showDraggableDialog(context, PhotoViewPage(projectViewModel.isArabic ? "assets/images/cc_ar.png" : "assets/images/cc_en.png"));
+// },
+// ),
+// ),
+// ),
+// ],
+// ),
+// ],
+// ),
+// ),
+// ),
+// Container(
+// color: Colors.white,
+// padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21),
+// child: DefaultButton(
+// TranslationBase.of(context).next,
+// () async {
+// if (widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList!.length != 0 || widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList == null) {
+// // int index = widget.model.cmcAllServicesList.length;
+// PatientERCMCInsertServicesList patientERCMCInsertServicesList = new PatientERCMCInsertServicesList(
+// price: widget.model.cmcAllServicesList[selectedItem].price,
+// serviceID: widget.model.cmcAllServicesList[selectedItem].serviceID.toString(),
+// selectedServiceName: widget.model.cmcAllServicesList[selectedItem].text,
+// selectedServiceNameAR: widget.model.cmcAllServicesList[selectedItem].textN,
+// recordID: 1,
+// totalPrice: widget.model.cmcAllServicesList[selectedItem].priceTotal,
+// vAT: widget.model.cmcAllServicesList[selectedItem].priceVAT,
+// );
+//
+// widget.cMCInsertPresOrderRequestModel.patientID = projectViewModel.user!.patientID;
+// widget.cMCInsertPresOrderRequestModel.patientOutSA = projectViewModel.user!.outSA;
+//
+// widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList = [patientERCMCInsertServicesList];
+// navigateTo(
+// context,
+// NewCMCStepThreePage(
+// cmcInsertPresOrderRequestModel: widget.cMCInsertPresOrderRequestModel,
+// model: widget.model,
+// ),
+// );
+// // await widget.model.getCustomerInfo();
+// if (widget.model.state == ViewState.ErrorLocal) {
+// Utils.showErrorToast();
+// } else {
+// // navigateTo(
+// // context,
+// // NewCMCStepTowPage(
+// // longitude: widget.longitude,
+// // latitude: widget.latitude,
+// // cmcInsertPresOrderRequestModel: widget.cMCInsertPresOrderRequestModel,
+// // model: widget.model,
+// // ),
+// // );
+// }
+// }
+// },
+// ),
+// ),
+// ],
+// ),
+// );
+// }
+// }
diff --git a/lib/presentation/comprehensive_checkup/old_detail_page.dart b/lib/presentation/comprehensive_checkup/old_detail_page.dart
new file mode 100644
index 0000000..27070fe
--- /dev/null
+++ b/lib/presentation/comprehensive_checkup/old_detail_page.dart
@@ -0,0 +1,183 @@
+// import 'package:hmg_patient_app/core/enum/viewstate.dart';
+// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart';
+// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart';
+// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart';
+// import 'package:hmg_patient_app/core/viewModels/AlHabibMedicalService/cmc_view_model.dart';
+// import 'package:hmg_patient_app/core/viewModels/project_view_model.dart';
+// import 'package:hmg_patient_app/uitl/app_toast.dart';
+// import 'package:hmg_patient_app/uitl/date_uitl.dart';
+// import 'package:hmg_patient_app/uitl/gif_loader_dialog_utils.dart';
+// import 'package:hmg_patient_app/uitl/translations_delegate_base.dart';
+// import 'package:hmg_patient_app/uitl/utils.dart';
+// import 'package:hmg_patient_app/uitl/utils_new.dart';
+// import 'package:hmg_patient_app/widgets/buttons/defaultButton.dart';
+// import 'package:hmg_patient_app/widgets/buttons/secondary_button.dart';
+// import 'package:hmg_patient_app/widgets/data_display/text.dart';
+// import 'package:hmg_patient_app/widgets/dialogs/ConfirmWithMessageDialog.dart';
+// import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart';
+// import 'package:flutter/material.dart';
+// import 'package:provider/provider.dart';
+//
+// import 'Dialog/confirm_cancel_order_dialog.dart';
+//
+// class OrdersLogDetailsPage extends StatelessWidget {
+// final CMCViewModel model;
+//
+// const OrdersLogDetailsPage({Key ?key, required this.model}) : super(key: key);
+//
+// @override
+// Widget build(BuildContext context) {
+// ProjectViewModel projectViewModel = Provider.of(context);
+//
+// void showConfirmMessage(CMCViewModel model, GetCMCAllOrdersResponseModel order) {
+// showDialog(
+// context: context,
+// builder: (cxt) => ConfirmWithMessageDialog(
+// message: TranslationBase.of(context).cancelOrderMsg,
+// onTap: () {
+// UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.iD, rejectionReason: "", presOrderStatus: 4, editedBy: 3);
+// Future.delayed(new Duration(milliseconds: 300)).then((value) async {
+// GifLoaderDialogUtils.showMyDialog(context);
+// await model.updateCmcPresOrder(updatePresOrderRequestModel);
+// if (model.state == ViewState.ErrorLocal) {
+// Utils.showErrorToast(model.error);
+// GifLoaderDialogUtils.hideDialog(context);
+// } else {
+// AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully);
+// await model.getCmcAllPresOrders();
+// GifLoaderDialogUtils.hideDialog(context);
+// }
+// });
+// },
+// ));
+// return;
+// }
+//
+// return AppScaffold(
+// isShowAppBar: false,
+// baseViewModel: model,
+// body: model.cmcAllPresOrders.length > 0 ? ListView.separated(
+// padding: EdgeInsets.all(21),
+// physics: BouncingScrollPhysics(),
+// itemBuilder: (context, index) {
+// GetCMCAllOrdersResponseModel order = model.cmcAllPresOrders.reversed.toList()[index];
+//
+// int status = order.statusId!;
+// String _statusDisp = order.statusText!;
+// late Color _color;
+// if (status == 1) {
+// //pending
+// _color = Color(0xffCC9B14);
+// } else if (status == 2) {
+// //processing
+// _color = Color(0xff2E303A);
+// } else if (status == 3) {
+// //completed
+// _color = Color(0xff359846);
+// } else if (status == 4 || status == 6 || status == 7) {
+// //cancel // Rejected
+// _color = Color(0xffD02127);
+// }
+// return Container(
+// decoration: BoxDecoration(
+// color: _color,
+// borderRadius: BorderRadius.all(
+// Radius.circular(10.0),
+// ),
+// boxShadow: [
+// BoxShadow(
+// color: Color(0xff000000).withOpacity(.05),
+// blurRadius: 27,
+// offset: Offset(0, -3),
+// ),
+// ],
+// ),
+// child: Container(
+// margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0),
+// padding: EdgeInsets.symmetric(vertical: 14, horizontal: 12),
+// decoration: BoxDecoration(
+// color: Colors.white,
+// border: Border.all(color: Colors.white, width: 1),
+// borderRadius: BorderRadius.only(
+// bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0),
+// topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0),
+// bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0),
+// topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0),
+// ),
+// ),
+// // clipBehavior: Clip.antiAlias,
+// child: Row(
+// crossAxisAlignment: CrossAxisAlignment.start,
+// children: [
+// Expanded(
+// child: Column(
+// mainAxisAlignment: MainAxisAlignment.start,
+// crossAxisAlignment: CrossAxisAlignment.start,
+// children: [
+// Text(
+// _statusDisp,
+// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10),
+// ),
+// SizedBox(height: 6),
+// Text(
+// '${TranslationBase.of(context).requestID}: ${order.iD}',
+// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
+// ),
+// Row(
+// crossAxisAlignment: CrossAxisAlignment.start,
+// children: [
+// Text(
+// TranslationBase.of(context).hospital + ": ",
+// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10),
+// ),
+// Expanded(
+// child: Text(
+// // !projectViewModel.isArabic ? order.nearestProjectDescription.trim().toString() : order.nearestProjectDescriptionN.toString(),
+// order.projectName != null ? order.projectName!.trim().toString() : "",
+// style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56),
+// ),
+// ),
+// ],
+// )
+// ],
+// ),
+// ),
+// Column(
+// mainAxisAlignment: MainAxisAlignment.spaceBetween,
+// crossAxisAlignment: CrossAxisAlignment.end,
+// children: [
+// Text(
+// DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(order.created!)!),
+// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10),
+// ),
+// SizedBox(height: 12),
+// if (order.statusId == 1 || order.statusId == 2)
+// InkWell(
+// onTap: () {
+// showConfirmMessage(model, order);
+// },
+// child: Container(
+// padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14),
+// decoration: BoxDecoration(
+// color: Color(0xffD02127),
+// border: Border.all(color: Colors.white, width: 1),
+// borderRadius: BorderRadius.circular(10),
+// ),
+// child: Text(
+// TranslationBase.of(context).cancel_nocaps,
+// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4),
+// ),
+// ),
+// ),
+// ],
+// ),
+// ],
+// ),
+// ),
+// );
+// },
+// separatorBuilder: (context, index) => SizedBox(height: 12),
+// itemCount: model.cmcAllPresOrders.length) : getNoDataWidget(context),
+// );
+// }
+// }
diff --git a/lib/presentation/emergency_services/emergency_services_page.dart b/lib/presentation/emergency_services/emergency_services_page.dart
index 3cbce23..ce4ae2b 100644
--- a/lib/presentation/emergency_services/emergency_services_page.dart
+++ b/lib/presentation/emergency_services/emergency_services_page.dart
@@ -11,11 +11,9 @@ import 'package:hmg_patient_app_new/features/emergency_services/emergency_servic
import 'package:hmg_patient_app_new/features/location/location_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/RRT/rrt_request_type_select.dart';
-import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/call_ambulance_page.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/ambulance_option_selection_bottomsheet.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/pickup_location.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/history/er_history_listing.dart';
-import 'package:hmg_patient_app_new/presentation/emergency_services/nearest_er_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@@ -39,7 +37,7 @@ class EmergencyServicesPage extends StatelessWidget {
return CollapsingListView(
title: LocaleKeys.emergencyServices.tr(),
requests: () {
- Navigator.of(context).push(CustomPageRoute(page: ErHistoryListing(), direction: AxisDirection.up));
+ Navigator.of(context).push(CustomPageRoute(page: ErHistoryListing(), direction: AxisDirection.up));
},
child: Padding(
padding: EdgeInsets.all(24.h),
@@ -62,7 +60,9 @@ class EmergencyServicesPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Call Ambulance".needTranslation.toText16(isBold: true, color: AppColors.blackColor),
- "Request an ambulance in emergency from home or hospital".needTranslation.toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
+ "Request an ambulance in emergency from home or hospital"
+ .needTranslation
+ .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
],
),
),
@@ -70,13 +70,10 @@ class EmergencyServicesPage extends StatelessWidget {
Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, width: 13.h, height: 13.h),
],
).onPress(() {
-
-
showCommonBottomSheetWithoutHeight(
context,
child: Container(
- decoration:
- RoundedRectangleBorder().toSmoothCornerDecoration(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.primaryRedColor,
borderRadius: 24.h,
),
@@ -101,21 +98,13 @@ class EmergencyServicesPage extends StatelessWidget {
],
),
Lottie.asset(AppAnimations.ambulance_alert,
- repeat: false,
- reverse: false,
- frameRate: FrameRate(60),
- width: 120.h,
- height: 120.h,
- fit: BoxFit.contain),
+ repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
SizedBox(height: 8.h),
- "Confirmation".needTranslation.toText28(
- color: AppColors.whiteColor, isBold: true),
+ "Confirmation".needTranslation.toText28(color: AppColors.whiteColor, isBold: true),
SizedBox(height: 8.h),
"Are you sure you want to call an ambulance?"
.needTranslation
- .toText14(
- color: AppColors.whiteColor,
- weight: FontWeight.w500),
+ .toText14(color: AppColors.whiteColor, weight: FontWeight.w500),
SizedBox(height: 24.h),
CustomButton(
text: LocaleKeys.confirm.tr(context: context),
@@ -123,7 +112,7 @@ class EmergencyServicesPage extends StatelessWidget {
//
Navigator.of(context).pop();
await emergencyServicesViewModel.getTransportationOption();
- openTranportationSelectionBottomSheet(context);
+ openTranportationSelectionBottomSheet(context);
},
backgroundColor: AppColors.whiteColor,
borderColor: AppColors.whiteColor,
@@ -161,7 +150,9 @@ class EmergencyServicesPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Nearest ER Location".needTranslation.toText16(isBold: true, color: AppColors.blackColor),
- "Get the details of nearest branch including directions".needTranslation.toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
+ "Get the details of nearest branch including directions"
+ .needTranslation
+ .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
],
),
),
@@ -189,7 +180,8 @@ class EmergencyServicesPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Rapid Response Team (RRT)".toText16(isBold: true, color: AppColors.blackColor),
- "Comprehensive medical service for all sorts of urgent and stable cases".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
+ "Comprehensive medical service for all sorts of urgent and stable cases"
+ .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
],
),
),
@@ -224,11 +216,14 @@ class EmergencyServicesPage extends StatelessWidget {
}),
],
),
- Lottie.asset(AppAnimations.ambulance_alert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
+ Lottie.asset(AppAnimations.ambulance_alert,
+ repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
SizedBox(height: 8.h),
LocaleKeys.confirm.tr().toText28(color: AppColors.whiteColor, isBold: true),
SizedBox(height: 8.h),
- "Are you sure you want to call Rapid Response Team (RRT)?".needTranslation.toText14(color: AppColors.whiteColor, weight: FontWeight.w500),
+ "Are you sure you want to call Rapid Response Team (RRT)?"
+ .needTranslation
+ .toText14(color: AppColors.whiteColor, weight: FontWeight.w500),
SizedBox(height: 24.h),
CustomButton(
text: LocaleKeys.confirm.tr(context: context),
@@ -286,7 +281,9 @@ class EmergencyServicesPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Emergency Check-In".needTranslation.toText16(isBold: true, color: AppColors.blackColor),
- "Prior ER Check-In to skip the line & payment at the reception.".needTranslation.toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
+ "Prior ER Check-In to skip the line & payment at the reception."
+ .needTranslation
+ .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500),
],
),
),
@@ -321,7 +318,8 @@ class EmergencyServicesPage extends StatelessWidget {
}),
],
),
- Lottie.asset(AppAnimations.ambulance_alert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
+ Lottie.asset(AppAnimations.ambulance_alert,
+ repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
SizedBox(height: 8.h),
LocaleKeys.confirm.tr().toText28(color: AppColors.whiteColor, isBold: true),
SizedBox(height: 8.h),
@@ -362,14 +360,12 @@ class EmergencyServicesPage extends StatelessWidget {
);
}
- openPickupDetailsBottomSheet(BuildContext context){
+ openPickupDetailsBottomSheet(BuildContext context) {
showCommonBottomSheetWithoutHeight(
- onCloseClicked: (){
- context
- .read()
- .flushPickupInformation();
+ onCloseClicked: () {
+ context.read().flushPickupInformation();
},
- titleWidget: Transform.flip(
+ titleWidget: Transform.flip(
flipX: emergencyServicesViewModel.isArabic ? true : false,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
@@ -377,45 +373,38 @@ class EmergencyServicesPage extends StatelessWidget {
fit: BoxFit.contain,
),
).onPress(() {
- context
- .read()
- .flushPickupInformation();
+ context.read().flushPickupInformation();
Navigator.pop(context);
openTranportationSelectionBottomSheet(context);
}),
context,
- child: PickupLocation(
- onTap: () {
- Navigator.of(context).pop();
- context.read().flushSearchPredictions();
- context
- .read()
- .navigateTOAmbulancePage();
- }),
+ child: PickupLocation(onTap: () {
+ Navigator.of(context).pop();
+ context.read().flushSearchPredictions();
+ context.read().navigateTOAmbulancePage();
+ }),
isFullScreen: false,
isCloseButtonVisible: true,
hasBottomPadding: false,
-
backgroundColor: AppColors.bottomSheetBgColor,
callBackFunc: () {},
);
}
void openTranportationSelectionBottomSheet(BuildContext context) {
- if(emergencyServicesViewModel.transportationOptions.isNotEmpty) {
+ if (emergencyServicesViewModel.transportationOptions.isNotEmpty) {
showCommonBottomSheetWithoutHeight(
title: "Transport Options".needTranslation,
context,
child: SizedBox(
height: 400.h,
- child: AmbulanceOptionSelectionBottomSheet(
- onTap: () {
- Navigator.of(context).pop();
- openPickupDetailsBottomSheet(context);
- // context
- // .read()
- // .navigateTOAmbulancePage();
- }),
+ child: AmbulanceOptionSelectionBottomSheet(onTap: () {
+ Navigator.of(context).pop();
+ openPickupDetailsBottomSheet(context);
+ // context
+ // .read()
+ // .navigateTOAmbulancePage();
+ }),
),
isFullScreen: false,
isCloseButtonVisible: true,
diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart
index dc0803b..2242441 100644
--- a/lib/presentation/hmg_services/services_page.dart
+++ b/lib/presentation/hmg_services/services_page.dart
@@ -1,25 +1,37 @@
import 'package:flutter/material.dart';
-import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
-import 'package:hmg_patient_app_new/features/hmg_services/models/hmg_services.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/hmg_services_component_model.dart';
import 'package:hmg_patient_app_new/presentation/hmg_services/services_view.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
-class ServicesPage extends StatefulWidget {
- const ServicesPage({super.key});
+class ServicesPage extends StatelessWidget {
+ ServicesPage({super.key});
- @override
- State createState() => _ServicesPageState();
-}
-
-class _ServicesPageState extends State {
- List hmgServices = [];
-
- @override
- void initState() {
- hmgServices.add(HmgServices(11,"E Referral Services".needTranslation, "".needTranslation, "assets/images/svg/e-referral.svg", true, bgColor: Colors.orangeAccent, textColor: Colors.black, route: "/ereferralPage"));
- super.initState();
- }
+ final List hmgServices = [
+ HmgServicesComponentModel(
+ 11,
+ "E Referral Services".needTranslation,
+ "".needTranslation,
+ AppAssets.eReferral,
+ true,
+ bgColor: Colors.orange,
+ textColor: AppColors.blackColor,
+ route: AppRoutes.eReferralPage,
+ ),
+ HmgServicesComponentModel(
+ 12,
+ "Comprehensive Checkup".needTranslation,
+ "".needTranslation,
+ AppAssets.comprehensiveCheckup,
+ true,
+ bgColor: AppColors.bgGreenColor,
+ textColor: AppColors.blackColor,
+ route: AppRoutes.comprehensiveCheckupPage,
+ ),
+ ];
@override
Widget build(BuildContext context) {
@@ -32,28 +44,25 @@ class _ServicesPageState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Medical & Care Services".needTranslation.toText18(isBold: true),
- SizedBox(height: 20,),
- Padding(
- padding: const EdgeInsets.only(
- left: 16,
- right: 16,
- top: 0,
- ),
- child: GridView.builder(
- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 4, // 4 icons per row
- crossAxisSpacing: 16,
- mainAxisSpacing: 24,
- childAspectRatio: 0.75,
+ SizedBox(height: 20.h),
+ Padding(
+ padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 0),
+ child: GridView.builder(
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 3, // 4 icons per row
+ crossAxisSpacing: 16.w,
+ mainAxisSpacing: 24.h,
+ childAspectRatio: 0.75,
+ ),
+ physics: NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ itemCount: hmgServices.length,
+ padding: EdgeInsets.zero,
+ itemBuilder: (BuildContext context, int index) {
+ return ServiceGridViewItem(hmgServices[index], index, false);
+ },
),
- physics: NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: hmgServices.length,
- padding: EdgeInsets.zero,
- itemBuilder: (BuildContext context, int index) {
- return ServiceGridView(hmgServices[index], index, false);
- },
- ))
+ )
],
),
),
diff --git a/lib/presentation/hmg_services/services_view.dart b/lib/presentation/hmg_services/services_view.dart
index 25fd365..225bd96 100644
--- a/lib/presentation/hmg_services/services_view.dart
+++ b/lib/presentation/hmg_services/services_view.dart
@@ -1,62 +1,50 @@
import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/dependencies.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/hmg_services/models/hmg_services.dart';
-import 'package:hmg_patient_app_new/routes/app_routes.dart';
+import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/hmg_services_component_model.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
+class ServiceGridViewItem extends StatelessWidget {
+ final HmgServicesComponentModel hmgServiceComponentModel;
+ final int index;
+ final bool isHomePage;
+ final bool isLocked;
+
+ const ServiceGridViewItem(this.hmgServiceComponentModel, this.index, this.isHomePage, {super.key, this.isLocked = false});
-class ServiceGridView extends StatelessWidget {
- HmgServices hmgServices;
- int index;
- bool isHomePage;
- bool isLocked;
- ServiceGridView(this.hmgServices, this.index, this.isHomePage, {super.key, this.isLocked = false});
- static final NavigationService _navigationService = getIt.get();
@override
Widget build(BuildContext context) {
return InkWell(
- onTap: () {
- _navigationService.pushAndReplace(hmgServices.route);
- },
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container(
- height: 48,
- width: 48,
- padding: EdgeInsets.all(0),
- margin: EdgeInsets.all(0),
- decoration: BoxDecoration(
- color: hmgServices.bgColor,
- borderRadius: BorderRadius.circular(12),
+ onTap: () => getIt.get().pushPageRoute(hmgServiceComponentModel.route),
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ height: 48.h,
+ width: 48.w,
+ padding: EdgeInsets.zero,
+ margin: EdgeInsets.zero,
+ decoration: BoxDecoration(
+ color: hmgServiceComponentModel.bgColor,
+ borderRadius: BorderRadius.circular(12.r),
+ ),
+ child: Utils.buildSvgWithAssets(
+ icon: hmgServiceComponentModel.icon,
+ height: 21.h,
+ width: 21.w,
+ fit: BoxFit.none,
+ ),
),
- child:Utils.buildSvgWithAssets (
- icon: hmgServices.icon,
- height: 21,
- width: 21,
- fit: BoxFit.none,
+ SizedBox(height: 5.h),
+ hmgServiceComponentModel.title.toText12(
+ fontWeight: FontWeight.w500,
+ color: hmgServiceComponentModel.textColor,
+ maxLine: 1,
),
- ),
- const SizedBox(height: 5),
- hmgServices.title.toText12(
- fontWeight: FontWeight.w500,
- color:hmgServices.textColor,
-
- ),
- // Text(
- // hmgServices.subTitle,
- // textAlign: TextAlign.left,
- // style: TextStyle(
- // fontSize: 14,
- // fontWeight: FontWeight.w500,
- // color: hmgServices.textColor,
- // )),
- // )
- ],
- ));
+ ],
+ ));
}
-
}
diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart
index bd195c3..cdd9a2e 100644
--- a/lib/presentation/insurance/insurance_home_page.dart
+++ b/lib/presentation/insurance/insurance_home_page.dart
@@ -20,7 +20,7 @@ import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
-import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'widgets/insurance_history.dart';
diff --git a/lib/presentation/insurance/widgets/insurance_history.dart b/lib/presentation/insurance/widgets/insurance_history.dart
index 1c7b1b9..a5114dd 100644
--- a/lib/presentation/insurance/widgets/insurance_history.dart
+++ b/lib/presentation/insurance/widgets/insurance_history.dart
@@ -12,7 +12,7 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
-import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:provider/provider.dart';
class InsuranceHistory extends StatelessWidget {
diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart
index acdf1c7..753a36c 100644
--- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart
+++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart
@@ -12,7 +12,7 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
-import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:provider/provider.dart';
class PatientInsuranceCardUpdateCard extends StatelessWidget {
diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart
index 84efb9c..193b639 100644
--- a/lib/presentation/medical_file/medical_file_page.dart
+++ b/lib/presentation/medical_file/medical_file_page.dart
@@ -56,7 +56,7 @@ import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.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/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:provider/provider.dart';
import '../prescriptions/prescription_detail_page.dart';
@@ -460,7 +460,7 @@ class _MedicalFilePageState extends State {
SizedBox(height: 16.h),
Consumer(builder: (context, prescriptionVM, child) {
return prescriptionVM.isPrescriptionsOrdersLoading
- ? const MoviesShimmerWidget().paddingSymmetrical(24.w, 0.h)
+ ? const CommonShimmerWidget().paddingSymmetrical(24.w, 0.h)
: prescriptionVM.patientPrescriptionOrders.isNotEmpty
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart
index 1293c9c..87af39b 100644
--- a/lib/presentation/prescriptions/prescriptions_list_page.dart
+++ b/lib/presentation/prescriptions/prescriptions_list_page.dart
@@ -19,7 +19,7 @@ import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_deta
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/routes/custom_page_route.dart';
-import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
+import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart
index 1d7dfe2..cb925ef 100644
--- a/lib/presentation/radiology/radiology_orders_page.dart
+++ b/lib/presentation/radiology/radiology_orders_page.dart
@@ -4,22 +4,20 @@ 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/enums.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/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
-import 'package:hmg_patient_app_new/presentation/radiology/search_radiology.dart';
-import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/radiology/radiology_result_page.dart';
+import 'package:hmg_patient_app_new/presentation/radiology/search_radiology.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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/chip/custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
@@ -34,7 +32,7 @@ class RadiologyOrdersPage extends StatefulWidget {
class _RadiologyOrdersPageState extends State {
late RadiologyViewModel radiologyViewModel;
- String selectedFilterText ='';
+ String selectedFilterText = '';
int? expandedIndex;
@override
@@ -80,22 +78,22 @@ class _RadiologyOrdersPageState extends State {
children: [
selectedFilterText!.isNotEmpty
? AppCustomChipWidget(
- padding: EdgeInsets.symmetric(horizontal: 5.h),
- labelText: selectedFilterText!,
- deleteIcon:'assets/images/svg/cross_circle.svg',
- backgroundColor:AppColors.alertColor,
- textColor: AppColors.whiteColor,
- deleteIconColor: AppColors.whiteColor,
- deleteIconHasColor: true,
- onDeleteTap: (){
- setState(() {
- selectedFilterText ='';
- model.filterRadiologyReports('');
- });
- },
- // chipType: ChipTypeEnum.alert,
- // isSelected: true,
- )
+ padding: EdgeInsets.symmetric(horizontal: 5.h),
+ labelText: selectedFilterText!,
+ deleteIcon: 'assets/images/svg/cross_circle.svg',
+ backgroundColor: AppColors.alertColor,
+ textColor: AppColors.whiteColor,
+ deleteIconColor: AppColors.whiteColor,
+ deleteIconHasColor: true,
+ onDeleteTap: () {
+ setState(() {
+ selectedFilterText = '';
+ model.filterRadiologyReports('');
+ });
+ },
+ // chipType: ChipTypeEnum.alert,
+ // isSelected: true,
+ )
: SizedBox(),
ListView.builder(
shrinkWrap: true,
diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart
index 47a19a9..842710d 100644
--- a/lib/routes/app_routes.dart
+++ b/lib/routes/app_routes.dart
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/authentication/register.dart';
import 'package:hmg_patient_app_new/presentation/authentication/register_step2.dart';
+import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/comprehensive_checkup_page.dart';
import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_page_home.dart';
-import 'package:hmg_patient_app_new/presentation/home/landing_page.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/splashPage.dart';
@@ -15,14 +15,17 @@ class AppRoutes {
static const String registerStepTwo = '/registerStepTwo';
static const String landingScreen = '/landingScreen';
static const String medicalFilePage = '/medicalFilePage';
- static const String ereferralPage = '/ereferralPage';
+ static const String eReferralPage = '/erReferralPage';
+ static const String comprehensiveCheckupPage = '/comprehensiveCheckupPage';
+
static Map get routes => {
initialRoute: (context) => SplashPage(),
loginScreen: (context) => LoginScreen(),
landingScreen: (context) => LandingNavigation(),
register: (context) => RegisterNew(),
registerStepTwo: (context) => RegisterNewStep2(),
- medicalFilePage: (context) => MedicalFilePage(),
- ereferralPage: (context) => EReferralPage()
+ medicalFilePage: (context) => MedicalFilePage(),
+ eReferralPage: (context) => EReferralPage(),
+ comprehensiveCheckupPage: (context) => ComprehensiveCheckupPage()
};
}
diff --git a/lib/services/navigation_service.dart b/lib/services/navigation_service.dart
index cb4405c..fe95140 100644
--- a/lib/services/navigation_service.dart
+++ b/lib/services/navigation_service.dart
@@ -13,8 +13,8 @@ class NavigationService {
return navigatorKey.currentState!.push(route);
}
- Future pushAndRemoveUntil(Route route,RoutePredicate predicate) {
- return navigatorKey.currentState!.pushAndRemoveUntil(route,predicate);
+ Future pushAndRemoveUntil(Route route, RoutePredicate predicate) {
+ return navigatorKey.currentState!.pushAndRemoveUntil(route, predicate);
}
void pop([T? result]) {
@@ -38,11 +38,22 @@ class NavigationService {
navigatorKey.currentState?.pushReplacementNamed(routeName);
}
+ void pushPageRoute(String routeName) {
+ navigatorKey.currentState?.pushNamed(routeName);
+ }
-
- Future pushToOtpScreen({required String phoneNumber, required Function(int code) checkActivationCode, required Function(String phoneNumber) onResendOTPPressed, bool isFormFamilyFile = false}) {
+ Future pushToOtpScreen(
+ {required String phoneNumber,
+ required Function(int code) checkActivationCode,
+ required Function(String phoneNumber) onResendOTPPressed,
+ bool isFormFamilyFile = false}) {
return navigatorKey.currentState!.push(
- MaterialPageRoute(builder: (_) => OTPVerificationScreen(phoneNumber: phoneNumber, checkActivationCode: checkActivationCode, onResendOTPPressed: onResendOTPPressed, isFormFamilyFile : isFormFamilyFile)),
+ MaterialPageRoute(
+ builder: (_) => OTPVerificationScreen(
+ phoneNumber: phoneNumber,
+ checkActivationCode: checkActivationCode,
+ onResendOTPPressed: onResendOTPPressed,
+ isFormFamilyFile: isFormFamilyFile)),
);
}
diff --git a/lib/widgets/media_viewer/full_screen_image_viewer.dart b/lib/widgets/media_viewer/full_screen_image_viewer.dart
new file mode 100644
index 0000000..0fb92f0
--- /dev/null
+++ b/lib/widgets/media_viewer/full_screen_image_viewer.dart
@@ -0,0 +1,31 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+
+class FullScreenImageViewer extends StatelessWidget {
+ final bool isSvg;
+ final String path;
+
+ const FullScreenImageViewer({super.key, required this.isSvg, required this.path});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: Colors.black,
+ leading: IconButton(
+ icon: Icon(Icons.close, color: AppColors.whiteColor),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ),
+ backgroundColor: Colors.black,
+ body: Center(
+ child: InteractiveViewer(
+ child: isSvg
+ ? SvgPicture.asset(path, width: double.infinity, fit: BoxFit.contain)
+ : Image.asset(width: double.infinity, path, fit: BoxFit.contain),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/radio_list_tile_widget.dart b/lib/widgets/radio_list_tile_widget.dart
new file mode 100644
index 0000000..209866b
--- /dev/null
+++ b/lib/widgets/radio_list_tile_widget.dart
@@ -0,0 +1,89 @@
+import 'package:flutter/material.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/theme/colors.dart';
+
+class RadioListTileWidget extends StatelessWidget {
+ final T value;
+ final T? groupValue;
+ final String title;
+ final Widget? subtitleWidget;
+ final String? subtitle;
+ final ValueChanged onChanged;
+ final bool enabled;
+
+ const RadioListTileWidget({
+ super.key,
+ required this.value,
+ required this.groupValue,
+ required this.title,
+ this.subtitleWidget,
+ this.subtitle,
+ required this.onChanged,
+ this.enabled = true,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ final bool isSelected = value == groupValue;
+
+ return InkWell(
+ onTap: enabled ? () => onChanged(value) : null,
+ child: Container(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.h,
+ hasShadow: false,
+ ),
+ margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h),
+ padding: EdgeInsets.all(16.h),
+ child: Row(
+ children: [
+ Container(
+ width: 20.h,
+ height: 20.h,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(
+ color: isSelected ? AppColors.blackColor : const Color(0xff9E9E9E),
+ width: 2,
+ ),
+ ),
+ child: isSelected
+ ? Center(
+ child: Container(
+ width: 10.h,
+ height: 10.h,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: AppColors.blackColor,
+ ),
+ ),
+ )
+ : null,
+ ),
+ SizedBox(width: 16.w),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ title.toText15(weight: FontWeight.w500, letterSpacing: -0.64),
+ if (subtitleWidget != null) ...[subtitleWidget!],
+ if (subtitle != null) ...[
+ SizedBox(height: 4.h),
+ title.toText13(
+ weight: FontWeight.w400,
+ color: AppColors.greyTextColor,
+ letterSpacing: -0.56,
+ ),
+ ],
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/shimmer/movies_shimmer_widget.dart b/lib/widgets/shimmer/common_shimmer_widget.dart
similarity index 93%
rename from lib/widgets/shimmer/movies_shimmer_widget.dart
rename to lib/widgets/shimmer/common_shimmer_widget.dart
index fb1af25..d6a2906 100644
--- a/lib/widgets/shimmer/movies_shimmer_widget.dart
+++ b/lib/widgets/shimmer/common_shimmer_widget.dart
@@ -1,10 +1,10 @@
+import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/extensions/int_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
-import 'package:flutter/material.dart';
-class MoviesShimmerWidget extends StatelessWidget {
- const MoviesShimmerWidget({super.key});
+class CommonShimmerWidget extends StatelessWidget {
+ const CommonShimmerWidget({super.key});
@override
Widget build(BuildContext context) {