This commit is contained in:
Hamza-Ayed
2024-08-11 10:59:50 +03:00
parent 1c6748133d
commit 2468e6466f
205 changed files with 28509 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
import 'dart:convert';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../constant/links.dart';
import '../../constant/style.dart';
import '../../main.dart';
class FirebaseMessagesController extends GetxController {
final fcmToken = FirebaseMessaging.instance;
List<String> tokens = [];
List dataTokens = [];
late String driverID;
late String driverToken;
NotificationSettings? notificationSettings;
Future<void> getNotificationSettings() async {
// Get the current notification settings
NotificationSettings? notificationSettings =
await FirebaseMessaging.instance.getNotificationSettings();
'Notification authorization status: ${notificationSettings.authorizationStatus}';
// Call the update function if needed
update();
}
Future<void> requestFirebaseMessagingPermission() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
// Check if the platform is Android
if (Platform.isAndroid) {
// Request permission for Android
await messaging.requestPermission();
} else if (Platform.isIOS) {
// Request permission for iOS
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: true,
criticalAlert: true,
provisional: false,
sound: true,
);
messaging.setForegroundNotificationPresentationOptions(
alert: true, badge: true, sound: true);
}
}
Future getTokens() async {
String? basicAuthCredentials =
await storage.read(key: BoxName.basicAuthCredentials);
var res = await http.post(
Uri.parse(AppLink.getTokens),
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
body: {},
);
var jsonResponse = jsonDecode(res.body);
if (jsonResponse['status'] == 'success') {
dataTokens = jsonResponse['data'];
for (var i = 0; i < dataTokens.length; i++) {
tokens.add(jsonResponse['data'][i]['token']);
}
box.write(BoxName.tokens, tokens);
} else {
Get.defaultDialog(title: "Warning", middleText: "Server Error");
}
}
Future getToken() async {
fcmToken.getToken().then((token) {
box.write(BoxName.tokenFCM, token);
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// If the app is in the background or terminated, show a system tray message
RemoteNotification? notification = message.notification;
AndroidNotification? android = notification?.android;
// if (notification != null && android != null) {
if (message.data.isNotEmpty && message.notification != null) {
fireBaseTitles(message);
}
});
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {
// Handle background message
if (message.data.isNotEmpty && message.notification != null) {
fireBaseTitles(message);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message.data.isNotEmpty && message.notification != null) {
fireBaseTitles(message);
}
});
}
void fireBaseTitles(RemoteMessage message) {
if (message.notification!.title! == 'Order'.tr) {
} else if (message.notification!.title! == 'Apply Ride'.tr) {
var passengerList = message.data['passengerList'];
var myList = jsonDecode(passengerList) as List<dynamic>;
driverID = myList[0].toString();
}
}
}

View File

