This commit is contained in:
Hamza-Ayed
2024-07-16 18:13:40 +03:00
parent 4ffaa591fa
commit e6305f4ddc
9 changed files with 246 additions and 140 deletions

View File

@@ -55,8 +55,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 23
targetSdkVersion 34
versionCode 56
versionName '1.5.56'
versionCode 57
versionName '1.5.57'
// manifestPlaceholders = [mapsApiKey: 'android/app/src/main/AndroidManifest.xml']
}

View File

@@ -21,7 +21,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>48</string>
<string>49</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
@@ -36,7 +36,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>4.0.48</string>
<string>4.0.49</string>
<key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string>
<key>GMSApiKey</key>

View File

@@ -201,6 +201,8 @@ class AppLink {
static String addInviteDriver = "$server/ride/invitor/add.php";
static String getInviteDriver = "$server/ride/invitor/get.php";
static String updateInviteDriver = "$server/ride/invitor/update.php";
static String updateInvitationCodeFromRegister =
"$server/ride/invitor/updateInvitationCodeFromRegister.php";
//===================Auth============

View File

@@ -101,8 +101,8 @@ class InviteController extends GetxController {
'${'before'.tr} *${d['message']['expirationTime'].toString()}*\n\n'
'_*${d['message']['inviteCode'].toString()}*_\n\n'
'${"Install our app:".tr}\n'
'Android: https://play.google.com/store/apps/details?id=com.sefer_driver\n'
'iOS: https://apps.apple.com/ae/app/sefer-driver/id6502189302';
'*Android:* https://play.google.com/store/apps/details?id=com.sefer_driver\n\n\n'
'*iOS:* https://apps.apple.com/ae/app/sefer-driver/id6502189302';
launchCommunication(
'whatsapp', '+2${invitePhoneController.text}', message);

View File

@@ -25,11 +25,32 @@ class AI extends GetxController {
bool approved = false;
bool isDriverSaved = false;
bool isCarSaved = false;
bool isInviteDriverFound = false;
final invitationCodeController = TextEditingController();
final formKey = GlobalKey<FormState>();
void setApproved() {
approved = true;
update();
}
Future updateInvitationCodeFromRegister() async {
if (formKey.currentState!.validate()) {
var res = await CRUD().post(
link: AppLink.updateInvitationCodeFromRegister,
payload: {"inviteCode": invitationCodeController.text});
if (res != 'failure') {
isInviteDriverFound = true;
update();
Get.snackbar("Code approved".tr, '',
backgroundColor: AppColor.greenColor);
} else {
Get.snackbar("Code not approved".tr, '',
backgroundColor: AppColor.redColor);
}
}
}
final today = DateTime.now();
Future<void> addDriverAndCarEgypt() async {
@@ -48,7 +69,7 @@ class AI extends GetxController {
taxExpiryDateTime != null && taxExpiryDateTime.isBefore(today);
// Check if the inspection date is before today
final inspectionDateTime = DateTime(year, 1, 1);
final inspectionDateTime = DateTime(year, 12, 31);
final isInspectionExpired = inspectionDateTime.isBefore(today);
if (isExpiredCar || isInspectionExpired) {
@@ -60,7 +81,7 @@ class AI extends GetxController {
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.'
"Your drivers license and/or car tax has expired. Please renew them before proceeding."
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
@@ -69,7 +90,7 @@ class AI extends GetxController {
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>().speakText(
'Your drivers license and/or car tax has expired. Please renew them before proceeding.'
"Your drivers license and/or car tax has expired. Please renew them before proceeding."
.tr,
);
},
@@ -95,7 +116,7 @@ class AI extends GetxController {
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
'Your drivers license has expired. Please renew it before proceeding.'
"Your drivers license has expired. Please renew it before proceeding."
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
@@ -104,9 +125,8 @@ class AI extends GetxController {
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>().speakText(
'Your drivers license has expired. Please renew it before proceeding.'
.tr,
);
"Your drivers license has expired. Please renew it before proceeding."
.tr);
},
icon: const Icon(Icons.volume_up),
),
@@ -132,7 +152,7 @@ class AI extends GetxController {
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.'
"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,
@@ -141,7 +161,8 @@ class AI extends GetxController {
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.',
"The national number on your drivers license does not match the one on your ID document. Please verify and provide the correct documents."
.tr,
);
},
icon: const Icon(Icons.volume_up),

View File

@@ -4,6 +4,12 @@ class MyTranslation extends Translations {
@override
Map<String, Map<String, String>> get keys => {
"ar": {
"ID Documents Front": "الوثيقه الشخصية - الأمامية",
"Vehicle Details Front": "تفاصيل المركبة - الأمامية",
"Vehicle Details Back": "تفاصيل المركبة - الخلفية",
"Criminal Record": "السجل الجنائي",
"ID Documents Back": "الوثيقه الشخصية - الخلفية",
"Driver's License": "رخصة القيادة",
"you can show video how to setup":
"يمكنك عرض فيديو حول كيفية الإعداد",
"don't start trip if not": "لا تبدأ الرحلة إذا لم",
@@ -248,6 +254,13 @@ class MyTranslation extends Translations {
"National ID": "الهوية الوطنية",
"Occupation": "المهنة",
"Gender": "الجنس",
"Your drivers license and/or car tax has expired. Please renew them before proceeding.":
"لقد انتهت صلاحية رخصة القيادة و/أو ضريبة السيارة الخاصة بك. يرجى تجديدها قبل المتابعة.",
"Your drivers license has expired. Please renew it before proceeding.":
"لقد انتهت صلاحية رخصة القيادة الخاصة بك. يرجى تجديدها قبل المتابعة.",
"The national number on your drivers license does not match the one on your ID document. Please verify and provide the correct documents.":
"الرقم الوطني على رخصة القيادة الخاصة بك لا يتطابق مع الرقم الموجود على مستند الهوية. يرجى التحقق وتقديم المستندات الصحيحة.",
"Religion": "الدين",
"You have 500": "لديك 500",
"You have got a gift for invitation": "لقد حصلت على هدية للدعوة",
@@ -257,7 +270,13 @@ class MyTranslation extends Translations {
"for your first registration!": "للتسجيل الأول!",
"Get it Now!": "احصل عليه الآن!",
"before": "قبل",
"Code not approved": "الرمز غير موافق عليه",
"3000 LE": "3000 جنيه مصري",
"Do you have an invitation code from another driver?":
"هل لديك كود دعوة من سائق آخر؟",
"Paste the code here": "الصق الكود هنا",
"No, I don't have a code": "لا، لا أملك كودا",
"Code approved": "تمت الموافقة على الكود",
"Install our app:": "قم بتثبيت تطبيقنا:",
"Invite another driver and both get a gift after he completes 100 trips!":
"ادع صديقًا ليكون سائقًا واحصلا على هدية بعد إكماله 100 مشوار!",

View File

@@ -54,8 +54,10 @@ class DriverWalletHistoryController extends GetxController {
Get.back();
},
));
} else {
weeklyList = jsonDecode(res)['message'];
}
weeklyList = jsonDecode(res)['message'];
isLoading = false;
update();
}

View File

@@ -1,13 +1,10 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/controller/functions/gemeni.dart';
import 'package:SEFER/controller/functions/tts.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_textField.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../../../../constant/colors.dart';
import '../../../../constant/links.dart';
import '../../../../constant/style.dart';
@@ -114,102 +111,153 @@ class EgyptCardAI extends StatelessWidget {
right: 30,
left: 30,
child: GetBuilder<AI>(builder: (controller) {
return controller.approved == false
? Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'Approve Driver Documents'.tr,
style: AppStyle.title,
),
const SizedBox(height: 8),
Text(
'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.'
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Container(
decoration: AppStyle.boxDecoration1,
child: TextButton.icon(
onPressed: () async {
await textToSpeechController.speakText(
'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.'
.tr);
},
icon: const Icon(
Icons.headphones,
size: 50,
),
label: Text(
'Press to hear'.tr,
style: AppStyle.title,
return controller.isInviteDriverFound == false
? Padding(
padding: const EdgeInsets.symmetric(vertical: 60),
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
"Do you have an invitation code from another driver?"
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
const SizedBox(
height: 30,
),
Form(
key: controller.formKey,
child: MyTextForm(
controller:
controller.invitationCodeController,
label: "Paste the code here".tr,
hint: "Paste the code here".tr,
type: TextInputType.name,
),
),
),
const SizedBox(height: 8),
GetBuilder<TextToSpeechController>(
builder: (textToSpeechController) {
return textToSpeechController.isComplete
? Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
MyElevatedButton(
title: 'OK'.tr,
kolor: AppColor.greenColor,
onPressed: () {
controller.setApproved();
}),
MyElevatedButton(
title: 'cancel'.tr,
kolor: AppColor.redColor,
onPressed: () {
Get.defaultDialog(
title:
'You will cancel registeration'
.tr,
middleText: '',
content: IconButton(
onPressed: () async {
await textToSpeechController
.speakText(
'You will cancel registeration'
.tr);
},
icon: const Icon(
Icons.headphones),
),
confirm: MyElevatedButton(
title: 'OK'.tr,
kolor: AppColor.redColor,
onPressed: () {
Get.back();
Get.back();
}),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
kolor:
AppColor.greenColor,
onPressed: () {
Get.back();
}));
}),
],
)
: const SizedBox();
})
],
const SizedBox(
height: 30,
),
MyElevatedButton(
title: 'Ok'.tr,
onPressed: () async {
controller
.updateInvitationCodeFromRegister();
}),
MyElevatedButton(
kolor: AppColor.yellowColor,
title: "No, I don't have a code".tr,
onPressed: () {
controller.isInviteDriverFound = true;
controller.update();
})
],
),
),
),
)
: const SizedBox();
: controller.approved == false
? Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
'Approve Driver Documents'.tr,
style: AppStyle.title,
),
const SizedBox(height: 8),
Text(
'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.'
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Container(
decoration: AppStyle.boxDecoration1,
child: TextButton.icon(
onPressed: () async {
await textToSpeechController.speakText(
'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.'
.tr);
},
icon: const Icon(
Icons.headphones,
size: 50,
),
label: Text(
'Press to hear'.tr,
style: AppStyle.title,
),
),
),
const SizedBox(height: 8),
GetBuilder<TextToSpeechController>(
builder: (textToSpeechController) {
return textToSpeechController.isComplete
? Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
MyElevatedButton(
title: 'OK'.tr,
kolor: AppColor.greenColor,
onPressed: () {
controller.setApproved();
}),
MyElevatedButton(
title: 'cancel'.tr,
kolor: AppColor.redColor,
onPressed: () {
Get.defaultDialog(
title:
'You will cancel registeration'
.tr,
middleText: '',
content: IconButton(
onPressed: () async {
await textToSpeechController
.speakText(
'You will cancel registeration'
.tr);
},
icon: const Icon(
Icons.headphones),
),
confirm: MyElevatedButton(
title: 'OK'.tr,
kolor:
AppColor.redColor,
onPressed: () {
Get.back();
Get.back();
}),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
kolor: AppColor
.greenColor,
onPressed: () {
Get.back();
}));
}),
],
)
: const SizedBox();
})
],
),
),
)
: const SizedBox();
}),
)
],
@@ -402,18 +450,28 @@ Important notes:
IconButton(
onPressed: () async {
await ai.allMethodForAI("""
Write a JSON from the following information extracted from the provided Arabic text:
- nationalID(in Latin numerals)
Given the following Arabic text values:
Please create a JSON object with the following fields:
- nationalID (use exactly 14 digits, no more and no less)
- issueDate (in format YYYY-MM-DD using Latin numerals)
- occupation
- gender
- country
- religion
- maritalStatus
- fullNameMarital (if maritalStatus is "أعزب", set this to "none")
- expirationDate (in format YYYY-MM-DD using Latin numerals)
Please ensure all date fields use Latin (Western) numerals (0-9) instead of Arabic numerals. For example, use "2023-04-03" instead of "٢٠٢٣-٠٤-٠٣".
""", AppLink.uploadEgypt, 'id_back'); //egypt
Important notes:
1. Ensure all date fields use Latin (Western) numerals (0-9) instead of Arabic numerals.
2. For the nationalID, use exactly 14 digits from the provided Arabic numeral string, converting to Latin numerals.
3. For issueDate, use the last day of the month since only year and month are provided.
4. Include the country field based on the provided information.
5. Format all string values consistently (e.g., all lowercase or proper case).
Please provide the resulting JSON object. """, AppLink.uploadEgypt,
'id_back'); //egypt
},
icon: const Icon(Icons.refresh),
),
@@ -482,25 +540,28 @@ Please ensure all date fields use Latin (Western) numerals (0-9) instead of Arab
child: InkWell(
onTap: () async {
await ai.allMethodForAI('''
Write a JSON object from the following information extracted from the provided Arabic text:
Given the following Arabic text values:
{
"nationalID": "",//(in Latin numerals)
"issueDate": "", // Format: YYYY-MM-DD using Latin numerals (0-9)
"occupation": "",
"gender": "",
"religion": "",
"maritalStatus": "",
"fullNameMaritial": "", // Set to "none" if maritalStatus is "أعزب"
"expirationDate": "" // Format: YYYY-MM-DD using Latin numerals (0-9)
}
Please create a JSON object with the following fields:
- nationalID (use exactly 14 digits, no more and no less)
- issueDate (in format YYYY-MM-DD using Latin numerals)
- occupation
- gender
- country
- religion
- maritalStatus
- fullNameMarital (if maritalStatus is "أعزب", set this to "none")
- expirationDate (in format YYYY-MM-DD using Latin numerals)
Important notes:
1. Ensure all dates (issueDate and expirationDate) are in the format YYYY-MM-DD using Latin (Western) numerals (0-9), not Arabic numerals.
2. If maritalStatus is "أعزب" (single), set fullNameMaritial to "none".
3. Fill in all fields based on the information provided in the Arabic text.
4. If any information is missing, leave the field as an empty string.
''', AppLink.uploadEgypt, 'id_back'); //egypt
1. Ensure all date fields use Latin (Western) numerals (0-9) instead of Arabic numerals.
2. For the nationalID, use exactly 14 digits from the provided Arabic numeral string, converting to Latin numerals.
3. For issueDate, use the last day of the month since only year and month are provided.
4. Include the country field based on the provided information.
5. Format all string values consistently (e.g., all lowercase or proper case).
Please provide the resulting JSON object. ''', AppLink.uploadEgypt,
'id_back'); //egypt
},
child: Column(
children: [
@@ -817,19 +878,20 @@ Please fill in the JSON object with the extracted information, following these g
final inspectionDate =
ai.responseIdCardDriverEgyptBack['inspection_date'];
final year = int.parse(inspectionDate.split('-')[0]);
// Set inspectionDateTime to December 31st of the given year
final inspectionDateTime = DateTime(year, 12, 31);
// Check if the tax expiry date is before today
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.
// 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
// final inspectionDateTime =
// DateTime(int.parse(year ?? ''), 1, 1);
final isInspectionExpired = inspectionDateTime.isBefore(today);
// Check if the inspection date is before today
bool isInspectionExpired = inspectionDateTime.isBefore(today);
return Card(
elevation: 4.0,
@@ -929,7 +991,7 @@ Please fill in the JSON object with the extracted information, following these g
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Inspection Date'.tr}: $inspectionDate',
'${'Inspection Date'.tr}: $carBackLicenseExpired',
style: TextStyle(
color:
isInspectionExpired ? Colors.red : Colors.green,

View File

@@ -424,5 +424,5 @@ bool _checkIfFirstTime() {
}
void _markAsNotFirstTime() {
box.write(BoxName.isFirstTime, true);
box.write(BoxName.isFirstTime, false);
}