26-1-20/1

This commit is contained in:
Hamza-Ayed
2026-01-20 10:11:10 +03:00
parent 374f9e9bf3
commit 3c0ae4cf2f
53 changed files with 89652 additions and 6861 deletions

View File

@@ -190,7 +190,7 @@ class LoginDriverController extends GetxController {
// ✅ بعد التأكد أن كل المفاتيح موجودة
await EncryptionHelper.initialize();
await AppInitializer().getKey();
// await AppInitializer().getKey();
} else {}
} else {
await EncryptionHelper.initialize();
@@ -215,7 +215,7 @@ class LoginDriverController extends GetxController {
final jwt = decodedResponse1['jwt'];
await box.write(BoxName.jwt, c(jwt));
await AppInitializer().getKey();
// await AppInitializer().getKey();
}
}
}

View File

@@ -72,7 +72,26 @@ class RegistrationController extends GetxController {
final carVinController = TextEditingController(); // Chassis number
final carRegistrationExpiryController = TextEditingController();
DateTime? carRegistrationExpiryDate;
// داخل RegistrationController
// المتغيرات لتخزين القيم المختارة (لإرسالها للـ API لاحقاً)
int? selectedVehicleCategoryId; // سيخزن 1 أو 2 أو 3
int? selectedFuelTypeId; // سيخزن 1 أو 2 أو 3 أو 4
// قائمة أنواع المركبات (مطابقة لقاعدة البيانات)
final List<Map<String, dynamic>> vehicleCategoryOptions = [
{'id': 1, 'name': 'Car'.tr}, // ترجمة: سيارة
{'id': 2, 'name': 'Motorcycle'.tr}, // ترجمة: دراجة نارية
{'id': 3, 'name': 'Van / Bus'.tr}, // ترجمة: فان / باص
];
// قائمة أنواع الوقود
final List<Map<String, dynamic>> fuelTypeOptions = [
{'id': 1, 'name': 'Petrol'.tr}, // ترجمة: بنزين
{'id': 2, 'name': 'Diesel'.tr}, // ترجمة: ديزل
{'id': 3, 'name': 'Electric'.tr}, // ترجمة: كهربائي
{'id': 4, 'name': 'Hybrid'.tr}, // ترجمة: هايبرد
];
// STEP 3: Document Uploads
File? driverLicenseFrontImage;
File? driverLicenseBackImage;
@@ -464,25 +483,30 @@ class RegistrationController extends GetxController {
Future<void> submitRegistration() async {
// 0) دوال/مساعدات محلية
void _addField(Map<String, String> fields, String key, String? value) {
if (value != null && value.isNotEmpty) {
fields[key] = value;
}
}
// 1) تحقق من وجود الروابط بدل الملفات
// 1) تحقق من وجود الروابط
final driverFrontUrl = docUrls['driver_license_front'];
final driverBackUrl = docUrls['driver_license_back'];
final carFrontUrl = docUrls['car_license_front'];
final carBackUrl = docUrls['car_license_back'];
isLoading.value = true;
update();
final registerUri = Uri.parse(AppLink.register_driver_and_car);
final client = http.Client();
try {
// ترويسات مشتركة
final bearer =
'Bearer ${r(box.read(BoxName.jwt)).split(AppInformation.addd)[0]}';
final hmac = '${box.read(BoxName.hmac)}';
// 2) جهّز طلب التسجيل الرئيسي: حقول فقط + روابط الصور (لا نرفع صور إطلاقًا)
final req = http.MultipartRequest('POST', registerUri);
req.headers.addAll({
'Authorization': bearer,
@@ -499,11 +523,10 @@ class RegistrationController extends GetxController {
_addField(fields, 'national_number', nationalIdController.text);
_addField(fields, 'birthdate', bithdateController.text);
_addField(fields, 'expiry_date', driverLicenseExpiryController.text);
_addField(
fields, 'password', 'generate_your_password_here'); // عدّل حسب منطقك
_addField(fields, 'password', 'generated_password_or_token');
_addField(fields, 'status', 'yet');
_addField(fields, 'email', 'Not specified');
_addField(fields, 'gender', 'Male');
_addField(fields, 'gender', 'Male'); // يفضل ربطها بـ Dropdown أيضاً
// --- Car Data ---
_addField(fields, 'vin', 'yet');
@@ -511,22 +534,53 @@ class RegistrationController extends GetxController {
_addField(fields, 'make', carMakeController.text);
_addField(fields, 'model', carModelController.text);
_addField(fields, 'year', carYearController.text);
_addField(fields, 'expiration_date', driverLicenseExpiryController.text);
_addField(
fields,
'expiration_date',
driverLicenseExpiryController
.text); // تأكد من أن هذا تاريخ انتهاء السيارة وليس الرخصة
_addField(fields, 'color', carColorController.text);
_addField(fields, 'fuel', 'Gasoline');
if (colorHex != null && colorHex!.isNotEmpty) {
_addField(fields, 'color_hex', colorHex!);
}
_addField(fields, 'owner',
'${firstNameController.text} ${lastNameController.text}');
// --- روابط الصور المخزنة مسبقًا ---
// ============================================================
// 🔥 التعديل الجديد: إرسال الأرقام (IDs) لتصنيف المركبة والوقود
// ============================================================
// 1. إرسال رقم تصنيف المركبة (1=سيارة, 2=دراجة...)
if (selectedVehicleCategoryId != null) {
_addField(fields, 'vehicle_category_id',
selectedVehicleCategoryId.toString());
} else {
_addField(fields, 'vehicle_category_id', '1'); // قيمة افتراضية (سيارة)
}
// 2. إرسال رقم ونوع الوقود
if (selectedFuelTypeId != null) {
// إرسال الرقم (للبحث السريع)
_addField(fields, 'fuel_type_id', selectedFuelTypeId.toString());
// إرسال الاسم نصاً (للتوافق مع العمود القديم 'fuel' إذا لزم الأمر)
// نبحث عن الاسم داخل القائمة بناءً على الرقم المختار
final fuelObj = fuelTypeOptions.firstWhere(
(e) => e['id'] == selectedFuelTypeId,
orElse: () => {'name': 'Petrol'});
_addField(fields, 'fuel', fuelObj['name'].toString());
} else {
_addField(fields, 'fuel_type_id', '1');
_addField(fields, 'fuel', 'Petrol');
}
// --- روابط الصور ---
_addField(fields, 'driver_license_front', driverFrontUrl!);
_addField(fields, 'driver_license_back', driverBackUrl!);
_addField(fields, 'car_license_front', carFrontUrl!);
_addField(fields, 'car_license_back', carBackUrl!);
// أضف الحقول
req.fields.addAll(fields);
// 3) الإرسال
@@ -534,80 +588,53 @@ class RegistrationController extends GetxController {
await client.send(req).timeout(const Duration(seconds: 60));
final resp = await http.Response.fromStream(streamed);
// 4) فحص النتيجة
// 4) معالجة الاستجابة
Map<String, dynamic>? json;
try {
json = jsonDecode(resp.body) as Map<String, dynamic>;
} catch (_) {}
if (resp.statusCode == 200 && json?['status'] == 'success') {
// final driverID =
// (json!['data']?['driverID'] ?? json['driverID'])?.toString();
// if (driverID != null && driverID.isNotEmpty) {
// box.write(BoxName.driverID, driverID);
// }
Get.snackbar('Success'.tr, 'Registration completed successfully!'.tr,
backgroundColor: Colors.green, colorText: Colors.white);
Get.snackbar(
'Success'.tr,
'Registration completed successfully!'.tr,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.green,
colorText: Colors.white,
);
// متابعة تسجيل الدخول إن لزم
// منطق التوكن والإشعارات وتسجيل الدخول...
final email = box.read(BoxName.emailDriver);
final driverID = box.read(BoxName.driverID);
final c = Get.isRegistered<LoginDriverController>()
? Get.find<LoginDriverController>()
: Get.put(LoginDriverController());
//token to server
String fingerPrint = await DeviceHelper.getDeviceFingerprint();
await CRUD().post(link: AppLink.addTokensDriver, payload: {
'captain_id': (box.read(BoxName.driverID)).toString(),
'token': (box.read(BoxName.tokenDriver)).toString(),
'fingerPrint': fingerPrint.toString(),
});
// CRUD().post(link: AppLink.addTokensDriverWallet, payload: {
// 'token': box.read(BoxName.tokenDriver).toString(),
// 'fingerPrint': fingerPrint.toString(),
// 'captain_id': box.read(BoxName.driverID).toString(),
// });
NotificationService.sendNotification(
target: 'service', // الإرسال لجميع المشتركين في "service"
title: 'طلب خدمة جديد',
body: 'تم استلام طلب خدمة جديد. الرجاء مراجعة التفاصيل.',
target: 'service',
title: 'New Driver Registration',
body: 'Driver $driverID has submitted registration.',
isTopic: true,
category: 'new_service_request', // فئة توضح نوع الإشعار
category: 'new_service_request',
);
final c = Get.isRegistered<LoginDriverController>()
? Get.find<LoginDriverController>()
: Get.put(LoginDriverController());
c.loginWithGoogleCredential(driverID, email);
} else {
final msg =
(json?['message'] ?? 'Registration failed. Please try again.')
.toString();
Log.print('msg: $msg');
Get.snackbar(
'Error'.tr,
msg,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
final msg = (json?['message'] ?? 'Registration failed.').toString();
Get.snackbar('Error'.tr, msg,
backgroundColor: Colors.red, colorText: Colors.white);
}
} catch (e) {
Get.snackbar(
'Error'.tr,
'${'An unexpected error occurred:'.tr} $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
Get.snackbar('Error'.tr, 'Error: $e',
backgroundColor: Colors.red, colorText: Colors.white);
} finally {
client.close();
isLoading.value = false;
update();
}
} // Future<void> submitRegistration() async {
}
// // 1) تحقق من الصور
// if (driverLicenseFrontImage == null ||
// driverLicenseBackImage == null ||