@@ -0,0 +1,216 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../main.dart';
import '../../print.dart';
class CRUD {
Future<dynamic> get({
required String link,
Map<String, dynamic>? payload,
}) async {
var url = Uri.parse(
link,
);
var response = await http.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
},
);
Log.print('response: ${response.body}');
Log.print('response: ${response.request}');
Log.print('payload: $payload');
// if (response.statusCode == 200) {
var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') {
return response.body;
}
return jsonData['status'];
}
// }
Future<dynamic> arabicTextExtractByVisionAndAI({
required String imagePath,
required String driverID,
}) async {
var headers = {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': AK.ocpApimSubscriptionKey
};
String imagePathFull =
'${AppLink.server}/card_image/$imagePath-$driverID.jpg';
Log.print('imagePathFull: $imagePathFull');
var request = http.Request(
'POST',
Uri.parse(
'https://eastus.api.cognitive.microsoft.com/computervision/imageanalysis:analyze?features=caption,read&model-version=latest&language=en&api-version=2024-02-01'));
request.body = json.encode({"url": imagePathFull});
Log.print('request.body: ${request.body}');
request.headers.addAll(headers);
Log.print('request.headers: ${request.headers}');
http.StreamedResponse response = await request.send();
Log.print('response: ${response}');
if (response.statusCode == 200) {
return await response.stream.bytesToString();
} else {}
}
Future<dynamic> getAgoraToken({
required String channelName,
required String uid,
}) async {
var uid = box.read(BoxName.phone) ?? box.read(BoxName.phoneDriver);
var res = await http.get(Uri.parse(
// 'https://repulsive-pig-rugby-shirt.cyclic.app/token?channelName=$channelName'),
'https://orca-app-b2i85.ondigitalocean.app/token?channelName=$channelName'),
// headers: {'Authorization': 'Bearer ${AK.agoraAppCertificate}'});
headers: {'Authorization': 'Bearer '});
if (res.statusCode == 200) {
var response = jsonDecode(res.body);
return response['token'];
} else {}
}
Future<dynamic> getLlama({
required String link,
required String payload,
required String prompt,
}) async {
var url = Uri.parse(
link,
);
var headers = {
'Content-Type': 'application/json',
'Authorization':
'Bearer LL-X5lJ0Px9CzKK0HTuVZ3u2u4v3tGWkImLTG7okGRk4t25zrsLqJ0qNoUzZ2x4ciPy'
// 'Authorization': 'Bearer ${Env.llamaKey}'
};
var data = json.encode({
"model": "Llama-3-70b-Inst-FW",
// "model": "llama-13b-chat",
"messages": [
{
"role": "user",
"content":
"Extract the desired information from the following passage as json decoded like $prompt just in this:\n\n$payload"
}
],
"temperature": 0.9
});
var response = await http.post(
url,
body: data,
headers: headers,
);
if (response.statusCode == 200) {
return response.body;
}
return response.statusCode;
}
Future<dynamic> post({
required String link,
Map<String, dynamic>? payload,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse(
link,
);
var response = await http.post(
url,
body: payload,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
);
print(response.request);
print(response.body);
// print(response.statusCode);
var jsonData = jsonDecode(response.body);
if (response.statusCode == 200) {
if (jsonData['status'] == 'success') {
return response.body;
} else {
String errorMessage = jsonData['message'];
// Get.snackbar('Error'.tr, errorMessage.tr,
// backgroundColor: AppColor.redColor);
return (jsonData['status']);
}
} else {
return response.statusCode;
}
}
sendEmail(
String link,
Map<String, String>? payload,
) async {
var headers = {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
};
var request = http.Request('POST', Uri.parse(link));
request.bodyFields = payload!;
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
} else {}
}
Future<dynamic> update({
required String endpoint,
required Map<String, dynamic> data,
required String id,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse('$endpoint/$id');
var response = await http.put(
url,
body: json.encode(data),
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
);
return json.decode(response.body);
}
Future<dynamic> delete({
required String endpoint,
required String id,
}) async {
// String? basicAuthCredentials =
// await storage.read(key: BoxName.basicAuthCredentials);
var url = Uri.parse('$endpoint/$id');
var response = await http.delete(
url,
headers: {
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
},
);
return json.decode(response.body);
}
extractTextFromLines(json) {}
}

View File

