diff --git a/android/app/build.gradle b/android/app/build.gradle
index c61fdff..2d432ec 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -148,8 +148,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = 23
targetSdk = flutter.targetSdkVersion
- versionCode = 98
- versionName = '1.5.98'
+ versionCode = 99
+ versionName = '1.5.99'
multiDexEnabled =true
// manifestPlaceholders can be specified here if needed
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 44be063..3513e88 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -41,11 +41,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 70
+ 71
CFBundleSignature
????
CFBundleVersion
- 4.3.70
+ 4.3.71
NSHumanReadableCopyright
FirebaseAppDelegateProxyEnabled
diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart
index 1a79e5b..f786103 100644
--- a/lib/controller/home/map_passenger_controller.dart
+++ b/lib/controller/home/map_passenger_controller.dart
@@ -146,6 +146,7 @@ class MapPassengerController extends GetxController {
double naturePrice = 0;
bool heightMenuBool = false;
String statusRide = 'wait';
+ String statusRideVip = 'wait';
bool statusRideFromStart = false;
bool isPickerShown = false;
bool isPointsPageForRider = false;
@@ -747,9 +748,91 @@ class MapPassengerController extends GetxController {
// update();
}
+ int progressTimerRideBeginVip = 0;
+ int elapsedTimeInSeconds = 0; // Timer starts from 0
+ String stringElapsedTimeRideBegin = '0:00';
+ String stringElapsedTimeRideBeginVip = '0:00';
+ bool rideInProgress = true; // To control when to stop the timer
+
+ void rideIsBeginPassengerTimerVIP() async {
+ rideInProgress = true; // Start the ride timer
+ bool sendSOS = false;
+ while (rideInProgress) {
+ await Future.delayed(const Duration(seconds: 1));
+
+ // Increment elapsed time
+ elapsedTimeInSeconds++;
+
+ // Update the time display
+ int minutes = (elapsedTimeInSeconds / 60).floor();
+ int seconds = elapsedTimeInSeconds % 60;
+ stringElapsedTimeRideBeginVip =
+ '$minutes:${seconds.toString().padLeft(2, '0')}';
+
+ // Check for speed and SOS conditions
+ if (speed > 100 && !sendSOS) {
+ Get.defaultDialog(
+ barrierDismissible: false,
+ title: "Warning: Speeding detected!".tr,
+ titleStyle: AppStyle.title,
+ content: Text(
+ "We noticed the speed is exceeding 100 km/h. Please slow down for your safety. If you feel unsafe, you can share your trip details with a contact or call the police using the red SOS button."
+ .tr,
+ style: AppStyle.title,
+ ),
+ confirm: MyElevatedButton(
+ title: "Share Trip Details".tr,
+ onPressed: () {
+ Get.back();
+ // Implement sharing trip details logic here
+ String message = "**Emergency SOS from Passenger:**\n";
+
+ // Get trip details from GetX or relevant provider
+ String origin = passengerLocation.toString();
+ String destination = myDestination.toString();
+ String driverName = firstName;
+ String driverCarPlate = licensePlate;
+
+ // Add trip details to the message
+ message += "* ${'Origin'.tr}: $origin\n";
+ message += "* ${'Destination'.tr}: $destination\n";
+ message += "* ${'Driver Name'.tr}: $driverName\n";
+ message += "* ${'Driver Car Plate'.tr}: $driverCarPlate\n\n";
+ message += "* ${'Driver Phone'.tr}: $driverPhone\n\n";
+
+ // Add current location
+ message +=
+ "${'Current Location'.tr}:https://www.google.com/maps/place/${passengerLocation.latitude},${passengerLocation.longitude} \n";
+
+ // Append a call to action
+ message += "Please help! Contact me as soon as possible.".tr;
+
+ // Launch WhatsApp communication
+ launchCommunication(
+ 'whatsapp', box.read(BoxName.sosPhonePassenger), message);
+ sendSOS = true;
+ },
+ kolor: AppColor.redColor,
+ ),
+ cancel: MyElevatedButton(
+ title: "Cancel".tr,
+ onPressed: () {
+ Get.back();
+ },
+ kolor: AppColor.greenColor,
+ ),
+ );
+ }
+
+ // Update the UI
+ update();
+ }
+ }
+
void tripFinishedFromDriver() async {
isRideFinished = true;
rideTimerBegin = false;
+ statusRideVip = 'Finished';
box.write(BoxName.arrivalTime, '');
remainingTimeTimerRideBegin = 0;
box.write(BoxName.passengerWalletTotal, '0');
@@ -795,6 +878,22 @@ class MapPassengerController extends GetxController {
}
}
+ begiVIPTripFromPassenger() async {
+ timeToPassengerFromDriverAfterApplied = 0;
+ remainingTime = 0;
+ isBottomSheetShown = false;
+ remainingTimeToPassengerFromDriverAfterApplied = 0;
+ remainingTimeDriverWaitPassenger5Minute = 0;
+ rideTimerBegin = true;
+ statusRideVip = 'Begin';
+ isDriverInPassengerWay = false;
+ isDriverArrivePassenger = false;
+ update();
+ // isCancelRidePageShown = true;
+ rideIsBeginPassengerTimerVIP();
+ runWhenRideIsBegin();
+ }
+
Map rideStatusFromStartApp = {};
getRideStatusFromStartApp() async {
try {
@@ -1053,6 +1152,7 @@ class MapPassengerController extends GetxController {
late String driverRate = '';
late String firstName = '';
late String carColor = '';
+ late String colorHex = '';
late String carYear = '';
late String model = '';
late String make = '';
@@ -1099,6 +1199,8 @@ class MapPassengerController extends GetxController {
.toString();
carColor =
dataCarsLocationByPassenger['data'][carsOrder]['color'].toString();
+ colorHex = dataCarsLocationByPassenger['data'][carsOrder]['color_hex'] ??
+ '#A52A2A';
driverRate = dataCarsLocationByPassenger['data'][carsOrder]
['ratingDriver']
.toString();
@@ -1971,7 +2073,10 @@ class MapPassengerController extends GetxController {
return jsonDecode(response)['data'];
}
- late String driverCarModel, driverCarMake, driverLicensePlate, driverName;
+ late String driverCarModel,
+ driverCarMake,
+ driverLicensePlate,
+ driverName = '';
getUpdatedRideForDriverApply(String rideId) async {
// if (isDriversTokensSend) {
final res = await CRUD().get(
@@ -4597,12 +4702,13 @@ class MapPassengerController extends GetxController {
}
Future mishwariOption() async {
- // isBottomSheetShown = false;
+ isLoading = true;
update();
// add dialoug for select driver and car
await selectDriverAndCarForMishwariTrip();
Future.delayed(Duration.zero);
-
+ isLoading = false;
+ update();
Get.to(() => CupertinoDriverListWidget());
// changeCashConfirmPageShown();
@@ -4651,13 +4757,62 @@ class MapPassengerController extends GetxController {
if (response != 'failure') {
// Trip saved successfully
// Get.snackbar('Success'.tr, 'Trip booked successfully'.tr);
- var id = response['message'].toString();
+ var id = response['message']['id'].toString();
+ await CRUD().post(
+ link: '${AppLink.seferCairoServer}/ride/rides/add.php',
+ payload: {
+ "start_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime":
+ DateTime.now().add(const Duration(hours: 2)).toString(),
+ "price": '50',
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": driver['driver_id'].toString(),
+ "status": "waiting",
+ 'carType': 'vip',
+ "price_for_driver": '50',
+ "price_for_passenger": '50',
+ "distance": '20',
+ "paymentMethod": 'cash',
+ }).then((value) {
+ if (value is String) {
+ final parsedValue = jsonDecode(value);
+ rideId = parsedValue['message'];
+ } else if (value is Map) {
+ rideId = value['message'];
+ } else {
+ Log.print('Unexpected response type: ${value.runtimeType}');
+ }
+ });
if (AppLink.endPoint != AppLink.seferCairoServer) {
await CRUD().post(
link: "${AppLink.endPoint}/ride/mishwari/add.php",
payload: tripData);
+ CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
+ "start_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "end_location":
+ '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "endtime": DateTime.now().add(const Duration(hours: 2)).toString(),
+ "price": '50',
+ "passenger_id": box.read(BoxName.passengerID).toString(),
+ "driver_id": driver['driver_id'].toString(),
+ "status": "waiting",
+ 'carType': 'vip',
+ "price_for_driver": '50',
+ "price_for_passenger": '50',
+ "distance": '20',
+ "paymentMethod": 'cash',
+ });
}
- driverIdVip = driver['driver_id'];
+ driverIdVip = driver['driver_id'].toString();
+ driverId = driver['driver_id'].toString();
DateTime timeSelected = DateTime.parse(tripDateTime.toIso8601String());
Get.find().scheduleNotificationsForTimeSelected(
@@ -4667,35 +4822,41 @@ class MapPassengerController extends GetxController {
timeSelected);
// Optionally, set up local notification or send a push notification
- // await FirebaseMessagesController().sendNotificationToDriverMAP(
- // 'OrderVIP',
- // rideId.toString(),
- // driver['token'].toString(),
- // [
- // id,
- // driver['id'],
- // passengerLocation.latitude.toString(),
- // passengerLocation.longitude.toString(),
- // box.read(BoxName.name).toString(),
- // box.read(BoxName.passengerID).toString(),
- // box.read(BoxName.phone).toString(),
- // box.read(BoxName.email).toString(),
- // box.read(BoxName.passengerPhotoUrl).toString(),
- // box.read(BoxName.tokenFCM).toString(),
- // driver['token'].toString(),
- // ],
- // 'order.wav');
+ await FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'OrderVIP',
+ rideId.toString(),
+ driver['token'].toString(),
+ [
+ id,
+ driver['id'],
+ passengerLocation.latitude.toString(),
+ passengerLocation.longitude.toString(),
+ box.read(BoxName.name).toString(),
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.phone).toString(),
+ box.read(BoxName.email).toString(),
+ box.read(BoxName.passengerPhotoUrl).toString(),
+ box.read(BoxName.tokenFCM).toString(),
+ driver['token'].toString(),
+ ],
+ 'order.wav');
if (response['message'] == "Trip updated successfully") {
mySnackbarSuccess("Trip updated successfully".tr);
- // FirebaseMessagesController().sendNotificationToDriverMAP(
- // 'Order VIP Canceld'.tr,
- // 'Passenger cancel order'.tr,
- // token,
- // [],
- // 'cancel.wav',
- // );
+ Log.print(
+ 'previous_driver_token: ${response['previous_driver_token']}');
+
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'Order VIP Canceld'.tr,
+ 'Passenger cancel order'.tr,
+ response['previous_driver_token'].toString(),
+ [],
+ 'cancel.wav',
+ );
}
- Get.to(() => const VipWaittingPage());
+ // data = [];
+ isBottomSheetShown = false;
+ update();
+ Get.to(() => VipWaittingPage());
} else {
throw Exception('Failed to save trip');
}
@@ -4723,6 +4884,16 @@ class MapPassengerController extends GetxController {
}
}
+ sendToDriverAgain(String token) {
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'Order VIP Canceld'.tr,
+ 'Passenger cancel order'.tr,
+ token,
+ [],
+ 'cancel.wav',
+ );
+ }
+
initilizeGetStorage() async {
if (box.read(BoxName.addWork) == null) {
box.write(BoxName.addWork, 'addWork');
diff --git a/lib/controller/home/vip_waitting_page.dart b/lib/controller/home/vip_waitting_page.dart
index 3f5a096..9cc1287 100644
--- a/lib/controller/home/vip_waitting_page.dart
+++ b/lib/controller/home/vip_waitting_page.dart
@@ -1,190 +1,323 @@
+import 'dart:async';
import 'dart:convert';
+import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
+import 'package:SEFER/constant/links.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/map_passenger_controller.dart';
+import 'package:SEFER/main.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
+import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
+import 'package:SEFER/views/widgets/mysnakbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
-import '../../constant/links.dart';
import '../functions/crud.dart';
+class VipOrderController extends GetxController {
+ RxBool isLoading = false.obs;
+ final arguments = Get.arguments;
+ RxList tripData = [].obs;
+ RxBool isButtonVisible = false.obs;
+ RxInt countdown = 60.obs;
+ Timer? _countdownTimer;
+
+ @override
+ void onInit() {
+ super.onInit();
+ fetchOrder();
+ startCountdown();
+ }
+
+ @override
+ void onClose() {
+ _countdownTimer?.cancel();
+ super.onClose();
+ }
+
+ Future fetchOrder() async {
+ try {
+ isLoading.value = true;
+ var mapPassengerController = Get.find();
+
+ var res = await CRUD().get(
+ link: AppLink.getMishwari,
+ payload: {
+ // 'driverId': mapPassengerController.driverIdVip.toString(),
+ 'driverId': box.read(BoxName.passengerID).toString(),
+ },
+ );
+
+ if (res != 'failure') {
+ var decodedResponse = jsonDecode(res);
+ if (decodedResponse['message'] is List) {
+ tripData.value = decodedResponse['message'];
+ } else {
+ tripData.clear(); // Ensure empty list if no data
+ mySnackeBarError('No trip data found');
+ }
+ } else {
+ tripData.clear();
+ mySnackeBarError('Failed to fetch trip data');
+ }
+ } catch (e) {
+ tripData.clear();
+ mySnackeBarError('An error occurred: $e');
+ } finally {
+ isLoading.value = false;
+ }
+ }
+
+ void startCountdown() {
+ _countdownTimer?.cancel(); // Cancel any existing timer
+ countdown.value = 60;
+
+ _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
+ if (countdown.value > 0) {
+ countdown.value--;
+ } else {
+ timer.cancel();
+ isButtonVisible.value = true;
+ }
+ });
+ }
+
+ void sendToDriverAgain() {
+ // Reset states
+ isButtonVisible.value = false;
+ fetchOrder(); // Refresh order
+ startCountdown(); // Restart countdown
+ }
+}
+
class VipWaittingPage extends StatelessWidget {
- const VipWaittingPage({super.key});
+ VipWaittingPage({super.key});
+ final VipOrderController vipOrderController = Get.put(VipOrderController());
@override
Widget build(BuildContext context) {
- Get.put(VipOrderController());
- return Scaffold(
- appBar: AppBar(
- title: Text("Waiting VIP".tr),
- ),
- body: GetBuilder(builder: (vipOrderController) {
- var data = vipOrderController.tripData[0];
-
- // Function to get the localized status string
- String getLocalizedStatus(String status) {
- switch (status) {
- case 'pending':
- return 'pending'.tr;
- case 'accepted':
- return 'accepted'.tr;
- case 'rejected':
- return 'rejected'.tr;
- default:
- return 'unknown'.tr; // Fallback for unexpected statuses
+ return MyScafolld(
+ title: "Waiting VIP".tr,
+ body: [
+ Obx(() {
+ // Loading state
+ if (vipOrderController.isLoading.value) {
+ return const Center(child: MyCircularProgressIndicator());
}
- }
-// Function to get the appropriate status color
- Color getStatusColor(String status) {
- switch (status) {
- case 'pending':
- return Colors.yellow;
- case 'accepted':
- return Colors.green;
- case 'rejected':
- return Colors.red;
- default:
- return Colors.grey; // Default color for unknown statuses
+ // No data state
+ if (vipOrderController.tripData.isEmpty) {
+ return Center(
+ child: Text(
+ 'No trip data available'.tr,
+ style: AppStyle.title,
+ ),
+ );
}
- }
- return vipOrderController.isLoading
- ? const MyCircularProgressIndicator()
- : Card(
- elevation: 4,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(12),
- ),
- margin: const EdgeInsets.all(16),
- child: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
+ // Data available
+ var data = vipOrderController.tripData[0];
+
+ // Function to get the localized status string
+ String getLocalizedStatus(String status) {
+ switch (status) {
+ case 'pending':
+ return 'pending'.tr;
+ case 'accepted':
+ return 'accepted'.tr;
+ case 'begin':
+ return 'begin'.tr;
+ case 'rejected':
+ return 'rejected'.tr;
+ case 'cancelled':
+ return 'cancelled'.tr;
+ default:
+ return 'unknown'.tr;
+ }
+ }
+
+ // Function to get the appropriate status color
+ Color getStatusColor(String status) {
+ switch (status) {
+ case 'pending':
+ return Colors.yellow;
+ case 'accepted':
+ return Colors.green;
+ case 'begin':
+ return Colors.green;
+ case 'rejected':
+ return Colors.red;
+ case 'cancelled':
+ return Colors.red;
+ default:
+ return Colors.grey;
+ }
+ }
+
+ return Card(
+ elevation: 4,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(12),
+ ),
+ margin: const EdgeInsets.all(16),
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "${'Driver Name:'.tr} ${data['name']}",
+ style: AppStyle.title,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- Text(
- "${'Driver Name:'.tr} ${data['name']}",
- style: AppStyle.title,
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- "${'Car Plate:'.tr} ${data['car_plate']}",
- style: AppStyle.title,
- ),
- Text(
- "${'Car Make:'.tr} ${data['make']}",
- style: AppStyle.title,
- ),
- Text(
- "${'Car Model:'.tr} ${data['model']}",
- style: AppStyle.title,
- ),
- Text(
- "${"Car Color:".tr} ${data['color']}",
- style: AppStyle.title,
- ),
- ],
+ Text(
+ "${'Car Plate:'.tr} ${data['car_plate']}",
+ style: AppStyle.title,
+ ),
+ Text(
+ "${'Car Make:'.tr} ${data['make']}",
+ style: AppStyle.title,
+ ),
+ Text(
+ "${'Car Model:'.tr} ${data['model']}",
+ style: AppStyle.title,
+ ),
+ Text(
+ "${"Car Color:".tr} ${data['color']}",
+ style: AppStyle.title,
),
- SizedBox(
- width: 100,
- height: 100,
- child: Icon(Fontisto.car,
- size: 80,
- color: Color(int.parse(data['color_hex']
- .replaceFirst('#', '0xff'))))),
],
),
- // Text(
- // "${'Driver Phone:'.tr} ${data['phone']}",
- // style: AppStyle.title,
- // ),
- const SizedBox(height: 12),
- const Divider(),
- const SizedBox(height: 12),
-
- Container(
- color: getStatusColor(
- data['status']), // Correctly assigns a Color
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Text(
- "${'Trip Status:'.tr} ${getLocalizedStatus(data['status'])}", // Uses the String function
- style: const TextStyle(
- fontSize: 16,
+ SizedBox(
+ width: 100,
+ height: 100,
+ child: Icon(
+ Fontisto.car,
+ size: 80,
+ color: Color(
+ int.parse(
+ data['color_hex'].replaceFirst('#', '0xff'),
),
),
),
),
- Text(
- "${'Scheduled Time:'.tr} ${DateFormat('yyyy-MM-dd hh:mm a').format(DateTime.parse(data['timeSelected']))}",
- style: const TextStyle(fontSize: 16),
- ),
- const SizedBox(height: 12),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- MyElevatedButton(
- title: "Cancel Trip".tr,
- kolor: AppColor.redColor,
- onPressed: () {
- Get.find().cancelVip(
- data['token'].toString(),
- data['id'].toString(),
- );
- },
- ),
- // MyElevatedButton(
- // title: "Accept Trip".tr,
- // kolor: AppColor.greenColor,
- // onPressed: () {
- // // Add your cancel trip logic here
- // },
- // ),
- ],
- ),
],
),
- ),
- );
- }),
+ const SizedBox(height: 12),
+ const Divider(),
+ const SizedBox(height: 12),
+ Container(
+ color: getStatusColor(data['status']),
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Text(
+ "${'Trip Status:'.tr} ${getLocalizedStatus(data['status'])}",
+ style: const TextStyle(fontSize: 16),
+ ),
+ ),
+ ),
+ Text(
+ "${'Scheduled Time:'.tr} ${DateFormat('yyyy-MM-dd hh:mm a').format(DateTime.parse(data['timeSelected']))}",
+ style: const TextStyle(fontSize: 16),
+ ),
+ const SizedBox(height: 12),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ data['status'].toString() != 'begin'
+ ? MyElevatedButton(
+ title: "Cancel Trip".tr,
+ kolor: AppColor.redColor,
+ onPressed: () {
+ Get.find().cancelVip(
+ data['token'].toString(),
+ data['id'].toString(),
+ );
+ },
+ )
+ : const SizedBox(),
+ Obx(() {
+ // If countdown is still running, show countdown
+ if (!vipOrderController.isButtonVisible.value) {
+ return Column(
+ children: [
+ CircularProgressIndicator(
+ value: 1 -
+ (vipOrderController.countdown.value / 60),
+ strokeWidth: 6.0,
+ color: AppColor.greenColor,
+ backgroundColor: AppColor.accentColor,
+ ),
+ const SizedBox(height: 10),
+ Text(
+ "${vipOrderController.countdown.value}s ${'remaining'.tr}",
+ style: const TextStyle(fontSize: 16),
+ ),
+ ],
+ );
+ }
+
+ // Once countdown is complete, show "Send to Driver Again" button
+ return MyElevatedButton(
+ title: "Send to Driver Again".tr,
+ kolor: AppColor.greenColor,
+ onPressed: () {
+ Get.find()
+ .sendToDriverAgain(data['token']);
+ vipOrderController.fetchOrder();
+ },
+ );
+ }),
+ ],
+ ),
+ const SizedBox(
+ height: 30,
+ ),
+ data['status'].toString() == 'begin'
+ ? MyElevatedButton(
+ title: "Click here to begin your trip\n\nGood luck, "
+ .tr +
+ box.read(BoxName.name).toString(),
+ kolor: AppColor.greenColor,
+ onPressed: () {
+ final mapPassengerController =
+ Get.find();
+ mapPassengerController.make = data['make'];
+ mapPassengerController.licensePlate =
+ data['car_plate'];
+ mapPassengerController.model = data['model'];
+ mapPassengerController.driverId = data['driverId'];
+ mapPassengerController.carColor = data['color'];
+ mapPassengerController.driverRate = data['rating'];
+ mapPassengerController.colorHex = data['color_hex'];
+ mapPassengerController.driverPhone = data['phone'];
+ mapPassengerController.driverToken = data['token'];
+ mapPassengerController.driverName =
+ data['name'].toString().split(' ')[0];
+
+ Get.back();
+
+ mapPassengerController.begiVIPTripFromPassenger();
+ },
+ )
+ : const SizedBox()
+ ],
+ ),
+ ),
+ );
+ }),
+ ],
+ isleading: true,
);
}
}
-
-class VipOrderController extends GetxController {
- bool isLoading = false;
- final arguments = Get.arguments;
- late String body;
- List tripData = [];
-
- fetchOrder() async {
- isLoading = true;
- update();
- var res = await CRUD().get(link: AppLink.getMishwari, payload: {
- 'driverId': Get.find().driverIdVip.toString(),
- });
- isLoading = false;
- update();
- if (res != 'failure') {
- tripData = jsonDecode(res)['message'];
- update();
- }
- }
-
- @override
- void onInit() async {
- fetchOrder();
- super.onInit();
- }
-}
diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart
index 3d96535..ba8998e 100644
--- a/lib/controller/local/translations.dart
+++ b/lib/controller/local/translations.dart
@@ -4,8 +4,10 @@ class MyTranslation extends Translations {
@override
Map> get keys => {
"ar": {
+ "Send to Driver Again": "إرسال إلى السائق مرة أخرى",
"Driver Name:": "اسم السائق:",
- "Car Plate:": "رقم اللوحة:",
+ 'No trip data available': "لا توجد بيانات رحلة متاحة",
+ "Car Plate:": "رقم اللوحة:", "remaining": "متبقي",
"Order Cancelled": "تم إلغاء الطلب",
'You canceled VIP trip': "ألغيت الرحلة",
"Passenger cancelled order": "الراكب قام بإلغاء الطلب",
@@ -797,7 +799,7 @@ iOS [https://getapp.cc/app/6458734951]
'Selected Date and Time': "التاريخ والوقت المحددان",
"Lets check Car license ":
"دَعْنَا نَتَحَقَّق مِن رُخْصَة السَّيَّارَة ",
- 'Driver List': 'قائمة السائقين',
+ // 'Driver List': 'قائمة السائقين',
'Car': 'السيارة',
'Plate': 'لوحة السيارة',
'N/A': 'غير متوفر',
diff --git a/lib/views/home/map_page_passenger.dart b/lib/views/home/map_page_passenger.dart
index b30a0f2..3c251df 100644
--- a/lib/views/home/map_page_passenger.dart
+++ b/lib/views/home/map_page_passenger.dart
@@ -23,6 +23,7 @@ import 'map_widget.dart/payment_method.page.dart';
import 'map_widget.dart/points_page_for_rider.dart';
import 'map_widget.dart/ride_from_start_app.dart';
import 'map_widget.dart/searching_captain_window.dart';
+import 'map_widget.dart/vip_begin.dart';
class MapPagePassenger extends StatelessWidget {
const MapPagePassenger({super.key});
@@ -63,6 +64,7 @@ class MapPagePassenger extends StatelessWidget {
// const TimerToPassengerFromDriver(),
const PassengerRideLocationWidget(),
const RideBeginPassenger(),
+ const VipRideBeginPassenger(),
const RideFromStartApp(),
cancelRidePage(),
const MenuIconMapPageWidget(),
diff --git a/lib/views/home/map_widget.dart/left_main_menu_icons.dart b/lib/views/home/map_widget.dart/left_main_menu_icons.dart
index bb77e2d..ff26bb6 100644
--- a/lib/views/home/map_widget.dart/left_main_menu_icons.dart
+++ b/lib/views/home/map_widget.dart/left_main_menu_icons.dart
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
+import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../../../constant/colors.dart';
-import '../../../controller/functions/crud.dart';
import '../../../controller/functions/tts.dart';
import '../../../controller/home/map_passenger_controller.dart';
import '../../../controller/home/vip_waitting_page.dart';
@@ -91,14 +91,32 @@ GetBuilder leftMainMenuIcons() {
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () async {
- Get.to(() => const VipWaittingPage());
+ Get.to(() => VipWaittingPage());
},
icon: const Icon(
- Icons.voice_chat,
+ Octicons.watch, // Replace this with your desired VIP icon
size: 29,
),
),
),
+ // AnimatedContainer(
+ // duration: const Duration(microseconds: 200),
+ // width: controller.widthMapTypeAndTraffic,
+ // decoration: BoxDecoration(
+ // color: AppColor.secondaryColor,
+ // border: Border.all(),
+ // borderRadius: BorderRadius.circular(15)),
+ // child: IconButton(
+ // onPressed: () async {
+ // print(Get.put(MapPassengerController()).data);
+ // },
+ // icon: const Icon(
+ // Octicons
+ // .telescope, // Replace this with your desired VIP icon
+ // size: 29,
+ // ),
+ // ),
+ // ),
],
);
})),
diff --git a/lib/views/home/map_widget.dart/vip_begin.dart b/lib/views/home/map_widget.dart/vip_begin.dart
new file mode 100644
index 0000000..b124710
--- /dev/null
+++ b/lib/views/home/map_widget.dart/vip_begin.dart
@@ -0,0 +1,319 @@
+import 'package:SEFER/constant/links.dart';
+import 'package:SEFER/views/home/profile/complaint_page.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_font_icons/flutter_font_icons.dart';
+import 'package:get/get.dart';
+import 'package:SEFER/constant/box_name.dart';
+import 'package:SEFER/controller/profile/profile_controller.dart';
+import 'package:SEFER/main.dart';
+
+import '../../../constant/colors.dart';
+import '../../../constant/style.dart';
+import '../../../controller/functions/audio_record1.dart';
+import '../../../controller/functions/launch.dart';
+import '../../../controller/functions/toast.dart';
+import '../../../controller/home/map_passenger_controller.dart';
+
+class VipRideBeginPassenger extends StatelessWidget {
+ const VipRideBeginPassenger({
+ super.key,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ ProfileController profileController = Get.put(ProfileController());
+ AudioRecorderController audioController =
+ Get.put(AudioRecorderController());
+ // Get.put(MapPassengerController());
+ return GetBuilder(builder: (controller) {
+ if (controller.statusRideVip == 'Begin' ||
+ !controller.statusRideFromStart) {
+ return Positioned(
+ left: 10,
+ right: 10,
+ bottom: 10,
+ child: Container(
+ decoration: AppStyle.boxDecoration,
+ height: controller.statusRideVip == 'Begin' ? Get.height * .33 : 0,
+ // width: 100,
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ CircleAvatar(
+ radius: 30,
+ backgroundImage: NetworkImage(
+ '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg',
+ ),
+ onBackgroundImageError: (_, __) {
+ // Handle error here
+ },
+ backgroundColor: Colors.grey,
+ child: const Icon(
+ Icons.person, // Default icon or placeholder
+ size: 30,
+ color: Colors.white,
+ ), // Placeholder background color
+ ),
+ Column(
+ children: [
+ Container(
+ decoration: AppStyle.boxDecoration,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 6, vertical: 2),
+ child: Text(
+ controller.driverName,
+ style: AppStyle.title,
+ ),
+ ),
+ ),
+ const SizedBox(
+ height: 10,
+ ),
+ Container(
+ decoration: AppStyle.boxDecoration,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 6, vertical: 2),
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceAround,
+ children: [
+ Text(
+ controller.make,
+ style: AppStyle.title,
+ ),
+ const SizedBox(
+ width: 10,
+ ),
+ Text(
+ controller.model,
+ style: AppStyle.title,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ Column(
+ children: [
+ Container(
+ decoration: AppStyle.boxDecoration,
+ child: Padding(
+ padding: const EdgeInsets.all(3),
+ child: Text(
+ 'vip',
+ style: AppStyle.title,
+ ),
+ ),
+ ),
+ Text(
+ '${controller.driverRate} 📈',
+ style: AppStyle.title,
+ ),
+ ],
+ ),
+ ],
+ ),
+ // SizedBox(
+ // height: 5,
+ // ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ Container(
+ width: Get.width * .15,
+ decoration: AppStyle.boxDecoration,
+ child: IconButton(
+ onPressed: () => Get.to(
+ () => ComplaintPage(),
+ transition: Transition.downToUp,
+ ),
+ icon: const Icon(
+ Icons.note_add,
+ color: AppColor.redColor,
+ ),
+ tooltip: ' Add Note', // Optional tooltip for clarity
+ ),
+ ),
+ Container(
+ width: Get.width * .15,
+ decoration: AppStyle.boxDecoration,
+ child: audioController.isRecording == false
+ ? IconButton(
+ onPressed: () async {
+ await audioController.startRecording();
+ Toast.show(context, 'Start Record'.tr,
+ AppColor.greenColor);
+ },
+ icon: const Icon(
+ Icons.play_circle_fill_outlined,
+ color: AppColor.greenColor,
+ ),
+ tooltip:
+ ' Add Note', // Optional tooltip for clarity
+ )
+ : IconButton(
+ onPressed: () async {
+ await audioController.stopRecording();
+ Toast.show(context, 'Record saved'.tr,
+ AppColor.greenColor);
+ },
+ icon: const Icon(
+ Icons.stop_circle,
+ color: AppColor.greenColor,
+ ),
+ tooltip:
+ ' Add Note', // Optional tooltip for clarity
+ ),
+ ),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ Container(
+ decoration: AppStyle.boxDecoration,
+ width: Get.width * .15,
+ child: IconButton(
+ onPressed: () async {
+ if (box.read(BoxName.sosPhonePassenger) == null) {
+ {
+ await profileController.updatField(
+ 'sosPhone', TextInputType.phone);
+ box.write(BoxName.sosPhonePassenger,
+ profileController.prfoileData['sosPhone']);
+ }
+ } else {
+ makePhoneCall('122');
+ // box.read(BoxName.sosPhonePassenger));
+ }
+ },
+ icon: const Icon(
+ Icons.sos_rounded,
+ color: AppColor.redColor,
+ ),
+ ),
+ ),
+ Container(
+ decoration: AppStyle.boxDecoration,
+ width: Get.width * .15,
+ child: IconButton(
+ onPressed: () async {
+ if (box.read(BoxName.sosPhonePassenger) == null ||
+ box.read(BoxName.sosPhonePassenger) == 'sos') {
+ {
+ await profileController.updatField(
+ 'sosPhone', TextInputType.phone);
+ box.write(BoxName.sosPhonePassenger,
+ profileController.prfoileData['sosPhone']);
+ }
+ } else {
+ String phoneNumber = box
+ .read(BoxName.sosPhonePassenger)
+ .toString();
+ // phoneNumber = phoneNumber.replaceAll('0', '');
+ var phone = box.read(BoxName.countryCode) ==
+ 'Egypt'
+ ? '+2${box.read(BoxName.sosPhonePassenger)}'
+ : '+962${box.read(BoxName.sosPhonePassenger)}';
+ controller.sendWhatsapp(phone);
+ }
+ },
+ icon: const Icon(
+ FontAwesome.whatsapp,
+ color: AppColor.greenColor,
+ ),
+ ),
+ ),
+ Container(
+ decoration: AppStyle.boxDecoration,
+ width: Get.width * .15,
+ child: IconButton(
+ onPressed: () async {
+ await controller.getTokenForParent();
+ },
+ icon: const Icon(
+ AntDesign.Safety,
+ color: AppColor.blueColor,
+ ),
+ ),
+ ),
+ ],
+ ),
+ Stack(
+ children: [
+ // StreamCounter(),
+ LinearProgressIndicator(
+ backgroundColor: AppColor.accentColor,
+ color:
+ // controller.remainingTimeTimerRideBegin < 60
+ // ? AppColor.redColor
+ // :
+ AppColor.greenColor,
+ minHeight: 25,
+ borderRadius: BorderRadius.circular(15),
+ value:
+ 24 //controller.progressTimerRideBegin.toDouble(),
+ ),
+ Center(
+ child: Text(
+ controller.stringElapsedTimeRideBeginVip,
+ style: AppStyle.title,
+ ),
+ )
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ );
+ } else {
+ return const SizedBox();
+ }
+ });
+ }
+}
+
+class StreamCounter extends StatelessWidget {
+ const StreamCounter({Key? key}) : super(key: key);
+
+ @override
+ // Build the UI based on the timer value
+ Widget build(BuildContext context) {
+ Get.put(MapPassengerController());
+ return GetBuilder(builder: (controller) {
+ return StreamBuilder(
+ initialData: 0,
+ stream: controller.timerController.stream,
+ builder: (context, snapshot) {
+ // Calculate the remaining time based on the current tick
+ final remainingTime = controller.durationToRide - snapshot.data!;
+
+ // Format the remaining time as a string
+ final formattedRemainingTime =
+ '${(remainingTime / 60).floor()}:${(remainingTime % 60).toString().padLeft(2, '0')}';
+
+ // Return the UI widgets based on the remaining time
+ return Column(
+ children: [
+ Text(formattedRemainingTime),
+ // ElevatedButton(
+ // onPressed: () {
+ // // Handle button press here
+ // },
+ // ),
+ ],
+ );
+ },
+ );
+ });
+ }
+}