This commit is contained in:
Hamza-Ayed
2024-05-18 09:39:55 +03:00
parent 81080ce292
commit c74b87b272
17 changed files with 1469 additions and 586 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:math';
import 'package:SEFER/controller/auth/captin/login_captin_controller.dart';
import 'package:SEFER/views/auth/captin/register_captin.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart';
@@ -15,9 +16,11 @@ import 'package:SEFER/views/auth/captin/verify_email_captain.dart';
import '../../../views/auth/captin/ai_page.dart';
import '../../../views/auth/captin/car_license_page.dart';
import '../../../views/home/Captin/home_captain/home_captin.dart';
import '../../functions/sms_egypt_controller.dart';
class RegisterCaptainController extends GetxController {
final formKey = GlobalKey<FormState>();
final formKey3 = GlobalKey<FormState>();
TextEditingController emailController = TextEditingController();
TextEditingController phoneController = TextEditingController();
@@ -27,6 +30,7 @@ class RegisterCaptainController extends GetxController {
String birthDate = 'Birth Date'.tr;
String gender = 'Male'.tr;
bool isLoading = false;
bool isSent = false;
late String name;
late String licenseClass;
late String documentNo;
@@ -62,11 +66,51 @@ class RegisterCaptainController extends GetxController {
);
}
@override
void onInit() {
// Get.put(SmsEgyptController());
super.onInit();
}
void changeGender(String value) {
gender = value;
update();
}
sendOtpMessage() async {
SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
int randomNumber = Random().nextInt(100000) + 1;
isLoading = true;
update();
if (formKey3.currentState!.validate()) {
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
'phone_number': phoneController.text,
'token_code': randomNumber.toString(),
});
await smsEgyptController.sendSmsEgypt(
phoneController.toString(), randomNumber.toString());
isSent = true;
isLoading = false;
update();
}
}
verifySMSCode() async {
if (formKey3.currentState!.validate()) {
var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
'phone_number': phoneController.text,
'token_code': verifyCode.text.toString(),
});
if (res != 'failure') {
// var dec = jsonDecode(res);
box.write(BoxName.phoneDriver, '+2${phoneController.text}');
Get.to(const RegisterCaptin());
}
}
}
sendVerifications() async {
var res = await CRUD().post(link: AppLink.verifyEmail, payload: {
'email': emailController.text.isEmpty

View File

@@ -1,5 +1,6 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/auth/captin/cards_egypt/egypt_card_a_i.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
@@ -13,11 +14,18 @@ class GoogleSignInHelper {
],
);
// Method to handle Google Sign-In
static Future<GoogleSignInAccount?> signIn() async {
try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
getDriverInfo();
Get.to(() => AiPage());
if (googleUser != null) {
await _handleSignUp(googleUser);
if (box.read(BoxName.countryCode) == 'Egypt') {
Get.to(() => EgyptCardAI());
} else if (box.read(BoxName.countryCode) == 'Jordan') {
Get.to(() => AiPage());
}
}
return googleUser;
} catch (error) {
print('Google Sign-In error: $error');
@@ -25,25 +33,50 @@ class GoogleSignInHelper {
}
}
// Method to handle Google Sign-Out
static Future<void> signOut() async {
try {
await _googleSignIn.signOut();
await _handleSignOut();
print('User signed out.');
} catch (error) {
print('Google Sign-Out error: $error');
}
}
// Method to get the current signed-in user
static GoogleSignInAccount? getCurrentUser() {
return _googleSignIn.currentUser;
}
static String? getDriverInfo() {
final GoogleSignInAccount? user = _googleSignIn.currentUser;
box.write(BoxName.driverID, user!.id);
// Method to handle sign-up process
static Future<void> _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);
print('emailDriver =${box.read(BoxName.emailDriver)}');
return user.displayName;
// Perform any additional sign-up tasks or API calls here
// For example, you can send the user data to your server for registration
print('driverID = ${box.read(BoxName.driverID)}');
print('emailDriver = ${box.read(BoxName.emailDriver)}');
print('nameDriver = ${box.read(BoxName.nameDriver)}');
print('driverPhotoUrl = ${box.read(BoxName.driverPhotoUrl)}');
}
// Method to handle sign-out process
static Future<void> _handleSignOut() async {
// Clear stored driver information
box.remove(BoxName.driverID);
box.remove(BoxName.emailDriver);
box.remove(BoxName.nameDriver);
box.remove(BoxName.driverPhotoUrl);
// Perform any additional sign-out tasks or API calls here
// For example, you can notify your server about the user sign-out
print('User data cleared.');
}
}