@@ -0,0 +1,335 @@
import 'dart:convert';
import 'dart:io';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:image/image.dart' as img;
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../main.dart';
class ImageController extends GetxController {
File? myImage;
bool isloading = false;
CroppedFile? croppedFile;
final picker = ImagePicker();
var image;
Future<img.Image> detectAndCropDocument(File imageFile) async {
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) throw Exception('Unable to decode image');
int left = image.width, top = image.height, right = 0, bottom = 0;
// Threshold for considering a pixel as part of the document (adjust as needed)
const int threshold = 240;
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
final pixel = image.getPixel(x, y);
final luminance = img.getLuminance(pixel);
if (luminance < threshold) {
left = x < left ? x : left;
top = y < top ? y : top;
right = x > right ? x : right;
bottom = y > bottom ? y : bottom;
}
}
}
// Add a small padding
left = (left - 5).clamp(0, image.width);
top = (top - 5).clamp(0, image.height);
right = (right + 5).clamp(0, image.width);
bottom = (bottom + 5).clamp(0, image.height);
return img.copyCrop(image,
x: left, y: top, width: right - left, height: bottom - top);
}
Future<File> rotateImageIfNeeded(File imageFile) async {
img.Image croppedDoc = await detectAndCropDocument(imageFile);
// Check if the document is in portrait orientation
bool isPortrait = croppedDoc.height > croppedDoc.width;
img.Image processedImage;
if (isPortrait) {
// Rotate the image by 90 degrees clockwise
processedImage = img.copyRotate(croppedDoc, angle: 90);
} else {
processedImage = croppedDoc;
}
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the processed image file
File processedFile = File('$tempPath/processed_image.jpg');
await processedFile.writeAsBytes(img.encodeJpg(processedImage));
return processedFile;
}
Future<File> rotateImage(File imageFile) async {
// Read the image file
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) return imageFile;
// Rotate the image by 90 degrees clockwise
img.Image rotatedImage = img.copyRotate(image, angle: 90);
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the rotated image file
File rotatedFile = File('$tempPath/rotated_image.jpg');
await rotatedFile.writeAsBytes(img.encodeJpg(rotatedImage));
return rotatedFile;
}
choosImage(String link, String driverId, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
);
if (pickedImage == null) return;
image = File(pickedImage.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
if (croppedFile == null) return;
myImage = File(croppedFile!.path);
isloading = true;
update();
// Rotate the compressed image
// File rotatedImage = await rotateImage(compressedImage);
File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
File compressedImage = await compressImage(processedImage);
print('link =$link');
try {
await uploadImage(
compressedImage,
{'driverID': driverId, 'imageType': imageType},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
choosFace(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.front,
);
if (pickedImage != null) {
image = File(pickedImage.path);
isloading = true;
update();
// Compress the image
File compressedImage = await compressImage(File(pickedImage.path));
// Save the picked image directly
// File savedImage = File(pickedImage.path);
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
}
uploadImage(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
var multipartFile = http.MultipartFile(
'image',
stream,
length,
filename: basename(file.path),
);
request.headers.addAll({
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
choosImagePicture(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
// preferredCameraDevice: CameraDevice.rear,
// maxHeight: Get.height * .3,
// maxWidth: Get.width * .9,
// imageQuality: 100,
);
image = File(pickedImage!.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
myImage = File(pickedImage.path);
isloading = true;
update();
// Save the cropped image
// File savedCroppedImage = File(croppedFile!.path);
File compressedImage = await compressImage(File(croppedFile!.path));
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
uploadImagePicture(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
var multipartFile = http.MultipartFile(
'image',
stream,
length,
filename: basename(file.path),
);
request.headers.addAll({
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
}
Future<File> compressImage(File file) async {
final dir = await path_provider.getTemporaryDirectory();
final targetPath = "${dir.absolute.path}/temp.jpg";
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path,
targetPath,
quality: 70,
minWidth: 1024,
minHeight: 1024,
);
return File(result!.path);
}

View File

@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/box_name.dart';
import '../../main.dart';
import '../themes/themes.dart';
class LocaleController extends GetxController {
Locale? language;
String countryCode = '';
void restartApp() {
runApp(MyApp());
}
ThemeData appTheme = themeEnglish;
changeLang(String langcode) {
Locale locale;
switch (langcode) {
case "ar":
locale = const Locale("ar");
appTheme = themeArabic;
box.write(BoxName.lang, 'ar');
break;
case "en":
locale = const Locale("en");
appTheme = themeEnglish;
box.write(BoxName.lang, 'en');
break;
case "tr":
locale = const Locale("tr");
appTheme = themeEnglish;
box.write(BoxName.lang, 'tr');
break;
case "fr":
locale = const Locale("fr");
appTheme = themeEnglish;
box.write(BoxName.lang, 'fr');
break;
case "it":
locale = const Locale("it");
appTheme = themeEnglish;
box.write(BoxName.lang, 'it');
break;
case "de":
locale = const Locale("de");
appTheme = themeEnglish;
box.write(BoxName.lang, 'de');
break;
case "el":
locale = const Locale("el");
appTheme = themeEnglish;
box.write(BoxName.lang, 'el');
break;
case "es":
locale = const Locale("es");
appTheme = themeEnglish;
box.write(BoxName.lang, 'es');
break;
case "fa":
locale = const Locale("fa");
appTheme = themeEnglish;
box.write(BoxName.lang, 'fa');
break;
case "zh":
locale = const Locale("zh");
appTheme = themeEnglish;
box.write(BoxName.lang, 'zh');
break;
case "ru":
locale = const Locale("ru");
appTheme = themeEnglish;
box.write(BoxName.lang, 'ru');
break;
case "hi":
locale = const Locale("hi");
appTheme = themeEnglish;
box.write(BoxName.lang, 'hi');
break;
default:
locale = Locale(Get.deviceLocale!.languageCode);
box.write(BoxName.lang, Get.deviceLocale!.languageCode);
appTheme = themeEnglish;
break;
}
box.write(BoxName.lang, langcode);
// box.write(BoxName.lang, langcode);
Get.changeTheme(appTheme);
Get.updateLocale(locale);
restartApp();
update();
}
@override
void onInit() {
String storedLang = box.read(BoxName.lang) ?? "";
switch (storedLang) {
case "ar":
language = const Locale("ar");
appTheme = themeArabic;
break;
case "en":
language = const Locale("en");
appTheme = themeEnglish;
break;
case "tr":
language = const Locale("tr");
appTheme = themeEnglish;
break;
case "fr":
language = const Locale("fr");
appTheme = themeEnglish;
break;
case "it":
language = const Locale("it");
appTheme = themeEnglish;
break;
case "de":
language = const Locale("de");
appTheme = themeEnglish;
break;
case "el":
language = const Locale("el");
appTheme = themeEnglish;
break;
case "es":
language = const Locale("es");
appTheme = themeEnglish;
break;
case "fa":
language = const Locale("fa");
appTheme = themeArabic;
break;
case "zh":
language = const Locale("zh");
appTheme = themeEnglish;
break;
case "ru":
language = const Locale("ru");
appTheme = themeEnglish;
break;
case "hi":
language = const Locale("hi");
appTheme = themeEnglish;
break;
default:
language = Locale(Get.deviceLocale!.languageCode);
// language = Locale(Get.deviceLocale!.languageCode);
appTheme = themeEnglish;
break;
}
super.onInit();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:service/constant/api_key.dart';
import 'package:service/constant/box_name.dart';
import 'package:service/constant/links.dart';
import 'package:service/controller/functions/crud.dart';
import 'package:service/main.dart';
import '../views/home/main.dart';
class LoginController extends GetxController {
var email = TextEditingController();
var password = TextEditingController();
final formKey = GlobalKey<FormState>();
void login() async {
if (box.read(BoxName.email) == AK.emailService) {
Get.off(Main());
} else {
if (formKey.currentState!.validate()) {
var res = await CRUD().get(link: AppLink.login, payload: {
"email": email.text,
"password": password.text,
});
if (res != 'failure') {
var d = jsonDecode(res);
if (d['message'] == "Login successful") {
box.write(BoxName.email, email.text);
Get.off(() => Main());
}
}
}
}
}
}

View 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();
}
}
}

View 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: []);
}
}

View 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)),
);
}
}

