Comprehensive checkup in progress

pull/98/head
faizatflutter 3 months ago
parent 8e132e964f
commit 721bf95c1b

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 3.75C9 2.09315 10.3431 0.75 12 0.75C13.6569 0.75 15 2.09315 15 3.75C15 4.82282 14.4369 5.76411 13.5901 6.29442C16.5251 6.71056 18.309 9.97478 17.1349 12.8582C16.8794 13.4857 16.2803 13.9167 15.5919 13.9167H15.0998L14.272 17.4022C14.019 18.4673 13.0967 19.25 12 19.25C10.9033 19.25 9.98103 18.4673 9.72805 17.4022L8.9002 13.9167L8.40809 13.9167C7.71969 13.9167 7.12056 13.4857 6.86508 12.8582C5.69103 9.97478 7.47495 6.71056 10.4099 6.29442C9.56313 5.76411 9 4.82282 9 3.75Z" fill="white"/>
<path d="M7 15.25H6C5.44772 15.25 5 15.6977 5 16.25C5 16.8023 5.44772 17.25 6 17.25H7C7.55228 17.25 8 16.8023 8 16.25C8 15.6977 7.55228 15.25 7 15.25Z" fill="white"/>
<path d="M17 15.25C16.4477 15.25 16 15.6977 16 16.25C16 16.8023 16.4477 17.25 17 17.25H18C18.5523 17.25 19 16.8023 19 16.25C19 15.6977 18.5523 15.25 18 15.25H17Z" fill="white"/>
<path d="M13 21.25C13 20.6977 12.5523 20.25 12 20.25C11.4477 20.25 11 20.6977 11 21.25V22.25C11 22.8023 11.4477 23.25 12 23.25C12.5523 23.25 13 22.8023 13 22.25V21.25Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.0493 1.25C14.7141 1.24997 15.287 1.24994 15.7457 1.31161C16.2373 1.37771 16.7086 1.52677 17.0908 1.90902C17.4731 2.29126 17.6222 2.76253 17.6883 3.25416C17.7499 3.7129 17.7499 4.28574 17.7499 4.95059V6.04937C17.7499 6.71423 17.7499 7.28712 17.6883 7.74585C17.6222 8.23749 17.4731 8.70875 17.0908 9.091C16.7086 9.47324 16.2373 9.6223 15.7457 9.6884C15.287 9.75008 14.7141 9.75004 14.0492 9.75001L13.2269 9.75001L10.4159 11.624C10.1857 11.7775 9.88983 11.7918 9.64597 11.6613C9.4021 11.5307 9.24986 11.2766 9.24986 11V9.7469C8.87641 9.74158 8.54263 9.7272 8.25402 9.6884C7.76238 9.6223 7.29112 9.47324 6.90887 9.091C6.52662 8.70875 6.37756 8.23749 6.31147 7.74585C6.24979 7.28712 6.24982 6.71427 6.24986 6.04943V4.95063C6.24982 4.28579 6.24979 3.7129 6.31147 3.25416C6.37756 2.76253 6.52662 2.29126 6.90887 1.90902C7.29112 1.52677 7.76238 1.37771 8.25402 1.31161C8.71274 1.24994 9.28556 1.24997 9.95039 1.25L14.0493 1.25Z" fill="white"/>
<path d="M3.17258 18.1177C4.89963 16.9608 7.10028 16.9608 8.82733 18.1177C9.13739 18.3137 9.84338 18.7614 10.2141 19.1697C10.4495 19.4288 10.6975 19.7967 10.7428 20.2626C10.7914 20.7627 10.5934 21.2221 10.2316 21.6099C9.68447 22.1963 8.95287 22.75 7.95957 22.75H4.04034C3.04704 22.75 2.31543 22.1963 1.76831 21.6099C1.40651 21.2221 1.20853 20.7627 1.25712 20.2626C1.30239 19.7967 1.55044 19.4288 1.78577 19.1697C2.15652 18.7614 2.86252 18.3137 3.17258 18.1177Z" fill="white"/>
<path d="M20.8273 18.1177C19.1003 16.9608 16.8996 16.9608 15.1726 18.1177C14.8625 18.3137 14.1565 18.7614 13.7858 19.1697C13.5504 19.4288 13.3024 19.7967 13.2571 20.2626C13.2085 20.7627 13.4065 21.2221 13.7683 21.6099C14.3154 22.1963 15.047 22.75 16.0403 22.75H19.9596C20.9529 22.75 21.6845 22.1963 22.2316 21.6099C22.5934 21.2221 22.7914 20.7627 22.7428 20.2626C22.6975 19.7967 22.4495 19.4288 22.2141 19.1697C21.8434 18.7614 21.1374 18.3137 20.8273 18.1177Z" fill="white"/>
<path d="M3.24986 13.5C3.24986 11.9812 4.48107 10.75 5.99986 10.75C7.51864 10.75 8.74986 11.9812 8.74986 13.5C8.74986 15.0188 7.51864 16.25 5.99986 16.25C4.48107 16.25 3.24986 15.0188 3.24986 13.5Z" fill="white"/>
<path d="M17.9999 10.75C16.4811 10.75 15.2499 11.9812 15.2499 13.5C15.2499 15.0188 16.4811 16.25 17.9999 16.25C19.5186 16.25 20.7499 15.0188 20.7499 13.5C20.7499 11.9812 19.5186 10.75 17.9999 10.75Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -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) {

