This commit is contained in:
Hamza-Ayed
2024-11-20 20:24:49 +02:00
parent f796f4bc48
commit 231405ce9f
14 changed files with 725 additions and 351 deletions

View File

@@ -148,8 +148,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = 23 minSdk = 23
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = 97 versionCode = 98
versionName = '1.5.97' versionName = '1.5.98'
multiDexEnabled =true multiDexEnabled =true
// manifestPlaceholders can be specified here if needed // manifestPlaceholders can be specified here if needed

View File

@@ -28,7 +28,7 @@ PODS:
- Firebase/Messaging (= 11.0.0) - Firebase/Messaging (= 11.0.0)
- firebase_core - firebase_core
- Flutter - Flutter
- FirebaseAppCheckInterop (11.2.0) - FirebaseAppCheckInterop (11.5.0)
- FirebaseAuth (11.0.0): - FirebaseAuth (11.0.0):
- FirebaseAppCheckInterop (~> 11.0) - FirebaseAppCheckInterop (~> 11.0)
- FirebaseAuthInterop (~> 11.0) - FirebaseAuthInterop (~> 11.0)
@@ -38,16 +38,16 @@ PODS:
- GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/Environment (~> 8.0)
- GTMSessionFetcher/Core (~> 3.4) - GTMSessionFetcher/Core (~> 3.4)
- RecaptchaInterop (~> 100.0) - RecaptchaInterop (~> 100.0)
- FirebaseAuthInterop (11.2.0) - FirebaseAuthInterop (11.5.0)
- FirebaseCore (11.0.0): - FirebaseCore (11.0.0):
- FirebaseCoreInternal (~> 11.0) - FirebaseCoreInternal (~> 11.0)
- GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/Logger (~> 8.0) - GoogleUtilities/Logger (~> 8.0)
- FirebaseCoreExtension (11.2.0): - FirebaseCoreExtension (11.4.1):
- FirebaseCore (~> 11.0) - FirebaseCore (~> 11.0)
- FirebaseCoreInternal (11.2.0): - FirebaseCoreInternal (11.5.0):
- "GoogleUtilities/NSData+zlib (~> 8.0)" - "GoogleUtilities/NSData+zlib (~> 8.0)"
- FirebaseInstallations (11.2.0): - FirebaseInstallations (11.4.0):
- FirebaseCore (~> 11.0) - FirebaseCore (~> 11.0)
- GoogleUtilities/Environment (~> 8.0) - GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0) - GoogleUtilities/UserDefaults (~> 8.0)
@@ -356,13 +356,13 @@ SPEC CHECKSUMS:
firebase_auth: 16ac5db3d064db837ecd845080d7e18e4be7c66d firebase_auth: 16ac5db3d064db837ecd845080d7e18e4be7c66d
firebase_core: ceec591a66629daaee82d3321551692c4a871493 firebase_core: ceec591a66629daaee82d3321551692c4a871493
firebase_messaging: 15d8b557010f3bb7b98d0302e1c7c8fbcd244425 firebase_messaging: 15d8b557010f3bb7b98d0302e1c7c8fbcd244425
FirebaseAppCheckInterop: ea21450529cf0ebd132788dd8916a0269abc684f FirebaseAppCheckInterop: d265d9f4484e7ec1c591086408840fdd383d1213
FirebaseAuth: d5cf28be74d7e82257f6a3f717509eff70d3cf4a FirebaseAuth: d5cf28be74d7e82257f6a3f717509eff70d3cf4a
FirebaseAuthInterop: 47c09558af5d1b31f16fb352387c72d4804f4a24 FirebaseAuthInterop: 1219bee9b23e6ebe84c256a0d95adab53d11c331
FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383 FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383
FirebaseCoreExtension: cda74ddfb001224bd8fd1d6e74698b4ed07803de FirebaseCoreExtension: f1bc67a4702931a7caa097d8e4ac0a1b0d16720e
FirebaseCoreInternal: 0c569513412da9f3b31bd0b340013bbee8f295c5 FirebaseCoreInternal: f47dd28ae7782e6a4738aad3106071a8fe0af604
FirebaseInstallations: 771177d89d6c451dc6e50085ec82e2fc77ed0a4a FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414
FirebaseMessaging: d2d1d9c62c46dd2db49a952f7deb5b16ad2c9742 FirebaseMessaging: d2d1d9c62c46dd2db49a952f7deb5b16ad2c9742
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983 flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983

View File

@@ -467,6 +467,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@@ -594,6 +595,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@@ -651,6 +653,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";

View File

@@ -41,11 +41,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>69</string> <string>70</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>4.3.69</string> <string>4.3.70</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string></string> <string></string>
<key>FirebaseAppDelegateProxyEnabled</key> <key>FirebaseAppDelegateProxyEnabled</key>

View File