View 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');
},
),
],
),
),
);
},
),
),
],
);
}),
],
);
}
}

View 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,
),
),
],
))
],
)),
);
}),
),
],
);
});
}
}

View File

@@ -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');
},
),
],
),
);
},
);
}),
],
);
}
}

View 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),
],
),
);
}
}

File diff suppressed because it is too large Load Diff

View 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,
);
}
}

View File

@@ -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 Drivers License'.tr,
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
"Your drivers license and/or car tax has expired. Please renew them before proceeding."
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
// await Get.find<TextToSpeechController>().speakText(
// 'Your drivers license and/or car tax has expired. Please renew them before proceeding.'
// .tr,
// );
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
} else if (isExpired) {
Get.defaultDialog(
title: 'Expired Drivers License'.tr,
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.warning, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text(
"Your drivers license has expired. Please renew it before proceeding."
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
// await Get.find<TextToSpeechController>().speakText(
// 'Your drivers license has expired. Please renew it before proceeding.'
// .tr,
// );
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
} else if (responseIdEgyptDriverLicense['national_number']
.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 drivers license does not match the one on your ID document. Please verify and provide the correct documents."
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
const SizedBox(height: 16),
IconButton(
onPressed: () async {
// await Get.find<TextToSpeechController>().speakText(
// 'The national number on your drivers license does not match the one on your ID document. Please verify and provide the correct documents.',
// );
},
icon: const Icon(Icons.volume_up),
),
],
),
actions: [
TextButton(
onPressed: () {
Get.back();
},
child: const Text('OK'),
),
],
);
}
// else if (responseCriminalRecordEgypt['FullName'] !=
// responseIdEgyptDriverLicense['name_arabic']) {
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'Criminal Record Mismatch',
// content: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// const Icon(Icons.warning, size: 48, color: Colors.red),
// const SizedBox(height: 16),
// Text(
// 'The full name on your criminal record does not match the one on your drivers license. Please verify and provide the correct documents.'
// .tr,
// textAlign: TextAlign.center,
// style: AppStyle.title,
// ),
// const SizedBox(height: 16),
// IconButton(
// onPressed: () async {
// await Get.find<TextToSpeechController>().speakText(
// 'The full name on your criminal record does not match the one on your drivers license. Please verify and provide the correct documents.'
// .tr,
// );
// },
// icon: const Icon(Icons.volume_up),
// ),
// ],
// ),
// actions: [
// TextButton(
// onPressed: () {
// Get.back();
// },
// child: const Text('OK'),
// ),
// ],
// );
// }
else {
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 {}
}
}