@ -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";

@ -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 {

@ -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<InsuranceRepo>(() => InsuranceRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<PayfortRepo>(() => PayfortRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<LocalAuthService>(
() => LocalAuthService(loggerService: getIt<LoggerService>(), localAuth: getIt<LocalAuthentication>()));
() => LocalAuthService(loggerService: getIt<LoggerService>(), localAuth: getIt<LocalAuthentication>()),
);
getIt.registerLazySingleton<HabibWalletRepo>(() => HabibWalletRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<MedicalFileRepo>(() => MedicalFileRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<ImmediateLiveCareRepo>(() => ImmediateLiveCareRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<EmergencyServicesRepo>(() => EmergencyServicesRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<TodoSectionRepo>(() => TodoSectionRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<LocationRepo>(
() => LocationRepoImpl(apiClient: getIt()));
getIt.registerLazySingleton<LocationRepo>(() => LocationRepoImpl(apiClient: getIt()));
getIt.registerLazySingleton<ContactUsRepo>(() => ContactUsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<HmgServicesRepo>(() => HmgServicesRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
// ViewModels
// Global/shared VMs LazySingleton
getIt.registerLazySingleton<LabViewModel>(
() => LabViewModel(labRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()),
);
getIt.registerLazySingleton<LabViewModel>(() => LabViewModel(labRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()));
getIt.registerLazySingleton<RadiologyViewModel>(
() => RadiologyViewModel(
radiologyRepo: getIt(),
errorHandlerService: getIt(),
),
);
getIt.registerLazySingleton<RadiologyViewModel>(() => RadiologyViewModel(radiologyRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<PrescriptionsViewModel>(
() => PrescriptionsViewModel(
prescriptionsRepo: getIt(),
errorHandlerService: getIt(),
),
);
getIt.registerLazySingleton<PrescriptionsViewModel>(() => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<InsuranceViewModel>(
() => InsuranceViewModel(
insuranceRepo: getIt(),
errorHandlerService: getIt(),
),
);
getIt.registerLazySingleton<InsuranceViewModel>(() => InsuranceViewModel(insuranceRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<MyAppointmentsViewModel>(
() => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()),
);
() => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton<PayfortViewModel>(
() => PayfortViewModel(
@ -198,53 +183,39 @@ class AppDependencies {
);
getIt.registerLazySingleton<ProfileSettingsViewModel>(() => ProfileSettingsViewModel());
getIt.registerLazySingleton<DateRangeSelectorRangeViewModel>(
() => DateRangeSelectorRangeViewModel(),
);
getIt.registerLazySingleton<DateRangeSelectorRangeViewModel>(() => DateRangeSelectorRangeViewModel());
getIt.registerLazySingleton<DoctorFilterViewModel>(
() => DoctorFilterViewModel(),
);
getIt.registerLazySingleton<DoctorFilterViewModel>(() => DoctorFilterViewModel());
getIt.registerLazySingleton<AppointmentViaRegionViewmodel>(
() => AppointmentViaRegionViewmodel(
navigationService: getIt(),
appState: getIt(),
),
() => AppointmentViaRegionViewmodel(navigationService: getIt(), appState: getIt()),
);
getIt.registerLazySingleton<EmergencyServicesViewModel>(
() => 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>(
() => LocationViewModel(
locationRepo: getIt(),
errorHandlerService: getIt(),
),
() => LocationViewModel(locationRepo: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton<ContactUsViewModel>(
() => ContactUsViewModel(
contactUsRepo: getIt(),
appState: getIt(),
errorHandlerService: getIt(),
),
() => ContactUsViewModel(contactUsRepo: getIt(), appState: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton<TodoSectionViewModel>(
() => TodoSectionViewModel(
todoSectionRepo: getIt(),
errorHandlerService: getIt(),
),
() => TodoSectionViewModel(todoSectionRepo: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton<HmgServicesViewModel>(
() => HmgServicesViewModel(hmgServicesRepo: getIt(), errorHandlerService: getIt()),
);
// Screen-specific VMs Factory

@ -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);
}
}
}

@ -44,13 +44,11 @@ abstract class EmergencyServicesRepo {
Future<Either<Failure, GenericApiModel<List<PatientERTransportationMethod>>>> getTransportationMethods({int? id});
Future<Either<Failure, GenericApiModel<bool>>> submitAmbulanceRequest(PatientER_RC request);
Future<Either<Failure, GenericApiModel<List<AmbulanceRequestOrdersModel>>>> getTransportationOrders({int? id});
Future<Either<Failure, GenericApiModel<bool>>> cancelOrder(int? iD, int patientId);
Future<Either<Failure, GenericApiModel<bool>>> 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<String, dynamic>)).toList().cast<PatientERTransportationMethod>();
final proceduresList = list
.map((item) => PatientERTransportationMethod.fromJson(item as Map<String, dynamic>))
.toList()
.cast<PatientERTransportationMethod>();
apiResponse = GenericApiModel<List<PatientERTransportationMethod>>(
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<String, dynamic>)).toList().cast<AmbulanceRequestOrdersModel>();
final proceduresList =
list.map((item) => AmbulanceRequestOrdersModel.fromJson(item as Map<String, dynamic>)).toList().cast<AmbulanceRequestOrdersModel>();
apiResponse = GenericApiModel<List<AmbulanceRequestOrdersModel>>(
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<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
@ -353,7 +353,6 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
}
}
@override
Future<Either<Failure, GenericApiModel<EROnlineCheckInPaymentDetailsResponse>>> checkPatientERPaymentInformation({int? projectID}) async {
Map<String, dynamic> mapDevice = {"ClinicID": 10, "ProjectID": projectID ?? 0};

@ -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<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllCmcOrders();
Future<Either<Failure, GenericApiModel<bool>>> updateCmcPresOrder(OrderUpdateRequestModel requestModel);
Future<Either<Failure, GenericApiModel<List<GetCMCServicesResponseModel>>>> getAllCmcServices({required int patientID});
}
class HmgServicesRepoImp implements HmgServicesRepo {
final ApiClient apiClient;
final LoggerService loggerService;
HmgServicesRepoImp({required this.apiClient, required this.loggerService});
@override
Future<Either<Failure, GenericApiModel<List<GetCMCAllOrdersResponseModel>>>> getAllCmcOrders() async {
Map<String, dynamic> requestBody = {};
try {
GenericApiModel<List<GetCMCAllOrdersResponseModel>>? 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<GetCMCAllOrdersResponseModel> 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<String, dynamic>) {
try {
cmcOrdersList.add(GetCMCAllOrdersResponseModel.fromJson(orderJson));
} catch (e) {
loggerService.logError("Error parsing individual order: ${e.toString()}");
}
}
}
}
apiResponse = GenericApiModel<List<GetCMCAllOrdersResponseModel>>(
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<Either<Failure, GenericApiModel<List<GetCMCServicesResponseModel>>>> getAllCmcServices({required int patientID}) async {
Map<String, dynamic> requestBody = {};
try {
GenericApiModel<List<GetCMCServicesResponseModel>>? 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<GetCMCServicesResponseModel> cmcServicesList = [];
if (response['response'] != null && response['response'] is List) {
final servicesList = response['response'] as List;
for (var serviceJson in servicesList) {
if (serviceJson is Map<String, dynamic>) {
cmcServicesList.add(GetCMCServicesResponseModel.fromJson(serviceJson));
}
}
}
apiResponse = GenericApiModel<List<GetCMCServicesResponseModel>>(
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<Either<Failure, GenericApiModel<bool>>> updateCmcPresOrder(OrderUpdateRequestModel requestModel) async {
try {
GenericApiModel<bool>? 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<bool>(
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()));
}
}
}

@ -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<GetCMCAllOrdersResponseModel> cmcOrdersList = [];
List<GetCMCServicesResponseModel> cmcServicesList = [];
Future<void> getOrdersList() async {
cmcOrdersList.clear();
isCmcOrdersLoading = true;
notifyListeners();
await getAllCmcOrders();
}
Future<void> 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<void> 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<bool> 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;
}
}

@ -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=''});
}

@ -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>? 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<String, dynamic> 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 = <PatientERCMCInsertServicesList>[];
json['PatientER_CMC_InsertServicesList'].forEach((v) {
patientERCMCInsertServicesList!.add(
new PatientERCMCInsertServicesList.fromJson(v),
);
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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<String, dynamic> json) {
recordID = json['RecordID'];
serviceID = json['ServiceID'];
selectedServiceName = json['selectedServiceName'];
selectedServiceNameAR = json['selectedServiceNameAR'];
price = json['Price'];
vAT = json['VAT'];
totalPrice = json['TotalPrice'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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;
}
}

@ -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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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;
}
}

@ -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<dynamic>? 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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
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;
}
}

@ -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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> 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;
}
}

@ -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 = '',
});
}

@ -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<EmergencyServicesViewModel>(
create: (_) => getIt.get<EmergencyServicesViewModel>(),
),ChangeNotifierProvider<LocationViewModel>(
),
ChangeNotifierProvider<LocationViewModel>(
create: (_) => getIt.get<LocationViewModel>(),
),
ChangeNotifierProvider<TodoSectionViewModel>(
@ -140,6 +142,9 @@ void main() async {
),
ChangeNotifierProvider<ContactUsViewModel>(
create: (_) => getIt.get<ContactUsViewModel>(),
),
ChangeNotifierProvider<HmgServicesViewModel>(
create: (_) => getIt.get<HmgServicesViewModel>(),
)
], child: MyApp()),
),

@ -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<AppointmentDetailsPage> {
SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
return prescriptionVM.isPrescriptionsDetailsLoading
? const MoviesShimmerWidget()
? const CommonShimmerWidget()
: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: Colors.white,

@ -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<CmcOrderDetailPage> createState() => _CmcOrderDetailPageState();
}
class _CmcOrderDetailPageState extends State<CmcOrderDetailPage> {
bool _isLoading = false;
@override
void initState() {
super.initState();
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
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<void> _showCancelConfirmationDialog({
required BuildContext context,
required HmgServicesViewModel viewModel,
required GetCMCAllOrdersResponseModel order,
}) async {
final dialogService = context.read<DialogService>();
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<HmgServicesViewModel>(),
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<HmgServicesViewModel>(
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);
},
);
},
),
);
}
}