@@ -171,6 +171,7 @@ class AppLink {
//-----------------mishwari------------------ //-----------------mishwari------------------
static String addMishwari = "$ride/mishwari/add.php"; static String addMishwari = "$ride/mishwari/add.php";
static String cancelMishwari = "$ride/mishwari/cancel.php";
static String getMishwari = "$ride/mishwari/get.php"; static String getMishwari = "$ride/mishwari/get.php";
//-----------------DriverOrder------------------ //-----------------DriverOrder------------------

View File

@@ -113,6 +113,104 @@ class NotificationController extends GetxController {
print('Notifications scheduled successfully for the next 7 days'); print('Notifications scheduled successfully for the next 7 days');
} }
void scheduleNotificationsForTimeSelected(
String title, String message, String tone, DateTime timeSelected) async {
final AndroidNotificationDetails android = AndroidNotificationDetails(
'high_importance_channel',
'High Importance Notifications',
importance: Importance.max,
priority: Priority.high,
sound: RawResourceAndroidNotificationSound(tone),
);
const DarwinNotificationDetails ios = DarwinNotificationDetails(
sound: 'default',
presentAlert: true,
presentBadge: true,
presentSound: true,
);
final NotificationDetails details =
NotificationDetails(android: android, iOS: ios);
// Check for the exact alarm permission on Android 12 and above
if (Platform.isAndroid) {
if (await Permission.scheduleExactAlarm.isDenied) {
if (await Permission.scheduleExactAlarm.request().isGranted) {
print('SCHEDULE_EXACT_ALARM permission granted');
} else {
print('SCHEDULE_EXACT_ALARM permission denied');
return;
}
}
}
// Schedule notifications for 10 and 30 minutes before the timeSelected
await _scheduleNotificationForTimeVIP(
timeSelected.subtract(const Duration(minutes: 10)), // 10 minutes before
title,
message,
details,
1, // Unique ID for 10-minute before notification
);
await _scheduleNotificationForTimeVIP(
timeSelected.subtract(const Duration(minutes: 30)), // 30 minutes before
title,
message,
details,
2, // Unique ID for 30-minute before notification
);
print('Notifications scheduled successfully for the time selected');
}
Future<void> _scheduleNotificationForTimeVIP(
DateTime scheduledDate,
String title,
String message,
NotificationDetails details,
int notificationId,
) async {
// Initialize and set Cairo timezone
tz.initializeTimeZones();
var cairoLocation = tz.getLocation('Africa/Cairo');
final now = tz.TZDateTime.now(cairoLocation);
// Convert to Cairo time
tz.TZDateTime scheduledTZDateTime =
tz.TZDateTime.from(scheduledDate, cairoLocation);
// Check if 10 minutes before the scheduled time is in the past
if (scheduledTZDateTime
.subtract(const Duration(minutes: 10))
.isBefore(now)) {
// If the 10 minutes before the scheduled time is in the past, don't schedule
print(
'Scheduled time minus 10 minutes is in the past. Skipping notification.');
return; // Skip this notification
}
print('Current time (Cairo): $now');
print('Scheduling notification for: $scheduledTZDateTime');
await _flutterLocalNotificationsPlugin.zonedSchedule(
notificationId, // Unique ID for each notification
title,
message,
scheduledTZDateTime,
details,
androidScheduleMode: AndroidScheduleMode.exact,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents:
null, // Don't repeat automatically; we handle manually
);
print('Notification scheduled successfully for: $scheduledTZDateTime');
}
Future<void> _scheduleNotificationForTime( Future<void> _scheduleNotificationForTime(
int dayOffset, int dayOffset,
int hour, int hour,
@@ -138,7 +236,7 @@ class NotificationController extends GetxController {
// If the scheduled time is in the past, move it to the next day // If the scheduled time is in the past, move it to the next day
if (scheduledDate.isBefore(now)) { if (scheduledDate.isBefore(now)) {
scheduledDate = scheduledDate.add(Duration(days: 1)); scheduledDate = scheduledDate.add(const Duration(days: 1));
} }
print('Current time (Cairo): $now'); print('Current time (Cairo): $now');

View File

@@ -5,6 +5,7 @@ import 'dart:math' as math;
import 'dart:ui'; import 'dart:ui';
import 'package:SEFER/constant/univeries_polygon.dart'; import 'package:SEFER/constant/univeries_polygon.dart';
import 'package:SEFER/controller/firebase/local_notification.dart'; import 'package:SEFER/controller/firebase/local_notification.dart';
import 'package:SEFER/views/widgets/mysnakbar.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_confetti/flutter_confetti.dart'; import 'package:flutter_confetti/flutter_confetti.dart';
import 'package:vector_math/vector_math.dart' show radians, degrees; import 'package:vector_math/vector_math.dart' show radians, degrees;
@@ -42,6 +43,7 @@ import '../functions/crud.dart';
import '../functions/launch.dart'; import '../functions/launch.dart';
import '../functions/secure_storage.dart'; import '../functions/secure_storage.dart';
import '../payment/payment_controller.dart'; import '../payment/payment_controller.dart';
import 'vip_waitting_page.dart';
class MapPassengerController extends GetxController { class MapPassengerController extends GetxController {
bool isLoading = true; bool isLoading = true;
@@ -3069,20 +3071,41 @@ class MapPassengerController extends GetxController {
} }
Future getPlaces() async { Future getPlaces() async {
var languageCode;
// Check if `placeDestinationController.text` contains English characters
if (RegExp(r'[a-zA-Z]').hasMatch(placeDestinationController.text)) {
languageCode = 'en';
} else {
languageCode = 'ar';
}
var url = var url =
// '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}'; // '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}';
'${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeDestinationController.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=50000&language=ar&key=${AK.mapAPIKEY.toString()}'; '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeDestinationController.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=250000&language=$languageCode&key=${AK.mapAPIKEY.toString()}';
print(url);
var response = await CRUD().getGoogleApi(link: url, payload: {}); var response = await CRUD().getGoogleApi(link: url, payload: {});
Log.print('response: ${response}');
placesDestination = response['results']; placesDestination = response['results'];
update(); update();
} }
Future getPlacesStart() async { Future getPlacesStart() async {
var languageCode = wayPoint0Controller.text;
// Regular expression to check for English alphabet characters
final englishRegex = RegExp(r'[a-zA-Z]');
// Check if text contains English characters
if (englishRegex.hasMatch(languageCode)) {
languageCode = 'en';
} else {
languageCode = 'ar';
}
var url = var url =
// '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}'; // '${AppLink.googleMapsLink}place/nearbysearch/json?location=${mylocation.longitude}&radius=25000&language=ar&keyword=&key=${placeController.text}${AK.mapAPIKEY}';
'${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeStartController.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=50000&language=ar&key=${AK.mapAPIKEY.toString()}'; '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeStartController.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=250000&language=$languageCode&key=${AK.mapAPIKEY.toString()}';
var response = await CRUD().getGoogleApi(link: url, payload: {}); var response = await CRUD().getGoogleApi(link: url, payload: {});
@@ -3091,15 +3114,45 @@ class MapPassengerController extends GetxController {
} }
Future getPlacesListsWayPoint(int index) async { Future getPlacesListsWayPoint(int index) async {
var languageCode = wayPoint0Controller.text;
// Regular expression to check for English alphabet characters
final englishRegex = RegExp(r'[a-zA-Z]');
// Check if text contains English characters
if (englishRegex.hasMatch(languageCode)) {
languageCode = 'en';
} else {
languageCode = 'ar';
}
var url = var url =
'${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint0Controller.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=50000&language=ar&key=${AK.mapAPIKEY.toString()}'; '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint0Controller.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=250000&language=$languageCode&key=${AK.mapAPIKEY.toString()}';
var response = await CRUD().getGoogleApi(link: url, payload: {}); try {
var response = await CRUD().getGoogleApi(link: url, payload: {});
wayPoint0 = response['results']; if (response != null && response['results'] != null) {
placeListResponseAll[index] = response['results']; wayPoint0 = response['results'];
update(); placeListResponseAll[index] = response['results'];
update();
} else {
print('Error: Invalid response from Google Places API');
}
} catch (e) {
print('Error fetching places: $e');
}
} }
// Future getPlacesListsWayPoint(int index) async {
// var url =
// '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${wayPoint0Controller.text}&location=${passengerLocation.latitude},${passengerLocation.longitude}&radius=80000&language=${}&key=${AK.mapAPIKEY.toString()}';
// var response = await CRUD().getGoogleApi(link: url, payload: {});
// wayPoint0 = response['results'];
// placeListResponseAll[index] = response['results'];
// update();
// }
LatLng fromString(String location) { LatLng fromString(String location) {
List<String> parts = location.split(','); List<String> parts = location.split(',');
@@ -3677,7 +3730,7 @@ class MapPassengerController extends GetxController {
isLoading = false; isLoading = false;
update(); update();
var url = var url =
('${AppLink.googleMapsLink}directions/json?&language=ar&avoid=tolls|ferries&destination=$destination&origin=$origin&key=${AK.mapAPIKEY}'); ('${AppLink.googleMapsLink}directions/json?&language=${box.read(BoxName.lang) ?? 'ar'}&avoid=tolls|ferries&destination=$destination&origin=$origin&key=${AK.mapAPIKEY}');
var response = await CRUD().getGoogleApi(link: url, payload: {}); var response = await CRUD().getGoogleApi(link: url, payload: {});
data = response['routes'][0]['legs']; data = response['routes'][0]['legs'];
@@ -4488,15 +4541,51 @@ class MapPassengerController extends GetxController {
} }
List driversForMishwari = []; List driversForMishwari = [];
Future selectDriverAndCarForMishwariTrip() async { Future selectDriverAndCarForMishwariTrip() async {
var res = await CRUD() // Calculate the bounds for 20km
.get(link: AppLink.selectDriverAndCarForMishwariTrip, payload: {}); double latitudeOffset = 0.1795; // 20km range in latitude
if (res != 'failure') { double longitudeOffset = 0.2074; // 20km range in longitude
var d = jsonDecode(res);
driversForMishwari = d['message']; // Calculate bounding box based on passenger's location
update(); double southwestLat = passengerLocation.latitude - latitudeOffset;
} else { double northeastLat = passengerLocation.latitude + latitudeOffset;
return 'No driver available now try later time\nthanks for using our app' double southwestLon = passengerLocation.longitude - longitudeOffset;
double northeastLon = passengerLocation.longitude + longitudeOffset;
// Create the payload with calculated bounds
var payload = {
'southwestLat': southwestLat.toString(),
'northeastLat': northeastLat.toString(),
'southwestLon': southwestLon.toString(),
'northeastLon': northeastLon.toString(),
};
try {
// Fetch data from the API
var res = await CRUD().get(
link: AppLink.selectDriverAndCarForMishwariTrip, payload: payload);
if (res != 'failure') {
// Check if response is valid JSON
try {
var d = jsonDecode(res);
driversForMishwari = d['message'];
Log.print('driversForMishwari: ${driversForMishwari}');
update();
} catch (e) {
// Handle invalid JSON format
print("Error decoding JSON: $e");
return 'Server returned invalid data. Please try again later.';
}
} else {
return 'No driver available now, try again later. Thanks for using our app.'
.tr;
}
} catch (e) {
// Handle network or other exceptions
print("Error fetching data: $e");
return 'There was an issue connecting to the server. Please try again later.'
.tr; .tr;
} }
} }
@@ -4519,22 +4608,23 @@ class MapPassengerController extends GetxController {
// changeCashConfirmPageShown(); // changeCashConfirmPageShown();
} }
var driverIdVip = '';
Future<void> saveTripData( Future<void> saveTripData(
Map<String, dynamic> driver, DateTime tripDateTime) async { Map<String, dynamic> driver, DateTime tripDateTime) async {
try { try {
// Prepare trip data // Prepare trip data
Map<String, dynamic> tripData = { Map<String, dynamic> tripData = {
'id': driver['id'].toString(), // Ensure the id is a string 'id': driver['driver_id'].toString(), // Ensure the id is a string
'phone': driver['phone'], 'phone': driver['phone'],
'gender': driver['gender'], 'gender': driver['gender'],
'name': driver['NAME'], 'name': driver['NAME'],
'name_english': driver['name_english'], 'name_english': driver['name_english'],
'address': driver['address'], 'address': driver['address'],
'religion': driver['religion'], 'religion': driver['religion'] ?? 'UnKnown',
'age': driver['age'].toString(), // Convert age to String 'age': driver['age'].toString(), // Convert age to String
'education': driver['education'], 'education': driver['education'] ?? 'UnKnown',
'license_type': driver['license_type'], 'license_type': driver['license_type'] ?? 'UnKnown',
'national_number': driver['national_number'], 'national_number': driver['national_number'] ?? 'UnKnown',
'car_plate': driver['car_plate'], 'car_plate': driver['car_plate'],
'make': driver['make'], 'make': driver['make'],
'model': driver['model'], 'model': driver['model'],
@@ -4546,12 +4636,12 @@ class MapPassengerController extends GetxController {
'token': driver['token'], 'token': driver['token'],
'rating': driver['rating'].toString(), // Convert rating to String 'rating': driver['rating'].toString(), // Convert rating to String
'countRide': 'countRide':
driver['countRide'].toString(), // Convert countRide to String driver['ride_count'].toString(), // Convert countRide to String
'passengerId': box.read(BoxName.passengerID), 'passengerId': box.read(BoxName.passengerID),
'timeSelected': tripDateTime.toIso8601String(), 'timeSelected': tripDateTime.toIso8601String(),
'status': 'pending', 'status': 'pending',
}; };
// Log.print('tripData: $tripData'); Log.print('tripData: $tripData');
// Send data to server // Send data to server
var response = var response =
@@ -4560,33 +4650,52 @@ class MapPassengerController extends GetxController {
if (response != 'failure') { if (response != 'failure') {
// Trip saved successfully // Trip saved successfully
Get.snackbar('Success'.tr, 'Trip booked successfully'.tr); // Get.snackbar('Success'.tr, 'Trip booked successfully'.tr);
var id = response['message'].toString(); var id = response['message'].toString();
if (AppLink.endPoint != AppLink.seferCairoServer) { if (AppLink.endPoint != AppLink.seferCairoServer) {
await CRUD().post( await CRUD().post(
link: "${AppLink.endPoint}/ride/mishwari/add.php", link: "${AppLink.endPoint}/ride/mishwari/add.php",
payload: tripData); payload: tripData);
} }
driverIdVip = driver['driver_id'];
DateTime timeSelected = DateTime.parse(tripDateTime.toIso8601String());
Get.find<NotificationController>().scheduleNotificationsForTimeSelected(
"Your trip is scheduled".tr,
"Don't forget your ride!".tr,
"tone1",
timeSelected);
// Optionally, set up local notification or send a push notification // Optionally, set up local notification or send a push notification
// await setLocalNotification(tripDateTime);
await FirebaseMessagesController().sendNotificationToDriverMAP( // await FirebaseMessagesController().sendNotificationToDriverMAP(
'OrderVIP', // 'OrderVIP',
rideId.toString(), // rideId.toString(),
driver['token'].toString(), // driver['token'].toString(),
[ // [
id, // id,
driver['id'], // driver['id'],
passengerLocation.latitude.toString(), // passengerLocation.latitude.toString(),
passengerLocation.longitude.toString(), // passengerLocation.longitude.toString(),
box.read(BoxName.name).toString(), // box.read(BoxName.name).toString(),
box.read(BoxName.passengerID).toString(), // box.read(BoxName.passengerID).toString(),
box.read(BoxName.phone).toString(), // box.read(BoxName.phone).toString(),
box.read(BoxName.email).toString(), // box.read(BoxName.email).toString(),
box.read(BoxName.passengerPhotoUrl).toString(), // box.read(BoxName.passengerPhotoUrl).toString(),
box.read(BoxName.tokenFCM).toString(), // box.read(BoxName.tokenFCM).toString(),
driver['token'].toString(), // driver['token'].toString(),
], // ],
'order.wav'); // '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',
// );
}
Get.to(() => const VipWaittingPage());
} else { } else {
throw Exception('Failed to save trip'); throw Exception('Failed to save trip');
} }
@@ -4598,6 +4707,22 @@ class MapPassengerController extends GetxController {
} }
} }
cancelVip(String token, tripId) async {
// FirebaseMessagesController().sendNotificationToDriverMAP(
// 'Order VIP Canceld'.tr,
// 'Passenger cancel order'.tr,
// token,
// [],
// 'cancel.wav',
// );
var res = await CRUD()
.post(link: AppLink.cancelMishwari, payload: {'id': tripId});
if (res != 'failur') {
Get.back();
mySnackbarSuccess('You canceled VIP trip'.tr);
}
}
initilizeGetStorage() async { initilizeGetStorage() async {
if (box.read(BoxName.addWork) == null) { if (box.read(BoxName.addWork) == null) {
box.write(BoxName.addWork, 'addWork'); box.write(BoxName.addWork, 'addWork');

View File

@@ -0,0 +1,190 @@
import 'dart:convert';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/map_passenger_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/mycircular.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 VipWaittingPage extends StatelessWidget {
const VipWaittingPage({super.key});
@override
Widget build(BuildContext context) {
Get.put(VipOrderController());
return Scaffold(
appBar: AppBar(
title: Text("Waiting VIP".tr),
),
body: GetBuilder<VipOrderController>(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
}
}
// 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
}
}
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,
children: [
Text(
"${'Driver Name:'.tr} ${data['name']}",
style: AppStyle.title,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
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,
),
],
),
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,
),
),
),
),
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<MapPassengerController>().cancelVip(
data['token'].toString(),
data['id'].toString(),
);
},
),
// MyElevatedButton(
// title: "Accept Trip".tr,
// kolor: AppColor.greenColor,
// onPressed: () {
// // Add your cancel trip logic here
// },
// ),
],
),
],
),
),
);
}),
);
}
}
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<MapPassengerController>().driverIdVip.toString(),
});
isLoading = false;
update();
if (res != 'failure') {
tripData = jsonDecode(res)['message'];
update();
}
}
@override
void onInit() async {
fetchOrder();
super.onInit();
}
}