View File

@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import '../../constant/colors.dart';
import '../../constant/style.dart';
ThemeData themeEnglish = ThemeData(
fontFamily: "PlayfairDisplay",
textTheme: TextTheme(
displaySmall: AppStyle.title,
displayLarge: AppStyle.title,
displayMedium: AppStyle.title,
bodyLarge: AppStyle.title,
bodyMedium: AppStyle.title),
primarySwatch: Colors.blue,
dialogTheme: DialogTheme(
backgroundColor: AppColor.secondaryColor,
contentTextStyle: AppStyle.title,
titleTextStyle: AppStyle.title,
),
appBarTheme: AppBarTheme(
elevation: 0,
color: AppColor.secondaryColor,
centerTitle: true,
iconTheme: const IconThemeData(
color: AppColor.primaryColor,
),
toolbarTextStyle: TextTheme(
titleSmall: AppStyle.subtitle,
headlineSmall: AppStyle.title,
titleLarge: AppStyle.headTitle2)
.bodyMedium,
titleTextStyle: TextTheme(
titleSmall: AppStyle.subtitle,
headlineSmall: AppStyle.title,
titleLarge: AppStyle.headTitle2)
.titleLarge,
),
);
ThemeData themeArabic = ThemeData(
fontFamily: "Cairo",
textTheme: const TextTheme(
displayLarge: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: AppColor.primaryColor),
displayMedium: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 26,
color: AppColor.primaryColor),
bodyLarge: TextStyle(
height: 2,
color: AppColor.accentColor,
fontWeight: FontWeight.bold,
fontSize: 14),
bodyMedium:
TextStyle(height: 2, color: AppColor.accentColor, fontSize: 14)),
primarySwatch: Colors.blue,
);