View File

@@ -7,6 +7,7 @@ import 'package:http/http.dart' as http;
import 'package:SEFER/env/env.dart';
import '../../constant/api_key.dart';
import '../../constant/colors.dart';
import 'gemeni.dart';
import 'llama_ai.dart';
import 'upload_image.dart';
@@ -246,6 +247,10 @@ class CRUD {
if (jsonData['status'] == 'success') {
return response.body;
} else {
String errorMessage = jsonData['message'];
Get.snackbar('Erroe'.tr, errorMessage.tr,
backgroundColor: AppColor.redColor);
print(errorMessage.tr);
return (jsonData['status']);
}
} else {

View File

@@ -1,6 +1,11 @@
import 'dart:convert';
import 'dart:io';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/main.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
@@ -10,17 +15,270 @@ import 'package:path_provider/path_provider.dart';
import '../../constant/api_key.dart';
import '../../constant/colors.dart';
import 'tts.dart';
import 'upload_image.dart';
class AI extends GetxController {
bool approved = false;
void setApproved() {
approved = true;
update();
}
final today = DateTime.now();
Future<void> addDriverAndCarEgypt() async {
final expiryDate = responseIdEgyptDriverLicense['expiry_date'];
final expiryDateTime = DateTime.tryParse(expiryDate);
final isExpired = expiryDateTime != null && expiryDateTime.isBefore(today);
final taxExpiryDate = responseIdCardDriverEgyptBack['tax_expiry'];
// Get the inspection date from the response
final inspectionDate = responseIdCardDriverEgyptBack['inspection_date'];
// Try parsing the tax expiry date. If it fails, set it to null.
final taxExpiryDateTime = DateTime.tryParse(taxExpiryDate ?? '');
final isExpiredCar =
taxExpiryDateTime != null && taxExpiryDateTime.isBefore(today);
// Check if the inspection date is before today
final inspectionDateTime = DateTime(int.parse(inspectionDate ?? ''), 1, 1);
final isInspectionExpired = inspectionDateTime.isBefore(today);
if (isExpiredCar || isInspectionExpired) {
Get.defaultDialog(
title: 'Expired Drivers License'.tr,
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
'Your drivers license and/or car tax has expired. Please renew them before proceeding.'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>().speakText(
'Your drivers license and/or car tax has expired. Please renew them before proceeding.'
.tr,
);
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
} else if (isExpired) {
Get.defaultDialog(
title: 'Expired Drivers License'.tr,
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
'Your drivers license has expired. Please renew it before proceeding.'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>().speakText(
'Your drivers license has expired. Please renew it before proceeding.'
.tr,
);
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
} else if (responseIdEgyptDriverLicense['national_number'] !=
responseIdEgyptBack['nationalID']) {
Get.defaultDialog(
barrierDismissible: false,
title: 'ID Mismatch',
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
'The national number on your drivers license does not match the one on your ID document. Please verify and provide the correct documents.'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>().speakText(
'The national number on your drivers license does not match the one on your ID document. Please verify and provide the correct documents.',
);
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
} else if (responseCriminalRecordEgypt['FullName'] !=
responseIdEgyptDriverLicense['name_arabic']) {
Get.defaultDialog(
barrierDismissible: false,
title: 'Criminal Record Mismatch',
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
'The full name on your criminal record does not match the one on your drivers license. Please verify and provide the correct documents.'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>().speakText(
'The full name on your criminal record does not match the one on your drivers license. Please verify and provide the correct documents.'
.tr,
);
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
} else {
isLoading = true;
update();
await addDriverEgypt();
await addRegistrationCarEgypt();
isLoading = false;
update();
}
}
Future<void> addDriverEgypt() async {
try {
var res = await CRUD().post(link: AppLink.signUpCaptin, payload: {
'first_name': responseIdEgyptDriverLicense['firstName'],
'last_name': responseIdEgyptDriverLicense['lastName'],
'email': box.read(BoxName.emailDriver),
'phone': '78787', //todo add phone //box.read(BoxName.phoneDriver),
'driverId': box.read(BoxName.driverID),
'password': '123456', // todo check
'gender': responseIdEgyptBack['gender'] == 'ذكر' ? 'Male' : 'Female',
'license_type': responseIdEgyptDriverLicense['license_type'],
'national_number': responseIdEgyptBack['nationalID'],
'name_arabic': responseIdEgyptDriverLicense['name_arabic'],
'name_english': responseIdEgyptDriverLicense['name_english'],
'issue_date': responseIdEgyptDriverLicense['issue_date'],
'expiry_date': responseIdEgyptDriverLicense['expiry_date'],
'license_categories':
responseIdEgyptDriverLicense['license_categories'],
'address': responseIdEgyptFront['address'],
'card_id': responseIdEgyptFront['card_id'],
'occupation': responseIdEgyptBack['occupation'],
'education': responseIdEgyptBack['occupation'],
'licenseIssueDate': responseIdEgyptDriverLicense['issue_date'],
'religion': responseIdEgyptBack['religion'],
'status': responseIdEgyptBack['fullName'],
'birthdate': responseIdEgyptFront['dob'] + '-01-01',
'maritalStatus': responseIdEgyptBack['maritalStatus'],
'site': responseIdEgyptDriverLicense['address'],
'employmentType': responseIdEgyptDriverLicense['employmentType'],
});
var status = jsonDecode(res);
if (status == 'success') {
Get.snackbar('Success', 'message',
backgroundColor: AppColor.greenColor);
}
} catch (e) {
print('error is $e');
}
}
Future addRegistrationCarEgypt() async {
try {
var res = await CRUD().post(link: AppLink.addRegisrationCar, payload: {
'driverID': box.read(BoxName.driverID),
'vin': responseIdCardDriverEgyptBack['chassis'].toString(),
'car_plate': responseIdCardDriverEgyptFront['car_plate'].toString(),
'make': responseIdCardDriverEgyptBack['make'].toString(),
'model': responseIdCardDriverEgyptBack['model'],
'year': responseIdCardDriverEgyptBack['year'].toString(),
'expiration_date':
responseIdCardDriverEgyptFront['LicenseExpirationDate'].toString(),
'color': responseIdCardDriverEgyptBack['color'],
'owner': responseIdCardDriverEgyptFront['owner'],
'color_hex': responseIdCardDriverEgyptBack['color_hex'].toString(),
'address': responseIdCardDriverEgyptFront['address'].toString(),
'displacement': responseIdCardDriverEgyptBack['engine'].toString(),
'fuel': responseIdCardDriverEgyptBack['fuel'].toString(),
'registration_date':
'${responseIdCardDriverEgyptBack['inspection_date']}-01-01',
});
var status = jsonDecode(res);
if (status == 'success') {
Get.snackbar('Success', 'message',
backgroundColor: AppColor.greenColor);
}
} catch (e) {
print('error is $e');
}
}
final picker = ImagePicker();
Map<String, dynamic> responseMap = {};
Map<String, dynamic> responseCarLicenseMap = {};
Map<String, dynamic> responseCarLicenseMapJordan = {};
Map<String, dynamic> responseBackCarLicenseMap = {};
Map<String, dynamic> responseIdCardMap = {};
Map<String, dynamic> responseIdCardDriverEgyptBack = {};
Map<String, dynamic> responseIdCardDriverEgyptFront = {};
Map<String, dynamic> responseIdEgyptFront = {};
Map<String, dynamic> responseCriminalRecordEgypt = {};
Map<String, dynamic> responseIdEgyptBack = {};
Map<String, dynamic> responseIdEgyptDriverLicense = {};
String? responseIdCardDriverEgypt1;
@@ -87,7 +345,7 @@ class AI extends GetxController {
var json = jsonDecode(extractedString);
var textValues = CRUD().extractTextFromLines(json);
print(textValues);
// await Get.put(AI()).geminiAiExtraction(prompt, textValues);
// await Get.put(AI()).geminiAiExtraction(prompt, textValues, imagePath);
await Get.put(AI()).anthropicAI(textValues, prompt, imagePath);
isLoading = false;
update();
@@ -238,6 +496,10 @@ class AI extends GetxController {
responseIdEgyptDriverLicense =
jsonDecode(responseData['content'][0]['text']);
print(responseIdEgyptDriverLicense);
} else if (idType == 'criminalRecord') {
responseCriminalRecordEgypt =
jsonDecode(responseData['content'][0]['text']);
print(responseCriminalRecordEgypt);
}
update();
@@ -246,7 +508,7 @@ class AI extends GetxController {
return responseIdCardDriverEgyptBack.toString();
}
Future<void> geminiAiExtraction(String prompt, payload) async {
Future<void> geminiAiExtraction(String prompt, payload, String idType) async {
var requestBody = jsonEncode({
"contents": [
{
@@ -309,11 +571,28 @@ class AI extends GetxController {
// Convert the JSON object to a String
jsonString = jsonEncode(json.decode(jsonString));
responseIdCardDriverEgyptBack = jsonDecode(jsonString);
print(responseIdCardDriverEgyptBack);
if (idType == 'car_back') {
responseIdCardDriverEgyptBack = jsonDecode(jsonString);
print(responseIdCardDriverEgyptBack);
} else if (idType == 'car_front') {
responseIdCardDriverEgyptFront = jsonDecode(jsonString);
print(responseIdCardDriverEgyptFront);
} else if (idType == 'id_front') {
responseIdEgyptFront = jsonDecode(jsonString);
print(responseIdEgyptFront);
} else if (idType == 'id_back') {
responseIdEgyptBack = jsonDecode(jsonString);
print(responseIdEgyptBack);
} else if (idType == 'driver_license') {
responseIdEgyptDriverLicense = jsonDecode(jsonString);
print(responseIdEgyptDriverLicense);
}
update();
} else {
print("JSON string not found");
Get.snackbar('Error', "JSON string not found",
backgroundColor: AppColor.redColor);
}
// Rest of your code...
@@ -503,10 +782,10 @@ Output the extracted information in the following JSON format''',
if (jsonString != null) {
// Convert the JSON object to a String
jsonString = jsonEncode(json.decode(jsonString));
responseCarLicenseMap = jsonDecode(jsonString);
responseCarLicenseMapJordan = jsonDecode(jsonString);
print(jsonString);
print(responseCarLicenseMap);
print(responseCarLicenseMap['plate_number']);
print(responseCarLicenseMapJordan);
print(responseCarLicenseMapJordan['plate_number']);
} else {
print("JSON string not found");
}
@@ -604,10 +883,10 @@ Output the extracted information in the following JSON format''',
if (jsonString != null) {
// Convert the JSON object to a String
jsonString = jsonEncode(json.decode(jsonString));
responseCarLicenseMap = jsonDecode(jsonString);
responseCarLicenseMapJordan = jsonDecode(jsonString);
print(jsonString);
print(responseCarLicenseMap);
print(responseCarLicenseMap['plate_number']);
print(responseCarLicenseMapJordan);
print(responseCarLicenseMapJordan['plate_number']);
} else {
print("JSON string not found");
}
@@ -714,10 +993,10 @@ Output the extracted information in the following JSON formate and make date for
if (jsonString != null) {
// Convert the JSON object to a String
jsonString = jsonEncode(json.decode(jsonString));
responseCarLicenseMap = jsonDecode(jsonString);
responseCarLicenseMapJordan = jsonDecode(jsonString);
print(jsonString);
print(responseCarLicenseMap);
print(responseCarLicenseMap['plate_number']);
print(responseCarLicenseMapJordan);
print(responseCarLicenseMapJordan['plate_number']);
} else {
print("JSON string not found");
}

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:SEFER/constant/api_key.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/info.dart';
@@ -7,22 +9,28 @@ import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
class SmsEgypt extends GetxController {
class SmsEgyptController extends GetxController {
var headers = {'Content-Type': 'application/json'};
Future sendSmsEgypt(String phone, otp) async {
Future<dynamic> sendSmsEgypt(String phone, otp) async {
var body = jsonEncode({
"username": AppInformation.appName,
"password": AK.smsPassword,
"message": "${AppInformation.appName} app code is $otp\ncopy it to app",
"language": box.read(BoxName.lang) == 'en' ? "e" : 'r',
"sender": "Kazumi", // todo add sefer sender name
"receiver": "2$phone"
});
var res = await http.post(
Uri.parse(AppLink.sendSms),
body: {
"username": AppInformation.appName,
"password": AK.smsPassword,
"message": "${AppInformation.appName} app code is $otp\ncopy it to app",
"language": box.read(BoxName.lang) == 'en' ? "e" : 'r',
"sender": "Kazumi", // todo add sefer sender name
"receiver": "2$phone"
},
body: body,
headers: headers,
);
print(res.reasonPhrase);
print(res.request);
print(res.body);
if (res.statusCode == 200) {
Get.defaultDialog(
title: 'You will recieve code in sms message'.tr,

View File

@@ -6,7 +6,7 @@ import 'package:get/get.dart';
class TextToSpeechController extends GetxController {
final flutterTts = FlutterTts();
bool isComplete = false;
// Initialize TTS in initState
@override
void onInit() {
@@ -41,6 +41,8 @@ class TextToSpeechController extends GetxController {
if (result == 1) {
// TTS operation has started
// You can perform additional operations here, if needed
isComplete = true;
update();
}
} catch (error) {
// Handle error gracefully, e.g., show a message

View File

@@ -9,6 +9,7 @@ import 'package:SEFER/views/auth/login_page.dart';
import '../../constant/box_name.dart';
import '../../main.dart';
import '../../onbording_page.dart';
import '../../views/auth/captin/cards_egypt/sms_signup.dart';
import '../../views/auth/captin/login_captin.dart';
import '../../views/home/Captin/home_captain/home_captin.dart';
@@ -50,7 +51,7 @@ class SplashScreenController extends GetxController
box.read(BoxName.onBoarding) == null
? Get.off(() => OnBoardingPage())
: box.read(BoxName.emailDriver) != null
? Get.off(() => RegisterCaptin())
? Get.off(() => SmsSignupEgypt())
: Get.off(() => LoginCaptin());
});
}

View File

@@ -4,6 +4,70 @@ class MyTranslation extends Translations {
@override
Map<String, Map<String, String>> get keys => {
"ar": {
'You will recieve code in sms message': '',
'Please enter': '',
'We need your phone number to contact you and to help you receive orders.':
"نحتاج إلى رقم هاتفك للتواصل معك ولمساعدتك في تلقي الطلبات.",
'The full name on your criminal record does not match the one on your drivers license. Please verify and provide the correct documents.':
'الاسم الكامل في سجلك الجنائي لا يتطابق مع الاسم الموجود في رخصة القيادة الخاصة بك. يرجى التحقق وتقديم الوثائق الصحيحة.',
"The national number on your drivers license does not match the one on your ID document. Please verify and provide the correct documents.":
"الرقم الوطني على رخصة القيادة الخاصة بك لا يتطابق مع الرقم الموجود على وثيقة الهوية الخاصة بك. يرجى التحقق وتقديم الوثائق الصحيحة.",
"Capture an Image of Your Criminal Record":
"التقط صورة لسجلك الجنائي",
"IssueDate": "تاريخ الإصدار",
"Capture an Image of Your car license front ":
"التقط صورة للواجهة الأمامية لرخصة سيارتك",
"Capture an Image of Your ID Document front":
"التقط صورة للواجهة الأمامية لوثيقة هويتك",
"NationalID": "الرقم القومي",
"FullName": "الاسم الكامل",
"InspectionResult": "نتيجة الفحص",
"Criminal Record": "السجل الجنائي",
"The email or phone number is already registered.":
"البريد الإلكتروني أو رقم الهاتف مسجل بالفعل.",
'To become a ride-sharing driver on the Sefer app, you need to upload your driver\'s license, ID document, and car registration document. Our AI system will instantly review and verify their authenticity in just 2-3 minutes. If your documents are approved, you can start working as a driver on the Sefer app. Please note, submitting fraudulent documents is a serious offense and may result in immediate termination and legal consequences.':
'لِتُصْبِحَ سَائِقَاً لِلرُّكوبِ المُشْتَرَكِ عَلَى تَطْبِيق سَفَر، يَجِبُ عَلَيْكَ تَحْمِيل رُخْصَةِ القِيَادَةِ، وَثِيقَةِ الهُوِيَّةِ، وَوَثِيقَةَ تَسْجِيل السَّيَّارَةِ. سَيَقُومُ نِظَامُ الذَّكَاءِ الاِصْطِنَاعِيِّ لَدَيْنَا بِمُرَاجَعَةِ وَتَحْقِيقِ صِحَّةِ الوَثَائِقِ فِي غُضُونِ ٢-٣ دَقَائِقَ فَقَطْ. إِذَا تَمَّتْ المُوَافَقَةُ عَلَى وَثَائِقِكَ، يُمْكِنُكَ البَدْءُ فِي العَمَلِ كَسَائِقٍ عَلَى تَطْبِيق سَفَر. يُرْجَى مُلَاحَظَةُ، تَقْدِيمُ وَثَائِقَ مُزَورَةٍ يُعَدُّ جَرِيمَةً خَطِيرَةً وَقَدْ يَتَرَتَّبُ عَلَيْهِ اِنهَاءُ الحِسَابِ فَوْرِيَّاً وَعَوَاقِبُ قَانُونِيَّة.',
"Documents check": "فحص الوثائق",
"Driver's License": "رخصة القيادة",
"License Type": "نوع الرخصة",
"National Number": "الرقم الوطني",
"Name (Arabic)": "الاسم بالعربي",
"Name (English)": "الاسم بالإنجليزية",
"Address": "العنوان",
"Issue Date": "تاريخ الإصدار",
"Expiry Date": "تاريخ الانتهاء",
"License Categories": "فئات الرخصة",
"driver_license": "رخصة القيادة",
"Capture an Image of Your Driver License": "التقط صورة لرخصة قيادتك",
"ID Documents Back": "الوجه الخلفي لوثائق الهوية",
"National ID": "البطاقة الوطنية",
"Occupation": "المهنة",
"Gender": "الجنس",
"Religion": "الديانة",
"Marital Status": "الحالة الاجتماعية",
"Full Name (Marital)": "الاسم الكامل (حسب الحالة الاجتماعية)",
"Expiration Date": "تاريخ الانتهاء",
"Capture an Image of Your ID Document Back":
"التقط صورة للوجه الخلفي لوثيقة الهوية الخاصة بك",
"ID Documents Front": "الوجه الأمامي لوثائق الهوية",
"First Name": "الاسم الأول",
"CardID": "رقم البطاقة",
"Full Name": "الاسم الكامل",
"Vehicle Details Front": "تفاصيل المركبة ‏الوجه الأمامية",
"Plate Number": "رقم اللوحة",
"Owner Name": "اسم المالك",
"Vehicle Details Back": "تفاصيل المركبة ‏الوجه الخلفي",
"Make": "المصنع",
"Model": "الطراز",
"Year": "السنة",
"Chassis": "الشاسيه",
"Color": "اللون",
"Displacement": "السعة",
"Fuel": "الوقود",
"Tax Expiry Date": "تاريخ انتهاء الضريبة",
"Inspection Date": "تاريخ الفحص",
"Capture an Image of Your car license back":
"التقط صورة للوجه الخلفي لرخصة سيارتك",
'Capture an Image of Your Drivers License':
'التقط صورة لرخصة قيادتك',
'Sign in with Google for easier email and name entry':