@ -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<ComprehensiveCheckupPage> createState() => _ComprehensiveCheckupPageState();
}
class _ComprehensiveCheckupPageState extends State<ComprehensiveCheckupPage> {
int? _selectedServiceId;
GetCMCServicesResponseModel? _selectedService;
@override
void initState() {
super.initState();
final HmgServicesViewModel hmgServicesViewModel = context.read<HmgServicesViewModel>();
final AppState appState = getIt.get<AppState>();
scheduleMicrotask(() async {
final user = appState.getAuthenticatedUser();
if (user != null) {
await hmgServicesViewModel.getAllCmcOrders();
await hmgServicesViewModel.getAllCmcServices(patientID: user.patientId ?? 0);
}
});
}
GetCMCAllOrdersResponseModel? _getPendingOrder(List<GetCMCAllOrdersResponseModel> 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<GetCMCServicesResponseModel> 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<int>(
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<AppState>();
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<HmgServicesViewModel>(
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<HmgServicesViewModel>(
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)));
}
}

@ -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<NewCMCStepOnePage> {
// 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,
// // ),
// // );
// }
// }
// },
// ),
// ),
// ],
// ),
// );
// }
// }

@ -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),
// );
// }
// }

@ -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<EmergencyServicesViewModel>()
.flushPickupInformation();
onCloseClicked: () {
context.read<EmergencyServicesViewModel>().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<EmergencyServicesViewModel>()
.flushPickupInformation();
context.read<EmergencyServicesViewModel>().flushPickupInformation();
Navigator.pop(context);
openTranportationSelectionBottomSheet(context);
}),
context,
child: PickupLocation(
onTap: () {
Navigator.of(context).pop();
context.read<LocationViewModel>().flushSearchPredictions();
context
.read<EmergencyServicesViewModel>()
.navigateTOAmbulancePage();
}),
child: PickupLocation(onTap: () {
Navigator.of(context).pop();
context.read<LocationViewModel>().flushSearchPredictions();
context.read<EmergencyServicesViewModel>().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<EmergencyServicesViewModel>()
// .navigateTOAmbulancePage();
}),
child: AmbulanceOptionSelectionBottomSheet(onTap: () {
Navigator.of(context).pop();
openPickupDetailsBottomSheet(context);
// context
// .read<EmergencyServicesViewModel>()
// .navigateTOAmbulancePage();
}),
),
isFullScreen: false,
isCloseButtonVisible: true,

