25-7-28-2

This commit is contained in:
Hamza-Ayed
2025-07-28 12:21:28 +03:00
parent 660d60e1f5
commit 83a97baed1
549 changed files with 109870 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
import 'dart:convert';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
class GeminiEgypt extends GetxController {
Map<String, dynamic> responseIdCardDriverEgypt = {};
String? responseIdCardDriverEgypt1;
Future geminiAiExtraction(String prompt, payload) async {
var requestBody = jsonEncode({
'contents': [
{
'parts': [
// {
// 'inlineData': {
// 'mimeType': 'image/jpeg',
// 'data': imageData,
// },
// },
{
'text': """
$payload
$prompt ,and make dates format like year-month-day"""
},
],
},
],
'generationConfig': {
'temperature': 0.4,
'topK': 32,
'topP': 1,
'maxOutputTokens': 4096,
'stopSequences': [],
},
'safety_settings': [
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_NONE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_NONE"
},
]
});
final response = await http.post(
Uri.parse(
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'),
'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=AIzaSyCyoLcSkDzK5_SMe00nhut56SSXWPR074w'),
headers: {'Content-Type': 'application/json'},
body: requestBody,
);
if (response.statusCode == 200) {
var responseData = jsonDecode(response.body);
// Process the responseData as needed
var result = responseData['candidates'][0]['content']['parts'][0]['text'];
RegExp regex = RegExp(r"```json([^`]*)```");
String? jsonString =
regex.firstMatch(responseData.toString())?.group(1)?.trim();
if (jsonString != null) {
// Convert the JSON object to a String
jsonString = jsonEncode(json.decode(jsonString));
responseIdCardDriverEgypt1 = jsonString;
responseIdCardDriverEgypt = jsonDecode(responseIdCardDriverEgypt1!);
update();
return responseIdCardDriverEgypt;
} else {}
// Rest of your code...
} else {}
}
}

View File

@@ -0,0 +1,221 @@
import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/controller/auth/captin/register_captin_controller.dart';
import 'package:sefer_driver/views/widgets/elevated_btn.dart';
import 'package:sefer_driver/views/widgets/my_scafold.dart';
import 'package:sefer_driver/views/widgets/my_textField.dart';
import 'package:sefer_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: '5 digit'.tr,
hint: '5 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,
);
}
}

View File

@@ -0,0 +1,987 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/controller/functions/audio_controller.dart';
import 'package:sefer_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 Intaleq 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 Intaleq 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 Intaleq 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),
),
],
),
),
),
);
}
}