View File

@@ -4,6 +4,32 @@ class MyTranslation extends Translations {
@override @override
Map<String, Map<String, String>> get keys => { Map<String, Map<String, String>> get keys => {
"ar": { "ar": {
"Driver Name:": "اسم السائق:",
"Car Plate:": "رقم اللوحة:",
"Order Cancelled": "تم إلغاء الطلب",
'You canceled VIP trip': "ألغيت الرحلة",
"Passenger cancelled order": "الراكب قام بإلغاء الطلب",
"Your trip is scheduled": "رحلتك مجدولة",
"Don't forget your ride!": "لا تنسَ رحلتك!",
"Trip updated successfully": "تم تحديث الرحلة بنجاح",
"Car Make:": "ماركة السيارة:",
"Car Model:": "طراز السيارة:", "Car Color:": "لون السيارة:",
"Driver Phone:": "رقم هاتف السائق:",
'Pre-booking': 'احجز مسبقًا', "Waiting VIP": "انتظار VIP",
"Driver List": "قائمة السائقين", "Confirm Trip": "تأكيد الرحلة",
"Select date and time of trip": "حدد تاريخ ووقت الرحلة",
"Date and Time Picker": "اختيار التاريخ والوقت",
"Trip Status:": "حالة الرحلة:", "pending": "قيد الانتظار",
"accepted": "تم القبول",
"rejected": "تم الرفض",
"Scheduled Time:": "الوقت المحدد:",
"No drivers available": "لا يوجد سائقين متاحين",
"Please try again in a few moments":
"يرجى المحاولة مرة أخرى بعد قليل",
"Unknown Driver": "سائق غير معروف",
"rides": "الرحلات",
"The reason is": "السبب هو",
"User does not have a wallet #1652": "المستخدم ليس لديه محفظة ",
"Price of trip": "سعر الرحلة", "Price of trip": "سعر الرحلة",
"For Speed and Delivery trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance": "For Speed and Delivery trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance":
"بالنسبة لرحلات السرعة والتوصيل، يتم حساب السعر ديناميكياً. بالنسبة لرحلات الراحة، يتم حساب السعر بناءً على الوقت والمسافة", "بالنسبة لرحلات السرعة والتوصيل، يتم حساب السعر ديناميكياً. بالنسبة لرحلات الراحة، يتم حساب السعر بناءً على الوقت والمسافة",

View File

@@ -19,6 +19,7 @@ import '../../constant/colors.dart';
import '../../constant/info.dart'; import '../../constant/info.dart';
import '../../constant/links.dart'; import '../../constant/links.dart';
import '../../main.dart'; import '../../main.dart';
import '../../print.dart';
import '../functions/crud.dart'; import '../functions/crud.dart';
import '../functions/toast.dart'; import '../functions/toast.dart';
import 'paymob/paymob_wallet.dart'; import 'paymob/paymob_wallet.dart';
@@ -697,7 +698,7 @@ class PaymentController extends GetxController {
billingData: PaymobBillingDataWallet(), billingData: PaymobBillingDataWallet(),
onPayment: (PaymobResponseWallet response) {}, onPayment: (PaymobResponseWallet response) {},
); );
// Log.print('response.message!: ${response!.responseCode!}');
// if (response!.success == true && response.responseCode == '200') { // if (response!.success == true && response.responseCode == '200') {
if (response!.responseCode.toString() == '200' && if (response!.responseCode.toString() == '200' &&
response.success == true) { response.success == true) {

View File

@@ -190,7 +190,8 @@ class CarDetailsTypeToChoose extends StatelessWidget {
.totalPassengerRayehGai .totalPassengerRayehGai
.toStringAsFixed( .toStringAsFixed(
1) 1)
: '50', : 'Pre-booking'
.tr,
style: style:
AppStyle.title.copyWith(fontSize: 20), AppStyle.title.copyWith(fontSize: 20),
), ),

View File

@@ -1,17 +1,11 @@
import 'dart:math';
import 'package:SEFER/views/auth/login_page.dart';
import 'package:SEFER/views/auth/sms_verfy_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../../../constant/box_name.dart';
import '../../../constant/colors.dart'; import '../../../constant/colors.dart';
import '../../../constant/notification.dart'; import '../../../controller/functions/crud.dart';
import '../../../controller/firebase/local_notification.dart';
import '../../../controller/functions/tts.dart'; import '../../../controller/functions/tts.dart';
import '../../../controller/home/map_passenger_controller.dart'; import '../../../controller/home/map_passenger_controller.dart';
import '../../../main.dart'; import '../../../controller/home/vip_waitting_page.dart';
GetBuilder<MapPassengerController> leftMainMenuIcons() { GetBuilder<MapPassengerController> leftMainMenuIcons() {
final textToSpeechController = Get.put(TextToSpeechController()); final textToSpeechController = Get.put(TextToSpeechController());
@@ -88,135 +82,23 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
const SizedBox( const SizedBox(
width: 5, width: 5,
), ),
// AnimatedContainer( AnimatedContainer(
// duration: const Duration(microseconds: 200), duration: const Duration(microseconds: 200),
// width: controller.widthMapTypeAndTraffic, width: controller.widthMapTypeAndTraffic,
// decoration: BoxDecoration( decoration: BoxDecoration(
// color: AppColor.secondaryColor, color: AppColor.secondaryColor,
// border: Border.all(), border: Border.all(),
// borderRadius: BorderRadius.circular(15)), borderRadius: BorderRadius.circular(15)),
// child: IconButton( child: IconButton(
// onPressed: () async { onPressed: () async {
// Get.to(SmsSignupEgypt()); Get.to(() => const VipWaittingPage());
// }, },
// icon: const Icon( icon: const Icon(
// Icons.voice_chat, Icons.voice_chat,
// size: 29, 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 {
// Get.to(SmsSignupEgypt());
// List<String> d = [
// "30.003028,31.2419628",
// "30.0955661,31.2665336",
// "160.00",
// "25.92",
// "1488",
// "16.93",
// "114243034311436865474",
// "113172279072358305645",
// "hamza ayed",
// "rlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3",
// "+201023248456",
// "1 min",
// "1 m",
// "false",
// "QwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9",
// "0",
// "238",
// "false",
// "114243034311436865474",
// "1488",
// "startEnd",
// "30.049307749732176,31.274291574954987",
// "",
// "",
// "",
// "",
// "17.73",
// "0",
// "hamzaayedflutter@gmail.com",
// "الفسطاط، حي مصر القديمة، مصر",
// " الزاوية الحمراء، محافظة القاهرة، مصر",
// "Speed",
// "8",
// "5.00"
// ];
// FirebaseMessagesController()
// .sendNotificationToAnyWithoutData(
// 'Cancel'.tr,
// "How much longer will you be?".tr,
// 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq',
// // d,
// 'ding.wav',
// );
// Get.to(SmsSignupEgypt());
// Log.print(
// 'getUpdatedRideForDriverApply: ${Get.find<MapPassengerController>().driverToken}');
// Get.find<MapPassengerController>()
// .firstTimeRunToGetCoupon('SEFER25', '1 WEEEK', '25%');
// },
// icon: const Icon(
// Icons.chat,
// 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 {
// await CRUD().allMethodForAI(
// 'name,fullName,address,idNumber,cardId,dob',
// AppLink.uploadEgypt,
// 'idFront');
//
// // await ImageController().choosImage(
// // 'https://api.sefer.live/sefer/uploadEgypt.php',
// // 'FrontId');
// AC credentials = AC();
// String apiKey = 'zjujl_qvo_fwjfgjlXrXlBl';
// String convertedStringN = credentials.c(
// credentials.c(credentials.c(apiKey, cs), cC), cn);
// String retrievedStringS = credentials.r(
// credentials.r(credentials.r(convertedStringN, cn), cC),
// cs);
// //
// if (retrievedStringS == apiKey) {
// print('convertedStringN --- $convertedStringN');
// print('retrievedStringS ---$retrievedStringS');
// print('same');
// }
//
// // await Get.find<PaymentController>()
// // .payWithPayMob(context, '1100', 'EGP');
// // Initiates a payment with a card using the FlutterPaymob instance
//
// },
// icon: const Icon(
// // Get.put(AudioRecorderController()).isRecording
// Icons.start,
// size: 29,
// ),
// ),
// ),
], ],
); );
})), })),

