diff --git a/assets/images/svg/all_payment_method.svg b/assets/images/svg/all_payment_method.svg
new file mode 100644
index 0000000..ef72e6a
--- /dev/null
+++ b/assets/images/svg/all_payment_method.svg
@@ -0,0 +1,34 @@
+
diff --git a/assets/images/svg/ic_rrt_vehicle.svg b/assets/images/svg/ic_rrt_vehicle.svg
new file mode 100644
index 0000000..d858fb4
--- /dev/null
+++ b/assets/images/svg/ic_rrt_vehicle.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/svg/mada.svg b/assets/images/svg/mada.svg
new file mode 100644
index 0000000..99fd132
--- /dev/null
+++ b/assets/images/svg/mada.svg
@@ -0,0 +1,9 @@
+
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index b276dd7..6a5d34f 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -1,7 +1,7 @@
import Flutter
import UIKit
-import FirebaseCore
-import FirebaseMessaging
+//import FirebaseCore
+//import FirebaseMessaging
import GoogleMaps
@main
@objc class AppDelegate: FlutterAppDelegate {
@@ -10,13 +10,13 @@ import GoogleMaps
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng")
- FirebaseApp.configure()
+// FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
- Messaging.messaging().apnsToken = deviceToken
+// Messaging.messaging().apnsToken = deviceToken
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}
}
diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart
index 162f0fd..ebd0d34 100644
--- a/lib/core/api/api_client.dart
+++ b/lib/core/api/api_client.dart
@@ -202,7 +202,7 @@ 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("response.body: ${response.body}");
+ // log("response.body: ${response.body}");
if (statusCode < 200 || statusCode >= 400) {
onFailure('Error While Fetching data', statusCode, failureType: StatusCodeFailure("Error While Fetching data"));
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);
@@ -365,7 +365,7 @@ class ApiClientImp implements ApiClient {
debugPrint("URL : $url");
// print("Body : ${json.encode(body)}");
- if (await Utils.checkConnection()) {
+ if (await Utils.checkConnection(bypassConnectionCheck: true)) {
final response = await http.get(
Uri.parse(url.trim()),
headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index e8215ba..e5269cc 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -171,6 +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 all_payment_method = '$svgBasePath/all_payment_method.svg';
+ static const String ic_rrt_vehicle = '$svgBasePath/ic_rrt_vehicle.svg';
//bottom navigation//
diff --git a/lib/core/utils/date_util.dart b/lib/core/utils/date_util.dart
index d58aef6..00a5aa3 100644
--- a/lib/core/utils/date_util.dart
+++ b/lib/core/utils/date_util.dart
@@ -6,7 +6,7 @@ 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();
diff --git a/lib/features/emergency_services/emergency_services_repo.dart b/lib/features/emergency_services/emergency_services_repo.dart
index c54c3d1..83f8057 100644
--- a/lib/features/emergency_services/emergency_services_repo.dart
+++ b/lib/features/emergency_services/emergency_services_repo.dart
@@ -8,9 +8,11 @@ import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/PatientER_RC.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/RRTRequestModel.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/EROnlineCheckInPaymentDetailsResponse.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/ProjectAvgERWaitingTime.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/rrt_procedures_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
@@ -18,7 +20,7 @@ import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'models/resp_model/PatientERTransportationMethod.dart';
abstract class EmergencyServicesRepo {
- Future>>> getRRTProcedures();
+ Future>>> getRRTProcedures(int languageId);
Future>>> getNearestEr({int? id, int? projectID});
@@ -51,6 +53,11 @@ abstract class EmergencyServicesRepo {
Future>> cancelOrder(int? iD, int patientId);
+ Future>> submitRRTRequest(RRTRequestModel request);
+
+ Future>> getRRTOrders({int? id});
+
+ Future>> cancelRRTOrder(int? iD);
}
class EmergencyServicesRepoImp implements EmergencyServicesRepo {
@@ -97,8 +104,8 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
}
@override
- Future>>> getRRTProcedures() async {
- Map mapDevice = {"ProjectID": 15};
+ Future>>> getRRTProcedures(int languageId) async {
+ Map mapDevice = {"ProjectID": 15, "languageID":1};
try {
GenericApiModel>? apiResponse;
@@ -559,4 +566,120 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>> submitRRTRequest(RRTRequestModel request) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ body: request.toJson(),
+ ADD_RRT_ORDER_RC,
+ isRCService: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: true,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>> cancelRRTOrder(int? iD) async{
+ try {
+ GenericApiModel? apiResponse;
+
+ Map request = {"Id": iD, "ClickButton": 14};
+
+ Failure? failure;
+ await apiClient.post(
+ body: request,
+ UPDATE_RRT_ORDER_RC,
+ isRCService: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: true,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+
+ }
+
+ @override
+ Future>> getRRTOrders({int? id}) async {
+ try {
+ GenericApiModel? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ body: {},
+ GET_ALL_RRT_ORDERS_RC,
+ isRCService: true,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['response'];
+
+ RRTServiceData serviceData = RRTServiceData();
+ list.forEach((item) {
+ if (item["StatusId"] == 1 || item["StatusId"] == 2) {
+ // Pending
+ serviceData.pendingOrders.add(GetCMCAllOrdersResponseModel.fromJson(item));
+ }
+ serviceData.completedOrders.add(GetCMCAllOrdersResponseModel.fromJson(item));
+ });
+
+ apiResponse = GenericApiModel(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: serviceData,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+
}
diff --git a/lib/features/emergency_services/emergency_services_view_model.dart b/lib/features/emergency_services/emergency_services_view_model.dart
index 9526f16..0c202df 100644
--- a/lib/features/emergency_services/emergency_services_view_model.dart
+++ b/lib/features/emergency_services/emergency_services_view_model.dart
@@ -12,7 +12,10 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_repo.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/OrderDisplay.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/RRTRequestModel.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/EROnlineCheckInPaymentDetailsResponse.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/AmbulanceCallingPlace.dart';
@@ -30,6 +33,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/RRT/rrt_map_screen.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/er_online_checkin/er_online_checkin_home.dart';
import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart';
@@ -71,7 +75,6 @@ class EmergencyServicesViewModel extends ChangeNotifier {
List nearestERList = [];
List nearestERFilteredList = [];
- List RRTProceduresList = [];
List? hospitalList;
List? hmgHospitalList;
@@ -83,7 +86,7 @@ class EmergencyServicesViewModel extends ChangeNotifier {
int hmcCount = 0;
bool pickupFromInsideTheLocation = true;
List? appointments;
- List? orders = [];
+ List? ambulanceOrders = [];
//ambulance selection data section
List transportationOptions = [];
@@ -91,7 +94,6 @@ class EmergencyServicesViewModel extends ChangeNotifier {
AmbulanceCallingPlace callingPlace = AmbulanceCallingPlace.FROM_HOSPITAL;
AmbulanceDirection ambulanceDirection = AmbulanceDirection.ONE_WAY;
- late RRTProceduresResponseModel selectedRRTProcedure;
bool patientHasAdvanceERBalance = false;
bool isERBookAppointment = false;
@@ -99,6 +101,21 @@ class EmergencyServicesViewModel extends ChangeNotifier {
BottomSheetType bottomSheetType = BottomSheetType.FIXED;
+ ///RRT request data
+ List RRTProceduresList = [];
+ RRTProceduresResponseModel? selectedRRTProcedure;
+ bool agreedToTermsAndCondition = false;
+ RRTServiceData? ordersRRT;
+ TextEditingController rrtNotes = TextEditingController();
+
+
+ List allOrders = [];
+ List orderDisplayList = [];
+ bool historyLoading= false;
+ OrderDislpay currentlyDisplayedOrder = OrderDislpay.ALL;
+
+
+
setSelectedRRTProcedure(RRTProceduresResponseModel procedure) {
selectedRRTProcedure = procedure;
notifyListeners();
@@ -133,10 +150,21 @@ class EmergencyServicesViewModel extends ChangeNotifier {
bool isMyAppointmentsLoading = false;
Future getRRTProcedures({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+
+ print("the app state is ${appState.isAuthenticated}");
+ if (!appState.isAuthenticated) {
+ dialogService.showErrorBottomSheet(
+ message: "You Need To Login First To Continue".needTranslation,
+ onOkPressed: () {
+ getIt().onLoginPressed();
+ });
+ return;
+ }
+
RRTProceduresList.clear();
notifyListeners();
- final result = await emergencyServicesRepo.getRRTProcedures();
+ final result = await emergencyServicesRepo.getRRTProcedures(appState.getLanguageID());
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
@@ -733,12 +761,16 @@ class EmergencyServicesViewModel extends ChangeNotifier {
LoaderBottomSheet.showLoader(loadingText: "Fetching Orders");
}
int? id = appState.getAuthenticatedUser()?.patientId;
+ historyLoading = true;
+ notifyListeners();
var response = await emergencyServicesRepo.getTransportationOrders(id: id);
if(shouldNavigateToTrackingScreen == false && showLoader ) {
LoaderBottomSheet.hideLoader();}
response.fold(
(failure) async {
+ historyLoading = false;
+ notifyListeners();
if (shouldNavigateToTrackingScreen) {
navServices.pushAndRemoveUntil(CustomPageRoute(page: TrackingScreen(state: OrderTrackingState.waitingForCall)), ModalRoute.withName("/EmergencyServicesPage"));
}
@@ -753,8 +785,12 @@ class EmergencyServicesViewModel extends ChangeNotifier {
)),
ModalRoute.withName("/EmergencyServicesPage"));
}
-
- orders = apiResponse.data;
+ historyLoading = false;
+ ambulanceOrders = apiResponse.data;
+ allOrders.clear();
+ allOrders.addAll(ambulanceOrders??[]);
+ allOrders.addAll(ordersRRT?.completedOrders??[]);
+ changeOrderDisplayItems(OrderDislpay.ALL);
notifyListeners();
},
);
@@ -843,4 +879,157 @@ class EmergencyServicesViewModel extends ChangeNotifier {
navServices.pop();
});
}
+
+
+ RRTRequestModel createRRTRequest(GeocodeResult? result, PlaceDetails? place, PlacePrediction? placePrediction){
+ AuthenticatedUser? user = appState.getAuthenticatedUser();
+ if (user == null) throw Exception("Authentication Required to Continue");
+
+ RRTRequestModel rrtRequestModel = new RRTRequestModel();
+ Procedures procedures = new Procedures();
+ rrtRequestModel.procedures = [];
+
+
+ procedures.serviceID = selectedRRTProcedure?.procedureID;
+
+ rrtRequestModel.latitude = ((result?.geometry.location.lat) ?? place?.lat);
+ rrtRequestModel.longitude = ((result?.geometry.location.lat) ?? place?.lat);
+ rrtRequestModel.additionalDetails = "";
+ rrtRequestModel.nationality = user.nationalityId;
+ rrtRequestModel.paymentAmount = selectedRRTProcedure?.patientShareWithTax;
+ rrtRequestModel.nearestProjectId = 0;
+ rrtRequestModel.patientId = user.patientId;
+ rrtRequestModel.patientOutSa = user.outSa;
+ rrtRequestModel.procedures!.add(procedures);
+
+ return rrtRequestModel;
+ }
+
+ ///method to toggle the value for the aggremnent to the terms and conditon for the rrt
+ void setTermsAndConditions(bool value) {
+ agreedToTermsAndCondition = value;
+ notifyListeners();
+ }
+
+ FutureOr submitRRTRequest(GeocodeResult? result, PlaceDetails? place, PlacePrediction? placePrediction) async {
+ RRTRequestModel request = createRRTRequest(result, place, placePrediction);
+ navServices.push(CustomPageRoute(page: RequestingServicesPage()));
+
+ var response = await emergencyServicesRepo.submitRRTRequest(request);
+ response.fold((failure) {
+ navServices.pushAndRemoveUntil(
+ CustomPageRoute(
+ page: TrackingScreen(
+ isRRTOrder: true,
+ state: OrderTrackingState.failed,
+ )),
+ ModalRoute.withName("/EmergencyServicesPage"));
+ }, (success) {
+ getRRTOrders(shouldNavigateToTrackingScreen: true);
+ });
+ }
+
+ Future getRRTOrders({bool shouldNavigateToTrackingScreen = false, bool showLoader = false}) async {
+ if(shouldNavigateToTrackingScreen == false && showLoader ) {
+ LoaderBottomSheet.showLoader(loadingText: "Fetching Orders");
+ }
+ historyLoading = true;
+ notifyListeners();
+ int? id = appState.getAuthenticatedUser()?.patientId;
+
+ var response = await emergencyServicesRepo.getRRTOrders(id: id);
+ if(shouldNavigateToTrackingScreen == false && showLoader ) {
+ LoaderBottomSheet.hideLoader();}
+ response.fold(
+ (failure) async {
+ historyLoading = false;
+ notifyListeners();
+ if (shouldNavigateToTrackingScreen) {
+ navServices.pushAndRemoveUntil(CustomPageRoute(page: TrackingScreen(isRRTOrder: true,state: OrderTrackingState.waitingForCall)), ModalRoute.withName("/EmergencyServicesPage"));
+ }
+ },
+ (apiResponse) {
+ if (shouldNavigateToTrackingScreen) {
+ navServices.pushAndRemoveUntil(
+ CustomPageRoute(
+ page: TrackingScreen(
+ state: OrderTrackingState.waitingForCall,
+ isRRTOrder: true,
+ rrtOrder: apiResponse.data?.pendingOrders.first,
+ )),
+ ModalRoute.withName("/EmergencyServicesPage"));
+ }
+ historyLoading = false;
+ ordersRRT = apiResponse.data;
+ allOrders.clear();
+ allOrders.addAll(ambulanceOrders??[]);
+ allOrders.addAll(ordersRRT?.completedOrders??[]);
+ changeOrderDisplayItems(OrderDislpay.ALL);
+ notifyListeners();
+ },
+ );
+ }
+
+
+ FutureOr cancelRRTOrder(int? orderID, {bool shouldPop = false}) async {
+ dialogService.showCommonBottomSheetWithoutH(
+ message: "Do you want to cancel the order".needTranslation,
+ onOkPressed: () async {
+ navServices.pop();
+ LoaderBottomSheet.showLoader(loadingText: "Cancelling Order".needTranslation);
+ var response = await emergencyServicesRepo.cancelRRTOrder(orderID);
+ LoaderBottomSheet.hideLoader();
+ response.fold((failure) => errorHandlerService.handleError(failure: failure), (success) {
+ getRRTOrders();
+ if (shouldPop) navServices.pop();
+ });
+ },
+ onCancelPressed: () {
+ navServices.pop();
+ });
+ }
+
+ void changeOrderDisplayItems(OrderDislpay currentlyDisplayedOrder){
+ this.currentlyDisplayedOrder = currentlyDisplayedOrder;
+ switch(currentlyDisplayedOrder){
+ case OrderDislpay.ALL:
+ orderDisplayList = allOrders;
+ break;
+ case OrderDislpay.RRT:
+ orderDisplayList = ordersRRT?.completedOrders ?? [];
+ break;
+ case OrderDislpay.AMBULANCE:
+ orderDisplayList = ambulanceOrders??[];
+ break;
+ }
+ notifyListeners();
+ }
+
+ void openRRT(){
+ print("the app state is ${appState.isAuthenticated}");
+ if (appState.isAuthenticated) {
+ if(agreedToTermsAndCondition == false){
+ dialogService.showErrorBottomSheet(message: "You Need To Agree To Terms And Conditions".needTranslation);
+ return;
+ }
+ locationUtils!.getLocation(
+ isShowConfirmDialog: true,
+ onSuccess: (position) {
+ updateBottomSheetState(BottomSheetType.FIXED);
+ navServices.push(
+ CustomPageRoute(
+ page: RrtMapScreen(), direction: AxisDirection.down),
+ );
+ });
+ } else{
+ dialogService.showErrorBottomSheet(
+ message: "You Need To Login First To Continue".needTranslation,
+ onOkPressed: () {
+ getIt().onLoginPressed();
+ });
+ }
+ }
+ clearRRTData(){
+ selectedRRTProcedure = null;
+ }
}
diff --git a/lib/features/emergency_services/models/OrderDisplay.dart b/lib/features/emergency_services/models/OrderDisplay.dart
new file mode 100644
index 0000000..9f1e929
--- /dev/null
+++ b/lib/features/emergency_services/models/OrderDisplay.dart
@@ -0,0 +1,3 @@
+enum OrderDislpay{
+ ALL,RRT,AMBULANCE
+}
\ No newline at end of file
diff --git a/lib/features/emergency_services/models/request_model/RRTRequestModel.dart b/lib/features/emergency_services/models/request_model/RRTRequestModel.dart
new file mode 100644
index 0000000..dfb5b1b
--- /dev/null
+++ b/lib/features/emergency_services/models/request_model/RRTRequestModel.dart
@@ -0,0 +1,75 @@
+class RRTRequestModel {
+ num? patientId;
+ int? patientOutSa;
+ bool? isOutPatient;
+ int? nearestProjectId;
+ num? longitude;
+ num? latitude;
+ String? additionalDetails;
+ String? nationality;
+ num? paymentAmount;
+ List? procedures;
+
+ RRTRequestModel(
+ {this.patientId,
+ this.patientOutSa,
+ this.isOutPatient,
+ this.nearestProjectId,
+ this.longitude,
+ this.latitude,
+ this.additionalDetails,
+ this.nationality,
+ this.paymentAmount,
+ this.procedures});
+
+ RRTRequestModel.fromJson(Map json) {
+ patientId = json['patientId'];
+ patientOutSa = json['patientOutSa'];
+ isOutPatient = json['isOutPatient'];
+ nearestProjectId = json['nearestProjectId'];
+ longitude = json['longitude'];
+ latitude = json['latitude'];
+ additionalDetails = json['additionalDetails'];
+ nationality = json['nationality'];
+ paymentAmount = json['paymentAmount'];
+ if (json['procedures'] != null) {
+ procedures = [];
+ json['procedures'].forEach((v) {
+ procedures!.add(new Procedures.fromJson(v));
+ });
+ }
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['patientId'] = this.patientId;
+ data['patientOutSa'] = this.patientOutSa;
+ data['isOutPatient'] = this.isOutPatient;
+ data['nearestProjectId'] = this.nearestProjectId;
+ data['longitude'] = this.longitude;
+ data['latitude'] = this.latitude;
+ data['additionalDetails'] = this.additionalDetails;
+ data['nationality'] = this.nationality;
+ data['paymentAmount'] = this.paymentAmount;
+ if (this.procedures != null) {
+ data['procedures'] = this.procedures!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class Procedures {
+ String? serviceID;
+
+ Procedures({this.serviceID});
+
+ Procedures.fromJson(Map json) {
+ serviceID = json['ServiceID'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ServiceID'] = this.serviceID;
+ return data;
+ }
+}
diff --git a/lib/features/emergency_services/models/request_model/service_price.dart b/lib/features/emergency_services/models/request_model/service_price.dart
new file mode 100644
index 0000000..abb57be
--- /dev/null
+++ b/lib/features/emergency_services/models/request_model/service_price.dart
@@ -0,0 +1,53 @@
+class ServicePrice {
+ String? currency;
+ dynamic maxPrice;
+ dynamic maxTotalPrice;
+ dynamic maxVAT;
+ dynamic minPrice;
+ dynamic minTotalPrice;
+ dynamic minVAT;
+ dynamic price;
+ dynamic totalPrice;
+ dynamic vat;
+
+ ServicePrice({
+ this.currency,
+ this.maxPrice,
+ this.maxTotalPrice,
+ this.maxVAT,
+ this.minPrice,
+ this.minTotalPrice,
+ this.minVAT,
+ this.price,
+ this.totalPrice,
+ this.vat});
+
+ ServicePrice.fromJson(dynamic json) {
+ currency = json["Currency"];
+ maxPrice = json["MaxPrice"];
+ maxTotalPrice = json["MaxTotalPrice"];
+ maxVAT = json["MaxVAT"];
+ minPrice = json["MinPrice"];
+ minTotalPrice = json["MinTotalPrice"];
+ minVAT = json["MinVAT"];
+ price = json["Price"];
+ totalPrice = json["TotalPrice"];
+ vat = json["VAT"];
+ }
+
+ Map toJson() {
+ var map = {};
+ map["Currency"] = currency;
+ map["MaxPrice"] = maxPrice;
+ map["MaxTotalPrice"] = maxTotalPrice;
+ map["MaxVAT"] = maxVAT;
+ map["MinPrice"] = minPrice;
+ map["MinTotalPrice"] = minTotalPrice;
+ map["MinVAT"] = minVAT;
+ map["Price"] = price;
+ map["TotalPrice"] = totalPrice;
+ map["VAT"] = vat;
+ return map;
+ }
+
+}
\ No newline at end of file
diff --git a/lib/features/emergency_services/models/resp_model/RRTServiceData.dart b/lib/features/emergency_services/models/resp_model/RRTServiceData.dart
new file mode 100644
index 0000000..e4e7ce7
--- /dev/null
+++ b/lib/features/emergency_services/models/resp_model/RRTServiceData.dart
@@ -0,0 +1,406 @@
+class RRTServiceData {
+ List pendingOrders = [];
+ List completedOrders = [];
+ ServicePrice servicePrice = ServicePrice();
+}
+
+class GetCMCAllOrdersResponseModel {
+ int? iD;
+ int? patientId;
+ int? patientOutSa;
+ bool? isOutPatient;
+ int? projectId;
+ int? nearestProjectId;
+ dynamic longitude;
+ dynamic latitude;
+ dynamic appointmentNo;
+ dynamic dischargeId;
+ int? statusId;
+ int? serviceId;
+ int? channel;
+ Orderpayment? orderpayment;
+ dynamic orderselectedservice;
+ dynamic wforder;
+ dynamic orderapprovalobj;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+ String? statusText;
+ int? paymentStatus;
+ dynamic clientRequestid;
+ dynamic paymentStatusText;
+ String? projectName;
+ String? nearestProjectName;
+ dynamic paymentAmount;
+ WFOrder? wFOrder;
+ String? serviceText;
+ bool? isSentForApproval;
+ int? exaCartOrderId;
+ bool? isTimer;
+ int? timeSeconds;
+ int? totalPendingSeconds;
+ int? timeMinute;
+ int? timeHour;
+ int? timeTotalSeconds;
+ int? timeTotalMinute;
+ int? timeTotalHour;
+ dynamic approvalStatus;
+ bool? isActive;
+ int? clickButton;
+ List? procedures;
+ dynamic pickupLocation;
+ dynamic dropOffLocation;
+ dynamic clinicName;
+ dynamic doctorName;
+ dynamic branch;
+ dynamic time;
+ dynamic notes;
+
+ GetCMCAllOrdersResponseModel(
+ {this.iD,
+ this.patientId,
+ this.patientOutSa,
+ this.isOutPatient,
+ this.projectId,
+ this.nearestProjectId,
+ this.longitude,
+ this.latitude,
+ this.appointmentNo,
+ this.dischargeId,
+ this.statusId,
+ this.serviceId,
+ this.channel,
+ this.orderpayment,
+ this.orderselectedservice,
+ this.wforder,
+ this.orderapprovalobj,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted,
+ this.statusText,
+ this.paymentStatus,
+ this.clientRequestid,
+ this.paymentStatusText,
+ this.projectName,
+ this.nearestProjectName,
+ this.paymentAmount,
+ this.wFOrder,
+ this.serviceText,
+ this.isSentForApproval,
+ this.exaCartOrderId,
+ this.isTimer,
+ this.timeSeconds,
+ this.totalPendingSeconds,
+ this.timeMinute,
+ this.timeHour,
+ this.timeTotalSeconds,
+ this.timeTotalMinute,
+ this.timeTotalHour,
+ this.approvalStatus,
+ this.isActive,
+ this.clickButton,
+ this.procedures,
+ this.pickupLocation,
+ this.dropOffLocation,
+ this.clinicName,
+ this.doctorName,
+ this.branch,
+ this.time,
+ this.notes});
+
+ GetCMCAllOrdersResponseModel.fromJson(Map json) {
+ 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
+ ? new 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
+ ? new WFOrder.fromJson(json['WF_order'])
+ : null;
+ serviceText = json['ServiceText'];
+ isSentForApproval = json['isSentForApproval'];
+ exaCartOrderId = json['ExaCart_OrderId'];
+ isTimer = json['isTimer'];
+ timeSeconds = json['TimeSeconds'];
+ totalPendingSeconds = json['TotalPendingSeconds'];
+ timeMinute = json['TimeMinute'];
+ timeHour = json['TimeHour'];
+ timeTotalSeconds = json['TimeTotalSeconds'];
+ timeTotalMinute = json['TimeTotalMinute'];
+ timeTotalHour = json['TimeTotalHour'];
+ approvalStatus = json['ApprovalStatus'];
+ isActive = json['isActive'];
+ clickButton = json['ClickButton'];
+ pickupLocation = json['PickupLocation'];
+ dropOffLocation = json['DropOffLocation'];
+ clinicName = json['clinicName'];
+ doctorName = json['DoctorName'];
+ branch = json['Branch'];
+ time = json['Time'];
+ notes = json['Notes'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ID'] = this.iD;
+ data['PatientId'] = this.patientId;
+ data['PatientOutSa'] = this.patientOutSa;
+ data['IsOutPatient'] = this.isOutPatient;
+ data['ProjectId'] = this.projectId;
+ data['NearestProjectId'] = this.nearestProjectId;
+ data['Longitude'] = this.longitude;
+ data['Latitude'] = this.latitude;
+ data['AppointmentNo'] = this.appointmentNo;
+ data['DischargeId'] = this.dischargeId;
+ data['StatusId'] = this.statusId;
+ data['ServiceId'] = this.serviceId;
+ data['Channel'] = this.channel;
+ if (this.orderpayment != null) {
+ data['orderpayment'] = this.orderpayment!.toJson();
+ }
+ data['orderselectedservice'] = this.orderselectedservice;
+
+ data['wforder'] = this.wforder;
+ data['orderapprovalobj'] = this.orderapprovalobj;
+ data['Created'] = this.created;
+ data['CreatedBy'] = this.createdBy;
+ data['Modified'] = this.modified;
+ data['ModifiedBy'] = this.modifiedBy;
+ data['IsDeleted'] = this.isDeleted;
+ data['StatusText'] = this.statusText;
+ data['PaymentStatus'] = this.paymentStatus;
+ data['ClientRequestid'] = this.clientRequestid;
+ data['PaymentStatusText'] = this.paymentStatusText;
+ data['ProjectName'] = this.projectName;
+ data['NearestProjectName'] = this.nearestProjectName;
+ data['PaymentAmount'] = this.paymentAmount;
+ if (this.wFOrder != null) {
+ data['WF_order'] = this.wFOrder!.toJson();
+ }
+ data['ServiceText'] = this.serviceText;
+ data['isSentForApproval'] = this.isSentForApproval;
+ data['ExaCart_OrderId'] = this.exaCartOrderId;
+ data['isTimer'] = this.isTimer;
+ data['TimeSeconds'] = this.timeSeconds;
+ data['TotalPendingSeconds'] = this.totalPendingSeconds;
+ data['TimeMinute'] = this.timeMinute;
+ data['TimeHour'] = this.timeHour;
+ data['TimeTotalSeconds'] = this.timeTotalSeconds;
+ data['TimeTotalMinute'] = this.timeTotalMinute;
+ data['TimeTotalHour'] = this.timeTotalHour;
+ data['ApprovalStatus'] = this.approvalStatus;
+ data['isActive'] = this.isActive;
+ data['ClickButton'] = this.clickButton;
+ data['PickupLocation'] = this.pickupLocation;
+ data['DropOffLocation'] = this.dropOffLocation;
+ data['clinicName'] = this.clinicName;
+ data['DoctorName'] = this.doctorName;
+ data['Branch'] = this.branch;
+ data['Time'] = this.time;
+ data['Notes'] = this.notes;
+ return data;
+ }
+}
+
+class Orderpayment {
+ int? iD;
+ int? orderId;
+ dynamic clientRequestId;
+ dynamic totalAmount;
+ int? paymentStatus;
+ dynamic order;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+
+ Orderpayment(
+ {this.iD,
+ this.orderId,
+ this.clientRequestId,
+ this.totalAmount,
+ this.paymentStatus,
+ this.order,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted});
+
+ Orderpayment.fromJson(Map json) {
+ iD = json['ID'];
+ orderId = json['OrderId'];
+ clientRequestId = json['ClientRequestId'];
+ totalAmount = json['TotalAmount'];
+ paymentStatus = json['PaymentStatus'];
+ order = json['Order'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['ID'] = this.iD;
+ data['OrderId'] = this.orderId;
+ data['ClientRequestId'] = this.clientRequestId;
+ data['TotalAmount'] = this.totalAmount;
+ data['PaymentStatus'] = this.paymentStatus;
+ data['Order'] = this.order;
+ data['Created'] = this.created;
+ data['CreatedBy'] = this.createdBy;
+ data['Modified'] = this.modified;
+ data['ModifiedBy'] = this.modifiedBy;
+ data['IsDeleted'] = this.isDeleted;
+ return data;
+ }
+}
+
+class WFOrder {
+ dynamic wfButtonsDTO;
+ int? iD;
+ int? orderId;
+ int? previousStep;
+ int? nextStep;
+ int? serviceId;
+ dynamic order;
+ String? created;
+ dynamic createdBy;
+ dynamic modified;
+ dynamic modifiedBy;
+ bool? isDeleted;
+
+ WFOrder(
+ {this.wfButtonsDTO,
+ this.iD,
+ this.orderId,
+ this.previousStep,
+ this.nextStep,
+ this.serviceId,
+ this.order,
+ this.created,
+ this.createdBy,
+ this.modified,
+ this.modifiedBy,
+ this.isDeleted});
+
+ WFOrder.fromJson(Map json) {
+ wfButtonsDTO = json['wf_ButtonsDTO'];
+ iD = json['ID'];
+ orderId = json['OrderId'];
+ previousStep = json['PreviousStep'];
+ nextStep = json['NextStep'];
+ serviceId = json['ServiceId'];
+ order = json['Order'];
+ created = json['Created'];
+ createdBy = json['CreatedBy'];
+ modified = json['Modified'];
+ modifiedBy = json['ModifiedBy'];
+ isDeleted = json['IsDeleted'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['wf_ButtonsDTO'] = this.wfButtonsDTO;
+ data['ID'] = this.iD;
+ data['OrderId'] = this.orderId;
+ data['PreviousStep'] = this.previousStep;
+ data['NextStep'] = this.nextStep;
+ data['ServiceId'] = this.serviceId;
+ data['Order'] = this.order;
+ data['Created'] = this.created;
+ data['CreatedBy'] = this.createdBy;
+ data['Modified'] = this.modified;
+ data['ModifiedBy'] = this.modifiedBy;
+ data['IsDeleted'] = this.isDeleted;
+ return data;
+ }
+}
+
+
+class ServicePrice {
+ String? currency;
+ dynamic maxPrice;
+ dynamic maxTotalPrice;
+ dynamic maxVAT;
+ dynamic minPrice;
+ dynamic minTotalPrice;
+ dynamic minVAT;
+ dynamic price;
+ dynamic totalPrice;
+ dynamic vat;
+
+ ServicePrice({
+ this.currency,
+ this.maxPrice,
+ this.maxTotalPrice,
+ this.maxVAT,
+ this.minPrice,
+ this.minTotalPrice,
+ this.minVAT,
+ this.price,
+ this.totalPrice,
+ this.vat});
+
+ ServicePrice.fromJson(dynamic json) {
+ currency = json["Currency"];
+ maxPrice = json["MaxPrice"];
+ maxTotalPrice = json["MaxTotalPrice"];
+ maxVAT = json["MaxVAT"];
+ minPrice = json["MinPrice"];
+ minTotalPrice = json["MinTotalPrice"];
+ minVAT = json["MinVAT"];
+ price = json["Price"];
+ totalPrice = json["TotalPrice"];
+ vat = json["VAT"];
+ }
+
+ Map toJson() {
+ var map = {};
+ map["Currency"] = currency;
+ map["MaxPrice"] = maxPrice;
+ map["MaxTotalPrice"] = maxTotalPrice;
+ map["MaxVAT"] = maxVAT;
+ map["MinPrice"] = minPrice;
+ map["MinTotalPrice"] = minTotalPrice;
+ map["MinVAT"] = minVAT;
+ map["Price"] = price;
+ map["TotalPrice"] = totalPrice;
+ map["VAT"] = vat;
+ return map;
+ }
+
+}
\ No newline at end of file
diff --git a/lib/presentation/emergency_services/RRT/rrt_map_screen.dart b/lib/presentation/emergency_services/RRT/rrt_map_screen.dart
new file mode 100644
index 0000000..ca260d9
--- /dev/null
+++ b/lib/presentation/emergency_services/RRT/rrt_map_screen.dart
@@ -0,0 +1,636 @@
+import 'dart:io';
+
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.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/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/emergency_services/emergency_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/AmbulanceCallingPlace.dart';
+import 'package:hmg_patient_app_new/features/location/GeocodeResponse.dart';
+import 'package:hmg_patient_app_new/features/location/PlaceDetails.dart';
+import 'package:hmg_patient_app_new/features/location/PlacePrediction.dart';
+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/appointments/widgets/appointment_doctor_card.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/AddressItem.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart' show AppointmentBottomSheet;
+import 'package:hmg_patient_app_new/presentation/emergency_services/widgets/location_input_bottom_sheet.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/CustomSwitch.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+import 'package:hmg_patient_app_new/widgets/expandable_bottom_sheet/ExpandableBottomSheet.dart';
+import 'package:hmg_patient_app_new/widgets/expandable_bottom_sheet/model/BottomSheetType.dart';
+import 'package:hmg_patient_app_new/widgets/input_widget.dart';
+import 'package:hmg_patient_app_new/widgets/map/HMSMap.dart';
+import 'package:hmg_patient_app_new/widgets/map/map.dart';
+import 'package:provider/provider.dart';
+
+import '../../../widgets/common_bottom_sheet.dart';
+
+class RrtMapScreen extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ floatingActionButton: Visibility(
+ visible: context.watch().bottomSheetType ==
+ BottomSheetType.FIXED,
+ child: Padding(
+ padding: EdgeInsetsDirectional.only(end: 8.h, bottom: 68.h),
+ child: DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor, borderRadius: 12.h),
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.locate_me, width: 24.h, height: 24.h)
+ .paddingAll(12.h)
+ .onPress(() {
+ context
+ .read()
+ .moveToCurrentLocation();
+ }),
+ ),
+ ),
+ ),
+ bottomSheet: ExpandableBottomSheet(
+ bottomSheetType:
+ context.watch().bottomSheetType,
+ children: {
+ BottomSheetType.EXPANDED: ExpanedBottomSheet(context),
+ BottomSheetType.FIXED: FixedBottomSheet(context),
+ },
+ ),
+ body: Stack(
+ children: [
+ if (context.read().isGMSAvailable )
+ GMSMap(
+ currentLocation:
+ context.read().getGMSLocation(),
+ onCameraMoved: (value) => context
+ .read()
+ .handleGMSMapCameraMoved(value),
+ onCameraIdle:
+ context.read().handleOnCameraIdle,
+ myLocationEnabled: true,
+ inputController:
+ context.read().gmsController,
+ showCenterMarker: true,
+ )
+ else
+ HMSMap(
+ currentLocation:
+ context.read().getHMSLocation(),
+ onCameraMoved: (value) => context
+ .read()
+ .handleHMSMapCameraMoved(value),
+ onCameraIdle:
+ context.read().handleOnCameraIdle,
+ myLocationEnabled: false,
+ inputController:
+ context.read().hmsController,
+ showCenterMarker: true,
+ ),
+ Align(
+ alignment: AlignmentDirectional.topStart,
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.closeBottomNav, width: 32.h, height: 32.h)
+ .onPress(() {
+ context
+ .read()
+ .flushPickupInformation();
+ Navigator.pop(context);
+ }),
+ ).paddingOnly(top: 51.h, left: 24.h),
+ ],
+ ),
+ );
+ }
+
+ Widget FixedBottomSheet(BuildContext context) {
+ return GestureDetector(
+ onVerticalDragUpdate: (details){
+ },
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ spacing: 24.h,
+ children: [
+ inputFields(context),
+ SizedBox(
+ height: 200.h,
+ child: DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.scaffoldBgColor,
+ customBorder: BorderRadius.only(
+ topLeft: Radius.circular(24.h),
+ topRight: Radius.circular(24.h),
+ ),
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 24.h,
+ children: [
+ Column(
+ spacing: 4.h,
+ children: [
+ "Select Pickup Details".needTranslation.toText21(
+ weight: FontWeight.w600,
+ color: AppColors.textColor,
+ ),
+ " Please select the details of pickup"
+ .needTranslation
+ .toText12(
+ fontWeight: FontWeight.w500,
+ color: AppColors.greyTextColor,
+ )
+ ],
+ ),
+ CustomButton(
+ text: "Select Details".needTranslation,
+ onPressed: () {
+ LocationViewModel locationViewModel = context.read();
+ GeocodeResponse? response = locationViewModel.geocodeResponse;
+ PlaceDetails? placeDetails = locationViewModel.placeDetails;
+ PlacePrediction? placePrediction = locationViewModel.selectedPrediction;
+ context.read().submitRRTRequest(response?.results.first, placeDetails, placePrediction);
+ })
+ ],
+ ).paddingOnly(top: 24.h, bottom: 32.h, left: 24.h, right: 24.h),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget ExpanedBottomSheet(BuildContext context) {
+ return GestureDetector(
+ onVerticalDragUpdate: (details){
+ if(details.delta.dy>0){
+ context.read().updateBottomSheetState(BottomSheetType.FIXED);
+ }
+ },
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.scaffoldBgColor,
+ customBorder: BorderRadius.only(
+ topLeft: Radius.circular(24.h),
+ topRight: Radius.circular(24.h),
+ ),
+ ),
+ child: Column(
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 16.h,
+ children: [
+
+ hospitalAndPickUpSection(context),
+
+
+ ],
+ ).paddingOnly(top: 24.h, bottom: 32.h,left: 24.h, right: 24.h),
+
+ bottomPriceContent(context)
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ locationsSections(BuildContext context) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.h,
+ ),
+ child: Column(mainAxisSize: MainAxisSize.min, children: [
+ ListView.separated(
+ separatorBuilder: (_, __) => Column(
+ children: [
+ SizedBox(height: 16.h),
+ Divider(
+ color: AppColors.bottomNAVBorder,
+ height: 1,
+ thickness: 1,
+ ),
+ SizedBox(height: 16.h),
+ ],
+ ),
+ shrinkWrap: true,
+ itemCount: 3,
+ itemBuilder: (__, index) {
+ if (index ==
+ 2) // todo means the end of the list so handle as per the viewmodel
+ {
+ return CustomButton(
+ height: 40.h,
+ backgroundColor: AppColors.lightRedButtonColor,
+ borderColor: Colors.transparent,
+ text: "Add new address".needTranslation,
+ textColor: AppColors.primaryRedColor,
+ iconColor: AppColors.primaryRedColor,
+ onPressed: () {},
+ icon: AppAssets.add_icon);
+ } else {
+ return AddressItem(
+ isSelected: index == 0,
+ address:
+ "Flat No 301, Building No 12, Palm Spring Apartment, Sector 45, Gurugram, Haryana 122003",
+ title: index == 0
+ ? "Home".needTranslation
+ : "Work".needTranslation,
+ onTap: () {},
+ );
+ }
+ })
+ ]).paddingAll(16.h),
+ );
+ }
+
+ hospitalAndPickUpSection(BuildContext context) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.r,
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 16.h,
+ children: [
+ // Row(
+ // children: [
+ // hospitalAndPickUpItemContent(
+ // title: "Select Hospital".needTranslation,
+ // subTitle: "hospital".needTranslation,
+ // leadingIcon: AppAssets.hospital,
+ // ),
+ // Utils.buildSvgWithAssets(icon: AppAssets.down_cheveron,
+ // width: 24.h, height: 24.h)
+ // .paddingAll(16.h)
+ // ],
+ // ).onPress((){
+ // showHospitalBottomSheet(context);
+ // }),
+ // SizedBox(height: 16.h),
+ // Divider(
+ // color: AppColors.bottomNAVBorder,
+ // height: 1,
+ // thickness: 1,
+ // ),
+ // SizedBox(height: 16.h),
+
+ Row(
+ children: [
+ hospitalAndPickUpItemContent(
+ title: "Pick".needTranslation,
+ subTitle: "Inside the home".needTranslation,
+ leadingIcon: AppAssets.pickup_bed,
+ ),
+ CustomSwitch(
+ value: context
+ .watch()
+ .pickupFromInsideTheLocation,
+ onChanged: (value){
+ context
+ .read()
+ .updateThePickupPlaceFromLocation(value);
+ },
+ )
+ ],
+ ),
+
+ Row(
+ children: [
+ hospitalAndPickUpItemContent(
+ title: '',
+ subTitle: "Have any appointment".needTranslation,
+ leadingIcon: AppAssets.appointment_checkin_icon,
+ ),
+ CustomSwitch(
+ value: context
+ .watch()
+ .haveAnAppointment,
+ onChanged: (value) async {
+ // if (value) {
+ // openAppointmentList(context);
+ // }
+ await context.read()
+ .updateAppointment(value);
+ if (context.read().appointments?.isNotEmpty == true) {
+ openAppointmentList(context);
+ }
+ },
+ )
+ ],
+ ),
+ ],
+ ).paddingAll(16.h),
+ );
+ }
+
+ leadingIcon(String leadingIcon) {
+ return Container(
+ height: 40.h,
+ width: 40.h,
+ margin: EdgeInsets.only(right: 10.h),
+ padding: EdgeInsets.all(8.h),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ borderRadius: 12.h,
+ color: AppColors.greyColor,
+ ),
+ child: Utils.buildSvgWithAssets(icon: leadingIcon),
+ );
+ }
+
+ hospitalAndPickUpItemContent({
+ required String title,
+ required String subTitle,
+ required String leadingIcon,
+ }) {
+ return Expanded(
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ this.leadingIcon(leadingIcon),
+ Expanded(
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Visibility(
+ visible: title.isNotEmpty,
+ child: Column(
+ children: [
+ title.toText12(
+ color: AppColors.greyTextColor,
+ fontWeight: FontWeight.w500,
+ ),
+ SizedBox(height: 2.h),
+ ],
+ ),
+ ),
+ subTitle.toText14(
+ color: AppColors.textColor,
+ weight: FontWeight.w500,
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ bottomPriceContent(BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.scaffoldBgColor,
+ customBorder: BorderRadius.only(
+ topLeft: Radius.circular(24.h),
+ topRight: Radius.circular(24.h),
+ ),
+ hasShadow: true
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 12.h,
+ children: [
+ Row(
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 4.h,
+ children: [
+ "Total amount to pay".needTranslation.toText18(
+ weight: FontWeight.w600,
+ color: AppColors.textColor,
+ ),
+ Row(
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.warning,
+ height: 18.h, width: 18.h),
+ SizedBox(width: 4.h,),
+ "Amount will be paid at the hospital"
+ .needTranslation
+ .toText12(
+ fontWeight: FontWeight.w500,
+ color: AppColors.greyTextColor,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ Utils.getPaymentAmountWithSymbol(
+ (Utils.formatNumberToInternationalFormat(context
+ .read()
+ .getTotalPrice() ??
+ 0))
+ .toText24(
+ fontWeight: FontWeight.w600,
+ color: AppColors.textColor,
+ letterSpacing: -2),
+ AppColors.blackColor,
+ 17.h)
+
+ // Utils.getPaymentAmountWithSymbol2(context.read().selectedTransportOption?.priceTotal??"0", letterSpacing: -2)
+ ],
+ ),
+ CustomButton(
+ text: "Submit Request".needTranslation,
+ onPressed: () {
+ LocationViewModel locationViewModel = context.read();
+ GeocodeResponse? response = locationViewModel.geocodeResponse;
+ PlaceDetails? placeDetails = locationViewModel.placeDetails;
+ PlacePrediction? placePrediction = locationViewModel.selectedPrediction;
+ context.read().submitAmbulanceRequest(response?.results.first, placeDetails, placePrediction);
+ })
+ ],
+ ).paddingOnly(top: 24.h, bottom: 12.h, left: 24.h, right: 24.h),
+ ),
+ ],
+ );
+ }
+
+ showHospitalBottomSheet(BuildContext context){
+ showCommonBottomSheetWithoutHeight(
+ title:
+ LocaleKeys.selectHospital.tr(),
+ context,
+ child: Consumer(
+ builder:(_,vm,__)=> HospitalBottomSheetBody(
+ searchText: vm.searchController,
+ displayList: vm.displayList,
+ onFacilityClicked: (value) {
+ vm.setSelectedFacility(value);
+ vm.getDisplayList();
+ },
+ onHospitalClicked: (hospital) {
+ Navigator.pop(context);
+ vm.setSelectedHospital(hospital);
+ },
+ onHospitalSearch: (value) {
+ vm.searchHospitals(value ?? "");
+ },
+ selectedFacility:
+ vm.selectedFacility,
+ hmcCount: vm.hmcCount,
+ hmgCount: vm.hmgCount,
+ ),
+ ),
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ hasBottomPadding: false,
+ backgroundColor: AppColors.bottomSheetBgColor,
+ callBackFunc: () {
+ context.read().clearSearchText();
+ },
+ );
+ }
+
+ ///it will show the places field first and then hospital field
+ PlaceFirstThanHospitalField(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 16.h,
+ children: [
+ textPlaceInput(context),
+ hospitalField(context),
+ ],
+ ).paddingOnly(right: 24.h, left: 24.h);
+ }
+
+ HospitalFieldFirstThanPlaces(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 16.h,
+ children: [hospitalField(context), textPlaceInput(context)],
+ ).paddingOnly(right: 24.h, left: 24.h);
+ }
+
+ textPlaceInput(context) {
+ return Consumer(builder: (_, vm, __) {
+ print(
+ "the data is ${vm.geocodeResponse?.results.first.formattedAddress ?? vm.selectedPrediction?.description}");
+ return SizedBox(
+ width: MediaQuery.sizeOf(context).width,
+ child: TextInputWidget(
+ labelText: "Enter Pickup Location Manually".needTranslation,
+ hintText: "Enter Pickup Location".needTranslation,
+ controller: TextEditingController(
+ text: vm.geocodeResponse?.results.first.formattedAddress ??
+ vm.selectedPrediction?.description,
+ ),
+ leadingIcon: AppAssets.location_pickup,
+ isAllowLeadingIcon: true,
+ isEnable: false,
+ prefix: null,
+ autoFocus: false,
+ isBorderAllowed: false,
+ keyboardType: TextInputType.text,
+ padding: EdgeInsets.symmetric(
+ vertical: ResponsiveExtension(10).h,
+ horizontal: ResponsiveExtension(15).h,
+ ),
+ ).onPress(() {
+ openLocationInputBottomSheet(context);
+ }),
+ );
+ });
+ }
+
+ ///decide which field to show first based on the selected calling place
+ inputFields(BuildContext context) {
+ return textPlaceInput(context);
+ }
+
+ openLocationInputBottomSheet(BuildContext context) {
+ context.read().flushSearchPredictions();
+ showCommonBottomSheetWithoutHeight(
+ title: "".needTranslation,
+ context,
+ child: SizedBox(
+ height: MediaQuery.sizeOf(context).height * .8,
+ child: LocationInputBottomSheet(),
+ ),
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ hasBottomPadding: false,
+ backgroundColor: AppColors.bottomSheetBgColor,
+ callBackFunc: () {},
+ );
+ }
+
+ hospitalField(BuildContext context) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor, borderRadius: 12.h),
+ child: Row(
+ children: [
+ hospitalAndPickUpItemContent(
+ title: "Select Hospital".needTranslation,
+ subTitle: context
+ .read()
+ .getSelectedHospitalName() ??
+ "Select Hospital".needTranslation,
+ leadingIcon: AppAssets.hospital,
+ ),
+ Utils.buildSvgWithAssets(
+ icon: AppAssets.down_cheveron, width: 24.h, height: 24.h)
+ .paddingAll(16.h)
+ ],
+ ).onPress(() {
+ print("the item is clicked");
+ showHospitalBottomSheet(context);
+ }).paddingSymmetrical(
+ 10.w,
+ 12.h,
+ ),
+ );
+ }
+
+ void openAppointmentList(BuildContext context) {
+ showCommonBottomSheetWithoutHeight(
+ title: "Select Appointment".needTranslation,
+ context,
+ child: SizedBox(
+ height: MediaQuery.sizeOf(context).height * .5,
+ child: AppointmentBottomSheet(
+ list: context.read().appointments!,
+ onAppointmentSelection: (appointment) {
+ Navigator.pop(context);
+ context.read().setSelectedAppointment(appointment);
+ }),
+ ),
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ hasBottomPadding: false,
+ backgroundColor: AppColors.bottomSheetBgColor,
+ callBackFunc: () {
+ context.read().checkHasAppointment();
+ },
+ );
+ // );
+ }
+}
diff --git a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart
index 4d22610..8c3db26 100644
--- a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart
+++ b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart
@@ -1,9 +1,16 @@
+import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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/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/emergency_services/emergency_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/rrt_procedures_response_model.dart';
+import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/radio/custom_radio_button.dart';
import 'package:provider/provider.dart';
@@ -13,34 +20,250 @@ class RrtRequestTypeSelect extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer(builder: (context, emergencyServicesVM, child) {
+ print("the checkbox is ${emergencyServicesVM.agreedToTermsAndCondition}");
return Column(
children: [
- Container(
- padding: EdgeInsets.all(16.h),
- height: 200.h,
+ Column(
+ children: [
+ "Rapid Response Team (RRT) options".needTranslation.toText20(color: AppColors.textColor, isBold: true),
+ SizedBox(
+ height: 16.h,
+ ),
+ DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: Colors.white,
+ borderRadius: 20.r,
+ ),
+ child: OptionSelection(context)),
+ SizedBox(
+ height: 24.h,
+ ),
+ termsAndCondition(context, emergencyServicesVM),
+ ],
+ ).paddingSymmetrical(24.w, 0.h),
+ bottomPriceContent(context, emergencyServicesVM)
+ ],
+ );
+ });
+ }
+
+ bottomPriceContent(BuildContext context, EmergencyServicesViewModel emergencyServicesVM) {
+ if (emergencyServicesVM.selectedRRTProcedure == null) return SizedBox.shrink();
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ DecoratedBox(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
- color: AppColors.whiteColor,
- borderRadius: 24.h,
- ),
+ color: AppColors.scaffoldBgColor,
+ customBorder: BorderRadius.only(
+ topLeft: Radius.circular(24.h),
+ topRight: Radius.circular(24.h),
+ ),
+ hasShadow: true),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 12.h,
children: [
Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 12.h,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ "Total amount to pay".needTranslation.toText18(
+ weight: FontWeight.w600,
+ color: AppColors.textColor,
+ ),
+ Utils.getPaymentAmountWithSymbol(
+ (Utils.formatNumberToInternationalFormat(context.read().selectedRRTProcedure?.patientShare ?? 0))
+ .toText24(fontWeight: FontWeight.w600, color: AppColors.textColor, letterSpacing: -2),
+ AppColors.blackColor,
+ 17.h)
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.warning, height: 18.h, width: 18.h),
+ SizedBox(
+ width: 4.h,
+ ),
+ "Amount will be paid at the hospital".needTranslation.toText11(
+ color: AppColors.greyTextColor,
+ ),
+ ],
+ ),
+ Row(
+ children: [
+ "+ VAT 15%(".needTranslation.toText12(
+ fontWeight: FontWeight.w500,
+ color: AppColors.greyTextColor,
+ ),
+ "${emergencyServicesVM.selectedRRTProcedure?.patientTaxAmount})".needTranslation.toText14(
+ weight: FontWeight.w600,
+ color: AppColors.greyTextColor,
+ ),
+ ],
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+
+ // Utils.getPaymentAmountWithSymbol2(context.read().selectedTransportOption?.priceTotal??"0", letterSpacing: -2)
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- CustomRadioOption(
- value: "",
- groupValue: "",
- onChanged: (value) {},
- text: "Home Visit Emergency",
+ Row(
+ spacing: 6.w,
+ children: [
+ Image.asset(AppAssets.mada, width: 24.h, height: 24.h),
+ Image.asset(AppAssets.visa, width: 24.h, height: 24.h),
+ Image.asset(AppAssets.Mastercard, width: 24.h, height: 24.h),
+ Image.asset(AppAssets.apple_pay, width: 24.h, height: 24.h),
+ ],
+ ),
+ Column(
+ children: [
+ Divider(
+ color: AppColors.dividerColor,
+ thickness: 1.h,
+ ),
+ Utils.getPaymentAmountWithSymbol(
+ (Utils.formatNumberToInternationalFormat(context.read().selectedRRTProcedure?.patientShareWithTax ?? 0))
+ .toText24(fontWeight: FontWeight.w600, color: AppColors.textColor, letterSpacing: -2),
+ AppColors.blackColor,
+ 17.h),
+ ],
)
],
),
+ CustomButton(text: LocaleKeys.next.tr(), onPressed: () {
+ Navigator.pop(context);
+ emergencyServicesVM.openRRT();
+ })
],
- ),
+ ).paddingAll(24.h),
),
- SizedBox(height: 32.h),
],
);
- });
+ }
+
+ Widget OptionSelection(BuildContext context) {
+ return Selector?, RRTProceduresResponseModel?)>(
+ // Select both the list and the currently selected procedure
+ selector: (context, viewModel) => (viewModel.RRTProceduresList, viewModel.selectedRRTProcedure),
+ builder: (context, data, child) {
+ final procedureList = data.$1;
+ final selectedProcedure = data.$2;
+
+ // Handle loading or empty state
+ if (procedureList == null || procedureList.isEmpty) {
+ return const SizedBox.shrink();
+ }
+
+ return ListView.separated(
+ shrinkWrap: true,
+ padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 16.w),
+ // Important for ListView inside a Column
+ physics: const NeverScrollableScrollPhysics(),
+ // If the parent is scrollable
+ itemCount: procedureList.length,
+ separatorBuilder: (_, __) => Divider(thickness: 1.h, color: AppColors.dividerColor),
+ itemBuilder: (_, index) {
+ final procedure = procedureList[index];
+
+ final indexOfSelectedItem = selectedProcedure != null ? procedureList.indexOf(selectedProcedure) : -1;
+ return RadioListTile(
+ title: (procedure.procedureName ?? "").toText12(color: AppColors.textColor),
+ value: index,
+ fillColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.selected)) {
+ return AppColors.primaryRedColor;
+ }
+ return Color(0xffEEEEEE);
+ }),
+ contentPadding: EdgeInsets.zero,
+ groupValue: indexOfSelectedItem,
+ onChanged: (int? newValue) {
+ context.read().setSelectedRRTProcedure(procedure);
+ },
+ );
+ // return Row(
+ // children: [
+ // Radio(
+ // // Specify the type for the Radio button
+ // value: procedure.procedureID ?? "",
+ // groupValue: selectedProcedure?.procedureID,
+ // // Compare with the selected procedure's ID
+ // activeColor: AppColors.primaryRedColor,
+ // fillColor: MaterialStateProperty.all(AppColors.primaryRedColor),
+ // onChanged: (value) {
+ // // The onChanged of the Radio button should handle the state update
+ // context.read().setSelectedRRTProcedure(procedure);
+ // },
+ // ),
+ // Expanded(
+ // // Use Expanded to allow text to wrap if it's too long
+ // child: (procedure.procedureName ?? "").toText12(color: AppColors.textColor),
+ // )
+ // ],
+ },
+ );
+ },
+ );
+ }
+
+ termsAndCondition(
+ BuildContext context,
+ EmergencyServicesViewModel emergencyServicesVM,
+ ) {
+ return Row(
+ children: [
+ Checkbox(
+ value: emergencyServicesVM.agreedToTermsAndCondition,
+ checkColor: AppColors.whiteColor,
+ fillColor: MaterialStateProperty.resolveWith((Set states) {
+ print("the state is ${states}");
+ if (states.contains(WidgetState.selected)) {
+ return AppColors.errorColor;
+ }
+ return AppColors.whiteColor;
+ }),
+ onChanged: (value) {
+ emergencyServicesVM.setTermsAndConditions(value ?? false);
+ }),
+ Row(
+ children: [
+ LocaleKeys.agreeTo.tr().toText12(color: AppColors.textColor),
+ LocaleKeys.termsConditoins.tr().toText12(color: AppColors.errorColor, isUnderLine: true),
+ ],
+ ),
+ ],
+ );
+
+ // CheckboxListTile(
+ // title: Row(
+ // children: [
+ // LocaleKeys.agreeTo.tr().toText12(color: AppColors.textColor),
+ // LocaleKeys.termsConditoins.tr().toText12(color: AppColors.errorColor, isUnderLine: true),
+ // ],
+ // ),
+ // value: emergencyServicesVM.agreedToTermsAndCondition,
+ // onChanged: (value) {
+ // emergencyServicesVM.setTermsAndConditions(value ?? false);
+ // },
+ // );
}
}
diff --git a/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart b/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart
index eddca11..87bbead 100644
--- a/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart
+++ b/lib/presentation/emergency_services/call_ambulance/tracking_screen.dart
@@ -8,6 +8,7 @@ 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/emergency_services/emergency_services_view_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.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';
@@ -22,11 +23,13 @@ import 'package:url_launcher/url_launcher.dart' show launchUrl;
class TrackingScreen extends StatelessWidget {
OrderTrackingState? state ;
+ final bool isRRTOrder;
final AmbulanceRequestOrdersModel? order;
+ final GetCMCAllOrdersResponseModel? rrtOrder;
- TrackingScreen({super.key, OrderTrackingState? state, this.order}){
+ TrackingScreen({super.key, OrderTrackingState? state, this.order, this.isRRTOrder = false, this.rrtOrder}){
if(state == null){
- switch (order?.statusId) {
+ switch (order?.statusId ?? rrtOrder?.statusId) {
case 1: //pending
case 2: //processing
this.state = OrderTrackingState.waitingForCall;
@@ -70,7 +73,7 @@ class TrackingScreen extends StatelessWidget {
animationSection(),
Column(
spacing: 16.h,
- children: [orderStatus(context), orderTrackingId(), contactSection()],
+ children: [orderStatus(context), orderTrackingId(context), contactSection()],
).paddingAll(16.h),
],
))),
@@ -328,11 +331,12 @@ class TrackingScreen extends StatelessWidget {
}
}
- orderTrackingId() {
+ orderTrackingId(BuildContext context) {
if(state == OrderTrackingState.failed){
return SizedBox.shrink();
}
return Container(
+ width: MediaQuery.sizeOf(context).width-32.h,
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
@@ -344,20 +348,10 @@ class TrackingScreen extends StatelessWidget {
spacing: 8.h,
children: [
- Visibility(visible:order != null ,child: "Req ID: ${order?.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600)),
- Row(
- spacing: 8.h,
- children: [
- Flexible(child:
- chip(order?.pickupLocation??"", AppAssets.location_pickup, AppColors.blackBgColor),
-
- ),
- Flexible(child:
- chip(order?.dropOffLocation??"", AppAssets.hospital, AppColors.blackBgColor),
+ Visibility(visible:(order != null || rrtOrder != null) ,child: "Req ID: ${order?.iD?? rrtOrder?.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600)),
+ if(order != null) ambulanceOrderData()
+ // else rrtOrderData()
- )
- ],
- ),
],
),
);
@@ -456,6 +450,44 @@ class TrackingScreen extends StatelessWidget {
openCancelOrderBottomSheet(BuildContext context){
- context.read().cancelOrder(order, shouldPop: true);
+ if(isRRTOrder){
+ context.read().cancelRRTOrder(rrtOrder?.iD??-1, shouldPop: true);
+ return;
+ }else {
+ context.read().cancelOrder(order, shouldPop: true);
+ return;
+ }
+ }
+
+ Widget ambulanceOrderData() {
+ return Row(
+ spacing: 8.h,
+ children: [
+ Flexible(child:
+ chip(order?.pickupLocation??"", AppAssets.location_pickup, AppColors.blackBgColor),
+
+ ),
+ Flexible(child:
+ chip(order?.dropOffLocation??"", AppAssets.hospital, AppColors.blackBgColor),
+
+ )
+ ],
+ );
}
+
+ // Widget rrtOrderData() {
+ // return Row(
+ // spacing: 8.h,
+ // children: [
+ // Flexible(child:
+ // chip(rrtOrder?.pickupLocation??"", AppAssets.location_pickup, AppColors.blackBgColor),
+ //
+ // ),
+ // // Flexible(child:
+ // // chip(rrtOrder?.??"", AppAssets.hospital, AppColors.blackBgColor),
+ // //
+ // // )
+ // ],
+ // );
+ // }
}
diff --git a/lib/presentation/emergency_services/emergency_services_page.dart b/lib/presentation/emergency_services/emergency_services_page.dart
index 3cbce23..00cd13d 100644
--- a/lib/presentation/emergency_services/emergency_services_page.dart
+++ b/lib/presentation/emergency_services/emergency_services_page.dart
@@ -8,6 +8,7 @@ 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/emergency_services/emergency_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/OrderDisplay.dart';
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';
@@ -39,6 +40,7 @@ class EmergencyServicesPage extends StatelessWidget {
return CollapsingListView(
title: LocaleKeys.emergencyServices.tr(),
requests: () {
+ emergencyServicesViewModel.changeOrderDisplayItems(OrderDislpay.ALL);
Navigator.of(context).push(CustomPageRoute(page: ErHistoryListing(), direction: AxisDirection.up));
},
child: Padding(
@@ -209,21 +211,6 @@ class EmergencyServicesPage extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- "".toText14(),
- Utils.buildSvgWithAssets(
- icon: AppAssets.cancel_circle_icon,
- iconColor: AppColors.whiteColor,
- width: 24.h,
- height: 24.h,
- fit: BoxFit.contain,
- ).onPress(() {
- Navigator.of(context).pop();
- }),
- ],
- ),
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),
@@ -236,10 +223,23 @@ class EmergencyServicesPage extends StatelessWidget {
Navigator.of(context).pop();
LoaderBottomSheet.showLoader();
+ emergencyServicesViewModel.clearRRTData();
await emergencyServicesViewModel.getRRTProcedures(onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
- title: "Rapid Response Team (RRT)".needTranslation,
+ padding: EdgeInsets.only(top: 24.h),
+ titleWidget: Transform.flip(
+ flipX: emergencyServicesViewModel.isArabic,
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.arrow_back,
+ iconColor: Color(0xff2B353E),
+ fit: BoxFit.contain,
+ ),
+ ).onPress(() {
+
+ Navigator.pop(context);
+ }),
+ // title: "Rapid Response Team (RRT)".needTranslation,
context,
child: RrtRequestTypeSelect(),
isFullScreen: false,
@@ -370,7 +370,7 @@ class EmergencyServicesPage extends StatelessWidget {
.flushPickupInformation();
},
titleWidget: Transform.flip(
- flipX: emergencyServicesViewModel.isArabic ? true : false,
+ flipX: emergencyServicesViewModel.isArabic,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
iconColor: Color(0xff2B353E),
diff --git a/lib/presentation/emergency_services/history/er_history_listing.dart b/lib/presentation/emergency_services/history/er_history_listing.dart
index e5dd1e4..903e084 100644
--- a/lib/presentation/emergency_services/history/er_history_listing.dart
+++ b/lib/presentation/emergency_services/history/er_history_listing.dart
@@ -1,13 +1,20 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart' show AppAssets;
import 'package:hmg_patient_app_new/core/app_export.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/emergency_services/emergency_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/OrderDisplay.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
-import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/ambulance_history_item.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/ambulance_history_item.dart' show AmbulanceHistoryItem;
+import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/rrt_item.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/chip/app_custom_chip_widget.dart';
import 'package:provider/provider.dart';
class ErHistoryListing extends StatelessWidget {
@@ -16,30 +23,52 @@ class ErHistoryListing extends StatelessWidget {
return Scaffold(
body: Column(
children: [
+
Expanded(
child: CollapsingListView(
title: "History Log".needTranslation,
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Column(
- children: [Visibility(
- visible: context
- .read()
- .orders
- ?.isNotEmpty == true,
- child: ListView.builder(
- shrinkWrap: true,
- physics: NeverScrollableScrollPhysics(),
- itemCount: context
- .read()
- .orders
- ?.length ?? 0,
- itemBuilder: (_, index) =>
- Consumer( builder: (_, vm, __)=>
- AmbulanceHistoryItem(order: vm.orders![index]),
- )
+ children: [
+
+ Selector(
+ selector: (context, vm) => (vm.orderDisplayList, vm.historyLoading),
+ builder: (context, data, _) {
+
+ return Column(
+ children: [
+ orderChips(context, data.$2),
+
+ Visibility(
+ visible:data.$1.isNotEmpty == true,
+ child: ListView.builder(
+ shrinkWrap: true,
+ physics: NeverScrollableScrollPhysics(),
+ itemCount:data?.$1.length ?? 0,
+ itemBuilder: (_, index) {
+ var order = data.$1[index];
+ if (order is AmbulanceRequestOrdersModel) {
+ return AmbulanceHistoryItem(order: order).toShimmer2(isShow: data.$2);
+ } else {
+ return RRTItem(order: (order as GetCMCAllOrdersResponseModel)).toShimmer2(isShow: data.$2);
+ }
+ }),
+ ),
+ Visibility(
+ visible: data.$1
+ ?.isEmpty == true, child: Center(
+ child: Utils.getNoDataWidget(context,
+ noDataText: "You don't have any history"
+ .needTranslation),
+ )),
+ ],
+ );
+ }
),
- ),]
+
+
+ ]
).paddingAll(16.h)
))
@@ -47,16 +76,84 @@ class ErHistoryListing extends StatelessWidget {
),
- Visibility(
- visible: context
- .read()
- .orders
- ?.isEmpty == true,
- child: Utils.getNoDataWidget(context,
- noDataText: "You don't have any history"
- .needTranslation)),
+
],
),
);
}
+
+ orderChips(BuildContext context, bool isLoading) {
+
+ if (context
+ .read()
+ .displayList
+ ?.isEmpty == true) {
+ return SizedBox.shrink();
+ }
+ return
+ Selector(
+ selector: (context, vm) => vm.currentlyDisplayedOrder,
+ builder: (context, value, __) {
+ return Row(
+ spacing: 8.h,
+ children: [
+ if(context
+ .read()
+ .orderDisplayList
+ ?.isNotEmpty == true)
+ AppCustomChipWidget(
+ labelText: "All Facilities".needTranslation,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: value == OrderDislpay.ALL ? AppColors.errorColor : AppColors.chipBorderColorOpacity20,
+ width: 1,
+ ),
+ borderRadius: BorderRadius.circular(10)),
+ backgroundColor: value == OrderDislpay.ALL ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
+ textColor: value == OrderDislpay.ALL ? AppColors.errorColor : AppColors.blackColor,
+ ).onPress(() {
+ context.read().changeOrderDisplayItems(OrderDislpay.ALL);
+ }).toShimmer2(isShow: isLoading),
+ if(context
+ .read()
+ .ambulanceOrders
+ ?.isNotEmpty == true)
+ AppCustomChipWidget(
+ labelText: "Ambulance".needTranslation,
+ icon: AppAssets.ambulance,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: value == OrderDislpay.AMBULANCE ? AppColors.errorColor : AppColors.chipBorderColorOpacity20,
+ width: 1,
+ ),
+ borderRadius: BorderRadius.circular(10)),
+ backgroundColor: value == OrderDislpay.AMBULANCE ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
+ textColor: value == OrderDislpay.AMBULANCE ? AppColors.errorColor : AppColors.blackColor,
+ ).toShimmer2(isShow: isLoading).onPress(() {
+ context.read().changeOrderDisplayItems(OrderDislpay.AMBULANCE);
+ }),
+ if(context
+ .read()
+ .ordersRRT
+ ?.completedOrders
+ .isNotEmpty == true)
+ AppCustomChipWidget(
+ labelText: "Rapid Response Team".needTranslation,
+ icon: AppAssets.ic_rrt_vehicle,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: value == OrderDislpay.RRT ? AppColors.errorColor : AppColors.chipBorderColorOpacity20,
+ width: 1,
+ ),
+ borderRadius: BorderRadius.circular(10)),
+ backgroundColor: value == OrderDislpay.RRT ? AppColors.secondaryLightRedColor : AppColors.whiteColor,
+ textColor: value == OrderDislpay.RRT ? AppColors.errorColor : AppColors.blackColor,
+ ).toShimmer2(isShow: isLoading).onPress(() {
+ context.read().changeOrderDisplayItems(OrderDislpay.RRT);
+ }),
+ ],
+ );
+ });
+
+ }
}
diff --git a/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart b/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart
index 5f4c8b2..42bf257 100644
--- a/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart
+++ b/lib/presentation/emergency_services/history/widget/ambulance_history_item.dart
@@ -71,7 +71,7 @@ class AmbulanceHistoryItem extends StatelessWidget {
labelText: title,
icon: iconString,
iconColor: iconColor,
- iconSize: 14.h,
+ iconSize: 12.h,
);
}
diff --git a/lib/presentation/emergency_services/history/widget/rrt_item.dart b/lib/presentation/emergency_services/history/widget/rrt_item.dart
new file mode 100644
index 0000000..84108fb
--- /dev/null
+++ b/lib/presentation/emergency_services/history/widget/rrt_item.dart
@@ -0,0 +1,76 @@
+import 'package:flutter/material.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/core/utils/date_util.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/emergency_services/emergency_services_view_model.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart';
+import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
+import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/RequestStatus.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:provider/provider.dart';
+
+import '../../../../core/utils/utils.dart';
+
+
+class RRTItem extends StatelessWidget {
+ final GetCMCAllOrdersResponseModel order;
+
+ const RRTItem({super.key, required this.order});
+
+ @override
+ Widget build(BuildContext context) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: Colors.white,
+ hasShadow: true,
+ customBorder: BorderRadius.all(
+ Radius.circular(20.h),
+ ),
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 8.h,
+ children: [
+ RequestStatus(status: order.statusId ?? 0),
+ "Req ID: ${order.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600),
+ Row(
+ spacing: 4.w,
+ children: [
+ chip( Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor),
+ chip("Rapid Response Team(RRT)".needTranslation, AppAssets.ic_rrt_vehicle, AppColors.blackBgColor),
+ ],
+ ),
+
+ if (order.statusId == 1 || order.statusId == 2)
+ CustomButton(
+ text: "Cancel Request".needTranslation,
+ onPressed: () async {
+ openCancelOrderBottomSheet(context);
+ },
+ backgroundColor: AppColors.primaryRedColor,
+ borderColor: AppColors.primaryRedColor,
+ textColor: Colors.white,
+ icon: AppAssets.cancel,
+ ),
+ ],
+ ).paddingAll(16.h),
+ ).paddingOnly(bottom: 16.h);
+ }
+
+ chip(String title, String iconString, Color iconColor) {
+ return AppCustomChipWidget(
+ labelText: title,
+ icon: iconString,
+ iconColor: iconColor,
+ iconSize: 12.h,
+ );
+ }
+
+ openCancelOrderBottomSheet(BuildContext context) {
+ context.read().cancelRRTOrder(order.iD);
+ }
+}
diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart
index 234fad1..f54f442 100644
--- a/lib/presentation/home/widgets/small_service_card.dart
+++ b/lib/presentation/home/widgets/small_service_card.dart
@@ -110,6 +110,7 @@ class SmallServiceCard extends StatelessWidget {
case "emergency":
context.read().flushData();
context.read().getTransportationOrders(showLoader: false,);
+ context.read().getRRTOrders(showLoader: false,);
Navigator.of(context).push(
CustomPageRoute(
page: EmergencyServicesPage(),
diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart
index 318751f..6ad4d31 100644
--- a/lib/widgets/common_bottom_sheet.dart
+++ b/lib/widgets/common_bottom_sheet.dart
@@ -115,6 +115,7 @@ void showCommonBottomSheetWithoutHeight(
Widget? titleWidget,
bool useSafeArea = false,
bool hasBottomPadding = true,
+ EdgeInsets? padding,
Color backgroundColor = AppColors.bottomSheetBgColor,
VoidCallback? onCloseClicked
}) {
@@ -146,7 +147,7 @@ void showCommonBottomSheetWithoutHeight(
physics: ClampingScrollPhysics(),
child: isCloseButtonVisible
? Container(
- padding: EdgeInsets.only(
+ padding: padding ?? const EdgeInsets.only(
left: 24,
top: 24,
right: 24,
@@ -160,23 +161,26 @@ void showCommonBottomSheetWithoutHeight(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- titleWidget ??
- Expanded(
- child: title.toText20(weight: FontWeight.w600),
- ),
- if (isCloseButtonVisible) ...[
- Utils.buildSvgWithAssets(
- icon: AppAssets.close_bottom_sheet_icon,
- iconColor: Color(0xff2B353E),
- ).onPress(() {
- onCloseClicked?.call();
- Navigator.of(context).pop();
- }),],
- ],
+ Padding(
+ padding: padding != null? EdgeInsets.symmetric(horizontal: 24.w): EdgeInsets.zero,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ titleWidget ??
+ Expanded(
+ child: title.toText20(weight: FontWeight.w600),
+ ),
+ if (isCloseButtonVisible) ...[
+ Utils.buildSvgWithAssets(
+ icon: AppAssets.close_bottom_sheet_icon,
+ iconColor: Color(0xff2B353E),
+ ).onPress(() {
+ onCloseClicked?.call();
+ Navigator.of(context).pop();
+ }),],
+ ],
+ ),
),
SizedBox(height: 16.h),
child,