From 21f5105fa1cc5546c035125defde4dab986e92aa Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Fri, 26 Jun 2026 02:00:23 +0300 Subject: [PATCH] Update: 2026-06-26 02:00:23 --- backend/serviceapp/login.php | 8 ++- .../controller/auth/register_controller.dart | 2 +- .../lib/controller/functions/crud.dart | 27 +++++++++ siro_service/lib/controller/local/ar_eg.dart | 18 +++++- siro_service/lib/controller/local/ar_jo.dart | 18 +++++- siro_service/lib/controller/local/ar_sy.dart | 18 +++++- .../lib/controller/login_controller.dart | 59 +++++++++++-------- .../pages/alexandria_besr_driver.dart | 8 +-- .../pages/best_driver_page.dart | 8 +-- .../mainController/pages/driver_page.dart | 8 +-- .../pages/giza_best_driver.dart | 8 +-- .../pages/passengers_cant_regster.dart | 2 +- .../mainController/pages/passengers_page.dart | 8 +-- .../pages/review_driver_page.dart | 22 +++---- .../pages/ride_monitor_page.dart | 36 +++-------- .../mainController/pages/welcome_call.dart | 8 +-- .../review_driver_controller.dart | 24 ++++---- .../lib/views/auth/register_page.dart | 2 +- .../lib/views/widgets/elevated_btn.dart | 3 +- siro_service/lib/views/widgets/my_dialog.dart | 2 +- 20 files changed, 175 insertions(+), 114 deletions(-) diff --git a/backend/serviceapp/login.php b/backend/serviceapp/login.php index 7a60deae..bdc4a055 100644 --- a/backend/serviceapp/login.php +++ b/backend/serviceapp/login.php @@ -20,10 +20,14 @@ try { // البحث بالبصمة للموظف $fpHash = hash('sha256', $fingerprint); + $foundByFingerprint = false; $sql = "SELECT * FROM `users` WHERE `fingerprint_hash` = :fp AND `user_type` = 'service' LIMIT 1"; $stmt = $con->prepare($sql); $stmt->execute([':fp' => $fpHash]); $user = $stmt->fetch(PDO::FETCH_ASSOC); + if ($user) { + $foundByFingerprint = true; + } // إذا لم يتم العثور بالبصمة، وتم تمرير الإيميل (تسجيل دخول لأول مرة أو من جهاز جديد) if (!$user && !empty($email)) { @@ -109,7 +113,9 @@ try { "message" => "Login successful", "data" => $user, "jwt" => $jwt, - "expires_in" => $expires_in + "expires_in" => $expires_in, + "hmac" => hash_hmac('sha256', (string)$user['id'], getenv('SECRET_KEY_HMAC') ?: ''), + "otp_required" => !$foundByFingerprint ]); diff --git a/siro_service/lib/controller/auth/register_controller.dart b/siro_service/lib/controller/auth/register_controller.dart index 129e5bd2..90720972 100644 --- a/siro_service/lib/controller/auth/register_controller.dart +++ b/siro_service/lib/controller/auth/register_controller.dart @@ -49,7 +49,7 @@ class RegisterController extends GetxController { // Request OTP bool otpSent = await _sendOtp(phone.text); if (otpSent) { - _showOtpDialog(phone.text, res['message']?['message'] ?? "تم تقديم طلبك بنجاح. يرجى انتظار موافقة الإدارة."); + _showOtpDialog(phone.text, res['message']?['message'] ?? 'Your request has been submitted successfully. Please wait for admin approval.'.tr); } else { mySnackbarError('Failed to send OTP'.tr); } diff --git a/siro_service/lib/controller/functions/crud.dart b/siro_service/lib/controller/functions/crud.dart index e56e0691..078ff6ac 100644 --- a/siro_service/lib/controller/functions/crud.dart +++ b/siro_service/lib/controller/functions/crud.dart @@ -25,6 +25,33 @@ class CRUD { static DateTime _lastErrorTimestamp = DateTime(2000); static const Duration _errorLogDebounceDuration = Duration(minutes: 1); + // ── Country-aware phone normalizer ───────────────────────────── + static String normalizePhone(String input) { + final country = box.read(BoxName.countryCode)?.toString() ?? 'Jordan'; + + final clean = input.replaceAll(RegExp(r'\D+'), ''); + switch (country) { + case 'Syria': + if (clean.length == 10 && clean.startsWith('09')) + return '963${clean.substring(1)}'; + if (clean.length == 12 && clean.startsWith('963')) return clean; + if (clean.length == 9 && clean.startsWith('9')) return '963$clean'; + return clean; + case 'Egypt': + if (clean.length == 11 && clean.startsWith('01')) + return '20${clean.substring(1)}'; + if (clean.length == 13 && clean.startsWith('20')) return clean; + return clean; + case 'Jordan': + default: + if (clean.length == 10 && clean.startsWith('07')) + return '962${clean.substring(1)}'; + if (clean.length == 12 && clean.startsWith('962')) return clean; + if (clean.length == 9 && clean.startsWith('7')) return '962$clean'; + return clean; + } + } + // ── JWT Validity Check (No external libs) ────────────────────── static bool isJwtValid(String? token) { if (token == null || token.isEmpty) return false; diff --git a/siro_service/lib/controller/local/ar_eg.dart b/siro_service/lib/controller/local/ar_eg.dart index f87ca204..d5cfdf58 100644 --- a/siro_service/lib/controller/local/ar_eg.dart +++ b/siro_service/lib/controller/local/ar_eg.dart @@ -93,7 +93,7 @@ final Map ar_eg = { "Camera not initilaized yet": "Camera not initilaized yet", "Can I cancel my ride?": "Can I cancel my ride?", "Can we know why you want to cancel Ride ?": "Can we know why you want to cancel Ride ?", - "Cancel": "Cancel", + "Cancel": "إلغاء", "Cancel Ride": "Cancel Ride", "Cancel Trip": "Cancel Trip", "Canceled": "Canceled", @@ -142,7 +142,7 @@ final Map ar_eg = { "Created At": "أنشئ في", "created time": "created time", "Credit card is": "Credit card is", - "Criminal Record": "Criminal Record", + "Criminal Record": "سجل جنائي", "Cropper": "Cropper", "Current Location": "Current Location", "cyan": "سماوي", @@ -888,4 +888,18 @@ final Map ar_eg = { "Please enter a valid email.": "يرجى إدخال بريد إلكتروني صحيح", "Please enter a valid phone number.": "يرجى إدخال رقم هاتف صحيح", "Connection error": "خطأ في الاتصال", + "Edit": "تعديل", + "No rides found for this number": "لا توجد رحلات لهذا الرقم", + "User not found": "لم يتم العثور على المستخدم", + "No ride found for this number": "لم يتم العثور على رحلة بهذا الرقم", + "Failed to fetch rides": "فشل في جلب الرحلات", + "Your request has been submitted successfully. Please wait for admin approval.": "تم تقديم طلبك بنجاح. يرجى انتظار موافقة الإدارة.", + "Passenger ID": "معرف الراكب", + "Review the \"لا حكم عليه\" document. Verify name matches driver.": "Review the \"لا حكم عليه\" document. Verify name matches driver.", + "Review the \"عدم محكومية\" document. Verify name matches driver.": "Review the \"عدم محكومية\" document. Verify name matches driver.", + "Review the \"فيش وتشبيه\" document. Verify name matches driver.": "Review the \"فيش وتشبيه\" document. Verify name matches driver.", + "Review the criminal record document. Verify name matches driver.": "يرجى مراجعة وثيقة السجل الجنائي. التحقق من تطابق الاسم مع السائق.", + "حفظ": "حفظ", + "Failed to load data": "فشل في تحميل البيانات", + "گازوئيل": "گازوئيل", }; diff --git a/siro_service/lib/controller/local/ar_jo.dart b/siro_service/lib/controller/local/ar_jo.dart index a0a6262d..256deff1 100644 --- a/siro_service/lib/controller/local/ar_jo.dart +++ b/siro_service/lib/controller/local/ar_jo.dart @@ -93,7 +93,7 @@ final Map ar_jo = { "Camera not initilaized yet": "Camera not initilaized yet", "Can I cancel my ride?": "Can I cancel my ride?", "Can we know why you want to cancel Ride ?": "Can we know why you want to cancel Ride ?", - "Cancel": "Cancel", + "Cancel": "إلغاء", "Cancel Ride": "Cancel Ride", "Cancel Trip": "Cancel Trip", "Canceled": "Canceled", @@ -142,7 +142,7 @@ final Map ar_jo = { "Created At": "أنشئ في", "created time": "created time", "Credit card is": "Credit card is", - "Criminal Record": "Criminal Record", + "Criminal Record": "سجل جنائي", "Cropper": "Cropper", "Current Location": "Current Location", "cyan": "سماوي", @@ -888,4 +888,18 @@ final Map ar_jo = { "Please enter a valid email.": "يرجى إدخال بريد إلكتروني صحيح", "Please enter a valid phone number.": "يرجى إدخال رقم هاتف صحيح", "Connection error": "خطأ في الاتصال", + "Edit": "تعديل", + "No rides found for this number": "لا توجد رحلات لهذا الرقم", + "User not found": "لم يتم العثور على المستخدم", + "No ride found for this number": "لم يتم العثور على رحلة بهذا الرقم", + "Failed to fetch rides": "فشل في جلب الرحلات", + "Your request has been submitted successfully. Please wait for admin approval.": "تم تقديم طلبك بنجاح. يرجى انتظار موافقة الإدارة.", + "Passenger ID": "معرف الراكب", + "Review the \"لا حكم عليه\" document. Verify name matches driver.": "Review the \"لا حكم عليه\" document. Verify name matches driver.", + "Review the \"عدم محكومية\" document. Verify name matches driver.": "Review the \"عدم محكومية\" document. Verify name matches driver.", + "Review the \"فيش وتشبيه\" document. Verify name matches driver.": "Review the \"فيش وتشبيه\" document. Verify name matches driver.", + "Review the criminal record document. Verify name matches driver.": "يرجى مراجعة وثيقة السجل الجنائي. التحقق من تطابق الاسم مع السائق.", + "حفظ": "حفظ", + "Failed to load data": "فشل في تحميل البيانات", + "گازوئيل": "گازوئيل", }; diff --git a/siro_service/lib/controller/local/ar_sy.dart b/siro_service/lib/controller/local/ar_sy.dart index fda933e6..f196ad45 100644 --- a/siro_service/lib/controller/local/ar_sy.dart +++ b/siro_service/lib/controller/local/ar_sy.dart @@ -93,7 +93,7 @@ final Map ar_sy = { "Camera not initilaized yet": "Camera not initilaized yet", "Can I cancel my ride?": "Can I cancel my ride?", "Can we know why you want to cancel Ride ?": "Can we know why you want to cancel Ride ?", - "Cancel": "Cancel", + "Cancel": "إلغاء", "Cancel Ride": "Cancel Ride", "Cancel Trip": "Cancel Trip", "Canceled": "Canceled", @@ -142,7 +142,7 @@ final Map ar_sy = { "Created At": "أنشئ في", "created time": "created time", "Credit card is": "Credit card is", - "Criminal Record": "Criminal Record", + "Criminal Record": "سجل جنائي", "Cropper": "Cropper", "Current Location": "Current Location", "cyan": "سماوي", @@ -888,4 +888,18 @@ final Map ar_sy = { "Please enter a valid email.": "يرجى إدخال بريد إلكتروني صحيح", "Please enter a valid phone number.": "يرجى إدخال رقم هاتف صحيح", "Connection error": "خطأ في الاتصال", + "Edit": "تعديل", + "No rides found for this number": "لا توجد رحلات لهذا الرقم", + "User not found": "لم يتم العثور على المستخدم", + "No ride found for this number": "لم يتم العثور على رحلة بهذا الرقم", + "Failed to fetch rides": "فشل في جلب الرحلات", + "Your request has been submitted successfully. Please wait for admin approval.": "تم تقديم طلبك بنجاح. يرجى انتظار موافقة الإدارة.", + "Passenger ID": "معرف الراكب", + "Review the \"لا حكم عليه\" document. Verify name matches driver.": "Review the \"لا حكم عليه\" document. Verify name matches driver.", + "Review the \"عدم محكومية\" document. Verify name matches driver.": "Review the \"عدم محكومية\" document. Verify name matches driver.", + "Review the \"فيش وتشبيه\" document. Verify name matches driver.": "Review the \"فيش وتشبيه\" document. Verify name matches driver.", + "Review the criminal record document. Verify name matches driver.": "يرجى مراجعة وثيقة السجل الجنائي. التحقق من تطابق الاسم مع السائق.", + "حفظ": "حفظ", + "Failed to load data": "فشل في تحميل البيانات", + "گازوئيل": "گازوئيل", }; diff --git a/siro_service/lib/controller/login_controller.dart b/siro_service/lib/controller/login_controller.dart index 0d8db1fd..f57d84c3 100644 --- a/siro_service/lib/controller/login_controller.dart +++ b/siro_service/lib/controller/login_controller.dart @@ -62,13 +62,17 @@ class LoginController extends GetxController { await storage.write(key: 'email', value: emailStr); await box.write(BoxName.email, emailStr); - // Request OTP from unified module - String phone = d['data']['phone'] ?? ''; - bool otpSent = await _sendOtp(phone); - if (otpSent) { - _showOtpDialog(phone, pass, fingerprint, d); + bool otpRequired = d['otp_required'] ?? true; + if (otpRequired) { + String phone = d['data']['phone'] ?? ''; + bool otpSent = await _sendOtp(phone); + if (otpSent) { + _showOtpDialog(phone, pass, fingerprint, d); + } else { + mySnackbarError('Failed to send OTP'.tr); + } } else { - mySnackbarError('Failed to send OTP'.tr); + await _finalizeLogin(pass, d); } } else { mySnackbarError( @@ -138,26 +142,7 @@ class LoginController extends GetxController { Get.back(); // close loading if (response != 'failure' && response['status'] == 'success') { - // Finalize login - final jwt = loginData['jwt']; - final hmac = loginData['hmac']; - await box.write(BoxName.jwt, c(jwt)); - await storage.write(key: BoxName.jwt, value: c(jwt)); - if (hmac != null) { - await box.write(BoxName.hmac, hmac); - } - - var userData = loginData['data']; - await storage.write(key: 'name', value: userData['first_name']); - await storage.write(key: 'driverID', value: userData['id'].toString()); - await storage.write(key: 'password', value: pass); - await box.write(BoxName.employeename, userData['first_name']); - await box.write(BoxName.password, pass); - if (userData['country'] != null) { - await box.write(BoxName.countryCode, userData['country']); - } - - Get.offAll(() => Main()); + await _finalizeLogin(pass, loginData); } else { mySnackbarError('Invalid OTP'.tr); } @@ -168,6 +153,28 @@ class LoginController extends GetxController { } } + Future _finalizeLogin(String pass, dynamic loginData) async { + final jwt = loginData['jwt']; + final hmac = loginData['hmac']; + await box.write(BoxName.jwt, c(jwt)); + await storage.write(key: BoxName.jwt, value: c(jwt)); + if (hmac != null) { + await box.write(BoxName.hmac, hmac); + } + + var userData = loginData['data']; + await storage.write(key: 'name', value: userData['first_name']); + await storage.write(key: 'driverID', value: userData['id'].toString()); + await storage.write(key: 'password', value: pass); + await box.write(BoxName.employeename, userData['first_name']); + await box.write(BoxName.password, pass); + if (userData['country'] != null) { + await box.write(BoxName.countryCode, userData['country']); + } + + Get.offAll(() => Main()); + } + @override void onInit() async { await EncryptionHelper.initialize(); diff --git a/siro_service/lib/controller/mainController/pages/alexandria_besr_driver.dart b/siro_service/lib/controller/mainController/pages/alexandria_besr_driver.dart index 4ad22c85..aeea290e 100644 --- a/siro_service/lib/controller/mainController/pages/alexandria_besr_driver.dart +++ b/siro_service/lib/controller/mainController/pages/alexandria_besr_driver.dart @@ -28,9 +28,9 @@ class DriverTheBestAlexandria extends StatelessWidget { ), ), title: Text((driver['name_arabic']) ?? - 'Unknown Name'), + 'Unknown Name'.tr), subtitle: Text( - 'Phone: ${(driver['phone']) ?? 'N/A'}'), + '${'Phone'.tr}: ${(driver['phone']) ?? 'N/A'.tr}'), trailing: IconButton( onPressed: () async { Get.defaultDialog( @@ -45,8 +45,8 @@ class DriverTheBestAlexandria extends StatelessWidget { ); }, ) - : const Center( - child: Text('No drivers available.'), + : Center( + child: Text('No drivers available.'.tr), ); }) ], diff --git a/siro_service/lib/controller/mainController/pages/best_driver_page.dart b/siro_service/lib/controller/mainController/pages/best_driver_page.dart index 82e8ef6d..846c233d 100644 --- a/siro_service/lib/controller/mainController/pages/best_driver_page.dart +++ b/siro_service/lib/controller/mainController/pages/best_driver_page.dart @@ -55,9 +55,9 @@ class DriverTheBest extends StatelessWidget { ), ), title: Text((driver['name_arabic']) ?? - 'Unknown Name'), + 'Unknown Name'.tr), subtitle: Text( - 'Phone: ${(driver['phone']) ?? 'N/A'}'), + '${'Phone'.tr}: ${(driver['phone']) ?? 'N/A'.tr}'), trailing: IconButton( onPressed: () async { // Get.defaultDialog( @@ -79,8 +79,8 @@ class DriverTheBest extends StatelessWidget { }, ), ) - : const Center( - child: Text('No drivers available.'), + : Center( + child: Text('No drivers available.'.tr), ); }), ], diff --git a/siro_service/lib/controller/mainController/pages/driver_page.dart b/siro_service/lib/controller/mainController/pages/driver_page.dart index 77689c58..cc0a6b60 100644 --- a/siro_service/lib/controller/mainController/pages/driver_page.dart +++ b/siro_service/lib/controller/mainController/pages/driver_page.dart @@ -60,11 +60,11 @@ class DriverPage extends StatelessWidget { Get.bottomSheet( CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( - middle: Text("Edit $label"), + middle: Text('${'Edit'.tr} $label'), trailing: GestureDetector( - child: const Text( - "Save", - style: TextStyle(color: CupertinoColors.activeBlue), + child: Text( + 'Save'.tr, + style: const TextStyle(color: CupertinoColors.activeBlue), ), onTap: () { mainController.updateDriverField(key, controller.text); diff --git a/siro_service/lib/controller/mainController/pages/giza_best_driver.dart b/siro_service/lib/controller/mainController/pages/giza_best_driver.dart index 3fc0b060..a5409cd1 100644 --- a/siro_service/lib/controller/mainController/pages/giza_best_driver.dart +++ b/siro_service/lib/controller/mainController/pages/giza_best_driver.dart @@ -28,9 +28,9 @@ class DriverTheBestGiza extends StatelessWidget { ), ), title: Text((driver['name_arabic']) ?? - 'Unknown Name'), + 'Unknown Name'.tr), subtitle: Text( - 'Phone: ${(driver['phone']) ?? 'N/A'}'), + '${'Phone'.tr}: ${(driver['phone']) ?? 'N/A'.tr}'), trailing: IconButton( onPressed: () async { Get.defaultDialog( @@ -45,8 +45,8 @@ class DriverTheBestGiza extends StatelessWidget { ); }, ) - : const Center( - child: Text('No drivers available.'), + : Center( + child: Text('No drivers available.'.tr), ); }) ], diff --git a/siro_service/lib/controller/mainController/pages/passengers_cant_regster.dart b/siro_service/lib/controller/mainController/pages/passengers_cant_regster.dart index 87b1b803..c820992f 100644 --- a/siro_service/lib/controller/mainController/pages/passengers_cant_regster.dart +++ b/siro_service/lib/controller/mainController/pages/passengers_cant_regster.dart @@ -25,7 +25,7 @@ class PassengersCantRegister extends StatelessWidget { return Padding( padding: const EdgeInsets.all(8.0), child: CupertinoFormSection( - header: Text('Passenger ID: ${passenger['id']}'), + header: Text('${'Passenger ID'.tr}: ${passenger['id']}'), children: [ InkWell( onTap: () => diff --git a/siro_service/lib/controller/mainController/pages/passengers_page.dart b/siro_service/lib/controller/mainController/pages/passengers_page.dart index 76a2c81a..b4803eb6 100644 --- a/siro_service/lib/controller/mainController/pages/passengers_page.dart +++ b/siro_service/lib/controller/mainController/pages/passengers_page.dart @@ -28,12 +28,12 @@ class PassengersPage extends StatelessWidget { ], ) else - const Center( + Center( child: Padding( - padding: EdgeInsets.all(24.0), + padding: const EdgeInsets.all(24.0), child: Text( - 'No passenger data available.', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500), + 'No passenger data available.'.tr, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500), ), ), ), diff --git a/siro_service/lib/controller/mainController/pages/review_driver_page.dart b/siro_service/lib/controller/mainController/pages/review_driver_page.dart index adfa1308..0a8889c5 100644 --- a/siro_service/lib/controller/mainController/pages/review_driver_page.dart +++ b/siro_service/lib/controller/mainController/pages/review_driver_page.dart @@ -140,7 +140,7 @@ class ReviewDriverPage extends StatelessWidget { children: [ Icon(Icons.image_not_supported, size: 48, color: Colors.grey[400]), const SizedBox(height: 8), - Text('No image available', style: TextStyle(color: Colors.grey[500])), + Text('No image available'.tr, style: TextStyle(color: Colors.grey[500])), ], ), ), @@ -159,7 +159,7 @@ class ReviewDriverPage extends StatelessWidget { height: 180, color: Colors.grey[200], child: Center( - child: Text('Failed to load image', + child: Text('Failed to load image'.tr, style: TextStyle(color: Colors.grey[500])), ), ), @@ -193,7 +193,7 @@ class ReviewDriverPage extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('${c.country} - Criminal Record', + Text('${c.country} - ${'Criminal Record'.tr}', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const Divider(), Card( @@ -223,7 +223,7 @@ class ReviewDriverPage extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Profile Photo', + Text('Profile Photo'.tr, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const Divider(), Card( @@ -237,7 +237,7 @@ class ReviewDriverPage extends StatelessWidget { Expanded( child: Text( 'Verify the profile photo matches the person in the ID ' - 'and Driver License photos above.', + 'and Driver License photos above.'.tr, style: TextStyle(color: Colors.blue[800]), ), ), @@ -256,7 +256,7 @@ class ReviewDriverPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '${c.country} - ${c.tabLabels[tabKey] ?? tabKey}', + '${c.country} - ${(c.tabLabels[tabKey] ?? tabKey).tr}', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const Divider(), @@ -268,13 +268,13 @@ class ReviewDriverPage extends StatelessWidget { String _getCriminalRecordHint(String country) { switch (country) { case 'Syria': - return 'Review the "لا حكم عليه" document. Verify name matches driver.'; + return 'Review the "لا حكم عليه" document. Verify name matches driver.'.tr; case 'Jordan': - return 'Review the "عدم محكومية" document. Verify name matches driver.'; + return 'Review the "عدم محكومية" document. Verify name matches driver.'.tr; case 'Egypt': - return 'Review the "فيش وتشبيه" document. Verify name matches driver.'; + return 'Review the "فيش وتشبيه" document. Verify name matches driver.'.tr; default: - return 'Review the criminal record document. Verify name matches driver.'; + return 'Review the criminal record document. Verify name matches driver.'.tr; } } @@ -481,7 +481,7 @@ class ReviewDriverPage extends StatelessWidget { const EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), items: ReviewDriverController.kFuelOptions.map((v) { - return DropdownMenuItem(value: v, child: Text(v)); + return DropdownMenuItem(value: v, child: Text(v.tr)); }).toList(), onChanged: (v) { if (v != null) c.selectedFuel.value = v; diff --git a/siro_service/lib/controller/mainController/pages/ride_monitor_page.dart b/siro_service/lib/controller/mainController/pages/ride_monitor_page.dart index dbeb3098..fb17c024 100644 --- a/siro_service/lib/controller/mainController/pages/ride_monitor_page.dart +++ b/siro_service/lib/controller/mainController/pages/ride_monitor_page.dart @@ -55,28 +55,6 @@ class ActiveRideModel { } } -/// -------------------------------------------------------------------------- -/// تطبيع رقم الهاتف تلقائياً حسب الدولة -/// -------------------------------------------------------------------------- -String normalizePhone(String input) { - final clean = input.replaceAll(RegExp(r'\D+'), ''); - // Syria - if (clean.length == 10 && clean.startsWith('09')) - return '963${clean.substring(1)}'; - if (clean.length == 12 && clean.startsWith('963')) return clean; - if (clean.length == 9 && clean.startsWith('9')) return '963$clean'; - // Jordan - if (clean.length == 10 && clean.startsWith('07')) - return '962${clean.substring(1)}'; - if (clean.length == 12 && clean.startsWith('962')) return clean; - if (clean.length == 9 && clean.startsWith('7')) return '962$clean'; - // Egypt - if (clean.length == 11 && clean.startsWith('01')) - return '20${clean.substring(1)}'; - if (clean.length == 13 && clean.startsWith('20')) return clean; - return clean; -} - /// -------------------------------------------------------------------------- /// الـ Controller /// -------------------------------------------------------------------------- @@ -116,7 +94,7 @@ class RideMonitorServiceController extends GetxController { activeRides.clear(); try { - final normalizedPhone = normalizePhone(phone); + final normalizedPhone = CRUD.normalizePhone(phone); // محاولة البحث أولاً عن رحلة نشطة var res = await CRUD().post( @@ -158,15 +136,15 @@ class RideMonitorServiceController extends GetxController { hasResult.value = true; } else { hasError.value = true; - errorMessage.value = 'لا توجد رحلات لهذا الرقم'; + errorMessage.value = 'No rides found for this number'.tr; } } else { hasError.value = true; - errorMessage.value = 'لم يتم العثور على المستخدم'; + errorMessage.value = 'User not found'.tr; } } catch (e) { hasError.value = true; - errorMessage.value = 'خطأ في الاتصال: $e'; + errorMessage.value = '${'Connection error'.tr}: $e'; } finally { isLoading.value = false; } @@ -213,15 +191,15 @@ class RideMonitorServiceController extends GetxController { hasResult.value = true; } else { hasError.value = true; - errorMessage.value = 'لم يتم العثور على رحلة بهذا الرقم'; + errorMessage.value = 'No ride found for this number'.tr; } } else { hasError.value = true; - errorMessage.value = 'فشل في جلب الرحلات'; + errorMessage.value = 'Failed to fetch rides'.tr; } } catch (e) { hasError.value = true; - errorMessage.value = 'خطأ في الاتصال: $e'; + errorMessage.value = '${'Connection error'.tr}: $e'; } finally { isLoading.value = false; } diff --git a/siro_service/lib/controller/mainController/pages/welcome_call.dart b/siro_service/lib/controller/mainController/pages/welcome_call.dart index 20ec1185..cab16274 100644 --- a/siro_service/lib/controller/mainController/pages/welcome_call.dart +++ b/siro_service/lib/controller/mainController/pages/welcome_call.dart @@ -24,12 +24,12 @@ class WelcomeCall extends StatelessWidget { final drivers = mainController.newDriverRegister; if (drivers.isEmpty) { - return const Padding( - padding: EdgeInsets.all(32.0), + return Padding( + padding: const EdgeInsets.all(32.0), child: Center( child: Text( - 'No new drivers found.', - style: TextStyle(fontSize: 18), + 'No new drivers found.'.tr, + style: const TextStyle(fontSize: 18), ), ), ); diff --git a/siro_service/lib/controller/mainController/review_driver_controller.dart b/siro_service/lib/controller/mainController/review_driver_controller.dart index f66daabc..eefbce38 100644 --- a/siro_service/lib/controller/mainController/review_driver_controller.dart +++ b/siro_service/lib/controller/mainController/review_driver_controller.dart @@ -172,7 +172,7 @@ class ReviewDriverController extends GetxController { _populateDocUrls(raw['documents']); } } catch (e) { - mySnackbarError('Failed to load data: $e'); + mySnackbarError('${'Failed to load data'.tr}: $e'); } finally { isLoading.value = false; } @@ -258,7 +258,7 @@ class ReviewDriverController extends GetxController { ), ), CupertinoButton( - child: const Text('Done'), + child: Text('Done'.tr), onPressed: () { if (pickedDate != null) { controller.text = @@ -313,12 +313,12 @@ class ReviewDriverController extends GetxController { payload: payload, ); if (response != 'failure' && response['status'] == 'success') { - mySnackbarSuccess('Data saved successfully'); + mySnackbarSuccess('Data saved successfully'.tr); } else { - mySnackbarError('Failed to save changes'); + mySnackbarError('Failed to save changes'.tr); } } catch (e) { - mySnackbarError('Error: $e'); + mySnackbarError('${'Error'.tr}: $e'); } finally { isSaving.value = false; } @@ -333,14 +333,14 @@ class ReviewDriverController extends GetxController { payload: payload, ); if (response != 'failure' && response['status'] == 'success') { - mySnackbarSuccess('Driver activated successfully!'); + mySnackbarSuccess('Driver activated successfully!'.tr); await Future.delayed(const Duration(milliseconds: 500)); Get.back(); } else { - mySnackbarError('Failed to activate driver'); + mySnackbarError('Failed to activate driver'.tr); } } catch (e) { - mySnackbarError('Error: $e'); + mySnackbarError('${'Error'.tr}: $e'); } finally { isSaving.value = false; } @@ -348,7 +348,7 @@ class ReviewDriverController extends GetxController { Future rejectDriver(String reason) async { if (reason.trim().isEmpty) { - mySnackbarError('Please enter a rejection reason'); + mySnackbarError('Please enter a rejection reason'.tr); return; } isSaving.value = true; @@ -361,14 +361,14 @@ class ReviewDriverController extends GetxController { }, ); if (response != 'failure' && response['status'] == 'success') { - mySnackbarSuccess('Driver rejected'); + mySnackbarSuccess('Driver rejected'.tr); await Future.delayed(const Duration(milliseconds: 500)); Get.back(); } else { - mySnackbarError('Failed to reject driver'); + mySnackbarError('Failed to reject driver'.tr); } } catch (e) { - mySnackbarError('Error: $e'); + mySnackbarError('${'Error'.tr}: $e'); } finally { isSaving.value = false; } diff --git a/siro_service/lib/views/auth/register_page.dart b/siro_service/lib/views/auth/register_page.dart index 652fb505..47a9d1ef 100644 --- a/siro_service/lib/views/auth/register_page.dart +++ b/siro_service/lib/views/auth/register_page.dart @@ -160,7 +160,7 @@ class RegisterPage extends StatelessWidget { return Padding( padding: const EdgeInsets.only(bottom: 8.0, right: 4.0), child: Text( - title, + title.tr, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, diff --git a/siro_service/lib/views/widgets/elevated_btn.dart b/siro_service/lib/views/widgets/elevated_btn.dart index 44dfab91..f72b63de 100644 --- a/siro_service/lib/views/widgets/elevated_btn.dart +++ b/siro_service/lib/views/widgets/elevated_btn.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:get/get.dart'; import 'package:vibration/vibration.dart'; import '../../constant/box_name.dart'; @@ -60,7 +61,7 @@ class MyElevatedButton extends StatelessWidget { ) : child ?? Text( - title, + title.tr, textAlign: TextAlign.center, style: AppStyle.title.copyWith(color: AppColor.secondaryColor), ), diff --git a/siro_service/lib/views/widgets/my_dialog.dart b/siro_service/lib/views/widgets/my_dialog.dart index 4a4b3d67..e002a9be 100644 --- a/siro_service/lib/views/widgets/my_dialog.dart +++ b/siro_service/lib/views/widgets/my_dialog.dart @@ -31,7 +31,7 @@ class MyDialog extends GetxController { kolor: AppColor.greenColor, ), cancel: MyElevatedButton( - title: 'Cancel', + title: 'Cancel'.tr, kolor: AppColor.redColor, onPressed: () { Get.back();