Update: 2026-07-09 05:02:10

This commit is contained in:
Hamza-Ayed
2026-07-09 05:02:10 +03:00
parent 2152d34a8e
commit 45859883a5
18 changed files with 29 additions and 4497 deletions
@@ -1,419 +0,0 @@
import 'dart:convert';
import 'dart:math';
import 'package:siro_driver/controller/auth/captin/login_captin_controller.dart';
import 'package:siro_driver/views/widgets/error_snakbar.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_driver/constant/box_name.dart';
import 'package:siro_driver/constant/links.dart';
import 'package:siro_driver/controller/functions/crud.dart';
import 'package:siro_driver/controller/functions/ocr_controller.dart';
import 'package:siro_driver/main.dart';
import 'package:siro_driver/views/auth/captin/login_captin.dart';
import 'package:siro_driver/views/auth/captin/verify_email_captain.dart';
import '../../../constant/colors.dart';
import '../../../views/auth/captin/ai_page.dart';
import '../../../views/auth/syria/registration_view.dart';
import '../../../views/home/Captin/home_captain/home_captin.dart';
import '../../functions/country_logic.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();
TextEditingController passwordController = TextEditingController();
TextEditingController verifyCode = TextEditingController();
String birthDate = 'Birth Date'.tr;
String gender = 'Male'.tr;
bool isLoading = false;
bool isSent = false;
late String name;
late String licenseClass;
late String documentNo;
late String address;
late String height;
late String postalCode;
late String sex;
late String stateCode;
late String expireDate;
late String dob;
getBirthDate() {
Get.defaultDialog(
title: 'Select Date'.tr,
content: SizedBox(
width: 300,
child: CalendarDatePicker(
initialDate: DateTime.now().subtract(const Duration(days: 18 * 365)),
firstDate: DateTime.parse('1940-06-01'),
lastDate: DateTime.now().subtract(const Duration(days: 18 * 365)),
onDateChanged: (date) {
// Get the selected date and convert it to a DateTime object
DateTime dateTime = date;
// Call the getOrders() function from the controller
birthDate = dateTime.toString().split(' ')[0];
update();
Get.back();
},
// onDateChanged: (DateTime value) {},
),
),
);
}
@override
void onInit() {
// Get.put(SmsEgyptController());
super.onInit();
}
void changeGender(String value) {
gender = value;
update();
}
bool isValidEgyptianPhoneNumber(String phoneNumber) {
// Remove any non-digit characters (spaces, dashes, etc.)
phoneNumber = phoneNumber.replaceAll(RegExp(r'\D+'), '');
// Check if the phone number has exactly 11 digits
if (phoneNumber.length != 11) {
return false;
}
// Check if the phone number starts with 010, 011, 012, or 015
RegExp validPrefixes = RegExp(r'^01[0125]\d{8}$');
return validPrefixes.hasMatch(phoneNumber);
}
sendOtpMessage() async {
SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
isLoading = true;
update();
isLoading = true;
update();
if (formKey3.currentState!.validate()) {
if (box.read(BoxName.countryCode) == 'Egypt') {
if (isValidEgyptianPhoneNumber(phoneController.text)) {
var responseCheker = await CRUD()
.post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: {
'phone_number': ('+2${phoneController.text}'),
});
if (responseCheker != 'failure') {
var d = jsonDecode(responseCheker);
if (d['message'][0]['is_verified'].toString() == '1') {
Get.snackbar('Phone number is verified before'.tr, '',
backgroundColor: AppColor.greenColor);
box.write(BoxName.phoneVerified, '1');
box.write(BoxName.phone, ('+2${phoneController.text}'));
await Get.put(LoginDriverController()).loginDriver(
box.read(BoxName.driverID).toString(),
(box.read(BoxName.emailDriver).toString()),
);
} else {
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
'phone_number': ('+2${phoneController.text}'),
"driverId": box.read(BoxName.driverID),
"email": (box.read(BoxName.emailDriver)),
});
isSent = true;
isLoading = false;
update();
}
} else {
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
'phone_number': ('+2${phoneController.text}'),
"driverId": box.read(BoxName.driverID),
"email": box.read(BoxName.emailDriver),
});
isSent = true;
isLoading = false;
update();
}
} else {
mySnackbarError(
'Phone Number wrong'.tr,
);
}
}
}
isLoading = false;
update();
}
DateTime? lastOtpSentTime; // Store the last OTP sent time
int otpResendInterval = 300; // 5 minutes in seconds
// Main function to handle OTP sending
// sendOtpMessage() async {
// if (_isOtpResendAllowed()) {
// isLoading = true;
// update();
// if (formKey3.currentState!.validate()) {
// String countryCode = box.read(BoxName.countryCode);
// String phoneNumber = phoneController.text;
// if (countryCode == 'Egypt' && isValidEgyptianPhoneNumber(phoneNumber)) {
// await _checkAndSendOtp(phoneNumber);
// } else {
// _showErrorMessage('Phone Number is not Egypt phone '.tr);
// }
// }
// isLoading = false;
// update();
// } else {
// _showCooldownMessage();
// }
// }
// Check if the resend OTP request is allowed (5 minutes cooldown)
// bool _isOtpResendAllowed() {
// if (lastOtpSentTime == null) return true;
// final int elapsedTime =
// DateTime.now().difference(lastOtpSentTime!).inSeconds;
// return elapsedTime >= otpResendInterval;
// }
// // Show message when user tries to resend OTP too soon
// void _showCooldownMessage() {
// int remainingTime = otpResendInterval -
// DateTime.now().difference(lastOtpSentTime!).inSeconds;
// Get.snackbar(
// 'Please wait ${remainingTime ~/ 60}:${(remainingTime % 60).toString().padLeft(2, '0')} minutes before requesting again',
// '',
// backgroundColor: AppColor.redColor,
// );
// }
// // Check if the phone number has been verified, and send OTP if not verified
// _checkAndSendOtp(String phoneNumber) async {
// var responseChecker = await CRUD().post(
// link: AppLink.checkPhoneNumberISVerfiedDriver,
// payload: {
// 'phone_number': '+2$phoneNumber',
// },
// );
// if (responseChecker != 'failure') {
// var responseData = jsonDecode(responseChecker);
// if (_isPhoneVerified(responseData)) {
// _handleAlreadyVerified();
// } else {
// await _sendOtpAndSms(phoneNumber);
// }
// } else {
// await _sendOtpAndSms(phoneNumber);
// }
// }
// Check if the phone number is already verified
bool _isPhoneVerified(dynamic responseData) {
return responseData['message'][0]['is_verified'].toString() == '1';
}
// Handle case where phone number is already verified
_handleAlreadyVerified() {
mySnackbarSuccess('Phone number is already verified'.tr);
box.write(BoxName.phoneVerified, '1');
box.write(BoxName.phone, ('+2${phoneController.text}'));
Get.put(LoginDriverController()).loginDriver(
box.read(BoxName.driverID).toString(),
box.read(BoxName.emailDriver).toString(),
);
}
// Send OTP and SMS
_sendOtpAndSms(String phoneNumber) async {
SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
int randomNumber = Random().nextInt(900) + 100;
await CRUD().post(
link: AppLink.sendVerifyOtpMessage,
payload: {
'phone_number': ('+2$phoneNumber'),
'token_code': (randomNumber.toString()),
'driverId': box.read(BoxName.driverID),
'email': box.read(BoxName.emailDriver),
},
);
await smsEgyptController.sendSmsEgypt(phoneNumber);
lastOtpSentTime = DateTime.now(); // Update the last OTP sent time
isSent = true;
isLoading = false;
update();
}
verifySMSCode() async {
// var loginDriverController = Get.put(LoginDriverController());
if (formKey3.currentState!.validate()) {
var res = await CRUD().post(link: AppLink.verifyOtpDriver, payload: {
'phone_number': ('+2${phoneController.text}'),
'token_code': (verifyCode.text.toString()),
});
if (res != 'failure') {
// var dec = jsonDecode(res);
box.write(BoxName.phoneDriver, ('+2${phoneController.text}'));
box.write(BoxName.phoneVerified, '1');
// loginDriverController.isGoogleLogin == true
// ? await loginDriverController.loginUsingCredentialsWithoutGoogle(
// loginDriverController.passwordController.text.toString(),
// box.read(BoxName.emailDriver).toString(),
// )
// : await loginDriverController.loginUsingCredentials(
// box.read(BoxName.driverID).toString(),
// box.read(BoxName.emailDriver).toString(),
// );
Get.to(() => RegistrationView());
// Get.snackbar('title', 'message');
// }
}
} else {
mySnackbarError('you must insert token code '.tr);
}
}
sendVerifications() async {
var res = await CRUD().post(link: AppLink.verifyEmail, payload: {
'email': emailController.text.isEmpty
? (Get.find<LoginDriverController>().emailController.text.toString())
: (emailController.text),
'token': (verifyCode.text),
});
if (res != 'failure') {
if (Get.find<LoginDriverController>().emailController.text.toString() !=
'') {
Get.offAll(() => HomeCaptain());
} else {
// Get.to(() => CarLicensePage());
}
}
}
void nextToAIDetection() async {
//Todo dont forget this
if (formKey.currentState!.validate()) {
isLoading = true;
update();
Get.to(() => RegistrationView());
}
}
Map<String, dynamic> payloadLisence = {};
void getFromController() {
name = Get.find<ScanDocumentsByApi>().name;
licenseClass = Get.find<ScanDocumentsByApi>().licenseClass.toString();
documentNo = Get.find<ScanDocumentsByApi>().documentNo.toString();
address = Get.find<ScanDocumentsByApi>().address.toString();
height = Get.find<ScanDocumentsByApi>().height.toString();
postalCode = Get.find<ScanDocumentsByApi>().address.toString();
sex = Get.find<ScanDocumentsByApi>().sex.toString();
stateCode = Get.find<ScanDocumentsByApi>().postalCode.toString();
expireDate = Get.find<ScanDocumentsByApi>().expireDate.toString();
dob = Get.find<ScanDocumentsByApi>().dob.toString();
update();
}
Future addLisence() async {
getFromController();
var res = await CRUD().post(link: AppLink.addLicense, payload: {
'name': name,
'licenseClass': licenseClass,
'documentNo': documentNo,
'address': address,
'height': height,
'postalCode': postalCode,
'sex': sex,
'stateCode': stateCode,
'expireDate': expireDate,
'dateOfBirth': dob,
});
isLoading = false;
update();
if (jsonDecode(res)['status'] == 'success') {
// Get.to(() => AiPage()); //todo rplace this
}
}
void addRegisrationCarForDriver(String vin, make, model, year, color, owner,
expirationDate, registrationDate) async {
getFromController();
var res = await CRUD().post(link: AppLink.addRegisrationCar, payload: {
'vin': vin,
'make': make,
'model': model,
'year': year,
'expirationDate': expirationDate,
'color': color,
'owner': owner,
'registrationDate': registrationDate,
});
box.write(BoxName.vin, vin);
box.write(BoxName.make, make);
box.write(BoxName.model, model);
box.write(BoxName.year, year);
box.write(BoxName.expirationDate, expirationDate);
box.write(BoxName.color, color);
box.write(BoxName.owner, owner);
box.write(BoxName.registrationDate, registrationDate);
isLoading = false;
update();
if (jsonDecode(res)['status'] == 'success') {
Get.offAll(() => LoginCaptin()); //todo replace this
}
}
Future register() async {
getFromController();
if (formKey.currentState!.validate()) {
isLoading = true;
update();
final fixedPhone =
CountryLogic.formatCurrentCountryPhone(phoneController.text);
var res = await CRUD().post(link: AppLink.signUpCaptin, payload: {
'first_name': name.split(' ')[1],
'last_name': name.split(' ')[0],
'email': emailController.text,
'phone': fixedPhone,
'password': passwordController.text,
'gender': sex,
'site': address,
'birthdate': dob,
});
isLoading = false;
update();
if (jsonDecode(res)['status'] == 'success') {
box.write(BoxName.driverID, jsonDecode(res)['message']);
box.write(BoxName.dobDriver, dob);
box.write(BoxName.sexDriver, sex);
box.write(BoxName.phoneDriver, phoneController.text);
box.write(BoxName.lastNameDriver, name.split(' ')[0]);
int randomNumber = Random().nextInt(100000) + 1;
await CRUD().post(link: AppLink.sendVerifyEmail, payload: {
'email': emailController.text,
'token': randomNumber.toString(),
});
Get.to(() => VerifyEmailCaptainPage());
}
}
}
}
@@ -1,977 +0,0 @@
import 'package:siro_driver/controller/functions/crud.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_driver/constant/colors.dart';
import 'package:siro_driver/constant/style.dart';
import 'package:siro_driver/constant/table_names.dart';
import 'package:siro_driver/controller/auth/captin/register_captin_controller.dart';
import 'package:siro_driver/controller/functions/ocr_controller.dart';
import 'package:siro_driver/main.dart';
import 'package:siro_driver/views/widgets/elevated_btn.dart';
import 'package:siro_driver/views/widgets/my_scafold.dart';
import 'package:siro_driver/views/widgets/mycircular.dart';
import '../../../constant/links.dart';
import '../../../controller/functions/encrypt_decrypt.dart';
import '../../../controller/functions/gemeni.dart';
class AiPage extends StatelessWidget {
ScanDocumentsByApi scanDocumentsByApi = Get.put(ScanDocumentsByApi());
RegisterCaptainController registerCaptainController =
Get.put(RegisterCaptainController());
@override
Widget build(BuildContext context) {
Get.put(AI());
String text = '';
return MyScafolld(
title: 'Documents check'.tr,
body: [
GetBuilder<AI>(builder: (controller) {
return controller.isLoading
? const MyCircularProgressIndicator()
: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
// egyptDriverLicense(),
// egyptCarLicenceFront(),
// egyptCarLicenceBack(),
// egyptDriverIDFront(),
// egyptDriverIDBack(),
],
),
);
}),
],
isleading: true);
}
GetBuilder<AI> egyptDriverLicenseWidget() {
return GetBuilder<AI>(
builder: (contentController) => contentController.responseMap.isNotEmpty
? contentController.isloading
? Column(
children: [
const MyCircularProgressIndicator(),
Text(
'We are process picture please wait '.tr,
style: AppStyle.title,
)
],
)
: SizedBox(
height: Get.height * .7,
child: ListView(
children: [
Container(
decoration: AppStyle.boxDecoration1,
// height: Get.height * .4,
child: Padding(
padding: const EdgeInsets.all(5),
child: contentController.responseMap.isEmpty
? Center(
child: Text(
'Capture an Image of Your Driver’s License'
.tr,
style: AppStyle.title,
),
)
: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'${'Name'.tr} :${(contentController.responseMap['first_name'])}',
style: AppStyle.subtitle,
),
Text(
' ${(contentController.responseMap['last_name'])}',
style: AppStyle.subtitle,
),
],
),
Text(
'${'Name in arabic'.tr}: ${(contentController.responseMap['name_in_arabic'])}',
style: AppStyle.title,
),
Text(
'${'Drivers License Class'.tr}: ${contentController.responseMap['class']}',
style: AppStyle.title,
),
],
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'National Number'.tr}: ${(contentController.responseMap['id'])}',
style: AppStyle.title,
),
// Image.memory(
// scanDocumentsByApi
// .imagePortrait,
// width: 60,
// ),
]),
Text(
'${'Address'.tr}: ${(contentController.responseMap['address'])}',
style: AppStyle.title,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Date of Birth'.tr}: ${contentController.responseMap['dob']}',
style: AppStyle.title,
),
Text(
'${'Age'.tr} : ${contentController.responseMap['age_in_years']}',
style: AppStyle.title,
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Expiry Date'.tr}: ${contentController.responseMap['expiration_date']}',
style: DateTime.parse(
contentController
.responseMap[
'expiration_date']
.toString())
.isBefore(
contentController.now)
? AppStyle.title.copyWith(
color: AppColor.redColor)
: AppStyle.title.copyWith(
color: AppColor.greenColor),
),
],
),
],
),
),
),
const SizedBox(
height: 10,
),
DateTime.parse(contentController
.responseMap['expiration_date']
.toString())
.isBefore(contentController.now)
? Text(
'You can\'t continue with us .\nYou should renew Driver license'
.tr,
style: AppStyle.title
.copyWith(color: AppColor.redColor),
)
: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Lets check Car license '.tr,
onPressed: () => contentController
.getCarLicenseJordanContent()),
const SizedBox(
height: 10,
),
contentController.responseCarLicenseMapJordan.isNotEmpty
? Container(
decoration: AppStyle.boxDecoration,
// height: Get.height * .3,
width: Get.width * .9,
child: Column(
children: [
Text(
'${'Name'.tr} ${contentController.responseCarLicenseMapJordan['name']}',
style: AppStyle.title,
),
Text(
'${'Address'.tr} ${contentController.responseCarLicenseMapJordan['address']}',
style: AppStyle.title,
),
Text(
'${'Car Kind'.tr} ${contentController.responseCarLicenseMapJordan['car_kind']}',
style: AppStyle.title,
),
Text(
'${'Color'.tr} ${contentController.responseCarLicenseMapJordan['car_color']}',
style: AppStyle.title,
),
Text(
'${'Year'.tr} ${contentController.responseCarLicenseMapJordan['car_year']}',
style: AppStyle.title,
),
Text(
'${'Car Plate'.tr} ${contentController.responseCarLicenseMapJordan['car_plate']}',
style: AppStyle.title,
),
Text(
'${'Car Expire'.tr} ${contentController.responseCarLicenseMapJordan['expire_date_of_license']}',
style: contentController
.responseCarLicenseMapJordan
.isNotEmpty
? DateTime.parse(contentController
.responseCarLicenseMapJordan[
'expire_date_of_license']
.toString())
.isBefore(contentController.now)
? AppStyle.title.copyWith(
color: AppColor.redColor)
: AppStyle.title.copyWith(
color: AppColor.greenColor)
: null,
),
],
),
)
: const SizedBox(),
const SizedBox(
height: 10,
),
// DateTime.parse(contentController
// .responseCarLicenseMap[
// 'expire_date_of_license']
// .toString())
// .isBefore(contentController.now)
// ? Text(
// 'You can\'t continue with us .\nYou should renew Car license'
// .tr,
// style: AppStyle.title.copyWith(
// color: AppColor.redColor),
// )
// :
MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Lets check License Back Face'.tr,
onPressed: () => contentController
.generateBackCarLicenseJordanContent()),
const SizedBox(
height: 10,
),
contentController.responseBackCarLicenseMap.isNotEmpty
? Container(
decoration: AppStyle.boxDecoration,
// height: 300,
child: Column(children: [
Text(
'VIN ${contentController.responseBackCarLicenseMap['vin']}',
style: AppStyle.title,
),
Text(
'Fuel Type ${contentController.responseBackCarLicenseMap['fuelType']}',
style: AppStyle.title,
),
Text(
'Insurance Company ${contentController.responseBackCarLicenseMap['insuranceCompany']}',
style: AppStyle.title,
),
Text(
'Policy Number ${contentController.responseBackCarLicenseMap['policyNumber']}',
style: AppStyle.title,
),
Text(
'Insurance Type ${contentController.responseBackCarLicenseMap['insuranceType']}',
style: AppStyle.title,
)
]))
: const SizedBox()
],
),
)
: Positioned(
top: Get.height * .06,
left: Get.width * .051,
right: Get.width * .051,
child: scanDocumentsByApi.isLoading
? Column(
children: [
const MyCircularProgressIndicator(),
Text(
'We are process picture please wait '.tr,
style: AppStyle.title,
)
],
)
: Column(
children: [
Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .35,
child: Padding(
padding: const EdgeInsets.all(5),
child: Center(
child: InkWell(
onTap: () async {
await CRUD().allMethodForAI(
'name,address,dob,nationalNo,',
AppLink.uploadEgypt,
'idFront'); //egypt
},
child: Text(
'Take Picture Of ID Card'.tr,
style: AppStyle.title,
),
),
)),
),
],
),
),
);
}
GetBuilder<AI> jordanDriverLicenseWidget() {
return GetBuilder<AI>(
builder: (contentController) => contentController.responseMap.isNotEmpty
? Positioned(
top: Get.height * .09,
left: Get.width * .051,
right: Get.width * .051,
child: contentController.isloading
? Column(
children: [
const MyCircularProgressIndicator(),
Text(
'We are process picture please wait '.tr,
style: AppStyle.title,
)
],
)
: SizedBox(
height: Get.height * .7,
child: ListView(
children: [
Container(
decoration: AppStyle.boxDecoration,
// height: Get.height * .4,
child: Padding(
padding: const EdgeInsets.all(5),
child: contentController.responseMap.isEmpty
? Center(
child: Text(
'There is no data yet.'.tr,
style: AppStyle.title,
),
)
: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'${'Name'.tr} :${contentController.responseMap['first_name']}',
style: AppStyle.subtitle,
),
Text(
' ${contentController.responseMap['last_name']}',
style: AppStyle.subtitle,
),
],
),
Text(
'${'Name in arabic'.tr}: ${contentController.responseMap['name_in_arabic']}',
style: AppStyle.title,
),
Text(
'${'Drivers License Class'.tr}: ${contentController.responseMap['class']}',
style: AppStyle.title,
),
],
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'National Number'.tr}: ${contentController.responseMap['id']}',
style: AppStyle.title,
),
// Image.memory(
// scanDocumentsByApi
// .imagePortrait,
// width: 60,
// ),
]),
Text(
'${'Address'.tr}: ${contentController.responseMap['address']}',
style: AppStyle.title,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Date of Birth'.tr}: ${contentController.responseMap['dob']}',
style: AppStyle.title,
),
Text(
'${'Age'.tr} : ${contentController.responseMap['age_in_years']}',
style: AppStyle.title,
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Expiry Date'.tr}: ${contentController.responseMap['expiration_date']}',
style: DateTime.parse(
contentController
.responseMap[
'expiration_date']
.toString())
.isBefore(
contentController.now)
? AppStyle.title.copyWith(
color: AppColor.redColor)
: AppStyle.title.copyWith(
color:
AppColor.greenColor),
),
],
),
],
),
),
),
const SizedBox(
height: 10,
),
DateTime.parse(contentController
.responseMap['expiration_date']
.toString())
.isBefore(contentController.now)
? Text(
'You can\'t continue with us .\nYou should renew Driver license'
.tr,
style: AppStyle.title
.copyWith(color: AppColor.redColor),
)
: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Lets check Car license '.tr,
onPressed: () => contentController
.getTextFromCard(
'''Extract the following information from the front face of the car license card in Jordan:
* name
* Address
* Vehicle type
* car_kind
* car_color
* Vehicle category
* car_year
* car_plate
* Registration type
* Usage type
* expire_date_of_license
Output the extracted information in the following JSON formate and make date format like YYYY-MM-DD''')),
const SizedBox(
height: 10,
),
contentController
.responseCarLicenseMapJordan.isNotEmpty
? Container(
decoration: AppStyle.boxDecoration,
// height: Get.height * .3,
width: Get.width * .9,
child: Column(
children: [
Text(
'${'Name'.tr} ${contentController.responseCarLicenseMapJordan['name']}',
style: AppStyle.title,
),
Text(
'${'Address'.tr} ${contentController.responseCarLicenseMapJordan['address']}',
style: AppStyle.title,
),
Text(
'${'Car Kind'.tr} ${contentController.responseCarLicenseMapJordan['car_kind']}',
style: AppStyle.title,
),
Text(
'${'Color'.tr} ${contentController.responseCarLicenseMapJordan['car_color']}',
style: AppStyle.title,
),
Text(
'${'Year'.tr} ${contentController.responseCarLicenseMapJordan['car_year']}',
style: AppStyle.title,
),
Text(
'${'Car Plate'.tr} ${contentController.responseCarLicenseMapJordan['car_plate']}',
style: AppStyle.title,
),
Text(
'${'ُExpire Date'.tr} ${contentController.responseCarLicenseMapJordan['expire_date_of_license']}',
style: contentController
.responseCarLicenseMapJordan
.isNotEmpty
? DateTime.parse(contentController
.responseCarLicenseMapJordan[
'expire_date_of_license']
.toString())
.isBefore(
contentController.now)
? AppStyle.title.copyWith(
color: AppColor.redColor)
: AppStyle.title.copyWith(
color: AppColor.greenColor)
: null,
),
],
),
)
: const SizedBox(),
const SizedBox(
height: 10,
),
//todo temporary
// DateTime.parse(contentController
// .responseCarLicenseMap[
// 'expire_date_of_license']
// .toString())
// .isBefore(contentController.now)
// ? Text(
// 'You can\'t continue with us .\nYou should renew Car license'
// .tr,
// style: AppStyle.title.copyWith(
// color: AppColor.redColor),
// )
// :
MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Lets check License Back Face'.tr,
onPressed: () =>
contentController.getTextFromCard(
'write json output from extracting car license back face for these key ,vin,fuelType,passengerType,curbWeight,insuranceCompany,policyNumber,notes,insuranceType and output it json .dont add data else this image',
)),
const SizedBox(
height: 10,
),
contentController.responseBackCarLicenseMap.isNotEmpty
? Container(
decoration: AppStyle.boxDecoration,
// height: 300,
child: Column(children: [
Text(
'VIN ${contentController.responseBackCarLicenseMap['vin']}',
style: AppStyle.title,
),
Text(
'Fuel Type ${contentController.responseBackCarLicenseMap['fuelType']}',
style: AppStyle.title,
),
Text(
'Insurance Company ${contentController.responseBackCarLicenseMap['insuranceCompany']}',
style: AppStyle.title,
),
Text(
'Policy Number ${contentController.responseBackCarLicenseMap['policyNumber']}',
style: AppStyle.title,
),
Text(
'Insurance Type ${contentController.responseBackCarLicenseMap['insuranceType']}',
style: AppStyle.title,
)
]))
: const SizedBox()
// MyElevatedButton(
// title: 'Detect Your Face '.tr,
// onPressed: () => scanDocumentsByApi
// .checkMatchFaceApi(),
// ),
// scanDocumentsByApi.res.isEmpty
// ? const SizedBox()
// : scanDocumentsByApi.res['data']
// ['result']
// .toString() ==
// 'Same'
// ? MyElevatedButton(
// onPressed: () async {
// await registerCaptainController
// .register();
// await registerCaptainController
// .addLisence();
// // await scanDocumentsByApi
// // .uploadImagePortrate();
// },
// title:
// 'Go to next step\nscan Car License.'
// .tr,
// kolor: AppColor.greenColor,
// )
// : const SizedBox(),
// MyElevatedButton(
// title: 'get sql data',
// kolor: AppColor.yellowColor,
// onPressed: () {
// sql.deleteAllData(
// TableName.faceDetectTimes);
// sql
// .getAllData(
// TableName.faceDetectTimes)
// value[0]['faceDetectTimes']));
// },
// ),
],
),
),
)
: Positioned(
top: Get.height * .06,
left: Get.width * .051,
right: Get.width * .051,
child: scanDocumentsByApi.isLoading
? Column(
children: [
const MyCircularProgressIndicator(),
Text(
'We are process picture please wait '.tr,
style: AppStyle.title,
)
],
)
: Column(
children: [
Container(
decoration: AppStyle.boxDecoration,
height: Get.height * .35,
child: Padding(
padding: const EdgeInsets.all(5),
child: Center(
child: Text(
'There is no data yet.'.tr,
style: AppStyle.title,
),
)),
),
],
),
),
);
}
GetBuilder<ScanDocumentsByApi> usaDriverLicensWidget() {
return GetBuilder<ScanDocumentsByApi>(
builder: (scanDocumentsByApi) => scanDocumentsByApi.responseMap.isNotEmpty
? Positioned(
top: Get.height * .06,
left: Get.width * .051,
right: Get.width * .051,
child: scanDocumentsByApi.isLoading
? Column(
children: [
const MyCircularProgressIndicator(),
Text(
'We are process picture please wait '.tr,
style: AppStyle.title,
)
],
)
: Column(
children: [
Container(
decoration: AppStyle.boxDecoration,
height: Get.height * .4,
child: Padding(
padding: const EdgeInsets.all(5),
child: scanDocumentsByApi.responseMap.isEmpty
? Center(
child: Text(
'There is no data yet.'.tr,
style: AppStyle.title,
),
)
: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${'Name :'.tr}${scanDocumentsByApi.name}',
style: AppStyle.subtitle,
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'${'Drivers License Class: '.tr}${scanDocumentsByApi.licenseClass}',
style: AppStyle.title,
),
Image.memory(
scanDocumentsByApi
.imageSignature,
width: 100,
height: 30,
),
],
),
],
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Document Number: '.tr}${scanDocumentsByApi.documentNo}',
style: AppStyle.title,
),
Image.memory(
scanDocumentsByApi.imagePortrait,
width: 60,
),
]),
Text(
'${'Address: '.tr}${scanDocumentsByApi.address}',
style: AppStyle.title,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Height: '.tr}${scanDocumentsByApi.height}',
style: AppStyle.subtitle,
),
Text(
'Postal Code: ${scanDocumentsByApi.postalCode}',
style: AppStyle.subtitle,
),
Text(
'Sex: ${scanDocumentsByApi.sex}',
style: AppStyle.subtitle,
),
],
),
Text(
'Territorial Code: ${scanDocumentsByApi.stateCode}',
style: AppStyle.subtitle,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Expiry Date: '.tr}${scanDocumentsByApi.expireDate}',
style: DateTime.parse(
scanDocumentsByApi
.responseMap['data']
['ocr']
['dateOfExpiry']
.toString())
.isBefore(
scanDocumentsByApi.now)
? AppStyle.title.copyWith(
color: AppColor.redColor)
: AppStyle.title.copyWith(
color: AppColor.greenColor),
),
Text(
'${'Date of Birth: '.tr}${scanDocumentsByApi.dob}',
style: AppStyle.title,
),
],
),
],
),
),
),
DateTime.parse(scanDocumentsByApi.responseMap['data']
['ocr']['dateOfExpiry']
.toString())
.isBefore(scanDocumentsByApi.now)
? Text(
'You can\'t continue with us .\nYou should renew Driver license',
style: AppStyle.title
.copyWith(color: AppColor.redColor),
)
: MyElevatedButton(
title: 'Detect Your Face '.tr,
onPressed: () =>
scanDocumentsByApi.checkMatchFaceApi(),
),
scanDocumentsByApi.res.isEmpty
? const SizedBox()
: scanDocumentsByApi.res['data']['result']
.toString() ==
'Same'
? MyElevatedButton(
onPressed: () async {
await registerCaptainController
.register();
await registerCaptainController
.addLisence();
// await scanDocumentsByApi
// .uploadImagePortrate();
},
title:
'Go to next step\nscan Car License.'.tr,
kolor: AppColor.greenColor,
)
: const SizedBox(),
MyElevatedButton(
title: 'get sql data',
kolor: AppColor.yellowColor,
onPressed: () {
sql.deleteAllData(TableName.faceDetectTimes);
sql.getAllData(TableName.faceDetectTimes);
},
)
],
),
)
: Positioned(
top: Get.height * .06,
left: Get.width * .051,
right: Get.width * .051,
child: scanDocumentsByApi.isLoading
? Column(
children: [
const MyCircularProgressIndicator(),
Text(
'We are process picture please wait '.tr,
style: AppStyle.title,
)
],
)
: Column(
children: [
Container(
decoration: AppStyle.boxDecoration,
height: Get.height * .35,
child: Padding(
padding: const EdgeInsets.all(5),
child: Center(
child: Text(
'There is no data yet.'.tr,
style: AppStyle.title,
),
)),
),
],
),
),
);
}
}
class EgyptDocuments extends StatelessWidget {
const EgyptDocuments({
super.key,
required this.contentController,
});
final AI contentController;
@override
Widget build(BuildContext context) {
return Positioned(
top: 3,
left: Get.width * .1,
right: Get.width * .1,
child: MyElevatedButton(
title: 'Take Picture Of ID Card'.tr, //egypt
onPressed: () async {
await CRUD().allMethodForAI('name,address,dob,nationalNo,',
AppLink.uploadEgypt, 'idFront'); //egypt
},
));
}
}
class JordanDocumants extends StatelessWidget {
const JordanDocumants({
super.key,
required this.contentController,
});
final AI contentController;
@override
Widget build(BuildContext context) {
return Positioned(
top: 3,
left: Get.width * .1,
right: Get.width * .1,
child: MyElevatedButton(
title: 'Take Picture Of Driver License Card'.tr,
onPressed: () {
contentController.getDriverLicenseJordanContent();
},
));
}
}
class UsaAiDocuments extends StatelessWidget {
const UsaAiDocuments({
super.key,
required this.scanDocumentsByApi,
});
final ScanDocumentsByApi scanDocumentsByApi;
@override
Widget build(BuildContext context) {
return Positioned(
top: 3,
left: Get.width * .2,
right: Get.width * .2,
child: MyElevatedButton(
title: 'Take Picture Of ID Card'.tr,
onPressed: () {
scanDocumentsByApi.scanDocumentsByApi();
},
));
}
}
@@ -1,169 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_driver/controller/functions/ocr_controller.dart';
import '../../../constant/style.dart';
import '../../../controller/auth/captin/ml_google_doc.dart';
import '../../../controller/auth/captin/register_captin_controller.dart';
import '../../widgets/elevated_btn.dart';
import '../../widgets/my_scafold.dart';
// class CarLicensePage extends StatelessWidget {
// CarLicensePage({super.key});
// // CarRegistrationRecognizerController carRegistrationRecognizerController =
// // Get.put(CarRegistrationRecognizerController());
// RegisterCaptainController registerCaptainController =
// Get.put(RegisterCaptainController());
// @override
// Widget build(BuildContext context) {
// Get.find<ScanDocumentsByApi>().uploadImagePortrate();
// return MyScafolld(
// title: 'Car License Card'.tr,
// body: [
// Positioned(
// top: 3,
// left: Get.width * .2,
// right: Get.width * .2,
// child: MyElevatedButton(
// title: 'Take Picture Of ID Card'.tr,
// onPressed: () async {
// //0vQRyaYYDWpsv73A5CZOknseK7S2sgwE
// //3vQRyaYYSWpmv69A58ZOkxmeK6M1mgwEDlXrXlBl
// //0pALdqDDYHvzp73Q59SIgbzjG7Z2zkhJXr
// // String? visionApi = AK.serverPHP;
// await carRegistrationRecognizerController.scanText();
// },
// )),
// Positioned(
// top: 50,
// child: SizedBox(
// height: Get.height * .6,
// width: Get.width,
// child: buildImageWithBoundingBoxes(),
// ),
// ),
// Positioned(
// bottom: Get.height * .2,
// left: Get.width * .2,
// right: Get.width * .2,
// child: MyElevatedButton(
// title: 'Register'.tr,
// onPressed: () async {
// // registerCaptainController.addLisence();
// // registerCaptainController.register();
// registerCaptainController.addRegisrationCarForDriver(
// carRegistrationRecognizerController.extracted['vin'],
// carRegistrationRecognizerController.extracted['make'],
// carRegistrationRecognizerController.extracted['model'],
// carRegistrationRecognizerController.extracted['year'],
// carRegistrationRecognizerController.extracted['color'],
// carRegistrationRecognizerController.extracted['owner'],
// carRegistrationRecognizerController
// .extracted['expiration_date'],
// carRegistrationRecognizerController
// .extracted['registration_date'],
// );
// },
// )),
// ],
// isleading: true);
// }
// }
// Widget buildImageWithBoundingBoxes() {
// Get.put(CarRegistrationRecognizerController());
// return GetBuilder<CarRegistrationRecognizerController>(
// builder: (carRegistrationRecognizerController) =>
// carRegistrationRecognizerController.image == null ||
// carRegistrationRecognizerController.extracted.isEmpty
// ? Center(
// child: Text(
// 'No image selected yet'.tr,
// style: AppStyle.headTitle2,
// ))
// : Column(
// children: [
// SizedBox(
// width: Get.width * .8,
// height: Get.width * .5,
// child: Image.file(
// File(carRegistrationRecognizerController
// .croppedFile!.path),
// // fit: BoxFit.fill,
// )),
// const SizedBox(
// height: 20,
// ),
// Container(
// decoration: AppStyle.boxDecoration,
// height: Get.width * .5,
// width: Get.width * .9,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Text(
// '${'Made :'.tr}${carRegistrationRecognizerController.extracted['make']}',
// style: AppStyle.title,
// ),
// Text(
// '${'model :'.tr}${carRegistrationRecognizerController.extracted['model']}',
// style: AppStyle.title,
// ),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Text(
// '${'VIN :'.tr}${carRegistrationRecognizerController.extracted['vin']}',
// style: AppStyle.title,
// ),
// Text(
// '${'year :'.tr}${carRegistrationRecognizerController.extracted['year']}',
// style: AppStyle.title,
// ),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Column(
// children: [
// Text(
// 'expiration date :${carRegistrationRecognizerController.extracted['expiration_date']}',
// style: AppStyle.title,
// ),
// Text(
// 'registration date :${carRegistrationRecognizerController.extracted['registration_date']}',
// style: AppStyle.title,
// ),
// ],
// ),
// Text(
// 'color :${carRegistrationRecognizerController.extracted['color']}',
// style: AppStyle.title,
// ),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// Text(
// 'owner :${carRegistrationRecognizerController.extracted['owner']}',
// style: AppStyle.title,
// ),
// ],
// ),
// ],
// ),
// )
// ],
// ));
// }
@@ -1,221 +0,0 @@
import 'package:siro_driver/constant/colors.dart';
import 'package:siro_driver/constant/style.dart';
import 'package:siro_driver/controller/auth/captin/register_captin_controller.dart';
import 'package:siro_driver/views/widgets/elevated_btn.dart';
import 'package:siro_driver/views/widgets/my_scafold.dart';
import 'package:siro_driver/views/widgets/my_textField.dart';
import 'package:siro_driver/views/widgets/mycircular.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../Rate/rate_app_page.dart';
class SmsSignupEgypt extends StatelessWidget {
SmsSignupEgypt({super.key});
@override
Widget build(BuildContext context) {
Get.put(RegisterCaptainController());
return MyScafolld(
title: 'Phone Check'.tr,
body: [
GetBuilder<RegisterCaptainController>(
builder: (registerCaptainController) {
return ListView(
// mainAxisAlignment: MainAxisAlignment.center,
children: [
// Logo at the top
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Image.asset(
'assets/images/logo.gif', // Make sure you have a logo image in your assets folder
height: 100,
),
),
// Message to the driver
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text(
'We need your phone number to contact you and to help you receive orders.'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
),
// Enter phone number text
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text(
'Enter your phone number'.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
),
// Phone number input field
Padding(
padding: const EdgeInsets.all(16.0),
child: !registerCaptainController.isSent
? Form(
key: registerCaptainController.formKey3,
child: MyTextForm(
controller:
registerCaptainController.phoneController,
label: 'Enter your phone number'.tr,
hint: 'Enter your phone number'.tr,
type: TextInputType.phone),
)
: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
registerCaptainController.phoneController.text,
style: AppStyle.title,
),
),
)),
const SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.all(16.0),
child: registerCaptainController.isSent
? Form(
key: registerCaptainController.formKey3,
child: MyTextForm(
controller: registerCaptainController.verifyCode,
label: '3 digit'.tr,
hint: '3 digit'.tr,
type: TextInputType.number),
)
: const SizedBox()),
// Submit button
registerCaptainController.isLoading
? const MyCircularProgressIndicator()
: Padding(
padding: const EdgeInsets.all(16.0),
child: MyElevatedButton(
onPressed: () async {
!registerCaptainController.isSent
? await registerCaptainController.sendOtpMessage()
: await registerCaptainController.verifySMSCode();
},
title: 'Submit'.tr,
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: MyElevatedButton(
kolor: AppColor.yellowColor,
title: "Rate Our App".tr,
onPressed: () {
Get.to(RatingScreen());
}),
),
// IconButton(
// onPressed: () async {
// // final plainText =
// // 'https://server.sefer.live/sefer.click/sefer';
// // debugPrint('Plain Text: $plainText');
// // Encrypt the data
// // final encryptedData = encryptionHelper.encryptData(plainText);
// // debugPrint('Encrypted: $encryptedData');
// // Decrypt the data
// // final decryptedData = encryptionHelper.decryptData(
// // '2unGmj8jSMFBfxqH8+GN'); // Use the encryptedData variable
// // debugPrint('Decrypted: $decryptedData');
// // box.remove('DriversSecure');
// var drivers0 = await CRUD().get(
// link:
// 'https://server.sefer.live/sefer.click/sefer/auth/captin/getAllDriverSecure.php',
// payload: {});
// var decodedDriver;
// if (drivers0 != 'failure') {
// decodedDriver = jsonDecode(drivers0);
// // // // box.write('DriversSecure', decodedDriver['message']);
// }
// var drivers = decodedDriver['message'];
// Log.print('drivers.length: ${drivers.length}');
// for (var i = 0; i < drivers.length; i++) {
// Log.print('id: ${drivers[i]['id']}');
// var payload = {
// "phone": encryptionHelper
// .encryptData(drivers[i]['phone'].toString()),
// "email": encryptionHelper
// .encryptData(drivers[i]['email'].toString()),
// "gender": encryptionHelper
// .encryptData(drivers[i]['gender'] ?? 'unknown'),
// "birthdate": encryptionHelper
// .encryptData(drivers[i]['birthdate'].toString()),
// "first_name": encryptionHelper
// .encryptData(drivers[i]['first_name'].toString()),
// "last_name": encryptionHelper
// .encryptData(drivers[i]['last_name'].toString()),
// "sosPhone": encryptionHelper
// .encryptData(drivers[i]['sosPhone'].toString()),
// // "name_english": encryptionHelper
// // .encryptData(drivers[i]['name_english'].toString()),
// // "last_name": encryptionHelper
// // .encryptData(drivers[i]['last_name'].toString()),
// // "sosPhone": encryptionHelper
// // .encryptData(drivers[i]['sosPhone'].toString()),
// // "address": encryptionHelper
// // .encryptData(drivers[i]['address'].toString()),
// // "card_id": encryptionHelper
// // .encryptData(drivers[i]['card_id'].toString()),
// // "occupation": encryptionHelper
// // .encryptData(drivers[i]['occupation'].toString()),
// // "religion": encryptionHelper
// // .encryptData(drivers[i]['religion'].toString()),
// // "site": encryptionHelper
// // .encryptData(drivers[i]['site'].toString()),
// // "education": encryptionHelper
// // .encryptData(drivers[i]['education'].toString()),
// // "accountBank": encryptionHelper
// // .encryptData(drivers[i]['accountBank'].toString()),
// // "employmentType": encryptionHelper
// // .encryptData(drivers[i]['employmentType'].toString()),
// // "maritalStatus": (drivers[i]['maritalStatus'].toString()),
// // "fullNameMaritial": encryptionHelper.encryptData(
// // drivers[i]['fullNameMaritial'].toString()),
// 'id': drivers[i]['id'].toString()
// };
// // print(drivers[i]['idn']);
// // if (drivers[i]['id'].toString() !=
// // '01002165502a9sHC1tbrUrUw') {
// var result = await CRUD().post(
// link:
// 'https://server.sefer.live/sefer.click/sefer/auth/captin/updateDriverSecure.php',
// payload: payload);
// if (result != 'failure') {
// print(result);
// } else {
// print('failure');
// }
// // Future.delayed(Duration(microseconds: 200));
// // }
// }
// MyDialog().getDialog('title', 'midTitle', () {
// Get.back();
// });
// },
// icon: const Icon(
// FontAwesome5.grin_tears,
// size: 29,
// color: AppColor.blueColor,
// ),
// ),
],
);
}),
],
isleading: false,
);
}
}
@@ -1,987 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_driver/constant/box_name.dart';
import 'package:siro_driver/controller/functions/audio_controller.dart';
import 'package:siro_driver/main.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../../constant/colors.dart';
import '../../../../constant/links.dart';
import '../../../../constant/style.dart';
import '../../../../controller/functions/gemeni.dart';
import '../../../../controller/functions/package_info.dart';
import '../../../../controller/functions/tts.dart';
import '../../../../print.dart';
import '../../../widgets/elevated_btn.dart';
import '../../../widgets/my_circular_indicator_timer.dart';
import '../../../widgets/my_scafold.dart';
import '../../../widgets/mydialoug.dart';
// --- اقتراحات الألوان الجديدة ---
// يمكنك تعريف هذه الألوان في ملف AppColor.dart الخاص بك
class NewAppColor {
static const Color primaryColor = Color(0xFF0D47A1); // أزرق داكن
static const Color accentColor = Color(0xFF1976D2); // أزرق أفتح
static const Color backgroundColor = Color(0xFFF5F7FA); // رمادي فاتح للخلفية
static const Color cardColor = Colors.white;
static const Color textColor = Color(0xFF333333); // أسود ناعم للنصوص
static const Color subTextColor = Color(0xFF757575); // رمادي للنصوص الفرعية
static const Color successColor = Color(0xFF2E7D32); // أخضر للنجاح
static const Color errorColor = Color(0xFFC62828); // أحمر للخطأ
static const Color borderColor = Color(0xFFE0E0E0); // لون الحدود
}
// --- اقتراحات للخطوط ---
// يمكنك استخدام حزمة google_fonts وتعيين الخط 'Cairo' أو 'Tajawal' للتطبيق
class NewAppStyle {
static TextStyle get headlineStyle {
return const TextStyle(
fontFamily: 'Cairo', // اسم الخط المقترح
fontSize: 18,
fontWeight: FontWeight.bold,
color: NewAppColor.primaryColor,
);
}
static TextStyle get titleStyle {
return const TextStyle(
fontFamily: 'Cairo',
fontSize: 16,
fontWeight: FontWeight.bold,
color: NewAppColor.textColor,
);
}
static TextStyle get bodyStyle {
return const TextStyle(
fontFamily: 'Cairo',
fontSize: 14,
color: NewAppColor.subTextColor,
height: 1.5,
);
}
static TextStyle get valueStyle {
return const TextStyle(
fontFamily: 'Cairo',
fontSize: 15,
fontWeight: FontWeight.w600,
color: NewAppColor.textColor,
);
}
}
class SyrianCardAI extends StatelessWidget {
SyrianCardAI({super.key});
final TextToSpeechController textToSpeechController =
Get.put(TextToSpeechController());
@override
Widget build(BuildContext context) {
Get.put(AI());
WidgetsBinding.instance.addPostFrameCallback((_) {
checkForUpdate(context);
});
return MyScafolld(
// تم تغيير لون الخلفية للتصميم الجديد
// backgroundColor: NewAppColor.backgroundColor,
title: "Approve Driver Documents".tr,
action: GetBuilder<AI>(builder: (cont) {
return IconButton(
onPressed: () {
cont.isLoading = false;
cont.update();
},
icon: const Icon(Icons.refresh, color: NewAppColor.primaryColor),
);
}),
body: [
GetBuilder<AI>(builder: (controller) {
return controller.isLoading
? MyCircularProgressIndicatorWithTimer(
isLoading: controller.isLoading,
)
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12.0, vertical: 8.0),
child: Column(
children: [
// --- زر "التالي" بتصميم جديد ---
if (controller.licenceFrontSy.isNotEmpty &&
controller.licenceBackSy.isNotEmpty &&
(controller.idFrontSy.isNotEmpty) &&
(controller.idBackSy.isNotEmpty) &&
controller.vehicleFrontSy.isNotEmpty &&
controller.vehicleBackSy.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: MyElevatedButton(
title: 'التالي'.tr,
// استخدام اللون الجديد للنجاح
kolor: NewAppColor.successColor,
onPressed: () {
controller.addDriverAndCarEgypt();
},
),
),
Expanded(
child: ListView(
children: [
// --- فيديو الشرح بتصميم جديد ---
VideoButton(),
const SizedBox(height: 16),
egyptDriverLicense(),
const SizedBox(height: 16),
syriaDriverLicenseBack(),
const SizedBox(height: 16),
syriaVehicleCardFront(),
const SizedBox(height: 16),
syriaVehicleCardBack(),
const SizedBox(height: 16),
syriaIdCardFront(),
const SizedBox(height: 16),
syriaDriverIDBack(),
const SizedBox(height: 16),
// egyptCriminalRecord(),
// const SizedBox(height: 24),
],
),
),
],
),
);
}),
// --- شاشة الموافقة بتصميم جديد ---
Positioned(
top: 0,
bottom: 0,
right: 0,
left: 0,
child: GetBuilder<AI>(builder: (controller) {
return controller.approved == false
// --- إضافة خلفية معتمة ---
? Container(
color: Colors.black.withOpacity(0.6),
child: Center(
child: Container(
margin: const EdgeInsets.all(24),
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 15,
spreadRadius: 5,
)
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Approve Driver Documents".tr,
style: NewAppStyle.headlineStyle,
),
const SizedBox(height: 16),
Text(
"To become a ride-sharing driver on the Siro 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 Siro app. Please note, submitting fraudulent documents is a serious offense and may result in immediate termination and legal consequences."
.tr,
style: NewAppStyle.bodyStyle,
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
// --- زر الاستماع بتصميم جديد ---
TextButton.icon(
style: TextButton.styleFrom(
foregroundColor: NewAppColor.accentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
),
onPressed: () async {
controller.startTimer();
if (box.read(BoxName.lang) == 'ar') {
await Get.put(AudioController())
.playAudio1('assets/aggrement.wav');
} else {
await textToSpeechController.speakText(
'To become a ride-sharing driver on the Siro app...'
.tr);
}
},
icon: const Icon(Icons.volume_up_outlined,
size: 30),
label: Text('اضغط للاستماع'.tr,
style: AppStyle.title.copyWith(
color: NewAppColor.accentColor)),
),
const SizedBox(height: 24),
// --- أزرار الموافقة والرفض بتصميم جديد ---
controller.isTimerComplete
? Row(
children: [
Expanded(
child: MyElevatedButton(
title: 'إلغاء'.tr,
kolor: NewAppColor.errorColor,
onPressed: () {
MyDialog().getDialog(
'سيتم إلغاء التسجيل'.tr, '',
() async {
Get.back();
Get.back();
});
}),
),
const SizedBox(width: 16),
Expanded(
child: MyElevatedButton(
title: 'أوافق'.tr,
kolor: NewAppColor.successColor,
onPressed: () {
controller.setApproved();
}),
),
],
)
: Column(
children: [
CircularProgressIndicator(
value: controller.progressValue,
color: NewAppColor.primaryColor,
),
const SizedBox(height: 8),
Text(
'${'الوقت المتبقي'.tr}: ${controller.remainingSeconds} ${"ثانية".tr}',
style: NewAppStyle.bodyStyle,
),
],
),
],
),
),
),
)
: const SizedBox();
}),
)
],
isleading: true,
);
}
// --- واجهة عرض بيانات الوثيقة ---
Widget _buildDocumentDataCard({
required String title,
required VoidCallback onRefresh,
required List<Widget> children,
}) {
return Card(
elevation: 4.0,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
side: BorderSide(color: NewAppColor.borderColor, width: 1),
),
shadowColor: NewAppColor.primaryColor.withOpacity(0.1),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title, style: NewAppStyle.headlineStyle),
IconButton(
onPressed: onRefresh,
icon:
const Icon(Icons.refresh, color: NewAppColor.accentColor),
),
],
),
const Divider(
height: 24, thickness: 1, color: NewAppColor.borderColor),
...children,
],
),
),
);
}
// --- واجهة التقاط صورة الوثيقة ---
Widget _buildCaptureCard({
required String title,
required String imagePath,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap,
child: Card(
clipBehavior: Clip.antiAlias,
elevation: 2.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Image.asset(
imagePath,
height: Get.height * .20,
fit: BoxFit.cover,
// --- في حال لم يتم العثور على الصورة ---
errorBuilder: (context, error, stackTrace) {
return Container(
height: Get.height * .20,
color: NewAppColor.borderColor,
child: const Icon(
Icons.camera_alt_outlined,
size: 50,
color: NewAppColor.subTextColor,
),
);
},
),
Container(
padding: const EdgeInsets.all(16.0),
color: NewAppColor.cardColor,
child: Text(
title,
style: AppStyle.title,
textAlign: TextAlign.center,
),
),
],
),
),
);
}
// --- ويدجت لعرض معلومة (سطر) ---
Widget _infoRow(String label, String? value, {Color? valueColor}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 6.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('$label: ', style: NewAppStyle.bodyStyle),
Expanded(
child: Text(
value ?? 'غير متوفر',
style: NewAppStyle.valueStyle.copyWith(color: valueColor),
),
),
],
),
);
}
GetBuilder<AI> egyptDriverLicense() {
return GetBuilder<AI>(
builder: (ai) {
if (ai.licenceFrontSy.isNotEmpty) {
final data = ai.licenceFrontSy;
DateTime? expiryDateTime;
bool isExpired = false;
if (data['expiry_date'] != null) {
expiryDateTime = DateTime.tryParse(data['expiry_date']);
isExpired = expiryDateTime != null &&
expiryDateTime.isBefore(DateTime.now());
}
// بطاقة «رخصة القيادة – الوجه الأمامي» بتنسيق مضغوط وأيقونات
return Card(
elevation: 2,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: NewAppColor.borderColor, width: .8),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// العنوان + زر التحديث
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('رخصة القيادة – الوجه الأمامي'.tr,
style: NewAppStyle.headlineStyle),
IconButton(
icon: const Icon(Icons.refresh,
size: 20, color: NewAppColor.accentColor),
splashRadius: 18,
onPressed: () async => await ai
.pickAndSendImage('driving_license_sy_front'),
),
],
),
const SizedBox(height: 8),
// سطر الاسم الكامل
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['name_arabic'] != null)
_iconInfo(Icons.person, data['name_arabic']!),
if (data['birth_place'] != null)
_iconInfo(Icons.location_city, data['birth_place']!),
],
),
const SizedBox(height: 8),
// بقية الحقول داخل Wrap لتقليل الطول
Wrap(
spacing: 12,
runSpacing: 8,
children: [
if (data['national_number'] != null)
_iconInfo(Icons.badge, data['national_number']!),
if (data['civil_registry'] != null)
_iconInfo(Icons.location_on, data['civil_registry']!),
if (data['blood_type'] != null)
_iconInfo(Icons.water_drop, data['blood_type']!),
if (data['birth_year'] != null)
_iconInfo(Icons.calendar_today, data['birth_year']!),
],
),
],
),
),
);
}
return _buildCaptureCard(
title: 'التقط صورة لرخصة القيادة'.tr,
imagePath: 'assets/images/1.png',
onTap: () async {
await ai.pickAndSendImage('driving_license_sy_front');
},
);
},
);
}
GetBuilder<AI> syriaDriverLicenseBack() {
return GetBuilder<AI>(
builder: (ai) {
if (ai.licenceBackSy.isNotEmpty) {
final data = ai.licenceBackSy;
// صلاحية الرخصة
final DateTime? expDate =
DateTime.tryParse(data['expiry_date'] ?? '');
final bool expired =
expDate != null && expDate.isBefore(DateTime.now());
final Color expColor = expired
? NewAppColor.errorColor // أحمر إن انتهت
: NewAppColor.successColor; // أخضر إن صالحة
return Card(
elevation: 2,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: NewAppColor.borderColor, width: .8),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// عنوان البطاقة + زر الإنعاش
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('رخصة القيادة – الوجه الخلفي'.tr,
style: NewAppStyle.headlineStyle),
IconButton(
splashRadius: 18,
icon: const Icon(Icons.refresh,
size: 20, color: NewAppColor.accentColor),
onPressed: () async => await ai
.pickAndSendImage('driving_license_sy_back'),
),
],
),
const SizedBox(height: 8),
// صفّ أول (الفئة + الرقم)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['license_category'] != null)
_iconInfo(
Icons.star, data['license_category']!), // D1 / D2…
if (data['license_number'] != null)
_iconInfo(
Icons.confirmation_number, data['license_number']!),
],
),
const SizedBox(height: 8),
// صفّ ثانٍ (التواريخ) مع تلوين تاريخ الصلاحية
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['issue_date'] != null)
_iconInfo(Icons.event, data['issue_date']!),
if (data['expiry_date'] != null)
_iconInfo(Icons.event_busy, data['expiry_date']!,
valueColor: expColor),
],
),
],
),
),
);
}
// بطاقة الالتقاط الافتراضية
return _buildCaptureCard(
title: 'التقط صورة الوجه الخلفي للرخصة'.tr,
imagePath: 'assets/images/5.png',
onTap: () async =>
await ai.pickAndSendImage('driving_license_sy_back'),
);
},
);
}
GetBuilder<AI> syriaDriverIDBack() {
return GetBuilder<AI>(
builder: (ai) {
// استلمنا الحقول الأربعة فقط (governorate-address-gender-issue_date)
if (ai.idBackSy.isNotEmpty) {
final data = ai.idBackSy;
return Card(
elevation: 2,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: NewAppColor.borderColor, width: .8),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// العنوان + زر التحديث
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('بطاقة الهوية – الوجه الخلفي'.tr,
style: NewAppStyle.headlineStyle),
IconButton(
splashRadius: 18,
icon: const Icon(Icons.refresh,
size: 20, color: NewAppColor.accentColor),
onPressed: () async =>
await ai.pickAndSendImage('id_back_sy'),
),
],
),
const SizedBox(height: 8),
// المحافظة + العنوان
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['governorate'] != null)
_iconInfo(Icons.location_city, data['governorate']!),
if (data['address'] != null)
_iconInfo(Icons.home, data['address']!),
],
),
const SizedBox(height: 8),
// الجنس + تاريخ الإصدار
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['gender'] != null)
_iconInfo(Icons.person, data['gender']!),
if (data['issue_date'] != null)
_iconInfo(Icons.event, data['issue_date']!),
],
),
],
),
),
);
}
// البطاقة الافتراضية لالتقاط الصورة
return _buildCaptureCard(
title: 'التقط صورة للوجه الخلفي للهوية'.tr,
imagePath: 'assets/images/4.png',
onTap: () async => await ai.pickAndSendImage('id_back_sy'),
);
},
);
}
/// عنصر (أيقونة + قيمة) مع لون نص مخصّص عند الحاجة
Widget _iconInfo(IconData icon, String value, {Color? valueColor}) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 18, color: NewAppColor.accentColor),
const SizedBox(width: 4),
Flexible(
child: Text(
value.tr,
style: NewAppStyle.bodyStyle.copyWith(color: valueColor),
overflow: TextOverflow.ellipsis,
),
),
],
);
}
GetBuilder<AI> syriaIdCardFront() {
// أبقِ الاسم القديم إذا أردت
return GetBuilder<AI>(
builder: (ai) {
if (ai.idFrontSy.isNotEmpty) {
// غيّر المفتاح حسب متغيرك
final data = ai.idFrontSy;
return Card(
elevation: 2,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: NewAppColor.borderColor, width: .8),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// العنوان + زر التحديث
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('بطاقة الهوية – الوجه الأمامي'.tr,
style: NewAppStyle.headlineStyle),
IconButton(
splashRadius: 18,
icon: const Icon(Icons.refresh,
size: 20, color: NewAppColor.accentColor),
onPressed: () async => await ai.pickAndSendImage(
'id_front_sy', // أو id_front حسب تسمية end-point
),
),
],
),
const SizedBox(height: 8),
// سطر الاسم الكامل
if (data['full_name'] != null)
_iconInfo(Icons.person, data['full_name']!),
const SizedBox(height: 8),
// صفّ (الرقم الوطني + تاريخ الميلاد)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['national_number'] != null)
_iconInfo(Icons.badge, data['national_number']!),
if (data['dob'] != null)
_iconInfo(Icons.cake, data['dob']!),
],
),
const SizedBox(height: 8),
// العنوان كامل بمفرده
if (data['address'] != null)
_iconInfo(Icons.home, data['address']!),
],
),
),
);
}
// كارد الالتقاط الافتراضية
return _buildCaptureCard(
title: 'التقط صورة للوجه الأمامي للهوية'.tr,
imagePath: 'assets/images/2.png',
onTap: () async => await ai.pickAndSendImage('id_front_sy'),
);
},
);
}
GetBuilder<AI> syriaVehicleCardFront() {
// يمكنك إبقاء الاسم القديم إن شئت
return GetBuilder<AI>(
builder: (ai) {
if (ai.vehicleFrontSy.isNotEmpty) {
final data = ai.vehicleFrontSy;
// تاريخ الفحص القادم للفحص الدوري (inspection_date)
final DateTime? nextCheck =
DateTime.tryParse(data['inspection_date'] ?? '');
final bool overdue =
nextCheck != null && nextCheck.isBefore(DateTime.now());
final Color checkColor =
overdue ? NewAppColor.errorColor : NewAppColor.successColor;
return Card(
elevation: 2,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: NewAppColor.borderColor, width: .8),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// العنوان + تحديث
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('رخصة المركبة – الوجه الأمامي'.tr,
style: NewAppStyle.headlineStyle),
IconButton(
splashRadius: 18,
icon: const Icon(Icons.refresh,
size: 20, color: NewAppColor.accentColor),
onPressed: () async => await ai.pickAndSendImage(
'vehicle_license_sy_front',
),
),
],
),
const SizedBox(height: 8),
// الصف الأوّل (لوحة + مالك)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['car_plate'] != null)
_iconInfo(Icons.directions_car, data['car_plate']!),
if (data['owner'] != null)
_iconInfo(Icons.person, data['owner']!),
],
),
const SizedBox(height: 8),
// الصف الثاني (VIN + اللون)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['vin'] != null)
_iconInfo(Icons.confirmation_num, data['vin']!),
if (data['color'] != null)
_iconInfo(Icons.palette, data['color']!),
],
),
const SizedBox(height: 8),
// الصف الثالث (تاريخ المنح + الفحص القادم)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['issue_date'] != null)
_iconInfo(Icons.event, data['issue_date']!),
if (data['inspection_date'] != null)
_iconInfo(
Icons.event_available, data['inspection_date']!,
valueColor: checkColor),
],
),
],
),
),
);
}
// لو لم تُرفع صورة بعد
return _buildCaptureCard(
title: 'التقط صورة لوجه رخصة المركبة'.tr,
imagePath: 'assets/images/6.png',
onTap: () async =>
await ai.pickAndSendImage('vehicle_license_sy_front'),
);
},
);
}
GetBuilder<AI> syriaVehicleCardBack() {
// أبقِ الاسم القديم إن أردت
return GetBuilder<AI>(
builder: (ai) {
if (ai.vehicleBackSy.isNotEmpty) {
final data = ai.vehicleBackSy;
return Card(
elevation: 2,
color: NewAppColor.cardColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: NewAppColor.borderColor, width: .8),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// العنوان + زر تحديث
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('رخصة المركبة – الوجه الخلفي'.tr,
style: NewAppStyle.headlineStyle),
IconButton(
splashRadius: 18,
icon: const Icon(Icons.refresh,
size: 20, color: NewAppColor.accentColor),
onPressed: () async => await ai.pickAndSendImage(
'vehicle_license_sy_back',
),
),
],
),
const SizedBox(height: 8),
// صفّ (الشركة + الطراز)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['make'] != null)
_iconInfo(Icons.factory, data['make']!),
if (data['model'] != null)
_iconInfo(Icons.directions_car_filled, data['model']!),
],
),
const SizedBox(height: 8),
// صفّ (سنة الصنع + اللون)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (data['year'] != null)
_iconInfo(Icons.calendar_today, data['year']!),
if (data['fuel'] != null)
_iconInfo(Icons.local_gas_station, data['fuel']!),
],
),
const SizedBox(height: 8),
// رقم الهيكل بمفرده (قد يكون طويلًا)
if (data['chassis'] != null)
_iconInfo(Icons.confirmation_num, data['chassis']!),
],
),
),
);
}
// بطاقة الالتقاط الافتراضية
return _buildCaptureCard(
title: 'التقط صورة لخلفية رخصة المركبة'.tr,
imagePath: 'assets/images/3.png',
onTap: () async =>
await ai.pickAndSendImage('vehicle_license_sy_back'),
);
},
);
}
GetBuilder<AI> egyptCriminalRecord() {
return GetBuilder<AI>(
builder: (ai) {
if (ai.responseCriminalRecordEgypt.isNotEmpty) {
return _buildDocumentDataCard(
title: 'صحيفة الحالة الجنائية'.tr,
onRefresh: () async {
await ai.allMethodForAI(
(ai.prompts[5]['prompt'].toString()),
AppLink.uploadEgypt,
'criminalRecord',
);
},
children: [
_infoRow('نتيجة الفحص'.tr,
ai.responseCriminalRecordEgypt['InspectionResult']),
_infoRow(
'الاسم الكامل'.tr,
ai.responseCriminalRecordEgypt['FullName'],
valueColor: (ai.responseCriminalRecordEgypt['FullName']) ==
(ai.responseIdEgyptDriverLicense['name_arabic'])
? NewAppColor.successColor
: NewAppColor.errorColor,
),
_infoRow('الرقم القومي'.tr,
ai.responseCriminalRecordEgypt['NationalID']),
],
);
}
return _buildCaptureCard(
title: 'التقط صورة لصحيفة الحالة الجنائية'.tr,
imagePath: 'assets/images/6.png',
onTap: () async {
await ai.allMethodForAI(
(ai.prompts[5]['prompt'].toString()),
AppLink.uploadEgypt,
'criminalRecord',
);
},
);
},
);
}
}
// --- واجهة عرض الأقسام غير المصرية (بدون تغيير) ---
// --- زر الفيديو بتصميم جديد ---
class VideoButton extends StatelessWidget {
final String videoUrl =
"https://youtube.com/shorts/fC0RmYH5B_0?feature=share";
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: InkWell(
onTap: () async {
if (await canLaunchUrl(Uri.parse(videoUrl))) {
await launchUrl(Uri.parse(videoUrl));
} else {
Get.snackbar('خطأ', 'لا يمكن فتح الفيديو');
}
},
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.play_circle_outline,
color: NewAppColor.accentColor, size: 28),
const SizedBox(width: 12),
Text(
"شاهد فيديو الشرح".tr,
style: AppStyle.title.copyWith(color: NewAppColor.accentColor),
),
],
),
),
),
);
}
}
@@ -1,211 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../constant/box_name.dart';
import '../../../constant/colors.dart';
import '../../../constant/links.dart';
import '../../../constant/style.dart';
import '../../../controller/functions/encrypt_decrypt.dart';
import '../../../controller/functions/gemeni.dart';
import '../../../controller/functions/tts.dart';
import '../../../main.dart';
import '../../widgets/elevated_btn.dart';
import '../../widgets/my_scafold.dart';
class CriminalDocumemtPage extends StatelessWidget {
const CriminalDocumemtPage({super.key});
@override
Widget build(BuildContext context) {
Get.put(AI());
return MyScafolld(
title: "Criminal Document".tr,
isleading: false,
body: [
GetBuilder<AI>(builder: (controller) {
return Column(
children: [
Container(
decoration: AppStyle.boxDecoration,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('You have upload Criminal documents'.tr),
)),
egyptCriminalRecord(),
controller.responseCriminalRecordEgypt.isNotEmpty
? MyElevatedButton(
title: 'Next'.tr,
onPressed: () async {
if ((controller
.responseCriminalRecordEgypt['FullName']) !=
box.read(BoxName.nameArabic)) //todo get from server
{
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 driver’s 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 driver’s 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 {
await controller.addCriminalDocuments();
}
})
: const SizedBox(),
],
);
})
],
);
}
GetBuilder<AI> egyptCriminalRecord() {
return GetBuilder<AI>(
builder: (ai) {
if (ai.responseCriminalRecordEgypt.isNotEmpty) {
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('Criminal Record'.tr, style: AppStyle.headTitle2),
IconButton(
onPressed: () async {
await ai.allMethodForAI(
"""
Write a JSON object from the following information extracted from the provided Arabic text:
{
"InspectionResult": "",
"NationalID": "",
"FullName": "",
"IssueDate": "" // Format: YYYY-MM-DD
}
Important notes:
1. For the IssueDate, ensure the date is in YYYY-MM-DD format using Latin numerals (0-9).
2. Add appropriate spaces in all text fields to ensure readability.
3. If any information is missing, leave the corresponding field as an empty string.
4. Ensure all text is properly formatted and spaces are used correctly.
5. Convert any Arabic numerals to Latin numerals (0-9) where applicable.
Please fill in the JSON object with the extracted information, following these guidelines.
""",
AppLink.uploadEgypt,
'criminalRecord',
);
},
icon: const Icon(Icons.refresh),
),
],
),
const SizedBox(height: 8.0),
const Divider(color: AppColor.accentColor),
const SizedBox(height: 8.0),
Text(
'${'InspectionResult'.tr}: ${(ai.responseCriminalRecordEgypt['InspectionResult'])}'),
const SizedBox(height: 8.0),
Text(
'${'FullName'.tr}: ${(ai.responseCriminalRecordEgypt['FullName'])}',
style: AppStyle.title.copyWith(
color: (ai.responseCriminalRecordEgypt['FullName']) ==
(ai.responseIdEgyptDriverLicense['name_arabic'])
? AppColor.greenColor
: AppColor.redColor),
),
const SizedBox(height: 8.0),
Text(
'${'NationalID'.tr}: ${(ai.responseCriminalRecordEgypt['NationalID'])}'),
const SizedBox(height: 8.0),
Text(
'${'IssueDate'.tr}: ${ai.responseCriminalRecordEgypt['IssueDate']}'),
],
),
),
);
}
return Card(
child: InkWell(
onTap: () async {
await ai.allMethodForAI(
"""
Write a JSON object from the following information extracted from the provided Arabic text:
{
"InspectionResult": "",
"NationalID": "",
"FullName": "",
"IssueDate": "" // Format: YYYY-MM-DD
}
Important notes:
1. For the IssueDate, ensure the date is in YYYY-MM-DD format using Latin numerals (0-9).
2. Add appropriate spaces in all text fields to ensure readability.
3. If any information is missing, leave the corresponding field as an empty string.
4. Ensure all text is properly formatted and spaces are used correctly.
5. Convert any Arabic numerals to Latin numerals (0-9) where applicable.
Please fill in the JSON object with the extracted information, following these guidelines.
""",
AppLink.uploadEgypt,
'criminalRecord',
);
},
child: Column(
children: [
Image.asset(
'assets/images/6.png',
height: Get.height * .25,
width: double.maxFinite,
fit: BoxFit.fitHeight,
),
Text(
'Capture an Image of Your Criminal Record'.tr,
style: AppStyle.title,
),
],
),
),
);
},
);
}
}
@@ -493,111 +493,3 @@ class _OtpVerificationScreenState extends State<OtpVerificationScreen> {
}
}
class RegistrationScreen extends StatefulWidget {
final String phoneNumber;
const RegistrationScreen({super.key, required this.phoneNumber});
@override
State<RegistrationScreen> createState() => _RegistrationScreenState();
}
class _RegistrationScreenState extends State<RegistrationScreen> {
final _formKey = GlobalKey<FormState>();
final _firstNameController = TextEditingController();
final _lastNameController = TextEditingController();
final _emailController = TextEditingController();
bool _isLoading = false;
void _submit() async {
if (_formKey.currentState!.validate()) {
setState(() => _isLoading = true);
await PhoneAuthHelper.registerUser(
phoneNumber: widget.phoneNumber,
firstName: _firstNameController.text.trim(),
lastName: _lastNameController.text.trim(),
email: _emailController.text.trim(),
);
if (mounted) setState(() => _isLoading = false);
}
}
Widget _buildTextFormField({
required TextEditingController controller,
required String label,
TextInputType keyboardType = TextInputType.text,
String? Function(String?)? validator,
}) {
return TextFormField(
controller: controller,
style: const TextStyle(color: Colors.black87),
decoration: InputDecoration(
labelText: label,
labelStyle: const TextStyle(color: Colors.black54),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.black.withOpacity(0.1)),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: AppColor.greenColor, width: 2),
),
),
keyboardType: keyboardType,
validator: validator,
);
}
@override
Widget build(BuildContext context) {
return AuthScreen(
title: 'one last step title'.tr,
subtitle: 'complete profile subtitle'.tr,
form: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildTextFormField(
controller: _firstNameController,
label: 'first name label'.tr,
validator: (v) => v!.isEmpty ? 'first name required'.tr : null,
),
const SizedBox(height: 16),
_buildTextFormField(
controller: _lastNameController,
label: 'last name label'.tr,
validator: (v) => v!.isEmpty ? 'last name required'.tr : null,
),
const SizedBox(height: 16),
_buildTextFormField(
controller: _emailController,
label: 'email optional label'.tr,
keyboardType: TextInputType.emailAddress,
),
const SizedBox(height: 24),
_isLoading
? const CircularProgressIndicator(color: AppColor.greenColor)
: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _submit,
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.greenColor,
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
),
child: Text(
'complete registration button'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
),
],
),
),
);
}
}
@@ -1,91 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_driver/constant/colors.dart';
import 'package:siro_driver/constant/style.dart';
import 'package:siro_driver/controller/auth/captin/register_captin_controller.dart';
import 'package:siro_driver/views/widgets/elevated_btn.dart';
import 'package:siro_driver/views/widgets/my_scafold.dart';
class VerifyEmailCaptainPage extends StatelessWidget {
VerifyEmailCaptainPage({super.key});
RegisterCaptainController registerCaptinController =
Get.put(RegisterCaptainController());
@override
Widget build(BuildContext context) {
return MyScafolld(
title: 'Verify Email For Driver'.tr,
body: [
Positioned(
top: 10,
left: 20,
child: Text(
'We sent 5 digit to your Email provided'.tr,
style: AppStyle.title.copyWith(fontSize: 20),
)),
GetBuilder<RegisterCaptainController>(
builder: (controller) => Positioned(
top: 100,
left: 80,
right: 80,
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: [
SizedBox(
width: 100,
child: TextField(
controller: registerCaptinController.verifyCode,
decoration: InputDecoration(
labelStyle: AppStyle.title,
border: const OutlineInputBorder(),
hintText: '5 digit'.tr,
counterStyle: AppStyle.number,
hintStyle: AppStyle.subtitle
.copyWith(color: AppColor.accentColor),
),
maxLength: 5,
keyboardType: TextInputType.number,
),
),
const SizedBox(
height: 30,
),
MyElevatedButton(
title: 'Send Verfication Code'.tr,
onPressed: () {
registerCaptinController.sendVerifications();
})
],
),
),
)),
],
isleading: true,
);
}
Padding verifyEmail() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: AppColor.accentColor,
width: 2,
),
borderRadius: BorderRadius.circular(8),
),
child: const Padding(
padding: EdgeInsets.all(10),
child: SizedBox(
width: 20,
child: TextField(
maxLength: 1,
keyboardType: TextInputType.number,
),
),
),
),
);
}
}