@ -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<ServicesPage> createState() => _ServicesPageState();
}
class _ServicesPageState extends State<ServicesPage> {
List<HmgServices> 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<HmgServicesComponentModel> 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<ServicesPage> {
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);
},
))
)
],
),
),

@ -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<NavigationService>();
@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<NavigationService>().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,
// )),
// )
],
));
],
));
}
}

@ -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';

@ -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 {

@ -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 {

@ -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<MedicalFilePage> {
SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(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(

@ -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';

@ -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<RadiologyOrdersPage> {
late RadiologyViewModel radiologyViewModel;
String selectedFilterText ='';
String selectedFilterText = '';
int? expandedIndex;
@override
@ -80,22 +78,22 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
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,

@ -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<String, WidgetBuilder> 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()
};
}

@ -13,8 +13,8 @@ class NavigationService {
return navigatorKey.currentState!.push(route);
}
Future<T?> pushAndRemoveUntil<T>(Route<T> route,RoutePredicate predicate) {
return navigatorKey.currentState!.pushAndRemoveUntil(route,predicate);
Future<T?> pushAndRemoveUntil<T>(Route<T> route, RoutePredicate predicate) {
return navigatorKey.currentState!.pushAndRemoveUntil(route, predicate);
}
void pop<T extends Object?>([T? result]) {
@ -38,11 +38,22 @@ class NavigationService {
navigatorKey.currentState?.pushReplacementNamed(routeName);
}
void pushPageRoute(String routeName) {
navigatorKey.currentState?.pushNamed(routeName);
}
Future<T?> pushToOtpScreen<T>({required String phoneNumber, required Function(int code) checkActivationCode, required Function(String phoneNumber) onResendOTPPressed, bool isFormFamilyFile = false}) {
Future<T?> pushToOtpScreen<T>(
{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)),
);
}

@ -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),
),
),
);
}
}

@ -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<T> extends StatelessWidget {
final T value;
final T? groupValue;
final String title;
final Widget? subtitleWidget;
final String? subtitle;
final ValueChanged<T?> 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,
),
],
],
),
),
],
),
),
);
}
}

@ -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) {
Loading…
Cancel
Save