View File

@@ -8,6 +8,7 @@ import 'package:get/get.dart';
import '../../../constant/api_key.dart'; import '../../../constant/api_key.dart';
import '../../../constant/links.dart'; import '../../../constant/links.dart';
import '../../../print.dart';
class CupertinoDriverListWidget extends StatelessWidget { class CupertinoDriverListWidget extends StatelessWidget {
MapPassengerController mapPassengerController = MapPassengerController mapPassengerController =
@@ -16,170 +17,207 @@ class CupertinoDriverListWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CupertinoPageScaffold( return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
middle: Text('Driver List'.tr), middle: Text('Driver List'.tr), // Ensure text is properly localized
), ),
child: SafeArea( child: SafeArea(
child: ListView.separated( child: mapPassengerController.driversForMishwari.isEmpty
itemCount: mapPassengerController.driversForMishwari.length, ? Center(
separatorBuilder: (context, index) => const Divider(height: 1), child: Text(
itemBuilder: (context, index) { 'No drivers available at the moment. Please try again later.'
var driver = mapPassengerController.driversForMishwari[index]; .tr,
return Container( style: const TextStyle(
decoration: AppStyle.boxDecoration1, fontSize: 18, // Adjust the size as needed
child: CupertinoListTile( fontWeight: FontWeight.w600,
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), color: CupertinoColors.inactiveGray, // Customize color
leading: CircleAvatar( ),
radius: 25, textAlign: TextAlign.center, // Center-align the text
backgroundImage: NetworkImage(
'${AppLink.seferCairoServer}/portrate_captain_image/${driver['id']}.jpg',
),
child: Builder(
builder: (context) {
return Image.network(
'${AppLink.seferCairoServer}/portrate_captain_image/${driver['id']}.jpg',
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child; // Image is loaded
} else {
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ?? 1)
: null,
),
);
}
},
errorBuilder: (BuildContext context, Object error,
StackTrace? stackTrace) {
return const Icon(
Icons.person, // Icon to show when image fails to load
size: 25, // Adjust the size as needed
color: AppColor.blueColor, // Color for the error icon
);
},
);
},
),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${driver['NAME'].toString().split(' ')[0]} ${driver['NAME'].toString().split(' ')[1]}',
style: const TextStyle(fontWeight: FontWeight.bold),
), ),
Text('${'Age'.tr}: ${driver['age'].toString()}'), )
Row( : ListView.separated(
children: [ itemCount: mapPassengerController.driversForMishwari.length,
const Icon(CupertinoIcons.star_fill, separatorBuilder: (context, index) =>
size: 16, color: CupertinoColors.systemYellow), const Divider(height: 1),
const SizedBox(width: 4), itemBuilder: (context, index) {
Text(driver['rating']?.toStringAsFixed(1) ?? 'N/A'.tr), var driver =
const SizedBox(width: 8), mapPassengerController.driversForMishwari[index];
Text('${'Rides'.tr}: ${driver['countRide']}'), return Container(
], decoration: AppStyle.boxDecoration1,
), child: CupertinoListTile(
], padding: const EdgeInsets.symmetric(
), vertical: 4, horizontal: 8),
subtitle: Column( leading: CircleAvatar(
crossAxisAlignment: CrossAxisAlignment.start, radius: 25,
children: [ backgroundImage: NetworkImage(
Row( '${AppLink.seferCairoServer}/portrate_captain_image/${driver['id']}.jpg',
mainAxisAlignment: MainAxisAlignment.spaceBetween, ),
children: [ child: Builder(
Text( builder: (context) {
'${'Car'.tr}: ${driver['make']} ${driver['model']} (${driver['year']})'), return Image.network(
Text('${'Plate'.tr}: ${driver['car_plate']}'), '${AppLink.seferCairoServer}/portrate_captain_image/${driver['id']}.jpg',
], fit: BoxFit.cover,
), loadingBuilder: (BuildContext context,
// Row( Widget child,
// mainAxisAlignment: MainAxisAlignment.spaceBetween, ImageChunkEvent? loadingProgress) {
// children: [ if (loadingProgress == null) {
// Text('${'Education'.tr}: ${driver['education']}'), return child; // Image is loaded
// ], } else {
// ), return Center(
Row( child: CircularProgressIndicator(
mainAxisAlignment: MainAxisAlignment.spaceBetween, value: loadingProgress
children: [ .expectedTotalBytes !=
SizedBox( null
// width: Get.width * .3, ? loadingProgress
child: Row( .cumulativeBytesLoaded /
mainAxisAlignment: MainAxisAlignment.spaceBetween, (loadingProgress
children: [ .expectedTotalBytes ??
Text('${'Color'.tr}: ${driver['color']}'), 1)
const SizedBox(width: 8), : null,
Container( ),
width: 20, );
height: 20, }
decoration: BoxDecoration( },
color: driver['color_hex'].toString() == 'null' errorBuilder: (BuildContext context,
? Colors.amber Object error, StackTrace? stackTrace) {
: hexToColor( return const Icon(
driver['color_hex'].toString()), Icons
borderRadius: BorderRadius.circular(4), .person, // Icon to show when image fails to load
border: Border.all(), size: 25, // Adjust the size as needed
), color: AppColor
), .blueColor, // Color for the error icon
], );
},
);
},
),
), ),
), title: Row(
],
),
],
),
onTap: () {
// Handle driver selection
Get.defaultDialog(
title: '${'Selected driver'.tr}: ${driver['NAME']}',
content: Column(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'${'Car'.tr}: ${driver['make']} ${driver['model']} (${driver['year']})'), '${driver['NAME'].toString().split(' ')[0]} ${driver['NAME'].toString().split(' ')[1]}',
Text('${'Plate'.tr}: ${driver['car_plate']}'), style:
const TextStyle(fontWeight: FontWeight.bold),
),
Text('${'Age'.tr}: ${driver['age'].toString()}'),
Row( Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text('${'Color'.tr}: ${driver['color']}'), const Icon(CupertinoIcons.star_fill,
size: 16,
color: CupertinoColors.systemYellow),
const SizedBox(width: 4),
Text(driver['rating']?.toStringAsFixed(1) ??
'N/A'.tr),
const SizedBox(width: 8), const SizedBox(width: 8),
Container( Text('${'Rides'.tr}: ${driver['ride_count']}'),
width: 20, ],
height: 20, ),
decoration: BoxDecoration( ],
color: ),
driver['color_hex'].toString() == 'null' subtitle: Column(
? Colors.amber crossAxisAlignment: CrossAxisAlignment.start,
: hexToColor( children: [
driver['color_hex'].toString()), Row(
borderRadius: BorderRadius.circular(4), mainAxisAlignment: MainAxisAlignment.spaceBetween,
border: Border.all(), children: [
Text(
'${'Car'.tr}: ${driver['make']} ${driver['model']} (${driver['year']})'),
Text('${'Plate'.tr}: ${driver['car_plate']}'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
// width: Get.width * .3,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text('${'Color'.tr}: ${driver['color']}'),
const SizedBox(width: 8),
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: driver['color_hex']
.toString() ==
'null'
? Colors.amber
: hexToColor(driver['color_hex']
.toString()),
borderRadius:
BorderRadius.circular(4),
border: Border.all(),
),
),
],
), ),
), ),
], ],
), ),
], ],
), ),
], onTap: () {
), Log.print(' driver["id"]: ${driver['driver_id']}');
confirm: MyElevatedButton( Get.find<MapPassengerController>().driverIdVip =
title: 'OK'.tr, driver['driver_id'];
onPressed: () {
Get.back(); // Handle driver selection
showDateTimePickerDialog(driver); Get.defaultDialog(
})); title:
print('${'Selected driver'.tr}: ${driver['NAME']}'); '${'Selected driver'.tr}: ${driver['NAME']}',
// Get.back(); // Close the dialog content: Column(
}, children: [
), Column(
); mainAxisAlignment:
}, MainAxisAlignment.spaceBetween,
)), children: [
Text(
'${'Car'.tr}: ${driver['make']} ${driver['model']} (${driver['year']})'),
Text(
'${'Plate'.tr}: ${driver['car_plate']}'),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
'${'Color'.tr}: ${driver['color']}'),
const SizedBox(width: 8),
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: driver['color_hex']
.toString() ==
'null'
? Colors.amber
: hexToColor(
driver['color_hex']
.toString()),
borderRadius:
BorderRadius.circular(4),
border: Border.all(),
),
),
],
),
],
),
],
),
confirm: MyElevatedButton(
title: 'OK'.tr,
onPressed: () {
Get.back();
showDateTimePickerDialog(driver);
}));
print('${'Selected driver'.tr}: ${driver['NAME']}');
// Get.back(); // Close the dialog
},
),
);
},
)),
); );
} }
@@ -233,7 +271,7 @@ class CupertinoDriverListWidget extends StatelessWidget {
Get.defaultDialog( Get.defaultDialog(
barrierDismissible: false, barrierDismissible: false,
title: 'select date and time of trip'.tr, title: "Select date and time of trip".tr,
content: SizedBox( content: SizedBox(
// height: 400, // Adjust height as needed // height: 400, // Adjust height as needed
width: double.maxFinite, width: double.maxFinite,
@@ -253,6 +291,13 @@ class CupertinoDriverListWidget extends StatelessWidget {
await mapPassengerController.saveTripData(driver, selectedDateTime); await mapPassengerController.saveTripData(driver, selectedDateTime);
}, },
), ),
cancel: MyElevatedButton(
kolor: AppColor.redColor,
title: 'Cancel'.tr,
onPressed: () {
Get.back();
},
),
); );
} }
} }
@@ -263,10 +308,10 @@ class DateTimePickerWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CupertinoPageScaffold( return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
transitionBetweenRoutes: false, transitionBetweenRoutes: false,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
middle: Text('Date and Time Picker'), middle: Text('Date and Time Picker'.tr),
), ),
child: SafeArea( child: SafeArea(
child: Column( child: Column(

View File

@@ -2,10 +2,8 @@ import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart'; import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/toast.dart'; import 'package:SEFER/controller/functions/toast.dart';
import 'package:SEFER/controller/payment/payment_controller.dart'; import 'package:SEFER/controller/payment/payment_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import '../../../main.dart'; import '../../../main.dart';
@@ -138,6 +136,8 @@ void showPaymentOptions(BuildContext context, PaymentController controller) {
child: Text('💰 Pay with Wallet'.tr), child: Text('💰 Pay with Wallet'.tr),
onPressed: () { onPressed: () {
if (controller.selectedAmount != 0) { if (controller.selectedAmount != 0) {
controller.isLoading = true;
controller.update();
controller.payWithPayMobWallet( controller.payWithPayMobWallet(
context, context,
controller.selectedAmount.toString(), controller.selectedAmount.toString(),
@@ -148,6 +148,8 @@ void showPaymentOptions(BuildContext context, PaymentController controller) {
await controller.getPassengerWallet(); await controller.getPassengerWallet();
}, },
); );
controller.isLoading = false;
controller.update();
} else { } else {
Toast.show(context, '⚠️ You need to choose an amount!'.tr, Toast.show(context, '⚠️ You need to choose an amount!'.tr,
AppColor.redColor); AppColor.redColor);