8/11/1
This commit is contained in:
268
lib/controller/mainController/main_controller.dart
Normal file
268
lib/controller/mainController/main_controller.dart
Normal file
@@ -0,0 +1,268 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/constant/colors.dart';
|
||||
import 'package:service/constant/links.dart';
|
||||
import 'package:service/controller/functions/crud.dart';
|
||||
import 'package:service/controller/mainController/pages/driver_page.dart';
|
||||
import 'package:service/views/widgets/my_dialog.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../print.dart';
|
||||
import 'pages/passengers_page.dart';
|
||||
|
||||
class MainController extends GetxController {
|
||||
final formKey = GlobalKey<FormState>();
|
||||
bool isLoading = false;
|
||||
final passengerPhoneController = TextEditingController();
|
||||
final driverPhoneController = TextEditingController();
|
||||
final notesController = TextEditingController();
|
||||
final carplateController = TextEditingController();
|
||||
Map passengerData = {};
|
||||
Map driverData = {};
|
||||
List filteredDrivers = [];
|
||||
|
||||
searchPassengerByPhone() async {
|
||||
if (formKey.currentState!.validate()) {
|
||||
await getPassengersByPhone();
|
||||
Get.back();
|
||||
Get.to(() => PassengersPage());
|
||||
}
|
||||
}
|
||||
|
||||
void searchDrivers(String query) {
|
||||
if (query.isEmpty) {
|
||||
filteredDrivers = driverNotCompleteRegistration;
|
||||
update();
|
||||
} else {
|
||||
filteredDrivers = driverNotCompleteRegistration
|
||||
.where((driver) => driver['phone_number']
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.contains(query.toLowerCase()))
|
||||
.toList();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> makePhoneCall(String phoneNumber) async {
|
||||
final Uri launchUri = Uri(
|
||||
scheme: 'tel',
|
||||
path: phoneNumber,
|
||||
);
|
||||
await launchUrl(launchUri);
|
||||
}
|
||||
|
||||
void launchCommunication(
|
||||
String method, String contactInfo, String message) async {
|
||||
String url;
|
||||
|
||||
if (Platform.isIOS) {
|
||||
switch (method) {
|
||||
case 'phone':
|
||||
url = 'tel:$contactInfo';
|
||||
break;
|
||||
case 'sms':
|
||||
url = 'sms:$contactInfo?body=${Uri.encodeComponent(message)}';
|
||||
break;
|
||||
case 'whatsapp':
|
||||
url =
|
||||
'https://api.whatsapp.com/send?phone=$contactInfo&text=${Uri.encodeComponent(message)}';
|
||||
break;
|
||||
case 'email':
|
||||
url =
|
||||
'mailto:$contactInfo?subject=Subject&body=${Uri.encodeComponent(message)}';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else if (Platform.isAndroid) {
|
||||
switch (method) {
|
||||
case 'phone':
|
||||
url = 'tel:$contactInfo';
|
||||
break;
|
||||
case 'sms':
|
||||
url = 'sms:$contactInfo?body=${Uri.encodeComponent(message)}';
|
||||
break;
|
||||
case 'whatsapp':
|
||||
// Check if WhatsApp is installed
|
||||
final bool whatsappInstalled =
|
||||
await canLaunchUrl(Uri.parse('whatsapp://'));
|
||||
if (whatsappInstalled) {
|
||||
url =
|
||||
'whatsapp://send?phone=$contactInfo&text=${Uri.encodeComponent(message)}';
|
||||
} else {
|
||||
// Provide an alternative action, such as opening the WhatsApp Web API
|
||||
url =
|
||||
'https://api.whatsapp.com/send?phone=$contactInfo&text=${Uri.encodeComponent(message)}';
|
||||
}
|
||||
break;
|
||||
case 'email':
|
||||
url =
|
||||
'mailto:$contactInfo?subject=Subject&body=${Uri.encodeComponent(message)}';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (await canLaunchUrl(Uri.parse(url))) {
|
||||
await launchUrl(Uri.parse(url));
|
||||
} else {}
|
||||
}
|
||||
|
||||
List driverNotCompleteRegistration = [];
|
||||
getDriverNotCompleteRegistration() async {
|
||||
var res = await CRUD()
|
||||
.get(link: AppLink.getDriverNotCompleteRegistration, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
driverNotCompleteRegistration = d;
|
||||
filteredDrivers = driverNotCompleteRegistration;
|
||||
update();
|
||||
} else {
|
||||
Get.snackbar(res, '');
|
||||
}
|
||||
}
|
||||
|
||||
List newDriverRegister = [];
|
||||
getNewDriverRegister() async {
|
||||
var res = await CRUD().get(link: AppLink.getNewDriverRegister, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
newDriverRegister = d;
|
||||
update();
|
||||
} else {
|
||||
Get.snackbar(res, '');
|
||||
}
|
||||
}
|
||||
|
||||
addWelcomeCall(String driveId) async {
|
||||
var res = await CRUD().post(link: AppLink.addWelcomeDriverNote, payload: {
|
||||
"driverId": driveId,
|
||||
"notes": notesController.text,
|
||||
});
|
||||
if (res != 'failue') {
|
||||
Get.snackbar('Success'.tr, '', backgroundColor: AppColor.greenColor);
|
||||
}
|
||||
}
|
||||
|
||||
String selectedStatus = "I'm not ready yet".tr;
|
||||
List passengerNotCompleteRegistration = [];
|
||||
getPassengerNotCompleteRegistration() async {
|
||||
var res = await CRUD()
|
||||
.get(link: AppLink.getPassengersNotCompleteRegistration, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
passengerNotCompleteRegistration = d;
|
||||
update();
|
||||
} else {
|
||||
Get.snackbar(res, '');
|
||||
}
|
||||
}
|
||||
|
||||
void setSelectedStatus(String status) {
|
||||
selectedStatus = status;
|
||||
update();
|
||||
}
|
||||
|
||||
final List<String> statusOptions = [
|
||||
"I'm not ready yet".tr,
|
||||
"I don't have a suitable vehicle".tr,
|
||||
"I'll register when the app is fully launched".tr,
|
||||
"I need more help understanding the app".tr,
|
||||
"My documents have expired".tr,
|
||||
];
|
||||
|
||||
List carPlateNotEdit = [];
|
||||
|
||||
getCarPlateNotEdit() async {
|
||||
var res = await CRUD().get(link: AppLink.getCarPlateNotEdit, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
carPlateNotEdit = d;
|
||||
update();
|
||||
} else {
|
||||
MyDialog().getDialog('No Car found yet'.tr, 'thanks'.tr, const SizedBox(),
|
||||
() {
|
||||
Get.back();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
editCarPlateNotEdit(String driverId, carPlate) async {
|
||||
var res = await CRUD().post(link: AppLink.editCarPlate, payload: {
|
||||
"driverId": driverId,
|
||||
"carPlate": carPlate,
|
||||
});
|
||||
if (res != 'failure') {
|
||||
Get.snackbar(res, '', backgroundColor: AppColor.greenColor);
|
||||
carplateController.clear();
|
||||
await getCarPlateNotEdit();
|
||||
update();
|
||||
} else {
|
||||
Get.snackbar(res, '', backgroundColor: AppColor.redColor);
|
||||
}
|
||||
}
|
||||
|
||||
saveNoteForDriverNotCompleteRegistration(String phone, editor, note) async {
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.addNotesDriver,
|
||||
payload: {"phone": phone, "editor": editor, "note": note});
|
||||
if (res != 'failure') {
|
||||
Get.snackbar(res, '', backgroundColor: AppColor.greenColor);
|
||||
notesController.clear();
|
||||
} else {
|
||||
Get.snackbar(res, '', backgroundColor: AppColor.redColor);
|
||||
}
|
||||
}
|
||||
|
||||
saveNoteForPassengerNotCompleteRegistration(
|
||||
String phone, editor, note) async {
|
||||
var res = await CRUD().post(
|
||||
link: AppLink.addNotesPassenger,
|
||||
payload: {"phone": phone, "editor": editor, "note": note});
|
||||
if (res != 'failure') {
|
||||
Get.snackbar(res, '', backgroundColor: AppColor.greenColor);
|
||||
notesController.clear();
|
||||
} else {
|
||||
Get.snackbar(res, '', backgroundColor: AppColor.redColor);
|
||||
}
|
||||
}
|
||||
|
||||
searchDriverByPhone() async {
|
||||
if (formKey.currentState!.validate()) {
|
||||
await getDriverByPhone();
|
||||
Get.back();
|
||||
Get.to(() => DriverPage());
|
||||
}
|
||||
}
|
||||
|
||||
getPassengersByPhone() async {
|
||||
var res = await CRUD().get(
|
||||
link: AppLink.getPassengersByPhone,
|
||||
payload: {"phone": '+2${passengerPhoneController.text}'});
|
||||
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res);
|
||||
passengerData = d;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
getDriverByPhone() async {
|
||||
var res = await CRUD().get(
|
||||
link: AppLink.getDriverByPhone,
|
||||
payload: {"phone": '+2${driverPhoneController.text}'});
|
||||
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res);
|
||||
driverData = d;
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
lib/controller/mainController/pages/complaint.dart
Normal file
12
lib/controller/mainController/pages/complaint.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
|
||||
class Complaint extends StatelessWidget {
|
||||
const Complaint({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MyScaffold(title: "View complaint".tr, isleading: true, body: []);
|
||||
}
|
||||
}
|
||||
127
lib/controller/mainController/pages/driver_page.dart
Normal file
127
lib/controller/mainController/pages/driver_page.dart
Normal file
@@ -0,0 +1,127 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
|
||||
import '../main_controller.dart';
|
||||
|
||||
class DriverPage extends StatelessWidget {
|
||||
DriverPage({super.key});
|
||||
MainController mainController = MainController();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: GetBuilder<MainController>(builder: (mainController) {
|
||||
Map data = mainController.driverData['message'][0];
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('${data['first_name']} ${data['last_name']}'),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: CupertinoScrollbar(
|
||||
child: ListView(
|
||||
children: [
|
||||
_buildDriverInfoSection(
|
||||
mainController.driverData['message'][0]),
|
||||
_buildStatisticsSection(
|
||||
mainController.driverData['message'][0]),
|
||||
_buildCarInfoSection(mainController.driverData['message'][0]),
|
||||
_buildLicenseInfoSection(
|
||||
mainController.driverData['message'][0]),
|
||||
_buildBankInfoSection(
|
||||
mainController.driverData['message'][0]),
|
||||
// buildCarInfo(mainController.driverData['message'][0]),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDriverInfoSection(Map<String, dynamic> data) {
|
||||
return CupertinoListSection.insetGrouped(
|
||||
header: Text('Driver Information'.tr),
|
||||
children: [
|
||||
_buildInfoRow('Name'.tr, data['name_arabic']),
|
||||
_buildInfoRow('Name (English)'.tr, data['name_english']),
|
||||
_buildInfoRow('Phone'.tr, data['phone']),
|
||||
_buildInfoRow('Email'.tr, data['email']),
|
||||
_buildInfoRow('Gender'.tr, data['gender']),
|
||||
_buildInfoRow('Birthdate'.tr, data['birthdate']),
|
||||
_buildInfoRow('National Number'.tr, data['national_number']),
|
||||
_buildInfoRow('Religion'.tr, data['religion']),
|
||||
_buildInfoRow('Occupation'.tr, data['occupation']),
|
||||
_buildInfoRow('Education'.tr, data['education']),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatisticsSection(Map<String, dynamic> data) {
|
||||
return CupertinoListSection.insetGrouped(
|
||||
header: Text('Driver Statistics'.tr),
|
||||
children: [
|
||||
_buildInfoRow('Total Rides'.tr, data['countRide'].toString()),
|
||||
_buildInfoRow('Average Rating'.tr, data['rating'].toString()),
|
||||
_buildInfoRow('Total Payments'.tr, '\$${data['totalPayment']}'),
|
||||
_buildInfoRow('Wallet Balance'.tr, '\$${data['totalDriverWallet']}'),
|
||||
_buildInfoRow('Complaints'.tr, data['countComplaint'].toString()),
|
||||
_buildInfoRow('Scam Reports'.tr, data['countScam'].toString()),
|
||||
_buildInfoRow(
|
||||
'Passengers Rated'.tr, data['DRatingPassengersCount'].toString()),
|
||||
_buildInfoRow(
|
||||
'Avg Passenger Rating'.tr, data['avgDRatingPassenger'].toString()),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCarInfoSection(Map<String, dynamic> data) {
|
||||
return CupertinoListSection.insetGrouped(
|
||||
header: Text('Vehicle Information'.tr),
|
||||
children: [
|
||||
_buildInfoRow('VIN'.tr, data['vin']),
|
||||
_buildInfoRow('Plate Number'.tr, data['car_plate']),
|
||||
_buildInfoRow('Make'.tr, data['make']),
|
||||
_buildInfoRow('Model'.tr, data['model']),
|
||||
_buildInfoRow('Year'.tr, data['year']),
|
||||
_buildInfoRow('Color'.tr, data['color']),
|
||||
_buildInfoRow('Fuel Type'.tr, data['fuel']),
|
||||
_buildInfoRow('Displacement'.tr, data['displacement']),
|
||||
_buildInfoRow('Registration Date'.tr, data['registration_date']),
|
||||
_buildInfoRow('Expiration Date'.tr, data['expiration_date']),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLicenseInfoSection(Map<String, dynamic> data) {
|
||||
return CupertinoListSection.insetGrouped(
|
||||
header: Text('License Information'.tr),
|
||||
children: [
|
||||
_buildInfoRow('License Type'.tr, data['license_type']),
|
||||
_buildInfoRow('Card ID'.tr, data['card_id']),
|
||||
_buildInfoRow('Issue Date'.tr, data['issue_date']),
|
||||
_buildInfoRow('Expiry Date'.tr, data['expiry_date']),
|
||||
_buildInfoRow('Categories'.tr, data['license_categories']),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBankInfoSection(Map<String, dynamic> data) {
|
||||
return CupertinoListSection.insetGrouped(
|
||||
header: Text('Bank Information'.tr),
|
||||
children: [
|
||||
_buildInfoRow('Account Number'.tr, data['accountBank']),
|
||||
_buildInfoRow('Bank Code'.tr, data['bankCode']),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoRow(String label, String value) {
|
||||
return CupertinoListTile(
|
||||
title: Text(label),
|
||||
trailing: Text(value,
|
||||
style: const TextStyle(color: CupertinoColors.systemGrey)),
|
||||
);
|
||||
}
|
||||
}
|
||||
218
lib/controller/mainController/pages/drivers_cant_register.dart
Normal file
218
lib/controller/mainController/pages/drivers_cant_register.dart
Normal file
@@ -0,0 +1,218 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/constant/colors.dart';
|
||||
import 'package:service/controller/mainController/main_controller.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
|
||||
import 'registration_captain_page.dart';
|
||||
|
||||
class DriversCantRegister extends StatelessWidget {
|
||||
DriversCantRegister({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(MainController());
|
||||
return MyScaffold(
|
||||
title: 'Drivers Cant Register'.tr,
|
||||
isleading: true,
|
||||
body: [
|
||||
GetBuilder<MainController>(builder: (mainController) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CupertinoSearchTextField(
|
||||
keyboardType: TextInputType.phone,
|
||||
onChanged: (value) => mainController.searchDrivers(value),
|
||||
placeholder: 'Search by phone number'.tr,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: mainController.filteredDrivers.length,
|
||||
itemBuilder: (context, index) {
|
||||
final driver = mainController.filteredDrivers[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
color: driver['note'] == null
|
||||
? AppColor.greenColor
|
||||
: AppColor.greyColor,
|
||||
child: CupertinoFormSection(
|
||||
header: Text(
|
||||
'Driver ID: ${driver['driverId']}',
|
||||
),
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => mainController
|
||||
.makePhoneCall(driver['phone_number']),
|
||||
child: Container(
|
||||
height: 40,
|
||||
color: driver['note'] != null
|
||||
? AppColor.greenColor
|
||||
: AppColor.greyColor,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Text(driver['phone_number']),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
String message = "مرحباً،\n\n"
|
||||
"نلاحظ أنك لم تكمل عملية التسجيل في خدمة سفر درايفر. نود تذكيرك بأن إكمال التسجيل يتيح لك فرصة الانضمام إلى فريق سفر والاستفادة من خدماتنا المتنوعة.\n\n"
|
||||
"إذا كنت بحاجة إلى أي مساعدة أو لديك أي استفسارات، لا تتردد في الاتصال بنا. نحن هنا لمساعدتك.\n\n"
|
||||
"للاتصال بنا، يرجى الاتصال على الرقم التالي: +20 101 880 5430\n\n"
|
||||
"مع تحيات فريق سفر.";
|
||||
|
||||
mainController.launchCommunication(
|
||||
'whatsapp',
|
||||
'${driver['phone_number']}',
|
||||
message);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.send_time_extension_sharp,
|
||||
color: AppColor.secondaryColor,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Get.to(() => RegisterCaptain(),
|
||||
arguments: {
|
||||
"phone_number":
|
||||
driver['phone_number']
|
||||
.toString(),
|
||||
'driverId': driver['driverId']
|
||||
.toString(),
|
||||
'email':
|
||||
driver['email'].toString(),
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.save,
|
||||
color: AppColor.gold,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
// CupertinoFormRow(
|
||||
// prefix: Text('Phone Number'.tr),
|
||||
// child: CupertinoTextFormFieldRow(
|
||||
// initialValue: driver['phone_number'],
|
||||
// readOnly: true,
|
||||
// placeholder: 'Phone Number'.tr,
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
),
|
||||
CupertinoFormRow(
|
||||
prefix: Text('Created At'.tr),
|
||||
child: CupertinoTextFormFieldRow(
|
||||
initialValue: driver['created_at'],
|
||||
readOnly: true,
|
||||
placeholder: 'Created At',
|
||||
),
|
||||
),
|
||||
CupertinoFormRow(
|
||||
prefix: Text('Status'.tr),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
showCupertinoModalPopup<void>(
|
||||
context: Get.context!,
|
||||
builder: (BuildContext context) =>
|
||||
Container(
|
||||
height: 216,
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context)
|
||||
.viewInsets
|
||||
.bottom,
|
||||
),
|
||||
color: CupertinoColors.systemBackground
|
||||
.resolveFrom(context),
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
itemExtent: 32.0,
|
||||
scrollController:
|
||||
FixedExtentScrollController(
|
||||
initialItem: mainController
|
||||
.selectedStatus
|
||||
.indexOf(mainController
|
||||
.selectedStatus),
|
||||
),
|
||||
onSelectedItemChanged:
|
||||
(int selectedItem) {
|
||||
mainController.setSelectedStatus(
|
||||
mainController
|
||||
.statusOptions[selectedItem]
|
||||
.tr);
|
||||
},
|
||||
children: List<Widget>.generate(
|
||||
mainController.statusOptions
|
||||
.length, (int index) {
|
||||
return Center(
|
||||
child: Text(mainController
|
||||
.statusOptions[index].tr),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: CupertinoFormRow(
|
||||
child: Text(
|
||||
mainController.selectedStatus.tr,
|
||||
style: TextStyle(
|
||||
color: CupertinoColors.label
|
||||
.resolveFrom(Get.context!)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
CupertinoFormRow(
|
||||
prefix: Text('Notes'.tr),
|
||||
child: CupertinoTextFormFieldRow(
|
||||
cursorColor: AppColor.blueColor,
|
||||
controller: mainController.notesController,
|
||||
placeholder:
|
||||
driver['note'] ?? "Additional comments".tr,
|
||||
),
|
||||
),
|
||||
CupertinoButton(
|
||||
child: Text('Save Notes'.tr),
|
||||
onPressed: () {
|
||||
// Save the notes for the driver
|
||||
String notes =
|
||||
mainController.notesController.text == ''
|
||||
? mainController.selectedStatus
|
||||
.toString()
|
||||
: mainController.notesController.text;
|
||||
|
||||
mainController
|
||||
.saveNoteForDriverNotCompleteRegistration(
|
||||
driver['phone_number'],
|
||||
'girls name',
|
||||
notes);
|
||||
print(
|
||||
'Notes for driver ${driver['id']}: $notes');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
83
lib/controller/mainController/pages/edit_car_plate.dart
Normal file
83
lib/controller/mainController/pages/edit_car_plate.dart
Normal file
@@ -0,0 +1,83 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/constant/colors.dart';
|
||||
import 'package:service/constant/style.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
import 'package:service/views/widgets/my_textField.dart';
|
||||
|
||||
import '../main_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class EditCarPlate extends StatelessWidget {
|
||||
const EditCarPlate({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(MainController());
|
||||
|
||||
return GetBuilder<MainController>(builder: (mainController) {
|
||||
return MyScaffold(
|
||||
title: 'Edit car plate'.tr,
|
||||
isleading: true,
|
||||
body: [
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
itemCount: mainController
|
||||
.carPlateNotEdit.length, // 10 fields + 1 save button
|
||||
itemBuilder: (context, index) {
|
||||
var carData = mainController.carPlateNotEdit[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration1,
|
||||
child: Column(
|
||||
children: [
|
||||
Image.network(
|
||||
'https://api.sefer.live/sefer/card_image/car_front-${carData['driverID']}.jpg',
|
||||
height: 200,
|
||||
width: double.maxFinite,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 9,
|
||||
),
|
||||
Form(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await mainController.editCarPlateNotEdit(
|
||||
carData['driverID'].toString(),
|
||||
mainController.carplateController.text,
|
||||
);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.upload_outlined,
|
||||
color: AppColor.blueColor,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: Get.width * .6,
|
||||
child: MyTextForm(
|
||||
controller:
|
||||
mainController.carplateController,
|
||||
label: 'car plate'.tr,
|
||||
hint: 'car plate'.tr,
|
||||
type: TextInputType.name,
|
||||
),
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
)),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/controller/mainController/main_controller.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
|
||||
class PassengersCantRegister extends StatelessWidget {
|
||||
PassengersCantRegister({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(MainController());
|
||||
return MyScaffold(
|
||||
title: 'Passengers Cant Register'.tr,
|
||||
isleading: true,
|
||||
body: [
|
||||
GetBuilder<MainController>(builder: (mainController) {
|
||||
return ListView.builder(
|
||||
itemCount: mainController.passengerNotCompleteRegistration.length,
|
||||
itemBuilder: (context, index) {
|
||||
final passenger =
|
||||
mainController.passengerNotCompleteRegistration[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CupertinoFormSection(
|
||||
header: Text('Passenger ID: ${passenger['id']}'),
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => mainController
|
||||
.makePhoneCall(passenger['phone_number']),
|
||||
child: CupertinoFormRow(
|
||||
prefix: Text('Phone Number'.tr),
|
||||
child: CupertinoTextFormFieldRow(
|
||||
initialValue: passenger['phone_number'],
|
||||
readOnly: true,
|
||||
placeholder: 'Phone Number'.tr,
|
||||
),
|
||||
),
|
||||
),
|
||||
CupertinoFormRow(
|
||||
prefix: Text('Created At'.tr),
|
||||
child: CupertinoTextFormFieldRow(
|
||||
initialValue: passenger['created_at'],
|
||||
readOnly: true,
|
||||
placeholder: 'Created At',
|
||||
),
|
||||
),
|
||||
CupertinoFormRow(
|
||||
prefix: Text('Notes'.tr),
|
||||
child: CupertinoTextFormFieldRow(
|
||||
controller: mainController.notesController,
|
||||
placeholder:
|
||||
passenger['note'] ?? 'Enter notes after call'.tr,
|
||||
),
|
||||
),
|
||||
CupertinoButton(
|
||||
child: Text('Save Notes'.tr),
|
||||
onPressed: () {
|
||||
// Save the notes for the Passenger
|
||||
String notes = mainController.notesController.text;
|
||||
|
||||
mainController
|
||||
.saveNoteForPassengerNotCompleteRegistration(
|
||||
passenger['phone_number'], 'girls name', notes);
|
||||
print('Notes for Passenger ${passenger['id']}: $notes');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
133
lib/controller/mainController/pages/passengers_page.dart
Normal file
133
lib/controller/mainController/pages/passengers_page.dart
Normal file
@@ -0,0 +1,133 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/controller/mainController/main_controller.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
|
||||
class PassengersPage extends StatelessWidget {
|
||||
PassengersPage({super.key});
|
||||
final MainController mainController = MainController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MainController>(builder: (mainController) {
|
||||
Map data = mainController.passengerData['message'][0];
|
||||
return MyScaffold(
|
||||
title: (data['first_name']?.toString() ?? '') +
|
||||
' ' +
|
||||
(data['last_name']?.toString() ?? ''),
|
||||
isleading: true,
|
||||
body: [
|
||||
ListView(
|
||||
children: [
|
||||
_buildPersonalInfoCard(data),
|
||||
_buildLatestRideCard(data),
|
||||
_buildWalletInfoCard(data),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildPersonalInfoCard(Map data) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Personal Information'.tr,
|
||||
style:
|
||||
const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
_buildInfoRow('Phone'.tr, data['phone']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow('Email'.tr, data['email']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow('Gender'.tr, data['gender']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'Birthdate'.tr, data['birthdate']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'Education'.tr, data['education']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'Employment'.tr, data['employmentType']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow('Marital Status'.tr,
|
||||
data['maritalStatus']?.toString() ?? 'N/A'),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLatestRideCard(Map data) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Latest Ride'.tr,
|
||||
style:
|
||||
const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
_buildInfoRow('Ride ID'.tr, data['ride_id']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow('Date'.tr, data['ride_date']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'Start Time'.tr, data['ride_time']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'End Time'.tr, data['ride_endtime']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'Price'.tr, '\$${data['price']?.toString() ?? 'N/A'}'),
|
||||
_buildInfoRow(
|
||||
'Status'.tr, data['ride_status']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow('Payment Method'.tr,
|
||||
data['ride_payment_method']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow('Car Type'.tr, data['car_type']?.toString() ?? 'N/A'),
|
||||
_buildInfoRow(
|
||||
'Distance'.tr,
|
||||
data['distance'] != null
|
||||
? '${data['distance'].toStringAsFixed(2)} km'
|
||||
: 'N/A'),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWalletInfoCard(Map data) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Wallet Information'.tr,
|
||||
style:
|
||||
const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
_buildInfoRow('Wallet Balance'.tr,
|
||||
'\$${data['passenger_wallet_balance']?.toString() ?? 'N/A'}'),
|
||||
_buildInfoRow('Last Payment Amount'.tr,
|
||||
'\$${data['passenger_payment_amount']?.toString() ?? 'N/A'}'),
|
||||
_buildInfoRow('Last Payment Method'.tr,
|
||||
data['passenger_payment_method']?.toString() ?? 'N/A'),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
Text(value),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
2096
lib/controller/mainController/pages/registration_captain_page.dart
Normal file
2096
lib/controller/mainController/pages/registration_captain_page.dart
Normal file
File diff suppressed because it is too large
Load Diff
165
lib/controller/mainController/pages/welcome_call.dart
Normal file
165
lib/controller/mainController/pages/welcome_call.dart
Normal file
@@ -0,0 +1,165 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/constant/colors.dart';
|
||||
import 'package:service/constant/style.dart';
|
||||
import 'package:service/views/widgets/elevated_btn.dart';
|
||||
import 'package:service/views/widgets/my_scafold.dart';
|
||||
|
||||
import '../main_controller.dart';
|
||||
|
||||
class WelcomeCall extends StatelessWidget {
|
||||
const WelcomeCall({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(MainController());
|
||||
return MyScaffold(
|
||||
title: 'Welcome Drivers'.tr,
|
||||
isleading: true,
|
||||
body: [
|
||||
GetBuilder<MainController>(builder: (mainController) {
|
||||
return Expanded(
|
||||
child: CupertinoScrollbar(
|
||||
child: ListView.builder(
|
||||
itemCount: mainController.newDriverRegister.length,
|
||||
itemBuilder: (context, index) {
|
||||
final driver = mainController.newDriverRegister[index];
|
||||
return DriverCard(driver: driver);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DriverCard extends StatelessWidget {
|
||||
final Map<String, dynamic> driver;
|
||||
|
||||
const DriverCard({super.key, required this.driver});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoCard(
|
||||
margin: const EdgeInsets.all(16.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
decoration: AppStyle.boxDecoration1.copyWith(
|
||||
color: driver['isCall'].toString() == '1'
|
||||
? AppColor.greenColor
|
||||
: AppColor.accentColor),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||
child: Text(
|
||||
'Driver Information'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
InfoText('Name'.tr, driver['name_arabic'].toString()),
|
||||
InfoText('Phone'.tr, driver['phone'].toString()),
|
||||
InfoText('Email'.tr, driver['email'].toString()),
|
||||
InfoText('License Type'.tr, driver['license_type'].toString()),
|
||||
InfoText(
|
||||
'License Categories'.tr, driver['license_categories'] ?? ''),
|
||||
InfoText(
|
||||
'National Number'.tr, driver['national_number'].toString()),
|
||||
InfoText('Occupation'.tr, driver['occupation'].toString()),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Notes:'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
CupertinoTextField(
|
||||
controller: Get.find<MainController>().notesController,
|
||||
placeholder: driver['notes'] ?? 'Enter notes here...'.tr,
|
||||
maxLines: 3,
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: CupertinoColors.systemGrey),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: Get.width * .4,
|
||||
child: MyElevatedButton(
|
||||
title: 'Call Driver'.tr,
|
||||
onPressed: () {
|
||||
Get.find<MainController>()
|
||||
.makePhoneCall(driver['phone'].toString());
|
||||
})),
|
||||
CupertinoButton(
|
||||
onPressed: () async {
|
||||
await Get.find<MainController>().addWelcomeCall(
|
||||
driver['id'].toString(),
|
||||
);
|
||||
},
|
||||
child: Text('Save Changes'.tr),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InfoText extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const InfoText(this.label, this.value, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 4.0),
|
||||
child: Text(
|
||||
'$label: $value',
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CupertinoCard extends StatelessWidget {
|
||||
final Widget child;
|
||||
final EdgeInsetsGeometry margin;
|
||||
|
||||
const CupertinoCard(
|
||||
{super.key, required this.child, this.margin = EdgeInsets.zero});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: margin,
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.systemBackground,
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: CupertinoColors.systemGrey.withOpacity(0.2),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 5,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,993 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:service/views/widgets/elevated_btn.dart';
|
||||
|
||||
import '../../constant/api_key.dart';
|
||||
import '../../constant/box_name.dart';
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/info.dart';
|
||||
import '../../constant/links.dart';
|
||||
import '../../constant/style.dart';
|
||||
import '../../main.dart';
|
||||
import '../../print.dart';
|
||||
import '../functions/crud.dart';
|
||||
import '../functions/image.dart';
|
||||
|
||||
enum DocumentType {
|
||||
carLicenseFront,
|
||||
carLicenseBack,
|
||||
idCardFront,
|
||||
idCardBack,
|
||||
driverLicense,
|
||||
unknown,
|
||||
}
|
||||
|
||||
class RegisterCaptainController extends GetxController {
|
||||
bool isDriverSaved = false;
|
||||
bool isCarSaved = false;
|
||||
Map<String, dynamic>? arguments;
|
||||
String? driverId;
|
||||
String? email;
|
||||
String? phone;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
arguments = Get.arguments;
|
||||
|
||||
getPrompt();
|
||||
|
||||
initArguments();
|
||||
}
|
||||
|
||||
void driveInit() {
|
||||
arguments = Get.arguments;
|
||||
initArguments();
|
||||
}
|
||||
|
||||
void initArguments() {
|
||||
if (arguments != null) {
|
||||
driverId = arguments!['driverId'];
|
||||
email = arguments!['email'];
|
||||
phone = arguments!['phone_number'];
|
||||
} else {
|
||||
print('Arguments are null');
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> responseMap = {};
|
||||
Map<String, dynamic> responseCarLicenseMapJordan = {};
|
||||
Map<String, dynamic> responseBackCarLicenseMap = {};
|
||||
Map<String, dynamic> responseIdCardMap = {};
|
||||
Map<String, dynamic> responseIdCardDriverEgyptBack = {};
|
||||
Map<String, dynamic> responseForComplaint = {};
|
||||
Map<String, dynamic> responseIdCardDriverEgyptFront = {};
|
||||
Map<String, dynamic> responseIdEgyptFront = {};
|
||||
Map<String, dynamic> responseCriminalRecordEgypt = {};
|
||||
Map<String, dynamic> responseIdEgyptBack = {};
|
||||
Map<String, dynamic> responseIdEgyptDriverLicense = {};
|
||||
String? responseIdCardDriverEgypt1;
|
||||
bool isloading = false;
|
||||
var image;
|
||||
DateTime now = DateTime.now();
|
||||
|
||||
bool isLoading = false;
|
||||
String getExpectedDocument(String imagePath) {
|
||||
switch (imagePath) {
|
||||
case 'car_front':
|
||||
return 'car_license_front'.tr;
|
||||
case 'car_back':
|
||||
return 'car_license_back'.tr;
|
||||
case 'id_back':
|
||||
return 'id_card_back'.tr;
|
||||
case 'id_front':
|
||||
return 'id_card_front'.tr;
|
||||
case 'driver_license':
|
||||
return 'driver_license'.tr;
|
||||
default:
|
||||
return 'unknown_document'.tr;
|
||||
}
|
||||
}
|
||||
|
||||
DocumentType getExpectedType(String imagePath) {
|
||||
switch (imagePath) {
|
||||
case 'car_front':
|
||||
return DocumentType.carLicenseFront;
|
||||
case 'car_back':
|
||||
return DocumentType.carLicenseBack;
|
||||
case 'id_back':
|
||||
return DocumentType.idCardBack;
|
||||
case 'id_front':
|
||||
return DocumentType.idCardFront;
|
||||
case 'driver_license':
|
||||
return DocumentType.driverLicense;
|
||||
default:
|
||||
return DocumentType.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
String getDetectedDocument(DocumentType type) {
|
||||
switch (type) {
|
||||
case DocumentType.carLicenseFront:
|
||||
return 'car_license_front'.tr;
|
||||
case DocumentType.carLicenseBack:
|
||||
return 'car_license_back'.tr;
|
||||
case DocumentType.idCardFront:
|
||||
return 'id_card_front'.tr;
|
||||
case DocumentType.idCardBack:
|
||||
return 'id_card_back'.tr;
|
||||
case DocumentType.driverLicense:
|
||||
return 'driver_license'.tr;
|
||||
default:
|
||||
return 'unknown_document'.tr;
|
||||
}
|
||||
}
|
||||
|
||||
DocumentType checkDocumentType(String text) {
|
||||
// Convert text to lowercase and remove all spaces and new lines
|
||||
text = text.toLowerCase().replaceAll(RegExp(r'\s+'), '');
|
||||
|
||||
// Keywords for each document type
|
||||
final Map<DocumentType, List<String>> keywords = {
|
||||
DocumentType.carLicenseBack: ['شاسيه', 'موتور', 'سم٣'],
|
||||
DocumentType.carLicenseFront: ['رخصةتسيير'],
|
||||
DocumentType.idCardFront: [
|
||||
'بطاقةتحقيقالشخصية',
|
||||
'بطاقة تحقيق الشخصية',
|
||||
'تحقيق'
|
||||
],
|
||||
DocumentType.idCardBack: ['البطاقةساريةحتى'],
|
||||
DocumentType.driverLicense: ['قيادةخاصة', 'خاصه', 'قيادة'],
|
||||
};
|
||||
|
||||
// Check each document type
|
||||
for (var entry in keywords.entries) {
|
||||
if (entry.value.any((keyword) => text.contains(keyword))) {
|
||||
return entry.key;
|
||||
}
|
||||
}
|
||||
|
||||
// If no match is found
|
||||
return DocumentType.unknown;
|
||||
}
|
||||
|
||||
List prompts = [];
|
||||
getPrompt() async {
|
||||
var res = await CRUD()
|
||||
.get(link: AppLink.getPromptDriverDocumentsEgypt, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
prompts = d;
|
||||
} else {}
|
||||
}
|
||||
|
||||
Future allMethodForAI(String prompt, imagePath, driverID) async {
|
||||
isLoading = true;
|
||||
update();
|
||||
await ImageController()
|
||||
.choosImage(AppLink.uploadEgypt, driverID, imagePath);
|
||||
|
||||
var extractedString = await CRUD().arabicTextExtractByVisionAndAI(
|
||||
imagePath: imagePath, driverID: driverID);
|
||||
var json = jsonDecode(extractedString);
|
||||
var textValues = extractTextFromLines(json);
|
||||
Log.print('textValues: ${textValues}');
|
||||
// await Get.put(AI()).geminiAiExtraction(prompt, textValues, imagePath);
|
||||
|
||||
DocumentType detectedType = checkDocumentType(textValues);
|
||||
String expectedDocument = getExpectedDocument(imagePath);
|
||||
String detectedDocument = getDetectedDocument(detectedType);
|
||||
|
||||
bool isCorrectDocument = (detectedType == getExpectedType(imagePath));
|
||||
if (!isCorrectDocument) {
|
||||
Get.defaultDialog(
|
||||
title: 'incorrect_document_title'.tr,
|
||||
middleText:
|
||||
'${'expected'.tr}: $expectedDocument\n${'detected'.tr}: $detectedDocument',
|
||||
confirm: MyElevatedButton(
|
||||
title: 'OK'.tr,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
}));
|
||||
} else {
|
||||
// Process the correct document
|
||||
await anthropicAI(textValues, prompt, imagePath);
|
||||
}
|
||||
isLoading = false;
|
||||
update();
|
||||
}
|
||||
|
||||
String extractTextFromLines(Map<String, dynamic> jsonData) {
|
||||
final readResult = jsonData['readResult'];
|
||||
final blocks = readResult['blocks'];
|
||||
|
||||
final StringBuffer buffer = StringBuffer();
|
||||
|
||||
for (final block in blocks) {
|
||||
final lines = block['lines'];
|
||||
for (final line in lines) {
|
||||
final text = line['text'];
|
||||
buffer.write(text);
|
||||
buffer.write('\n');
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toString().trim();
|
||||
}
|
||||
|
||||
List driverNotCompleteRegistration = [];
|
||||
getDriverNotCompleteRegistration() async {
|
||||
var res = await CRUD()
|
||||
.get(link: AppLink.getDriverNotCompleteRegistration, payload: {});
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
driverNotCompleteRegistration = d;
|
||||
update();
|
||||
} else {
|
||||
Get.snackbar(res, '');
|
||||
}
|
||||
}
|
||||
|
||||
final today = DateTime.now();
|
||||
|
||||
Future<void> addDriverAndCarEgypt() async {
|
||||
final expiryDate = responseIdEgyptDriverLicense['expiry_date'];
|
||||
final expiryDateTime = DateTime.tryParse(expiryDate);
|
||||
Log.print('expiryDateTime: ${expiryDateTime}');
|
||||
final isExpired = expiryDateTime != null && expiryDateTime.isBefore(today);
|
||||
|
||||
final taxExpiryDate = responseIdCardDriverEgyptBack['tax_expiry'];
|
||||
Log.print('taxExpiryDate: ${taxExpiryDate}');
|
||||
|
||||
// Get the inspection date from the response
|
||||
final inspectionDate = responseIdCardDriverEgyptBack['inspection_date'];
|
||||
final year = int.parse(inspectionDate.split('-')[0]);
|
||||
// Try parsing the tax expiry date. If it fails, set it to null.
|
||||
final taxExpiryDateTime = DateTime.tryParse(taxExpiryDate ?? '');
|
||||
Log.print('taxExpiryDateTime: ${taxExpiryDateTime}');
|
||||
final isExpiredCar =
|
||||
taxExpiryDateTime != null && taxExpiryDateTime.isBefore(today);
|
||||
|
||||
// Check if the inspection date is before today
|
||||
final inspectionDateTime = DateTime(year, 12, 31);
|
||||
final isInspectionExpired = inspectionDateTime.isBefore(today);
|
||||
|
||||
if (isExpiredCar || isInspectionExpired) {
|
||||
Get.defaultDialog(
|
||||
title: 'Expired Driver’s License'.tr,
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.warning, size: 48, color: Colors.red),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
"Your driver’s license and/or car tax has expired. Please renew them before proceeding."
|
||||
.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
// await Get.find<TextToSpeechController>().speakText(
|
||||
// 'Your driver’s license and/or car tax has expired. Please renew them before proceeding.'
|
||||
// .tr,
|
||||
// );
|
||||
},
|
||||
icon: const Icon(Icons.volume_up),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (isExpired) {
|
||||
Get.defaultDialog(
|
||||
title: 'Expired Driver’s License'.tr,
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.warning, size: 48, color: Colors.red),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
"Your driver’s license has expired. Please renew it before proceeding."
|
||||
.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
// await Get.find<TextToSpeechController>().speakText(
|
||||
// 'Your driver’s license has expired. Please renew it before proceeding.'
|
||||
// .tr,
|
||||
// );
|
||||
},
|
||||
icon: const Icon(Icons.volume_up),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (responseIdEgyptDriverLicense['national_number']
|
||||
.toString()
|
||||
.substring(0, 12) !=
|
||||
responseIdEgyptBack['nationalID'].toString().substring(0, 12)) {
|
||||
Get.defaultDialog(
|
||||
barrierDismissible: false,
|
||||
title: 'ID Mismatch',
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.warning, size: 48, color: Colors.red),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
"The national number on your driver’s license does not match the one on your ID document. Please verify and provide the correct documents."
|
||||
.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
// await Get.find<TextToSpeechController>().speakText(
|
||||
// 'The national number on your driver’s license does not match the one on your ID document. Please verify and provide the correct documents.',
|
||||
// );
|
||||
},
|
||||
icon: const Icon(Icons.volume_up),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
// else if (responseCriminalRecordEgypt['FullName'] !=
|
||||
// responseIdEgyptDriverLicense['name_arabic']) {
|
||||
// Get.defaultDialog(
|
||||
// barrierDismissible: false,
|
||||
// title: 'Criminal Record Mismatch',
|
||||
// content: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// const Icon(Icons.warning, size: 48, color: Colors.red),
|
||||
// const SizedBox(height: 16),
|
||||
// Text(
|
||||
// 'The full name on your criminal record does not match the one on your 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 addDriverEgypt();
|
||||
await addRegistrationCarEgypt();
|
||||
|
||||
if (isCarSaved && isDriverSaved) {
|
||||
Get.snackbar('added', '',
|
||||
backgroundColor:
|
||||
AppColor.greenColor); // Get.offAll(() => HomeCaptain());
|
||||
// Get.offAll(() => HomeCaptain());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String extractDOB(String nationalNumber) {
|
||||
if (nationalNumber.length != 14) {
|
||||
throw ArgumentError('National number must be 14 digits long.');
|
||||
}
|
||||
|
||||
// Extract the first digit to determine the century
|
||||
String firstDigit = nationalNumber[0];
|
||||
|
||||
// Extract year, month, and day parts
|
||||
String yearPart = nationalNumber.substring(1, 3);
|
||||
String monthPart = nationalNumber.substring(3, 5);
|
||||
String dayPart = nationalNumber.substring(5, 7);
|
||||
|
||||
// Determine the year based on the first digit
|
||||
int yearPrefix;
|
||||
if (firstDigit == '2') {
|
||||
yearPrefix = 1900;
|
||||
} else if (firstDigit == '3') {
|
||||
yearPrefix = 2000;
|
||||
} else {
|
||||
throw ArgumentError('Invalid first digit in national number.');
|
||||
}
|
||||
|
||||
// Construct the full year
|
||||
int year = yearPrefix + int.parse(yearPart);
|
||||
|
||||
// Format the date as YYYY-MM-DD
|
||||
String dob =
|
||||
'$year-${monthPart.padLeft(2, '0')}-${dayPart.padLeft(2, '0')}';
|
||||
|
||||
return dob;
|
||||
}
|
||||
|
||||
Future<void> addDriverEgypt() async {
|
||||
isLoading = true;
|
||||
update();
|
||||
|
||||
var payload = {
|
||||
'first_name': responseIdEgyptDriverLicense['firstName']?.toString() ??
|
||||
'Not specified',
|
||||
'last_name': responseIdEgyptDriverLicense['lastName']?.toString() ??
|
||||
'Not specified',
|
||||
'email': email?.toString() ?? 'Not specified',
|
||||
'phone': phone?.toString() ?? 'Not specified',
|
||||
'id': driverId?.toString() ?? 'Not specified',
|
||||
'password': '123456',
|
||||
'gender': responseIdEgyptBack['gender']?.toString() ?? 'Not specified',
|
||||
'license_type':
|
||||
responseIdEgyptDriverLicense['license_type']?.toString() ??
|
||||
'Not specified',
|
||||
'national_number':
|
||||
responseIdEgyptBack['nationalID']?.toString() ?? 'Not specified',
|
||||
'name_arabic': responseIdEgyptDriverLicense['name_arabic']?.toString() ??
|
||||
'Not specified',
|
||||
'name_english':
|
||||
responseIdEgyptDriverLicense['name_english']?.toString() ??
|
||||
'Not specified',
|
||||
'issue_date': responseIdEgyptDriverLicense['issue_date']?.toString() ??
|
||||
'Not specified',
|
||||
'expiry_date': responseIdEgyptDriverLicense['expiry_date']?.toString() ??
|
||||
'Not specified',
|
||||
'license_categories': responseIdEgyptDriverLicense['license_categories']
|
||||
is List
|
||||
? responseIdEgyptDriverLicense['license_categories'].join(', ')
|
||||
: responseIdEgyptDriverLicense['license_categories']?.toString() ??
|
||||
'Not specified',
|
||||
'address': responseIdEgyptFront['address']?.toString() ?? 'Not specified',
|
||||
'card_id': responseIdEgyptFront['card_id']?.toString() ?? 'Not specified',
|
||||
'occupation':
|
||||
responseIdEgyptBack['occupation']?.toString() ?? 'Not specified',
|
||||
'education':
|
||||
responseIdEgyptBack['occupation']?.toString() ?? 'Not specified',
|
||||
'licenseIssueDate':
|
||||
responseIdEgyptDriverLicense['issue_date']?.toString() ??
|
||||
'Not specified',
|
||||
'religion':
|
||||
responseIdEgyptBack['religion']?.toString() ?? 'Not specified',
|
||||
'status': 'yet',
|
||||
'birthdate': extractDOB(
|
||||
responseIdEgyptDriverLicense['national_number'].toString()),
|
||||
'maritalStatus':
|
||||
responseIdEgyptBack['maritalStatus']?.toString() ?? 'Not specified',
|
||||
'site': responseIdEgyptDriverLicense['address']?.toString() ??
|
||||
'Not specified',
|
||||
'employmentType':
|
||||
responseIdEgyptDriverLicense['employmentType']?.toString() ??
|
||||
'Not specified',
|
||||
};
|
||||
var res = await CRUD().post(link: AppLink.signUpCaptin, payload: payload);
|
||||
var status1 = jsonDecode(res);
|
||||
isLoading = false;
|
||||
update();
|
||||
// Handle response
|
||||
if (status1['status'] == 'success') {
|
||||
isDriverSaved = true;
|
||||
Get.snackbar('Success', 'Driver data saved successfully',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
} else {
|
||||
Get.snackbar('Error', 'Failed to save driver data',
|
||||
backgroundColor: Colors.red);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addDriverEgyptHanding() async {
|
||||
isLoading = true;
|
||||
update();
|
||||
|
||||
var payload = {
|
||||
'first_name': firstName.value.isNotEmpty
|
||||
? firstName.value
|
||||
: responseIdEgyptDriverLicense['firstName'],
|
||||
'last_name': lastName.value.isNotEmpty
|
||||
? lastName.value
|
||||
: responseIdEgyptDriverLicense['lastName'],
|
||||
'email': email?.toString() ?? 'Not specified',
|
||||
'phone': phone?.toString() ?? 'Not specified',
|
||||
'id': driverId?.toString() ?? 'Not specified',
|
||||
'password': '123456',
|
||||
'gender': gender.value.isNotEmpty
|
||||
? gender.value
|
||||
: responseIdEgyptBack['gender'],
|
||||
'license_type': licenseType.value.isNotEmpty
|
||||
? licenseType.value
|
||||
: responseIdEgyptDriverLicense['license_type'],
|
||||
'national_number': nationalNumber.value.isNotEmpty
|
||||
? nationalNumber.value
|
||||
: responseIdEgyptBack['nationalID'],
|
||||
'name_arabic': nameArabic.value.isNotEmpty
|
||||
? nameArabic.value
|
||||
: responseIdEgyptDriverLicense['name_arabic'],
|
||||
'name_english': nameEnglish.value.isNotEmpty
|
||||
? nameEnglish.value
|
||||
: responseIdEgyptDriverLicense['name_english'],
|
||||
'issue_date': issueDate.value.isNotEmpty
|
||||
? issueDate.value
|
||||
: responseIdEgyptDriverLicense['issue_date'],
|
||||
'expiry_date': expiryDate.value.isNotEmpty
|
||||
? expiryDate.value
|
||||
: responseIdEgyptDriverLicense['expiry_date'],
|
||||
'license_categories': licenseCategories.value.isNotEmpty
|
||||
? licenseCategories.value
|
||||
: responseIdEgyptDriverLicense['license_categories'] is List
|
||||
? responseIdEgyptDriverLicense['license_categories'].join(', ')
|
||||
: responseIdEgyptDriverLicense['license_categories'],
|
||||
'address': address.value.isNotEmpty
|
||||
? address.value
|
||||
: responseIdEgyptFront['address'],
|
||||
'card_id': cardId.value.isNotEmpty
|
||||
? cardId.value
|
||||
: responseIdEgyptFront['card_id'],
|
||||
'occupation': occupation.value.isNotEmpty
|
||||
? occupation.value
|
||||
: responseIdEgyptBack['occupation'],
|
||||
'education': education.value.isNotEmpty
|
||||
? education.value
|
||||
: responseIdEgyptDriverLicense['issue_date'],
|
||||
'licenseIssueDate': licenseIssueDate.value.isNotEmpty
|
||||
? licenseIssueDate.value
|
||||
: responseIdEgyptBack['religion'],
|
||||
'religion': religion.value.isNotEmpty ? religion.value : 'Not specified',
|
||||
'status': status.value.isNotEmpty ? status.value : 'yet',
|
||||
'birthdate': birthdate.value.isNotEmpty
|
||||
? birthdate.value
|
||||
: extractDOB(
|
||||
responseIdEgyptDriverLicense['national_number'].toString()),
|
||||
'maritalStatus': maritalStatus.value.isNotEmpty
|
||||
? maritalStatus.value
|
||||
: responseIdEgyptBack['maritalStatus'],
|
||||
'site': site.value.isNotEmpty
|
||||
? site.value
|
||||
: responseIdEgyptDriverLicense['address'],
|
||||
'employmentType': employmentType.value.isNotEmpty
|
||||
? employmentType.value
|
||||
: responseIdEgyptDriverLicense['employmentType'],
|
||||
};
|
||||
|
||||
var res = await CRUD().post(link: AppLink.signUpCaptin, payload: payload);
|
||||
var status1 = jsonDecode(res);
|
||||
isLoading = false;
|
||||
update();
|
||||
|
||||
// Handle response
|
||||
if (status1['status'] == 'success') {
|
||||
isDriverSaved = true;
|
||||
Get.snackbar('Success', 'Driver data saved successfully',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
} else {
|
||||
Get.snackbar('Error', 'Failed to save driver data',
|
||||
backgroundColor: Colors.red);
|
||||
}
|
||||
}
|
||||
|
||||
addCriminalDeocuments() async {
|
||||
var res = await CRUD().post(link: AppLink.addCriminalDocuments, payload: {
|
||||
"driverId": box.read(BoxName.driverID),
|
||||
"IssueDate": responseCriminalRecordEgypt['IssueDate'],
|
||||
"InspectionResult": responseCriminalRecordEgypt['InspectionResult'],
|
||||
});
|
||||
if (res != 'failure') {
|
||||
Get.snackbar('uploaded sucssefuly'.tr, '');
|
||||
}
|
||||
}
|
||||
|
||||
var firstName = ''.obs;
|
||||
var lastName = ''.obs;
|
||||
var id = ''.obs;
|
||||
var password = '123456'.obs;
|
||||
var gender = ''.obs;
|
||||
var licenseType = ''.obs;
|
||||
var nationalNumber = ''.obs;
|
||||
var nameArabic = ''.obs;
|
||||
var nameEnglish = ''.obs;
|
||||
var issueDate = ''.obs;
|
||||
var expiryDate = ''.obs;
|
||||
var licenseCategories = ''.obs;
|
||||
var address = ''.obs;
|
||||
var cardId = ''.obs;
|
||||
var occupation = ''.obs;
|
||||
var education = ''.obs;
|
||||
var licenseIssueDate = ''.obs;
|
||||
var religion = ''.obs;
|
||||
var status = 'yet'.obs;
|
||||
var birthdate = ''.obs;
|
||||
var maritalStatus = ''.obs;
|
||||
var site = ''.obs;
|
||||
var employmentType = ''.obs;
|
||||
var vin = ''.obs;
|
||||
var carPlate = ''.obs;
|
||||
var make = ''.obs;
|
||||
var model = ''.obs;
|
||||
var year = ''.obs;
|
||||
var expirationDate = ''.obs;
|
||||
var color = ''.obs;
|
||||
var owner = ''.obs;
|
||||
var colorHex = ''.obs;
|
||||
var addressCar = ''.obs;
|
||||
var displacement = ''.obs;
|
||||
var fuel = ''.obs;
|
||||
var registrationDate = ''.obs;
|
||||
|
||||
Future addRegistrationCarEgypt() async {
|
||||
try {
|
||||
final inspectionDate =
|
||||
responseIdCardDriverEgyptBack['inspection_date'].toString();
|
||||
final year = int.parse(inspectionDate.split('-')[0]);
|
||||
final inspectionDateTime = DateTime(year, 12, 31);
|
||||
isLoading = true;
|
||||
update();
|
||||
var res = await CRUD().post(link: AppLink.addRegisrationCar, payload: {
|
||||
'driverID': driverId,
|
||||
'vin': responseIdCardDriverEgyptBack['chassis'].toString(),
|
||||
'car_plate': responseIdCardDriverEgyptFront['car_plate'].toString(),
|
||||
'make': responseIdCardDriverEgyptBack['make'].toString(),
|
||||
'model': responseIdCardDriverEgyptBack['model'],
|
||||
'year': responseIdCardDriverEgyptBack['year'].toString(),
|
||||
'expiration_date':
|
||||
responseIdCardDriverEgyptFront['LicenseExpirationDate'].toString(),
|
||||
'color': responseIdCardDriverEgyptBack['color'],
|
||||
'owner': responseIdCardDriverEgyptFront['owner'],
|
||||
'color_hex': responseIdCardDriverEgyptBack['color_hex'].toString(),
|
||||
'address': responseIdCardDriverEgyptFront['address'].toString(),
|
||||
'displacement': responseIdCardDriverEgyptBack['engine'].toString(),
|
||||
'fuel': responseIdCardDriverEgyptBack['fuel'].toString(),
|
||||
'registration_date': '$inspectionDateTime',
|
||||
});
|
||||
isLoading = false;
|
||||
update();
|
||||
var status = jsonDecode(res);
|
||||
if (status['status'] == 'success') {
|
||||
isCarSaved = true;
|
||||
Get.snackbar('Success', 'message',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
Future<void> addRegistrationCarEgyptHandling() async {
|
||||
try {
|
||||
final inspectionDate =
|
||||
responseIdCardDriverEgyptBack['inspection_date']?.toString() ?? '';
|
||||
final year = inspectionDate.isNotEmpty
|
||||
? int.parse(inspectionDate.split('-')[0])
|
||||
: DateTime.now().year;
|
||||
final inspectionDateTime = DateTime(year, 12, 31);
|
||||
Log.print('inspectionDateTime: $inspectionDateTime');
|
||||
|
||||
isLoading = true;
|
||||
update();
|
||||
|
||||
var payload = {
|
||||
'driverID': driverId,
|
||||
'vin': vin.value.isNotEmpty
|
||||
? vin.value
|
||||
: responseIdCardDriverEgyptBack['chassis']?.toString() ?? '',
|
||||
'car_plate': carPlate.value.isNotEmpty
|
||||
? carPlate.value
|
||||
: responseIdCardDriverEgyptFront['car_plate']?.toString() ?? '',
|
||||
'make': make.value.isNotEmpty
|
||||
? make.value
|
||||
: responseIdCardDriverEgyptBack['make']?.toString() ?? '',
|
||||
'model': model.value.isNotEmpty
|
||||
? model.value
|
||||
: responseIdCardDriverEgyptBack['model']?.toString() ?? '',
|
||||
'year': year.toString(),
|
||||
'expiration_date': expirationDate.value.isNotEmpty
|
||||
? expirationDate.value
|
||||
: responseIdCardDriverEgyptFront['LicenseExpirationDate']
|
||||
?.toString() ??
|
||||
'',
|
||||
'color': color.value.isNotEmpty
|
||||
? color.value
|
||||
: responseIdCardDriverEgyptFront['color']?.toString() ?? '',
|
||||
'owner': owner.value.isNotEmpty
|
||||
? owner.value
|
||||
: responseIdCardDriverEgyptFront['owner']?.toString() ?? '',
|
||||
'color_hex': getColorHex(color.value),
|
||||
'address': addressCar.value.isNotEmpty
|
||||
? addressCar.value
|
||||
: responseIdCardDriverEgyptFront['address']?.toString() ?? '',
|
||||
'displacement': displacement.value.isNotEmpty
|
||||
? displacement.value
|
||||
: responseIdCardDriverEgyptBack['engine']?.toString() ?? '',
|
||||
'fuel': fuel.value.isNotEmpty
|
||||
? fuel.value
|
||||
: responseIdCardDriverEgyptBack['fuel']?.toString() ?? '',
|
||||
'registration_date': inspectionDateTime.toIso8601String(),
|
||||
};
|
||||
|
||||
Log.print('Payload: $payload');
|
||||
|
||||
var res =
|
||||
await CRUD().post(link: AppLink.addRegisrationCar, payload: payload);
|
||||
|
||||
isLoading = false;
|
||||
update();
|
||||
|
||||
var status = jsonDecode(res);
|
||||
Log.print('res: $res');
|
||||
Log.print('status: $status');
|
||||
|
||||
if (status['status'] == 'success') {
|
||||
isCarSaved = true;
|
||||
Get.snackbar('Success', 'Registration successful',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
Get.back();
|
||||
} else {
|
||||
Log.print('Error: Unexpected status: ${status['status']}');
|
||||
Get.snackbar('Error', 'Registration failed',
|
||||
backgroundColor: Colors.red);
|
||||
}
|
||||
} catch (e) {
|
||||
Log.print('Error: $e');
|
||||
Get.snackbar('Error', 'An error occurred during registration',
|
||||
backgroundColor: Colors.red);
|
||||
}
|
||||
}
|
||||
|
||||
String getColorHex(String colorName) {
|
||||
Map<String, String> colorMap = {
|
||||
'red'.tr: '#FF0000',
|
||||
'green'.tr: '#008000',
|
||||
'blue'.tr: '#0000FF',
|
||||
'black'.tr: '#000000',
|
||||
'white'.tr: '#FFFFFF',
|
||||
'yellow'.tr: '#FFFF00',
|
||||
'purple'.tr: '#800080',
|
||||
'orange'.tr: '#FFA500',
|
||||
'pink'.tr: '#FFC0CB',
|
||||
'brown'.tr: '#A52A2A',
|
||||
'gray'.tr: '#808080',
|
||||
'cyan'.tr: '#00FFFF',
|
||||
'magenta'.tr: '#FF00FF',
|
||||
'lime'.tr: '#00FF00',
|
||||
'indigo'.tr: '#4B0082',
|
||||
'violet'.tr: '#EE82EE',
|
||||
'gold'.tr: '#FFD700',
|
||||
'silver'.tr: '#C0C0C0',
|
||||
'teal'.tr: '#008080',
|
||||
'navy'.tr: '#000080',
|
||||
'Eggplant'.tr: '#800000', // Eggplant
|
||||
'Dark Red'.tr: '#8B0000', // Dark Red (Maroon)
|
||||
'Sky Blue'.tr: '#87CEEB', // Sky Blue
|
||||
'Mocha'.tr: '#C3B091', // Mocha
|
||||
};
|
||||
|
||||
return colorMap[colorName.toLowerCase()] ??
|
||||
'#000000'; // Default to black if color name is not found
|
||||
}
|
||||
|
||||
Future getComplaintDataToAI() async {
|
||||
var res = await CRUD().get(
|
||||
link: AppLink.getComplaintAllDataForDriver,
|
||||
payload: {'driver_id': driverId.toString()},
|
||||
);
|
||||
if (res != 'failure') {
|
||||
var d = jsonDecode(res)['message'];
|
||||
return d;
|
||||
} else {
|
||||
return [
|
||||
{'data': 'no data'}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> anthropicAIForComplaint() async {
|
||||
var dataComplaint = await getComplaintDataToAI();
|
||||
var messagesData = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "$dataComplaint ${AppInformation.complaintPrompt} "
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
var requestBody = jsonEncode({
|
||||
"model": "claude-3-haiku-20240307",
|
||||
"max_tokens": 1024,
|
||||
"temperature": 0,
|
||||
"system": "Json output only without any additional ",
|
||||
"messages": messagesData,
|
||||
});
|
||||
final response = await http.post(
|
||||
Uri.parse('https://api.anthropic.com/v1/messages'),
|
||||
headers: {
|
||||
'x-api-key': AK.anthropicAIkeySeferNew,
|
||||
'anthropic-version': '2023-06-01',
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: requestBody,
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
var responseData = jsonDecode(utf8.decode(response.bodyBytes));
|
||||
// Process the responseData as needed
|
||||
|
||||
responseForComplaint = jsonDecode(responseData['content'][0]['text']);
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> anthropicAI(
|
||||
String payload, String prompt, String idType) async {
|
||||
var messagesData = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "$payload $prompt"}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
var requestBody = jsonEncode({
|
||||
"model": "claude-3-haiku-20240307",
|
||||
"max_tokens": 1024,
|
||||
"temperature": 0,
|
||||
"system": "Json output only without any additional ",
|
||||
"messages": messagesData,
|
||||
});
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse('https://api.anthropic.com/v1/messages'),
|
||||
headers: {
|
||||
'x-api-key': AK.anthropicAIkeySeferNew,
|
||||
'anthropic-version': '2023-06-01',
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: requestBody,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
var responseData = jsonDecode(utf8.decode(response.bodyBytes));
|
||||
// Process the responseData as needed
|
||||
if (idType == 'car_back') {
|
||||
responseIdCardDriverEgyptBack =
|
||||
jsonDecode(responseData['content'][0]['text']);
|
||||
} else if (idType == 'car_front') {
|
||||
responseIdCardDriverEgyptFront =
|
||||
jsonDecode(responseData['content'][0]['text']);
|
||||
} else if (idType == 'id_front') {
|
||||
responseIdEgyptFront = jsonDecode(responseData['content'][0]['text']);
|
||||
} else if (idType == 'id_back') {
|
||||
responseIdEgyptBack = jsonDecode(responseData['content'][0]['text']);
|
||||
} else if (idType == 'driver_license') {
|
||||
responseIdEgyptDriverLicense =
|
||||
jsonDecode(responseData['content'][0]['text']);
|
||||
} else if (idType == 'criminalRecord') {
|
||||
responseCriminalRecordEgypt =
|
||||
jsonDecode(responseData['content'][0]['text']);
|
||||
}
|
||||
|
||||
update();
|
||||
return responseData.toString();
|
||||
}
|
||||
return responseIdCardDriverEgyptBack.toString();
|
||||
}
|
||||
|
||||
Future<void> geminiAiExtraction(String prompt, payload, String idType) async {
|
||||
var requestBody = jsonEncode({
|
||||
"contents": [
|
||||
{
|
||||
"parts": [
|
||||
{"text": "$payload $prompt"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"generationConfig": {
|
||||
"temperature": 1,
|
||||
"topK": 64,
|
||||
"topP": 0.95,
|
||||
"maxOutputTokens": 8192,
|
||||
"stopSequences": []
|
||||
},
|
||||
"safetySettings": [
|
||||
{
|
||||
"category": "HARM_CATEGORY_HARASSMENT",
|
||||
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
||||
},
|
||||
{
|
||||
"category": "HARM_CATEGORY_HATE_SPEECH",
|
||||
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
||||
},
|
||||
{
|
||||
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
||||
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
||||
},
|
||||
{
|
||||
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
||||
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
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=${AK.geminiApi}'),
|
||||
// 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro:generateContent?key=${AK.geminiApi}'),
|
||||
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));
|
||||
|
||||
if (idType == 'car_back') {
|
||||
responseIdCardDriverEgyptBack = jsonDecode(jsonString);
|
||||
} else if (idType == 'car_front') {
|
||||
responseIdCardDriverEgyptFront = jsonDecode(jsonString);
|
||||
} else if (idType == 'id_front') {
|
||||
responseIdEgyptFront = jsonDecode(jsonString);
|
||||
} else if (idType == 'id_back') {
|
||||
responseIdEgyptBack = jsonDecode(jsonString);
|
||||
} else if (idType == 'driver_license') {
|
||||
responseIdEgyptDriverLicense = jsonDecode(jsonString);
|
||||
}
|
||||
|
||||
update();
|
||||
} else {
|
||||
Get.snackbar('Error', "JSON string not found",
|
||||
backgroundColor: AppColor.redColor);
|
||||
}
|
||||
|
||||
// Rest of your code...
|
||||
} else {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user