diff --git a/android/app/build.gradle b/android/app/build.gradle
index 4b8ceb6..44cc32f 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -54,8 +54,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = 23
targetSdk = flutter.targetSdkVersion
- versionCode = 113
- versionName = '1.5.13'
+ versionCode = 117
+ versionName = '1.5.17'
multiDexEnabled =true
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index f879353..9fa8907 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -28,6 +28,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 8d7a39e..7c88e58 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -35,7 +35,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 72
+ 77
CFBundleSignature
????
CFBundleURLTypes
@@ -50,7 +50,7 @@
CFBundleVersion
- 4.0.72
+ 4.0.77
FirebaseAppDelegateProxyEnabled
NO
GMSApiKey
diff --git a/lib/constant/links.dart b/lib/constant/links.dart
index 7cf7500..458d10e 100644
--- a/lib/constant/links.dart
+++ b/lib/constant/links.dart
@@ -48,7 +48,8 @@ class AppLink {
static String getWalletByDriver = "$walletDriver/getWalletByDriver.php";
static String driverStatistic = "$walletDriver/driverStatistic.php";
- static String getDriverDetails = "$walletDriver/getDriverDetails.php";
+ static String getDriverDetails =
+ "$seferCairoServer/ride/driverWallet/getDriverDetails.php";
static String getDriverWeekPaymentMove =
"$walletDriver/getDriverWeekPaymentMove.php";
static String getDriversWallet = "$walletDriver/get.php";
@@ -73,6 +74,7 @@ class AppLink {
//-----------------ridessss------------------
static String addRides = "$ride/rides/add.php";
static String getRides = "$ride/rides/get.php";
+ static String getMishwari = "$ride/ride/mishwari/get.php";
static String getTripCountByCaptain = "$ride/rides/getTripCountByCaptain.php";
static String getRideOrderID = "$ride/rides/getRideOrderID.php";
static String getRideStatus = "$ride/rides/getRideStatus.php";
@@ -235,6 +237,10 @@ class AppLink {
static String getTotalDriverDurationToday =
"$location/getTotalDriverDurationToday.php";
+ //==================cars new drivers=============
+ static String addNewCarsDrivers = '$server/ride/carDrivers/add.php';
+ static String getNewCarsDrivers = '$server/ride/carDrivers/get.php';
+
//==================Blog=============
static String profile = '$server/ride/profile';
static String getprofile = "$profile/get.php";
diff --git a/lib/constant/notification.dart b/lib/constant/notification.dart
new file mode 100644
index 0000000..7684973
--- /dev/null
+++ b/lib/constant/notification.dart
@@ -0,0 +1,22 @@
+List driverMessages = [
+ "💸 فرص الربح: افتح تطبيق سفر الآن وزد دخلك اليوم! المزيد من الطلبات بانتظارك! 🚗",
+ "🚀 طلبات جديدة: لا تضيع الفرصة! المزيد من الركاب ينتظرونك الآن على تطبيق سفر. 🏃♂️",
+ "📈 زيادة الدخل: حقق أعلى أرباح اليوم مع سفر! افتح التطبيق وابدأ عملك الآن. 💵",
+ "🕒 أوقات الذروة: استعد لكسب المزيد خلال فترات الطلب المرتفعة. افتح التطبيق الآن! 📲",
+ "🚗 طلبات جديدة: كن مستعداً، افتح تطبيق سفر الآن واستقبل المزيد من الطلبات. 🔔",
+ "🎉 فرص النجاح: ابدأ رحلتك إلى النجاح! افتح تطبيق سفر لزيادة دخلك اليوم. 💼",
+ "🌍 طلبات مرتفعة: المزيد من الركاب بانتظارك، لا تفوّت الفرص، افتح التطبيق الآن! 🚖",
+ "💪 زيادة الدخل: انطلق نحو تحقيق أهدافك المالية، افتح تطبيق سفر واكسب المزيد. 🏆",
+ "💰 أرباح إضافية: افتح التطبيق واستعد لتحقيق أرباح إضافية مع سفر! المزيد من الطلبات في انتظارك. 🛣️",
+ "🔥 فرص جديدة: تطبيق سفر مزدحم الآن! افتح التطبيق وزد أرباحك بفرص جديدة. 🚗",
+ "🚨 طلبات متزايدة: افتح تطبيق سفر الآن! الطلب مرتفع وفرص الربح كبيرة! 💸",
+ "💼 زيادة الدخل: هل أنت جاهز لتحقيق المزيد من الدخل؟ افتح التطبيق وانطلق الآن! 🚖",
+ "🚗 أوقات الذروة: احجز مقعدك في فترات الطلب العالي، افتح تطبيق سفر الآن واكسب المزيد. 📈",
+ "📲 بدء اليوم: ابدأ يومك مع سفر، وافتح التطبيق الآن لتزيد من فرص الربح. 💵",
+ "💸 فرص مستمرة: لا تفوت فرص الربح، افتح تطبيق سفر الآن وكن على استعداد للمزيد! 🔔",
+ "📆 زيادة الطلب: انطلق اليوم واستفد من الطلبات المتزايدة على تطبيق سفر! افتح التطبيق الآن. 🚗",
+ "💥 دخل إضافي: افتح تطبيق سفر الآن واستقبل طلبات جديدة تحقق لك المزيد من الدخل. 💰",
+ "🏆 فرص مرتفعة: استفد من طلبات اليوم المرتفعة، افتح التطبيق الآن مع سفر. 📲",
+ "🚗 تفضيل العملاء: كن السائق الذي يختاره الجميع! افتح تطبيق سفر اليوم واربح المزيد. 🔥",
+ "💸 دخل إضافي: فرص الدخل الإضافي في انتظارك! افتح تطبيق سفر واستمتع بالطلبات المتزايدة. 💼",
+];
diff --git a/lib/controller/auth/captin/login_captin_controller.dart b/lib/controller/auth/captin/login_captin_controller.dart
index 7637d07..785728c 100644
--- a/lib/controller/auth/captin/login_captin_controller.dart
+++ b/lib/controller/auth/captin/login_captin_controller.dart
@@ -187,12 +187,12 @@ class LoginDriverController extends GetxController {
if (token != 'failure') {
if (jsonDecode(token)['data'][0]['token'] !=
box.read(BoxName.tokenDriver)) {
- Get.put(FirebaseMessagesController())
- .sendNotificationToAnyWithoutData(
- 'token change'.tr,
- 'change device'.tr,
- jsonDecode(token)['data'][0]['token'].toString(),
- 'promo.wav');
+ Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
+ 'token change'.tr,
+ 'change device'.tr,
+ jsonDecode(token)['data'][0]['token'].toString(),
+ [],
+ 'promo.wav');
Get.defaultDialog(
title: 'you will use this device?'.tr,
middleText: '',
@@ -316,12 +316,12 @@ class LoginDriverController extends GetxController {
if (token != 'failure') {
if (jsonDecode(token)['data'][0]['token'] !=
box.read(BoxName.tokenDriver)) {
- Get.put(FirebaseMessagesController())
- .sendNotificationToAnyWithoutData(
- 'token change'.tr,
- 'change device'.tr,
- jsonDecode(token)['data'][0]['token'].toString(),
- 'promo.wav');
+ Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
+ 'token change'.tr,
+ 'change device'.tr,
+ jsonDecode(token)['data'][0]['token'].toString(),
+ [],
+ 'promo.wav');
Get.defaultDialog(
title: 'you will use this device?'.tr,
middleText: '',
diff --git a/lib/controller/auth/google_sign.dart b/lib/controller/auth/google_sign.dart
index 05015f8..bf8f3ff 100644
--- a/lib/controller/auth/google_sign.dart
+++ b/lib/controller/auth/google_sign.dart
@@ -90,15 +90,28 @@ class GoogleSignInHelper {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
if (googleUser != null) {
+ // Handle sign-up and store user information
await _handleSignUp(googleUser);
- // Add detailed debug print statements
+ // Retrieve driverID and emailDriver with added validation
final driverID = box.read(BoxName.driverID)?.toString() ?? 'Unknown ID';
final emailDriver =
box.read(BoxName.emailDriver)?.toString() ?? 'Unknown Email';
+ // Debug print statements
+ print('Driver ID: $driverID');
+ print('Driver Email: $emailDriver');
+
+ // Check if driverID is a valid numeric string
+ // if (driverID != 'Unknown ID' && int.tryParse(driverID) != null) {
await Get.find()
.loginUsingCredentials(driverID, emailDriver);
+ // }
+ // else {
+ // print('Invalid driverID format: $driverID');
+ // Get.snackbar('Login Error', 'Invalid driver ID format.',
+ // backgroundColor: AppColor.redColor);
+ // }
}
return googleUser;
@@ -110,6 +123,13 @@ class GoogleSignInHelper {
}
}
+ static Future _handleSignUp(GoogleSignInAccount user) async {
+ // Store driver information
+ box.write(BoxName.driverID,
+ user.id ?? 'Unknown ID'); // Ensure there's a fallback value
+ box.write(BoxName.emailDriver, user.email ?? 'Unknown Email');
+ }
+
// Method to handle Google Sign-Out
static Future signOut() async {
try {
@@ -145,16 +165,4 @@ class GoogleSignInHelper {
static GoogleSignInAccount? getCurrentUser() {
return _googleSignIn.currentUser;
}
-
- // Method to handle sign-up process
- static Future _handleSignUp(GoogleSignInAccount user) async {
- // Store driver information
- box.write(BoxName.driverID, user.id);
- box.write(BoxName.emailDriver, user.email);
- // box.write(BoxName.nameDriver, user.displayName);
- // box.write(BoxName.driverPhotoUrl, user.photoUrl);
-
- // Perform any additional sign-up tasks or API calls here
- // For example, you can send the user data to your server for registration
- }
}
diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart
index 152129e..e862b2e 100644
--- a/lib/controller/firebase/firbase_messge.dart
+++ b/lib/controller/firebase/firbase_messge.dart
@@ -33,7 +33,8 @@ class FirebaseMessagesController extends GetxController {
late String driverID;
late String driverToken;
NotificationSettings? notificationSettings;
-
+ NotificationController notificationController =
+ Get.put(NotificationController());
Future getNotificationSettings() async {
// Get the current notification settings
NotificationSettings? notificationSettings =
@@ -78,34 +79,15 @@ class FirebaseMessagesController extends GetxController {
RemoteNotification? notification = message.notification;
AndroidNotification? android = notification?.android;
// if (notification != null && android != null) {
+
+ if (message.data.isNotEmpty && message.notification != null) {
+ fireBaseTitles(message);
+ }
if (message.data.isNotEmpty && message.notification != null) {
fireBaseTitles(message);
}
});
- FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {
- // if (message.notification!.title! == 'Order'.tr) {
- // if (Platform.isAndroid) {
- // NotificationController1()
- // .showNotification('Order'.tr, '', 'order', 'order_page_payload');
- // }
- // // await FirebaseMessagesController().showOverlayNotification(message);
- // var myListString = message.data['DriverList'];
- // // var points = message.data['PolylineJson'];
-
- // var myList = jsonDecode(myListString) as List;
- // // var myPoints = jsonDecode(points) as List;
- // driverToken = myList[14].toString();
- // // This is for location using and uploading status
- // Get.put(HomeCaptainController()).changeRideId();
- // update();
- // Get.to(() => OrderRequestPage(), arguments: {
- // 'myListString': myListString,
- // 'DriverList': myList,
- // // 'PolylineJson': myPoints,
- // 'body': message.notification!.body
- // });
- // }
- });
+ FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message.data.isNotEmpty && message.notification != null) {
@@ -117,7 +99,7 @@ class FirebaseMessagesController extends GetxController {
Future fireBaseTitles(RemoteMessage message) async {
if (message.notification!.title! == 'OrderSpeed'.tr) {
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
message.notification!.title.toString(),
message.notification!.body.toString(),
'order',
@@ -139,9 +121,25 @@ class FirebaseMessagesController extends GetxController {
// 'PolylineJson': myPoints,
'body': message.notification!.body
});
- } else if (message.notification!.title == 'Cancel Trip') {
+ } else if (message.notification!.title == 'OrderVIP') {
+ var myListString = message.data['DriverList'];
+
+ var myList = jsonDecode(myListString) as List;
+
+ // driverToken = myList[10].toString();
if (Platform.isAndroid) {
- NotificationController1().showNotification(
+ notificationController.showNotification(
+ 'OrderVIP'.tr, 'OrderVIP'.tr, 'order', '');
+ }
+ Get.to(VipOrderPage(), arguments: {
+ 'myListString': myListString,
+ 'DriverList': myList,
+ // 'PolylineJson': myPoints,
+ 'body': message.notification!.body
+ });
+ } else if (message.notification!.title == 'Cancel Trip'.tr) {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
'Cancel Trip'.tr, 'Passenger Cancel Trip'.tr, 'cancel', '');
}
cancelTripDialog();
@@ -149,8 +147,8 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['DriverList'];
var driverList = jsonDecode(myListString) as List;
if (Platform.isAndroid) {
- NotificationController1()
- .showNotification('VIP Order'.tr, '', 'order', '');
+ notificationController.showNotification(
+ 'VIP Order'.tr, '', 'order', '');
}
MyDialog().getDialog('VIP Order'.tr, 'midTitle', () {
sendNotificationToPassengerToken(
@@ -162,26 +160,19 @@ class FirebaseMessagesController extends GetxController {
});
// Get.to(const VipOrderPage());
- } else if (message.notification!.title! == 'message From passenger'.tr) {
- // passengerDialog(message.notification!.body!);
+ } else if (message.notification!.title == 'message From passenger') {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('message From passenger'.tr, ''.tr, 'ding', '');
+ notificationController.showNotification(
+ 'message From passenger'.tr, ''.tr, 'ding', '');
}
MyDialog().getDialog(
'message From passenger'.tr, message.notification!.body!, () {
- // FirebaseMessagesController().sendNotificationToPassengerToken(
- // 'Hi ,I will go now'.tr,
- // 'I will go now'.tr,
- // Get.find().driverToken, []);
- // Get.find()
- // .startTimerDriverWaitPassenger5Minute();
Get.back();
});
} else if (message.notification!.title == 'Cancel') {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('Cancel'.tr, ''.tr, 'cancel', '');
+ notificationController.showNotification(
+ 'Cancel'.tr, ''.tr, 'cancel', '');
}
MyDialog().getDialog(
'Passenger Cancel Trip'.tr,
@@ -192,14 +183,14 @@ class FirebaseMessagesController extends GetxController {
});
// cancelTripDialog1();
} else if (message.notification!.title! == 'token change') {
- // NotificationController1()
+ // notificationController
// .showNotification('token change'.tr, 'token change', 'cancel');
// GoogleSignInHelper.signOut();
GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'face detect') {
if (Platform.isAndroid) {
- NotificationController()
- .showNotification('face detect'.tr, ''.tr, 'tone2', '');
+ notificationController.showNotification(
+ 'face detect'.tr, ''.tr, 'tone2', '');
}
String result0 = await faceDetector();
// Handle the result here, e.g., show a dialog or update the UI
@@ -220,7 +211,7 @@ class FirebaseMessagesController extends GetxController {
// Get.snackbar('Hi ,I will go now', '',
// backgroundColor: AppColor.greenColor);
if (Platform.isAndroid) {
- NotificationController1().showNotification(
+ notificationController.showNotification(
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2', '');
}
update();
@@ -230,7 +221,7 @@ class FirebaseMessagesController extends GetxController {
var driverList = jsonDecode(myListString) as List;
// if (Platform.isAndroid) {
if (Platform.isAndroid) {
- NotificationController1().showNotification('Call Income'.tr,
+ notificationController.showNotification('Call Income'.tr,
message.notification!.body!, 'iphone_ringtone', '');
}
// }
@@ -248,7 +239,7 @@ class FirebaseMessagesController extends GetxController {
var driverList = jsonDecode(myListString) as List;
// if (Platform.isAndroid) {
if (Platform.isAndroid) {
- NotificationController1().showNotification('Call Income'.tr,
+ notificationController.showNotification('Call Income'.tr,
message.notification!.body!, 'iphone_ringtone', '');
}
// }
@@ -262,11 +253,8 @@ class FirebaseMessagesController extends GetxController {
} else if (message.notification!.title! ==
"Criminal Document Required".tr) {
if (Platform.isAndroid) {
- NotificationController1().showNotification(
- "Criminal Document Required".tr,
- message.notification!.body!,
- 'tone2',
- '');
+ notificationController.showNotification("Criminal Document Required".tr,
+ message.notification!.body!, 'tone2', '');
}
MyDialog().getDialog(
"Criminal Document Required".tr, 'You should have upload it .'.tr,
@@ -279,7 +267,7 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List;
if (Platform.isAndroid) {
- NotificationController1().showNotification(
+ notificationController.showNotification(
'Call End'.tr, message.notification!.body!, 'tone2', '');
}
// Assuming GetMaterialApp is initialized and context is valid for navigation
@@ -296,7 +284,7 @@ class FirebaseMessagesController extends GetxController {
);
} else if (message.notification!.title! == 'Order') {
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
message.notification!.title.toString(),
message.notification!.body.toString(),
'order',
@@ -318,7 +306,7 @@ class FirebaseMessagesController extends GetxController {
});
} else if (message.notification!.title! == 'Order Applied'.tr) {
if (Platform.isAndroid) {
- NotificationController1().showNotification(
+ notificationController.showNotification(
'The order Accepted by another Driver'.tr,
'We regret to inform you that another driver has accepted this order.'
.tr,
@@ -761,98 +749,6 @@ class FirebaseMessagesController extends GetxController {
}
}
- void sendNotificationToAnyWithoutData(
- String title, String body, String token, String tone,
- {int retryCount = 2}) async {
- try {
- String serviceAccountKeyJson = '''{
- "type": "service_account",
- "project_id": "ride-b1bd8",
- "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249",
- "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n",
- "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com",
- "client_id": "111210077025005706623",
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
- "token_uri": "https://oauth2.googleapis.com/token",
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com",
- "universe_domain": "googleapis.com"
-}
-'''; // As defined above
-
- // Initialize AccessTokenManager
- final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
-
- // Obtain an OAuth 2.0 access token
- final accessToken = await accessTokenManager.getAccessToken();
-
- // Send the notification
- final response = await http.post(
- Uri.parse(
- 'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'),
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer $accessToken',
- },
- body: jsonEncode({
- 'message': {
- 'token': token,
- 'notification': {
- 'title': title,
- 'body': body,
- },
- // 'data': {
- // 'DriverList': jsonEncode([]),
- // },
- 'android': {
- 'priority': 'high', // Set priority to high
- 'notification': {
- 'sound': tone,
- },
- },
- 'apns': {
- 'headers': {
- 'apns-priority': '10', // Set APNs priority to 10
- },
- 'payload': {
- 'aps': {
- 'sound': tone,
- },
- },
- },
- },
- }),
- );
-
- if (response.statusCode == 200) {
- print(
- 'Notification sent successfully. Status code: ${response.statusCode}');
- print('Response body: ${response.body}');
- } else {
- print(
- 'Failed to send notification. Status code: ${response.statusCode}');
-
- print('Response body: ${response.body}');
- if (retryCount > 0) {
- print('Retrying... Attempts remaining: $retryCount');
- await Future.delayed(
- const Duration(seconds: 2)); // Optional delay before retrying
- return sendNotificationToAnyWithoutData(title, body, token, tone,
- retryCount: retryCount - 1);
- }
- }
- } catch (e) {
- print('Error sending notification: $e');
- if (retryCount > 0) {
- print('Retrying... Attempts remaining: $retryCount');
- await Future.delayed(
- const Duration(seconds: 2)); // Optional delay before retrying
- return sendNotificationToAnyWithoutData(title, body, token, tone,
- retryCount: retryCount - 1);
- }
- }
- }
-
void sendNotificationToDriverMAP(
String title, String body, String token, List data, String tone,
{int retryCount = 2}) async {
@@ -946,79 +842,6 @@ class FirebaseMessagesController extends GetxController {
}
}
}
-
- void sendNotificationToDriverMapPolyline(String title, String body,
- String token, List data, String polylineJson, String tone) async {
- try {
- String serviceAccountKeyJson = '''{
- "type": "service_account",
- "project_id": "ride-b1bd8",
- "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249",
- "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n",
- "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com",
- "client_id": "111210077025005706623",
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
- "token_uri": "https://oauth2.googleapis.com/token",
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com",
- "universe_domain": "googleapis.com"
-}
-'''; // As defined above
-
- // Initialize AccessTokenManager
- final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
-
- // Obtain an OAuth 2.0 access token
- final accessToken = await accessTokenManager.getAccessToken();
-
- // Send the notification
- final response = await http.post(
- Uri.parse(
- 'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'),
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer $accessToken',
- },
- body: jsonEncode({
- 'message': {
- 'token': token,
- 'notification': {
- 'title': title,
- 'body': body,
- },
- 'data': {
- 'DriverList': jsonEncode(data),
- },
- 'android': {
- 'priority': 'high', // Set priority to high
- 'notification': {
- 'sound': tone,
- },
- },
- 'apns': {
- 'headers': {
- 'apns-priority': '10', // Set APNs priority to 10
- },
- 'payload': {
- 'aps': {
- 'sound': tone,
- },
- },
- },
- },
- }),
- );
-
- if (response.statusCode == 200) {
- // Notification sent successfully
- } else {
- // Handle error response
- 'Failed to send notification. Status code: ${response.statusCode}';
- }
- } catch (e) {
- // Handle other exceptions
- }
- }
}
class OverlayContent extends StatelessWidget {
diff --git a/lib/controller/firebase/local_notification.dart b/lib/controller/firebase/local_notification.dart
index cf94801..1f16930 100644
--- a/lib/controller/firebase/local_notification.dart
+++ b/lib/controller/firebase/local_notification.dart
@@ -1,4 +1,6 @@
+import 'dart:async';
import 'dart:convert';
+import 'dart:io';
import 'dart:typed_data';
import 'package:SEFER/constant/colors.dart';
@@ -6,7 +8,11 @@ import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart';
import 'package:SEFER/views/home/Captin/orderCaptin/order_speed_request.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:timezone/data/latest.dart' as tz;
+import 'package:timezone/timezone.dart' as tz;
+import '../../constant/box_name.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/notification/notification_captain.dart';
@@ -19,10 +25,17 @@ class NotificationController extends GetxController {
Future initNotifications() async {
const AndroidInitializationSettings android =
AndroidInitializationSettings('@mipmap/launcher_icon');
-
- const InitializationSettings initializationSettings =
- InitializationSettings(android: android);
-
+ DarwinInitializationSettings ios = DarwinInitializationSettings(
+ requestAlertPermission: true,
+ requestBadgePermission: true,
+ requestSoundPermission: true,
+ onDidReceiveLocalNotification:
+ (int id, String? title, String? body, String? payload) async {},
+ );
+ InitializationSettings initializationSettings =
+ InitializationSettings(android: android, iOS: ios);
+ tz.initializeTimeZones();
+ print('Notifications initialized');
await _flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
@@ -85,13 +98,266 @@ class NotificationController extends GetxController {
],
category: AndroidNotificationCategory.progress,
);
-
- NotificationDetails details = NotificationDetails(android: android);
+ DarwinNotificationDetails ios = const DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+ NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.show(0, title, message, details,
payload: jsonEncode({'title': title, 'data': payLoad}));
}
+ void scheduleNotificationAtSpecificTime(
+ String title, String message, String tone, int hour, int minute) async {
+ // Initialize and set Cairo time zone
+ tz.initializeTimeZones();
+ var cairoLocation;
+ if (box.read(BoxName.countryCode).toString() == 'Egypt') {
+ cairoLocation = tz.getLocation('Africa/Cairo');
+ } else {} // todo get for location country
+
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ showWhen: false,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
+
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
+
+ final now =
+ tz.TZDateTime.now(cairoLocation); // Use Cairo timezone for current time
+ tz.TZDateTime scheduledTime = tz.TZDateTime(
+ cairoLocation, now.year, now.month, now.day, hour, minute);
+
+ // If the scheduled time has already passed for today, schedule it for the next day
+ if (scheduledTime.isBefore(now)) {
+ scheduledTime = scheduledTime.add(const Duration(days: 1));
+ }
+
+ 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;
+ }
+ }
+ }
+
+ print('Current time: $now');
+ print('Scheduling notification for: $scheduledTime');
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ 0,
+ title,
+ message,
+ scheduledTime,
+ details,
+ androidAllowWhileIdle: true,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ matchDateTimeComponents:
+ DateTimeComponents.time, // Triggers daily at the same time
+ );
+ print('Notification scheduled successfully');
+ }
+
+ void scheduleNotificationAfter1Minute(
+ String title, String message, String tone) async {
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ showWhen: false,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
+
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
+
+// Schedule the notification to be shown after 1 minute
+ Timer.periodic(const Duration(seconds: 15), (timer) async {
+ final now = tz.TZDateTime.now(tz.local);
+ final scheduledTime = now.add(const Duration(seconds: 10));
+ Log.print('scheduledTime: ${scheduledTime}');
+ 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;
+ }
+ }
+ }
+
+ print('Scheduling notification for: $scheduledTime');
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ 0,
+ title,
+ message,
+ scheduledTime,
+ details,
+ androidAllowWhileIdle: true,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ matchDateTimeComponents: DateTimeComponents.time,
+ );
+ print('Notification scheduled successfully');
+ });
+ }
+
+ void scheduleDailyNotifications(
+ String title, String message, String tone) 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:00 AM and 3:00 PM daily
+ await _scheduleNotificationForTime(7, 0, title, message, details);
+ await _scheduleNotificationForTime(13, 0, title, message, details);
+ await _scheduleNotificationForTime(18, 0, title, message, details);
+ // await _scheduleNotificationForTime(0, 22, title, message, details);
+
+ print('Daily notifications scheduled successfully');
+ }
+
+// Helper function to get the next instance of a specific hour and minute
+ Future _scheduleNotificationForTime(int hour, int minute, String title,
+ String message, NotificationDetails details) async {
+ // Initialize and set Cairo timezone
+ tz.initializeTimeZones();
+ final cairoLocation = tz.getLocation('Africa/Cairo'); // Set Cairo timezone
+
+ final now = tz.TZDateTime.now(
+ cairoLocation); // Use Cairo timezone for the current time
+ tz.TZDateTime scheduledDate = tz.TZDateTime(
+ cairoLocation, now.year, now.month, now.day, hour, minute);
+
+ // If scheduled time is already past today, schedule it for the next day
+ if (scheduledDate.isBefore(now)) {
+ scheduledDate = scheduledDate.add(const Duration(days: 1));
+ }
+
+ print('Current time (Cairo): $now');
+ print('Scheduling notification for: $scheduledDate');
+
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ 0, // Use unique IDs if you want to manage each notification separately
+ title,
+ message,
+ scheduledDate,
+ details,
+ androidAllowWhileIdle: true,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ matchDateTimeComponents: DateTimeComponents.time,
+ );
+ print('Notification scheduled successfully for Cairo timezone');
+ }
+
+ void scheduleNotificationEvery10Hours(
+ String title, String message, String tone) async {
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ showWhen: false,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
+
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
+
+ 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;
+ }
+ }
+ }
+
+ Timer.periodic(const Duration(hours: 10), (timer) async {
+ final now = tz.TZDateTime.now(tz.local);
+ final scheduledTime = now.add(const Duration(minutes: 10));
+
+ print('Scheduling notification for: $scheduledTime');
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ 0,
+ title.tr,
+ message.tr,
+ scheduledTime,
+ details,
+ androidAllowWhileIdle: true,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ matchDateTimeComponents: DateTimeComponents.time,
+ );
+ });
+
+ print('Notifications scheduled every 5 seconds');
+ }
+
// Callback when the notification is tapped
void onDidReceiveNotificationResponse(NotificationResponse response) {
handleNotificationResponse(response);
diff --git a/lib/controller/functions/gemeni.dart b/lib/controller/functions/gemeni.dart
index 8b6bf38..8b520b2 100644
--- a/lib/controller/functions/gemeni.dart
+++ b/lib/controller/functions/gemeni.dart
@@ -626,6 +626,51 @@ class AI extends GetxController {
}
}
+ Future allMethodForAINewCar(
+ String prompt, String linkPHP, String imagePath, String carID) async {
+ isLoading = true;
+ update();
+
+ try {
+ await ImageController().choosImageNewCAr(linkPHP, imagePath);
+
+ // if (imagePath == 'driver_license') {
+ // await ImageController().choosFaceFromDriverLicense(linkPHP, 'face');
+ // }
+
+ await Future.delayed(const Duration(seconds: 2));
+
+ var extractedString =
+ await CRUD().arabicTextExtractByVisionAndAI(imagePath: imagePath);
+ var json = jsonDecode(extractedString);
+ var textValues = CRUD().extractTextFromLines(json);
+
+ DocumentType detectedType = checkDocumentType(textValues);
+ String expectedDocument = getExpectedDocument(imagePath);
+ String detectedDocument = getDetectedDocument(detectedType);
+
+ bool isCorrectDocument = (detectedType == getExpectedType(imagePath));
+
+ if (!isCorrectDocument) {
+ MyDialog().getDialog('incorrect_document_title'.tr,
+ '${'expected'.tr}: $expectedDocument\n${'detected'.tr}: $detectedDocument',
+ () {
+ Get.back();
+ });
+ } else {
+ // Process the correct document
+ await Get.put(AI()).anthropicAI(textValues, prompt, imagePath);
+ }
+ } catch (e) {
+ MyDialog().getDialog('error'.tr, 'error_processing_document'.tr, () {
+ Get.back();
+ });
+ } finally {
+ isLoading = false;
+ update();
+ }
+ }
+
String getExpectedDocument(String imagePath) {
switch (imagePath) {
case 'car_front':
diff --git a/lib/controller/functions/sms_egypt_controller.dart b/lib/controller/functions/sms_egypt_controller.dart
index d172e90..13169cf 100644
--- a/lib/controller/functions/sms_egypt_controller.dart
+++ b/lib/controller/functions/sms_egypt_controller.dart
@@ -30,8 +30,8 @@ class SmsEgyptController extends GetxController {
Future sendSmsEgypt(String phone, otp) async {
String sender = await getSender();
var body = jsonEncode({
- "username": AppInformation.appName,
- "password": AK.smsPasswordEgypt, //'E)Pu=an/@Z',
+ "username": 'Sefer',
+ "password": AK.smsPasswordEgypt,
"message": "${AppInformation.appName} app code is $otp\ncopy it to app",
"language": box.read(BoxName.lang) == 'en' ? "e" : 'r',
"sender": sender, //"Sefer Egy", // todo add sefer sender name
diff --git a/lib/controller/functions/upload_image.dart b/lib/controller/functions/upload_image.dart
index 09339c0..f2d11cf 100644
--- a/lib/controller/functions/upload_image.dart
+++ b/lib/controller/functions/upload_image.dart
@@ -139,8 +139,8 @@ class ImageController extends GetxController {
File compressedImage = await compressImage(processedImage);
print('link =$link');
- Log.print('link: ${link}');
-
+ // Log.print('link: ${link}');
+//n8u22456
await uploadImage(
compressedImage,
{
@@ -160,6 +160,65 @@ class ImageController extends GetxController {
}
}
+ choosImageNewCAr(String link, String imageType) async {
+ try {
+ final pickedImage = await picker.pickImage(
+ source: ImageSource.camera,
+ preferredCameraDevice: CameraDevice.rear,
+ );
+
+ if (pickedImage == null) return;
+
+ image = File(pickedImage.path);
+
+ croppedFile = await ImageCropper().cropImage(
+ sourcePath: image!.path,
+ uiSettings: [
+ AndroidUiSettings(
+ toolbarTitle: 'Cropper'.tr,
+ toolbarColor: AppColor.blueColor,
+ toolbarWidgetColor: AppColor.yellowColor,
+ initAspectRatio: CropAspectRatioPreset.original,
+ lockAspectRatio: false,
+ ),
+ IOSUiSettings(
+ title: 'Cropper'.tr,
+ ),
+ ],
+ );
+
+ if (croppedFile == null) return;
+
+ myImage = File(croppedFile!.path);
+ isloading = true;
+ update();
+
+ // Rotate the compressed image
+ File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
+ File compressedImage = await compressImage(processedImage);
+
+ print('link =$link');
+ // Log.print('link: ${link}');
+//n8u22456
+ await uploadNewCar(
+ compressedImage,
+ {
+ 'driverID':
+ box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
+ 'imageType': imageType,
+ },
+ link,
+ );
+ } catch (e) {
+ print('Error in choosImage: $e');
+ Get.snackbar('Image Upload Failed'.tr, e.toString(),
+ backgroundColor: AppColor.primaryColor);
+ } finally {
+ isloading = false;
+ update();
+ }
+ }
+
// choosFaceFromDriverLicense(String link, String imageType) async {
// final pickedImage = await picker.pickImage(
// source: ImageSource.camera,
@@ -278,6 +337,47 @@ class ImageController extends GetxController {
}
}
+ uploadNewCar(File file, Map data, String link) async {
+ var request = http.MultipartRequest(
+ 'POST',
+ Uri.parse(link),
+ );
+
+ var length = await file.length();
+ var stream = http.ByteStream(file.openRead());
+ var multipartFile = http.MultipartFile(
+ 'image',
+ stream,
+ length,
+ filename: basename(file.path),
+ );
+ request.headers.addAll({
+ 'Authorization':
+ 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
+ });
+ // Set the file name to the driverID
+ request.files.add(
+ http.MultipartFile(
+ 'image',
+ stream,
+ length,
+ filename: '${box.read(BoxName.driverID)}.jpg',
+ ),
+ );
+ data.forEach((key, value) {
+ request.fields[key] = value;
+ });
+ var myrequest = await request.send();
+ var res = await http.Response.fromStream(myrequest);
+ if (res.statusCode == 200) {
+ Log.print('jsonDecode(res.body): ${jsonDecode(res.body)}');
+ return jsonDecode(res.body);
+ } else {
+ throw Exception(
+ 'Failed to upload image: ${res.statusCode} - ${res.body}');
+ }
+ }
+
choosImagePicture(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
diff --git a/lib/controller/home/captin/map_driver_controller.dart b/lib/controller/home/captin/map_driver_controller.dart
index 3c5133c..e4ff59b 100644
--- a/lib/controller/home/captin/map_driver_controller.dart
+++ b/lib/controller/home/captin/map_driver_controller.dart
@@ -300,10 +300,11 @@ class MapDriverController extends GetxController {
}
// Get.find().changeToAppliedRide('Applied');
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'DriverIsGoingToPassenger',
box.read(BoxName.name).toString(),
tokenPassenger,
+ [],
'start.wav');
}
@@ -390,11 +391,8 @@ class MapDriverController extends GetxController {
'status': 'Begin',
});
}
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
- 'RideIsBegin',
- box.read(BoxName.name).toString(),
- tokenPassenger,
- 'start.wav');
+ FirebaseMessagesController().sendNotificationToDriverMAP('RideIsBegin',
+ box.read(BoxName.name).toString(), tokenPassenger, [], 'start.wav');
rideIsBeginPassengerTimer();
// var d = jsonDecode(res);
@@ -673,7 +671,7 @@ class MapDriverController extends GetxController {
'driverID': box.read(BoxName.driverID).toString(),
});
Future.delayed(const Duration(milliseconds: 300));
- FirebaseMessagesController().sendNotificationToPassengerToken(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'Driver Finish Trip',
'${'you will pay to Driver'.tr} $paymentAmount \$',
tokenPassenger,
diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart
index 81205de..62ac7bf 100644
--- a/lib/controller/local/translations.dart
+++ b/lib/controller/local/translations.dart
@@ -196,14 +196,22 @@ class MyTranslation extends Translations {
"Total Earnings": "إجمالي الأرباح",
"Choose from contact": "اختر من جهات الاتصال",
"Cancel": "إلغاء",
+ "Open App": "افتح التطبيق",
+ "Add new car": "أضف سيارة جديدة",
+ "Open the app to stay updated and ready for upcoming tasks.":
+ "افتح التطبيق لتبقى على اطلاع واستعداد للمهام القادمة.",
"No invitation found": "لم يتم العثور على دعوة",
'You are not near the passenger location':
"أنت لست بالقرب من موقع الراكب",
+ 'Please upload this license.': "يرجى تحميل هذه الرخصة.",
+ 'If your car license has the new design, upload the front side with two images.':
+ "إذا كانت رخصة سيارتك ذات التصميم الجديد، يرجى تحميل الوجه الأمامي بصورتين.",
'If you need assistance, contact us':
"إذا كنت بحاجة إلى المساعدة، تواصل معنا",
'You Can Cancel the Trip and get Cost From ':
"يمكنك إلغاء الرحلة والحصول على التكلفة من",
-
+ 'Please make sure to read the license carefully.':
+ "يرجى التأكد من قراءة الرخصة بعناية",
'Videos Tutorials': "فيديوهات تعليمية",
'Please go to the pickup location exactly':
"يرجى الذهاب إلى موقع الالتقاط بالضبط",
diff --git a/lib/controller/rate/rate_conroller.dart b/lib/controller/rate/rate_conroller.dart
index 780dabe..81669c8 100644
--- a/lib/controller/rate/rate_conroller.dart
+++ b/lib/controller/rate/rate_conroller.dart
@@ -87,10 +87,11 @@ class RateController extends GetxController {
// 'token': paymentToken4,
// 'driverID': box.read(BoxName.driverID).toString(),
// });
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'Wallet Added'.tr,
'Wallet Added${(remainingFee).toStringAsFixed(0)}'.tr,
Get.find().tokenPassenger,
+ [],
'tone2.wav');
walletChecked = 'true';
// }
diff --git a/lib/main.dart b/lib/main.dart
index 37f3565..5b16a68 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
+import 'dart:math';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/payment/paymob/paymob_response.dart';
import 'package:SEFER/views/home/Captin/orderCaptin/order_request_page.dart';
@@ -18,6 +19,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'constant/api_key.dart';
import 'constant/info.dart';
+import 'constant/notification.dart';
import 'controller/firebase/firbase_messge.dart';
import 'controller/firebase/local_notification.dart';
import 'controller/functions/location_controller.dart';
@@ -58,14 +60,13 @@ Future backgroundMessageHandler(RemoteMessage message) async {
Log.print('Error decoding JSON: $e');
myList = [];
}
-
- await Future.delayed(const Duration(seconds: 1));
NotificationController().showNotification(
message.notification!.title.toString(),
message.notification!.body.toString(),
'order',
myListString,
);
+ await Future.delayed(const Duration(seconds: 1));
bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
@@ -137,9 +138,23 @@ void main() async {
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
// NotificationController1().initNotifications();
// NotificationController().initNotifications();
- if (Platform.isAndroid) {
- await Get.put(NotificationController()).initNotifications();
- }
+ // if (Platform.isAndroid) {
+ // await Get.put(NotificationController()).initNotifications();
+ // }
+ NotificationController notificationController =
+ Get.put(NotificationController());
+ await notificationController.initNotifications();
+
+ // Generate a random index to pick a message
+ final random = Random();
+ final randomMessage = driverMessages[random.nextInt(driverMessages.length)];
+
+ // Schedule the notification with the random message
+ notificationController.scheduleDailyNotifications(
+ randomMessage.split(':')[0],
+ randomMessage.split(':')[1],
+ "ding",
+ );
await Future.wait([
FirebaseMessagesController().getNotificationSettings(),
diff --git a/lib/views/auth/captin/driver_car_controller.dart b/lib/views/auth/captin/driver_car_controller.dart
new file mode 100644
index 0000000..04fad6c
--- /dev/null
+++ b/lib/views/auth/captin/driver_car_controller.dart
@@ -0,0 +1,76 @@
+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/controller/functions/crud.dart';
+import 'package:SEFER/main.dart';
+import 'package:get/get.dart';
+
+class DriverCarController extends GetxController {
+ bool isLoading = false;
+ List cars = [];
+ int? carId;
+ fetchCatrsForDrivers() async {
+ isLoading = true;
+ update();
+ var res = await CRUD().get(link: AppLink.getNewCarsDrivers, payload: {
+ "driverID": box.read(BoxName.driverID).toString(),
+ });
+ if (res != 'failure') {
+ var d = jsonDecode(res)['message'];
+ cars = d;
+ carId = cars.isEmpty ? 1 : cars.length + 1;
+ }
+ isLoading = false;
+ update();
+ }
+
+ addCarsForDrivers(
+ String vin,
+ String car_plate,
+ String make,
+ String model,
+ String year,
+ String expiration_date,
+ String color,
+ String color_hex,
+ String address,
+ String owner,
+ String registration_date,
+ String displacement,
+ String fuel) async {
+ var res = await CRUD().post(
+ link: AppLink.addNewCarsDrivers,
+ payload: {
+ "driverID": box.read(BoxName.driverID).toString(),
+ "vin": vin,
+ "car_plate": car_plate,
+ "make": make,
+ "model": model,
+ "year": year,
+ "expiration_date": expiration_date,
+ "color": color,
+ "owner": owner,
+ "color_hex": color_hex,
+ "address": address,
+ "displacement": displacement,
+ "fuel": fuel,
+ "registration_date": registration_date,
+ },
+ );
+ if (res != 'failure') {
+ Get.snackbar('Success'.tr, '', backgroundColor: AppColor.greenColor);
+ fetchCatrsForDrivers();
+ } else {
+ Get.snackbar('Error'.tr, '', backgroundColor: AppColor.redColor);
+ }
+ }
+
+ removeCar(String car) async {}
+ @override
+ void onInit() {
+ fetchCatrsForDrivers();
+ super.onInit();
+ }
+}
diff --git a/lib/views/home/Captin/home_captain/drawer_captain.dart b/lib/views/home/Captin/home_captain/drawer_captain.dart
index 7b21e99..ec3acf3 100644
--- a/lib/views/home/Captin/home_captain/drawer_captain.dart
+++ b/lib/views/home/Captin/home_captain/drawer_captain.dart
@@ -98,7 +98,7 @@ class CupertinoDrawerCaptain extends StatelessWidget {
_buildDrawerItem(
icon: CupertinoIcons.mail,
text: "Contact Us".tr,
- onTap: () => Get.to(() => const SettingsCaptain()),
+ onTap: () => Get.to(() => ContactUsPage()),
),
_buildDivider(),
_buildDrawerItem(
diff --git a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart
index 346f368..1a945e7 100644
--- a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart
+++ b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart
@@ -1,4 +1,5 @@
import 'dart:convert';
+import 'dart:math';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/firebase/local_notification.dart';
@@ -10,8 +11,12 @@ import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
+import 'package:timezone/data/latest.dart' as tz;
+import 'package:timezone/timezone.dart' as tz;
import '../../../../../constant/colors.dart';
+import '../../../../../constant/notification.dart';
import '../../../../../controller/functions/audio_controller.dart';
+import '../../../../../print.dart';
import '../../../../Rate/ride_calculate_driver.dart';
import '../../../../../controller/functions/location_controller.dart';
import '../../driver_map_page.dart';
@@ -180,30 +185,53 @@ GetBuilder leftMainMenuCaptainIcons() {
),
// Platform.isAndroid
// ?
- // AnimatedContainer(
- // duration: const Duration(microseconds: 200),
- // width: controller.widthMapTypeAndTraffic,
- // decoration: BoxDecoration(
- // color: AppColor.secondaryColor,
- // border: Border.all(color: AppColor.blueColor),
- // borderRadius: BorderRadius.circular(15)),
- // child: Builder(builder: (context) {
- // return IconButton(
- // onPressed: () async {
- // // NotificationController().showNotification(
- // // ' message.notification!.title.toString()',
- // // ' message.notification!.body.toString()',
- // // 'order',
- // // '');
- // },
- // icon: const Icon(
- // FontAwesome5.window_close,
- // size: 29,
- // color: AppColor.blueColor,
- // ),
- // );
- // }),
- // ),
+ AnimatedContainer(
+ duration: const Duration(microseconds: 200),
+ width: controller.widthMapTypeAndTraffic,
+ decoration: BoxDecoration(
+ color: AppColor.secondaryColor,
+ border: Border.all(color: AppColor.blueColor),
+ borderRadius: BorderRadius.circular(15)),
+ child: Builder(builder: (context) {
+ return IconButton(
+ onPressed: () async {
+ // NotificationController().showNotification(
+ // ' message.notification!.title.toString()',
+ // ' message.notification!.body.toString()',
+ // 'order',
+ // '');
+
+ NotificationController notificationController =
+ Get.put(NotificationController());
+ await notificationController.initNotifications();
+ final random = Random();
+ final randomMessage =
+ driverMessages[random.nextInt(driverMessages.length)];
+ Log.print(
+ ' randomMessage.split[0]: ${randomMessage.split(':')[0]}');
+ Log.print(
+ ' randomMessage.split([1]: ${randomMessage.split(':')[1]}');
+ // Schedule the notification with the random message
+ notificationController.showNotification(
+ randomMessage.split(':')[0],
+ randomMessage.split(':')[1],
+ "ding",
+ '');
+
+ // notificationController.scheduleNotificationEvery10Hours(
+ // "افتح التطبيق".tr,
+ // "افتح التطبيق لتبقى على اطلاع واستعداد للمهام القادمة.".tr,
+ // "ding",
+ // );
+ },
+ icon: const Icon(
+ FontAwesome5.window_close,
+ size: 29,
+ color: AppColor.blueColor,
+ ),
+ );
+ }),
+ ),
// : const SizedBox(),
// AnimatedContainer(
// duration: const Duration(microseconds: 200),
diff --git a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart
index 8f45804..4a4cfe2 100644
--- a/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart
+++ b/lib/views/home/Captin/mapDriverWidgets/passenger_info_window.dart
@@ -101,12 +101,13 @@ class PassengerInfoWindow extends StatelessWidget {
children: [
InkWell(
onTap: () {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Where are you, sir?"
.tr,
controller
.tokenPassenger,
+ [],
'ding.wav');
Get.back();
},
@@ -132,12 +133,13 @@ class PassengerInfoWindow extends StatelessWidget {
),
InkWell(
onTap: () {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"I've been trying to reach you but your phone is off."
.tr,
controller
.tokenPassenger,
+ [],
'ding.wav');
Get.back();
},
@@ -163,12 +165,13 @@ class PassengerInfoWindow extends StatelessWidget {
),
InkWell(
onTap: () {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late, I'm waiting for you at the specified location."
.tr,
controller
.tokenPassenger,
+ [],
'ding.wav');
Get.back();
},
@@ -194,13 +197,14 @@ class PassengerInfoWindow extends StatelessWidget {
),
InkWell(
onTap: () {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
+ FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late"
.tr,
controller
.tokenPassenger,
- 'ding.wav');
+ [],
+ 'cancel.wav');
Get.back();
},
child: Container(
@@ -247,10 +251,11 @@ class PassengerInfoWindow extends StatelessWidget {
IconButton(
onPressed:
() {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
- 'message From Driver'.tr,
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'message From Driver',
controller.messageToPassenger.text,
controller.tokenPassenger,
+ [],
'ding.wav');
controller
.messageToPassenger
@@ -471,13 +476,13 @@ class PassengerInfoWindow extends StatelessWidget {
140) {
// Notify Passenger
FirebaseMessagesController()
- .sendNotificationToPassengerToken(
- 'Hi, I Arrive at your site',
+ .sendNotificationToDriverMAP(
+ 'Hi ,I Arrive your site',
'I Arrive at your site'
.tr,
controller.tokenPassenger,
[],
- 'start.wav',
+ 'ding.wav',
);
controller
.startTimerToShowDriverWaitPassengerDuration();
@@ -553,7 +558,7 @@ class PassengerInfoWindow extends StatelessWidget {
'Are you sure to cancel?'.tr,
'', () async {
FirebaseMessagesController()
- .sendNotificationToPassengerToken(
+ .sendNotificationToDriverMAP(
'Driver Cancelled Your Trip',
'You will need to pay the cost to the driver, or it will be deducted from your next trip'
.tr,
diff --git a/lib/views/home/Captin/orderCaptin/order_speed_request.dart b/lib/views/home/Captin/orderCaptin/order_speed_request.dart
index 8c1da67..4b46d93 100644
--- a/lib/views/home/Captin/orderCaptin/order_speed_request.dart
+++ b/lib/views/home/Captin/orderCaptin/order_speed_request.dart
@@ -330,7 +330,7 @@ class OrderSpeedRequest extends StatelessWidget {
if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
link:
- "${AppLink.endPoint}/rides/updateStausFromSpeed.php",
+ "${AppLink.endPoint}/ride/rides/updateStausFromSpeed.php",
payload: {
'id': orderRequestController.myList[16],
'rideTimeStart': DateTime.now().toString(),
@@ -364,6 +364,17 @@ class OrderSpeedRequest extends StatelessWidget {
box.read(BoxName.nameDriver).toString(),
box.read(BoxName.tokenDriver).toString(),
];
+ FirebaseMessagesController()
+ .sendNotificationToPassengerToken(
+ 'Accepted Ride',
+ 'your ride is applied'.tr,
+ // arguments['DriverList'][9].toString(),
+ orderRequestController
+ .arguments['DriverList'][9]
+ .toString(),
+ // box.read(BoxName.tokenDriver).toString(),
+ bodyToPassenger,
+ 'start.wav');
await CRUD().postFromDialogue(
link: AppLink.addDriverOrder,
payload: {
@@ -388,7 +399,7 @@ class OrderSpeedRequest extends StatelessWidget {
if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
link:
- "${AppLink.endPoint}/driver_order/add.php",
+ "${AppLink.endPoint}/ride/driver_order/add.php",
payload: {
'driver_id': orderRequestController
.myList[6]
@@ -400,17 +411,7 @@ class OrderSpeedRequest extends StatelessWidget {
'status': 'Apply'
});
}
- FirebaseMessagesController()
- .sendNotificationToPassengerToken(
- 'Apply Ride',
- 'your ride is applied'.tr,
- // arguments['DriverList'][9].toString(),
- orderRequestController
- .arguments['DriverList'][9]
- .toString(),
- // box.read(BoxName.tokenDriver).toString(),
- bodyToPassenger,
- 'start.wav');
+
Get.back();
// 'Arguments passed to PassengerLocationMapPage:');
diff --git a/lib/views/home/Captin/orderCaptin/vip_order_page.dart b/lib/views/home/Captin/orderCaptin/vip_order_page.dart
index fb268a6..cf1fe8d 100644
--- a/lib/views/home/Captin/orderCaptin/vip_order_page.dart
+++ b/lib/views/home/Captin/orderCaptin/vip_order_page.dart
@@ -1,16 +1,69 @@
+import 'dart:convert';
+
+import 'package:SEFER/constant/box_name.dart';
+import 'package:SEFER/constant/links.dart';
+import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
+import '../../../../main.dart';
+
class VipOrderPage extends StatelessWidget {
const VipOrderPage({super.key});
@override
Widget build(BuildContext context) {
+ Get.put(VipOrderController());
return MyScafolld(
title: 'VIP Order'.tr,
- body: [],
+ body: [
+ GetBuilder(builder: (vipOrderController) {
+ return SafeArea(
+ child: Column(
+ children: [],
+ ));
+ })
+ ],
isleading: true,
);
}
}
+
+class VipOrderController extends GetxController {
+ bool isLoading = false;
+ final arguments = Get.arguments;
+ late String body;
+ List tripData = [];
+ var myList;
+
+ initilize() {
+ final myListString = arguments['myListString'];
+
+ if (arguments['DriverList'] == null || arguments['DriverList'].isEmpty) {
+ myList = jsonDecode(myListString);
+ } else {
+ myList = arguments['DriverList'];
+ }
+
+ body = arguments['body'];
+ update();
+ }
+
+ fetchOrder() async {
+ var res = await CRUD().get(link: AppLink.getMishwari, payload: {
+ 'driverId': box.read(BoxName.driverID).toString(),
+ });
+ if (res != 'failure') {
+ tripData = jsonDecode(res)['message'];
+ update();
+ }
+ }
+
+ @override
+ void onInit() async {
+ await initilize();
+ fetchOrder();
+ super.onInit();
+ }
+}
diff --git a/lib/views/home/profile/captains_cars.dart b/lib/views/home/profile/captains_cars.dart
new file mode 100644
index 0000000..01150b4
--- /dev/null
+++ b/lib/views/home/profile/captains_cars.dart
@@ -0,0 +1,105 @@
+import 'package:SEFER/constant/colors.dart';
+import 'package:SEFER/constant/style.dart';
+import 'package:SEFER/views/widgets/my_scafold.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 '../../auth/captin/driver_car_controller.dart';
+import '../../widgets/elevated_btn.dart';
+import 'cars_inserting_page.dart';
+
+class CaptainsCars extends StatelessWidget {
+ const CaptainsCars({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ Get.put(DriverCarController());
+ return MyScafolld(
+ title: "Add new car".tr,
+ body: [
+ Column(
+ children: [
+ MyElevatedButton(
+ title: "Add new car".tr,
+ onPressed: () async {
+ Get.to(() => CarsInsertingPage());
+ },
+ ),
+ Expanded(
+ child: GetBuilder(
+ builder: (controller) {
+ return controller.isLoading
+ ? const MyCircularProgressIndicator()
+ : ListView.builder(
+ itemCount: controller.cars.length,
+ itemBuilder: (context, index) {
+ final car = controller.cars[index];
+ return Padding(
+ padding: const EdgeInsets.all(4.0),
+ child: Card(
+ elevation: 2,
+ child: ListTile(
+ leading: Icon(
+ Fontisto.car,
+ size: 50,
+ color: Color(int.parse(car['color_hex']
+ .replaceFirst('#', '0xff'))),
+ ),
+ title: Text(
+ car['make'],
+ style: AppStyle.title,
+ ), // Assuming `make` is a field in each car item
+ subtitle: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ car['model'],
+ style: AppStyle.title,
+ ),
+ Container(
+ decoration: BoxDecoration(
+ border: Border.all(
+ color: AppColor.blueColor)),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 4),
+ child: Text(
+ car['car_plate'],
+ style: AppStyle.title,
+ ),
+ ),
+ ),
+ Text(
+ car['year'],
+ style: AppStyle.title,
+ ),
+ ],
+ ), // Assuming `model` is a field in each car item
+ trailing: IconButton(
+ icon: const Icon(Icons.delete),
+ onPressed: () {
+ // Add logic here to remove a car
+ controller
+ .removeCar(car['id'].toString());
+ },
+ ),
+ onTap: () {
+ // Add logic to view or edit the car details
+ },
+ ),
+ ),
+ );
+ },
+ );
+ },
+ ),
+ ),
+ ],
+ )
+ ],
+ isleading: true);
+ }
+}
diff --git a/lib/views/home/profile/cars_inserting_page.dart b/lib/views/home/profile/cars_inserting_page.dart
new file mode 100644
index 0000000..2af3b11
--- /dev/null
+++ b/lib/views/home/profile/cars_inserting_page.dart
@@ -0,0 +1,300 @@
+import 'package:SEFER/splash_screen_page.dart';
+import 'package:SEFER/views/widgets/elevated_btn.dart';
+import 'package:SEFER/views/widgets/my_scafold.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+
+import '../../../constant/colors.dart';
+import '../../../constant/links.dart';
+import '../../../constant/style.dart';
+import '../../../controller/functions/gemeni.dart';
+import '../../auth/captin/driver_car_controller.dart';
+
+class CarsInsertingPage extends StatelessWidget {
+ CarsInsertingPage({super.key});
+ final driverCarController = Get.put(DriverCarController());
+ @override
+ Widget build(BuildContext context) {
+ Get.put(AI());
+ return MyScafolld(
+ title: 'Insert New Car'.tr,
+ body: [
+ Container(
+ color: AppColor.accentColor.withOpacity(.2),
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ egyptCarLicenceFront(),
+ egyptCarLicenceBack(),
+ const SizedBox(height: 10),
+ Text('Please make sure to read the license carefully.'.tr),
+ Text(
+ 'If your car license has the new design, upload the front side with two images.'
+ .tr),
+ const SizedBox(height: 10),
+ MyElevatedButton(
+ title: 'Please upload this license.'.tr,
+ onPressed: () {
+ final aiFront =
+ Get.find().responseIdCardDriverEgyptFront;
+ final aiBack =
+ Get.find().responseIdCardDriverEgyptBack;
+ driverCarController.addCarsForDrivers(
+ aiBack['vin'].toString(),
+ aiBack['car_plate'].toString(),
+ aiBack['make'].toString(),
+ aiBack['model'].toString(),
+ aiBack['year'].toString(),
+ aiFront['expiration_date'].toString(),
+ aiBack['color'].toString(),
+ aiBack['color_hex'].toString(),
+ aiFront['address'].toString(),
+ aiFront['owner'].toString(),
+ aiBack['registration_date'].toString(),
+ aiBack['displacement'].toString(),
+ aiBack['fuel'].toString(),
+ );
+ })
+ ],
+ ),
+ ),
+ )
+ ],
+ isleading: true);
+ }
+}
+
+GetBuilder egyptCarLicenceFront() {
+ return GetBuilder(
+ builder: (ai) {
+ if (ai.responseIdCardDriverEgyptFront.isNotEmpty) {
+ // No need to access ai.responseIdCardDriverEgyptBack anymore
+ final licenseExpiryDate = DateTime.parse(
+ ai.responseIdCardDriverEgyptFront['LicenseExpirationDate']);
+
+ // Check if license has expired
+ final today = DateTime.now();
+ final isLicenseExpired = licenseExpiryDate.isBefore(today);
+
+ return Card(
+ elevation: 4.0,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(16.0),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Text('Vehicle Details Front'.tr,
+ style: AppStyle.headTitle2),
+ IconButton(
+ onPressed: () async {
+ ai.allMethodForAI(ai.prompts[3]['prompt'].toString(),
+ AppLink.uploadEgypt, 'car_front');
+ },
+ icon: const Icon(Icons.refresh),
+ ),
+ ],
+ ),
+ const SizedBox(height: 8.0),
+ const Divider(color: AppColor.accentColor),
+ const SizedBox(height: 8.0),
+ // Removed Make, Model, etc. as they are not available
+
+ Text(
+ '${'Plate Number'.tr}: ${ai.responseIdCardDriverEgyptFront['car_plate']}',
+ ),
+ const SizedBox(height: 8.0),
+ Text(
+ '${'Owner Name'.tr}: ${ai.responseIdCardDriverEgyptFront['owner']}',
+ ),
+ const SizedBox(height: 8.0),
+ Text(
+ '${'Address'.tr}: ${ai.responseIdCardDriverEgyptFront['address']}',
+ ),
+ const SizedBox(height: 8.0),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ '${'License Expiry Date'.tr}: ${licenseExpiryDate.toString().substring(0, 10)}',
+ style: TextStyle(
+ color: isLicenseExpired ? Colors.red : Colors.green,
+ ),
+ ),
+ // Removed Fuel as it's not available
+ ],
+ ),
+ // Removed Inspection Date as it's not available
+ ],
+ ),
+ ),
+ );
+ }
+ return Card(
+ child: InkWell(
+ onTap: () async {
+ ai.allMethodForAINewCar(ai.prompts[3]['prompt'].toString(),
+ AppLink.uploadEgypt, 'car_front', 'carId'); //todo
+ },
+ child: Column(
+ children: [
+ Image.asset(
+ 'assets/images/3.png',
+ height: Get.height * .25,
+ width: double.maxFinite,
+ fit: BoxFit.fitHeight,
+ ),
+ Text(
+ 'Capture an Image of Your car license front '.tr,
+ style: AppStyle.title,
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+}
+
+GetBuilder egyptCarLicenceBack() {
+ return GetBuilder(
+ builder: (ai) {
+ if (ai.responseIdCardDriverEgyptBack.isNotEmpty) {
+ // Get the tax expiry date from the response
+ final taxExpiryDate =
+ ai.responseIdCardDriverEgyptBack['tax_expiry'].toString();
+ // final displacement = ai.responseIdCardDriverEgyptBack['displacement'];
+ // if (int.parse(displacement) < 1000) {}
+ // Get the inspection date from the response
+ final inspectionDate =
+ ai.responseIdCardDriverEgyptBack['inspection_date'].toString();
+ final year = int.parse(inspectionDate.toString().split('-')[0]);
+
+// Set inspectionDateTime to December 31st of the given year
+ final inspectionDateTime = DateTime(year, 12, 31);
+ String carBackLicenseExpired =
+ inspectionDateTime.toString().split(' ')[0];
+// Get the current date
+ final today = DateTime.now();
+
+// Try parsing the tax expiry date. If it fails, set it to null.
+ final taxExpiryDateTime = DateTime.tryParse(taxExpiryDate ?? '');
+ final isExpired =
+ taxExpiryDateTime != null && taxExpiryDateTime.isBefore(today);
+// Check if the inspection date is before today
+ bool isInspectionExpired = inspectionDateTime.isBefore(today);
+
+ return Card(
+ elevation: 4.0,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(16.0),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text('Vehicle Details Back'.tr, style: AppStyle.headTitle2),
+ IconButton(
+ onPressed: () async {
+ ai.allMethodForAI(ai.prompts[4]['prompt'].toString(),
+ AppLink.uploadEgypt, 'car_back');
+ },
+ icon: const Icon(Icons.refresh),
+ ),
+ ],
+ ),
+ const SizedBox(height: 8.0),
+ const Divider(color: AppColor.accentColor),
+ const SizedBox(height: 8.0),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ '${'Make'.tr}: ${ai.responseIdCardDriverEgyptBack['make']}'),
+ Text(
+ '${'Model'.tr}: ${ai.responseIdCardDriverEgyptBack['model']}'),
+ ],
+ ),
+ const SizedBox(height: 8.0),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ '${'Year'.tr}: ${ai.responseIdCardDriverEgyptBack['year']}'),
+ Text(
+ '${'Chassis'.tr}: ${ai.responseIdCardDriverEgyptBack['chassis']}'),
+ ],
+ ),
+ const SizedBox(height: 8.0),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ '${'Color'.tr}: ${ai.responseIdCardDriverEgyptBack['color']}'),
+ Text(
+ '${'Displacement'.tr}: ${ai.responseIdCardDriverEgyptBack['displacement']} cc'),
+ ],
+ ),
+ const SizedBox(height: 8.0),
+ Text(
+ '${'Fuel'.tr}: ${ai.responseIdCardDriverEgyptBack['fuel']}'),
+ const SizedBox(height: 8.0),
+ if (taxExpiryDateTime != null)
+ Text(
+ '${'Tax Expiry Date'.tr}: $taxExpiryDate',
+ style: TextStyle(
+ color: isExpired ? Colors.red : Colors.green,
+ ),
+ ),
+ const SizedBox(height: 8.0),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ '${'Inspection Date'.tr}: $carBackLicenseExpired',
+ style: TextStyle(
+ color: isInspectionExpired ? Colors.red : Colors.green,
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+ return Card(
+ child: InkWell(
+ onTap: () async {
+ ai.allMethodForAI(ai.prompts[4]['prompt'].toString(),
+ AppLink.uploadEgypt, 'car_back');
+ },
+ child: Column(
+ children: [
+ Image.asset(
+ 'assets/images/4.png',
+ height: Get.height * .25,
+ width: double.maxFinite,
+ fit: BoxFit.fitHeight,
+ ),
+ Text(
+ 'Capture an Image of Your car license back'.tr,
+ style: AppStyle.title,
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+}
diff --git a/lib/views/home/profile/profile_captain.dart b/lib/views/home/profile/profile_captain.dart
index d65eb71..3409167 100644
--- a/lib/views/home/profile/profile_captain.dart
+++ b/lib/views/home/profile/profile_captain.dart
@@ -1,5 +1,6 @@
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/payment/captain_wallet_controller.dart';
+import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -7,6 +8,7 @@ import 'package:SEFER/controller/profile/captain_profile_controller.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import '../my_wallet/walet_captain.dart';
+import 'captains_cars.dart';
class ProfileCaptain extends StatelessWidget {
ProfileCaptain({super.key});
@@ -41,6 +43,15 @@ class ProfileCaptain extends StatelessWidget {
),
),
),
+ const SizedBox(
+ height: 5,
+ ),
+ MyElevatedButton(
+ title: 'Show my Cars'.tr,
+ onPressed: () async {
+ Get.to(() => CaptainsCars());
+ },
+ ),
SizedBox(
height: Get.height * .8,
child: DriverProfileCard(