8/11/1
This commit is contained in:
19
lib/constant/api_key.dart
Normal file
19
lib/constant/api_key.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:secure_string_operations/secure_string_operations.dart';
|
||||
|
||||
import '../env/env.dart';
|
||||
import 'char_map.dart';
|
||||
|
||||
class AK {
|
||||
static final String basicAuthCredentials =
|
||||
X.r(X.r(X.r(Env.basicAuthCredentials, cn), cC), cs);
|
||||
static final String visionApi = X.r(X.r(X.r(Env.visionApi, cn), cC), cs);
|
||||
static final String smsPasswordEgypt =
|
||||
X.r(X.r(X.r(Env.smsPasswordEgypt, cn), cC), cs);
|
||||
static final String ocpApimSubscriptionKey = Env.ocpApimSubscriptionKey;
|
||||
static final String anthropicAIkeySeferNew =
|
||||
X.r(X.r(X.r(Env.anthropicAIkeySeferNew, cn), cC), cs);
|
||||
static final String emailService = (Env.emailService);
|
||||
|
||||
///////////
|
||||
static final String keyOfApp = X.r(X.r(X.r(Env.keyOfApp, cn), cC), cs);
|
||||
}
|
||||
78
lib/constant/box_name.dart
Normal file
78
lib/constant/box_name.dart
Normal file
@@ -0,0 +1,78 @@
|
||||
class BoxName {
|
||||
static const String driverID = "driverID";
|
||||
static const String countryCode = "countryCode";
|
||||
static const String googlaMapApp = "googlaMapApp";
|
||||
|
||||
static const String tokenParent = "tokenParent";
|
||||
static const String lang = "lang";
|
||||
static const String gender = "gender";
|
||||
static const String carType = "carType";
|
||||
static const String carPlate = "carPlate";
|
||||
static const String isVerified = '0';
|
||||
static const String statusDriverLocation = "statusDriverLocation";
|
||||
static const String password = "password";
|
||||
static const String arrivalTime = "arrivalTime";
|
||||
static const String passwordDriver = "passwordDriver";
|
||||
static const String agreeTerms = "agreeTerms";
|
||||
static const String addWork = 'addWork';
|
||||
static const String addHome = 'addHome';
|
||||
static const String tipPercentage = 'tipPercentage';
|
||||
static const String accountIdStripeConnect = "accountIdStripeConnect";
|
||||
static const String faceDetectTimes = "faceDetectTimes";
|
||||
static const String sosPhonePassenger = "sosPhonePassenger";
|
||||
static const String sosPhoneDriver = "sosPhoneDriver";
|
||||
static const String passengerID = "pasengerID";
|
||||
static const String phone = "phone";
|
||||
static const String phoneDriver = "phoneDriver";
|
||||
static const String dobDriver = "dobDriver";
|
||||
static const String sexDriver = "sexDriver";
|
||||
static const String lastNameDriver = "lastNameDriver";
|
||||
static const String name = "name";
|
||||
static const String locationPermission = "locationPermission";
|
||||
static const String nameDriver = "nameDriver";
|
||||
static const String driverPhotoUrl = "driverPhotoUrl";
|
||||
static const String passengerPhotoUrl = "passengerPhotoUrl";
|
||||
static const String email = "email";
|
||||
static const String emailDriver = "emailDriver";
|
||||
static const String tokens = "tokens";
|
||||
static const String tokenFCM = "tokenFCM";
|
||||
static const String tokenDriver = "tokenDriver";
|
||||
static const String cardNumber = "cardNumber";
|
||||
static const String cardNumberDriver = "cardNumberDriver";
|
||||
static const String cardHolderName = "cardHolderName";
|
||||
static const String cardHolderNameDriver = "cardHolderNameDriver";
|
||||
static const String expiryDate = "expiryDate";
|
||||
static const String expiryDateDriver = "expiryDateDriver";
|
||||
static const String cvvCode = "cvvCode";
|
||||
static const String cvvCodeDriver = "cvvCodeDriver";
|
||||
static const String passengerWalletDetails = "passengerWalletDetails";
|
||||
static const String passengerWalletTotal = "passengerWalletTotal";
|
||||
static const String passengerWalletFound = "passengerWalletFound";
|
||||
static const String periods = 'periods';
|
||||
static const String onBoarding = 'onBoarding';
|
||||
static const String stripePublishableKey = 'stripe_publishableKe';
|
||||
static const String apiKeyRun = 'apiKeyRun';
|
||||
static const String serverAPI = 'serverAPI';
|
||||
static const String secretKey = 'secretKey';
|
||||
static const String basicAuthCredentials = 'basicAuthCredentials';
|
||||
static const String mapAPIKEY = 'mapAPIKEY';
|
||||
static const String twilloRecoveryCode = 'twilloRecoveryCode';
|
||||
static const String accountSIDTwillo = 'accountSIDTwillo';
|
||||
static const String authTokenTwillo = 'authTokenTwillo';
|
||||
static const String chatGPTkey = 'chatGPTkey';
|
||||
static const String chatGPTkeySefer = 'chatGPTkeySefer';
|
||||
static const String transactionCloude = 'transactionCloude';
|
||||
static const String visionApi = 'visionApi';
|
||||
static const String vin = "vin";
|
||||
static const String isvibrate = "isvibrate";
|
||||
static const String make = "make";
|
||||
static const String model = "model";
|
||||
static const String year = "year";
|
||||
static const String expirationDate = "expirationDate";
|
||||
static const String color = "color";
|
||||
static const String owner = "owner";
|
||||
static const String registrationDate = "registrationDate";
|
||||
static const String recentLocations = 'recentLocations';
|
||||
static const String tripData = 'tripData';
|
||||
static const String parentTripSelected = 'parentTripSelected';
|
||||
}
|
||||
68
lib/constant/char_map.dart
Normal file
68
lib/constant/char_map.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
Map<String, String> cn = {
|
||||
"0": "3",
|
||||
"1": "7",
|
||||
"2": "1",
|
||||
"3": "9",
|
||||
"4": "0",
|
||||
"5": "5",
|
||||
"6": "2",
|
||||
"7": "6",
|
||||
"8": "4",
|
||||
"9": "8"
|
||||
};
|
||||
Map<String, String> cs = {
|
||||
"a": "q",
|
||||
"b": "x",
|
||||
"c": "f",
|
||||
"d": "y",
|
||||
"e": "j",
|
||||
"f": "u",
|
||||
"g": "k",
|
||||
"h": "w",
|
||||
"i": "o",
|
||||
"j": "e",
|
||||
"k": "g",
|
||||
"l": "r",
|
||||
"m": "n",
|
||||
"n": "b",
|
||||
"o": "i",
|
||||
"p": "v",
|
||||
"q": "a",
|
||||
"r": "l",
|
||||
"s": "z",
|
||||
"t": "c",
|
||||
"u": "h",
|
||||
"v": "p",
|
||||
"w": "t",
|
||||
"x": "d",
|
||||
"y": "s",
|
||||
"z": "m"
|
||||
};
|
||||
Map<String, String> cC = {
|
||||
"A": "Q",
|
||||
"B": "X",
|
||||
"C": "F",
|
||||
"D": "Y",
|
||||
"E": "J",
|
||||
"F": "U",
|
||||
"G": "K",
|
||||
"H": "W",
|
||||
"I": "O",
|
||||
"J": "E",
|
||||
"K": "G",
|
||||
"L": "R",
|
||||
"M": "N",
|
||||
"N": "B",
|
||||
"O": "I",
|
||||
"P": "V",
|
||||
"Q": "A",
|
||||
"R": "L",
|
||||
"S": "Z",
|
||||
"T": "C",
|
||||
"U": "H",
|
||||
"V": "P",
|
||||
"W": "T",
|
||||
"X": "D",
|
||||
"Y": "S",
|
||||
"Z": "M"
|
||||
};
|
||||
20
lib/constant/colors.dart
Normal file
20
lib/constant/colors.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppColor {
|
||||
static const Color primaryColor = Color(0xFF1DA1F2);
|
||||
static const Color writeColor = Color(0xff222359);
|
||||
|
||||
static const Color bronze = Color(0xFFCD7F32);
|
||||
static const Color goldenBronze = Color(0xFFB87333); // Golden bronze color
|
||||
static const Color gold = Color(0xFFD4AF37);
|
||||
static const Color secondaryColor = Colors.white;
|
||||
static const Color accentColor = Colors.grey;
|
||||
static const Color twitterColor = Color(0xFF1DA1F2); // Twitter blue
|
||||
static const Color greyColor = Colors.grey;
|
||||
static const Color redColor = Color(0xFFEA4335); // Google Red
|
||||
static const Color greenColor = Color(0xFF34A853); // Google Green
|
||||
static const Color blueColor = Color(0xFF1DA1F2); // Google Blue
|
||||
static const Color yellowColor = Color(0xFFFBBC05); // Google Yellow
|
||||
static Color deepPurpleAccent =
|
||||
const Color.fromARGB(255, 123, 76, 254).withOpacity(0.3);
|
||||
}
|
||||
141
lib/constant/credential.dart
Normal file
141
lib/constant/credential.dart
Normal file
@@ -0,0 +1,141 @@
|
||||
import 'dart:convert';
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import 'box_name.dart';
|
||||
|
||||
class AC {
|
||||
gAK() async {
|
||||
if (box.read(BoxName.apiKeyRun).toString() != 'run') {
|
||||
// var res = await CRUD().get(link: AppLink.getApiKey, payload: {});
|
||||
// var decod = jsonDecode(res);
|
||||
// print(decod);
|
||||
// Map<String, dynamic> jsonData = {};
|
||||
// for (var i = 0; i < decod['message'].length; i++) {
|
||||
// String h = decod['message'][i]['hashed_key'].toString();
|
||||
// String retrievedString = r(r(r(h, cn), cC), cs);
|
||||
|
||||
// await storage.write(
|
||||
// key: decod['message'][i]['name'].toString(),
|
||||
// value: retrievedString.toString(),
|
||||
// );
|
||||
// //
|
||||
// String name = decod['message'][i]['name'].toString();
|
||||
// String value = decod['message'][i]['hashed_key'].toString();
|
||||
|
||||
// jsonData[name] = value;
|
||||
// }
|
||||
// String jsonString = json.encode(jsonData);
|
||||
// print(jsonString);
|
||||
// box.write(BoxName.apiKeyRun, 'run');
|
||||
}
|
||||
}
|
||||
|
||||
String q(String b, String c) {
|
||||
final d = utf8.encode(c);
|
||||
final e = utf8.encode(b);
|
||||
|
||||
final f = Hmac(sha256, d);
|
||||
final g = f.convert(e);
|
||||
|
||||
final h = g.bytes;
|
||||
final i = base64Url.encode(h);
|
||||
return i;
|
||||
}
|
||||
|
||||
String j(String k, String l) {
|
||||
final m = utf8.encode(l);
|
||||
final n = base64Url.decode(k);
|
||||
|
||||
final o = Hmac(sha256, m);
|
||||
final p = o.convert(n);
|
||||
|
||||
final q = utf8.decode(p.bytes);
|
||||
return q;
|
||||
}
|
||||
|
||||
String a(String b, String c) {
|
||||
int d = b.length;
|
||||
int e = d ~/ 4;
|
||||
|
||||
List<String> f = [];
|
||||
for (int g = 0; g < d; g += e) {
|
||||
int h = g + e;
|
||||
if (h > d) {
|
||||
h = d;
|
||||
}
|
||||
String i = b.substring(g, h);
|
||||
f.add(i);
|
||||
}
|
||||
|
||||
print(f);
|
||||
Map<String, String> j = {};
|
||||
j['birinci'] = f[4];
|
||||
j['ikinci'] = f[2];
|
||||
j['üçüncü'] = c + f[1];
|
||||
j['dördüncü'] = f[0];
|
||||
j['beş'] = f[3];
|
||||
|
||||
String k = '';
|
||||
j.forEach((l, m) {
|
||||
k += m;
|
||||
});
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
Map<String, String> n(String o, String c) {
|
||||
String p = o.replaceAll(c, '');
|
||||
|
||||
Map<String, String> q = {};
|
||||
q['birinci'] = p[p.length - 5] + p[p.length - 3];
|
||||
q['ikinci'] = p[p.length - 1] + p[p.length - 15];
|
||||
q['üçüncü'] = p[p.length - 9] + p[p.length - 12];
|
||||
q['dördüncü'] = p[p.length - 11] + p[p.length - 6];
|
||||
q['beş'] = p[p.length - 2] + p[p.length - 8];
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
String c(String a, Map<String, String> b) {
|
||||
StringBuffer c = StringBuffer();
|
||||
c.write(a);
|
||||
|
||||
String d = "Bl";
|
||||
c.write(b[d] ?? d);
|
||||
|
||||
StringBuffer e = StringBuffer();
|
||||
String f = c.toString();
|
||||
|
||||
for (int g = 0; g < f.length; g++) {
|
||||
String h = f[g];
|
||||
e.write(b[h] ?? h);
|
||||
}
|
||||
|
||||
return e.toString();
|
||||
}
|
||||
|
||||
String r(String a, Map<String, String> b) {
|
||||
StringBuffer c = StringBuffer();
|
||||
String d = "Bl";
|
||||
int e = d.length;
|
||||
|
||||
for (int f = 0; f < a.length; f++) {
|
||||
String g = a[f];
|
||||
String h = b.keys.firstWhere(
|
||||
(i) => b[i] == g,
|
||||
orElse: () => g,
|
||||
);
|
||||
|
||||
c.write(h);
|
||||
}
|
||||
|
||||
String j = c.toString();
|
||||
|
||||
if (j.endsWith(d)) {
|
||||
j = j.substring(0, j.length - e);
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
}
|
||||
4470
lib/constant/info.dart
Normal file
4470
lib/constant/info.dart
Normal file
File diff suppressed because one or more lines are too long
55
lib/constant/links.dart
Normal file
55
lib/constant/links.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
import '../env/env.dart';
|
||||
|
||||
class AppLink {
|
||||
static final String server = Env.serverPHP;
|
||||
static String googleMapsLink = 'https://maps.googleapis.com/maps/api/';
|
||||
static String llama = 'https://api.llama-api.com/chat/completions';
|
||||
static String getTokens = "$server/ride/firebase/get.php";
|
||||
|
||||
static String gemini =
|
||||
'https://generativelanguage.googleapis.com/v1beta3/models/text-bison-001:generateText';
|
||||
static String uploadEgypt = "$server/uploadEgypt.php";
|
||||
static String auth = '$server/auth';
|
||||
static String login = "$serviceApp/login.php";
|
||||
static String signUp = "$auth/signup.php";
|
||||
static String sendVerifyEmail = "$auth/sendVerifyEmail.php";
|
||||
static String passengerRemovedAccountEmail =
|
||||
"$auth/passengerRemovedAccountEmail.php";
|
||||
static String verifyEmail = "$auth/verifyEmail.php";
|
||||
static String getPromptDriverDocumentsEgypt =
|
||||
"$server/auth/captin/getPromptDriverDocumentsEgypt.php";
|
||||
|
||||
//===================Auth Captin============
|
||||
static String authCaptin = '$server/auth/captin';
|
||||
static String loginCaptin = "$authCaptin/login.php";
|
||||
static String signUpCaptin = "$authCaptin/register.php";
|
||||
static String sendVerifyEmailCaptin = "$authCaptin/sendVerifyEmail.php";
|
||||
static String verifyEmailCaptin = "$authCaptin/verifyEmail.php";
|
||||
static String removeUser = "$authCaptin/removeAccount.php";
|
||||
static String deletecaptainAccounr = "$authCaptin/deletecaptainAccounr.php";
|
||||
static String updateAccountBank = "$authCaptin/updateAccountBank.php";
|
||||
static String getAccount = "$authCaptin/getAccount.php";
|
||||
static String test = "$server/test.php";
|
||||
static String serviceApp = "$server/serviceApp";
|
||||
static String getPassengersByPhone =
|
||||
"$server/serviceApp/getPassengersByPhone.php";
|
||||
static String getDriverByPhone = "$serviceApp/getDriverByPhone.php";
|
||||
static String getNewDriverRegister = "$serviceApp/getNewDriverRegister.php";
|
||||
static String addWelcomeDriverNote = "$serviceApp/addWelcomeDriverNote.php";
|
||||
static String getDriverNotCompleteRegistration =
|
||||
"$serviceApp/getDriverNotCompleteRegistration.php";
|
||||
static String getPassengersNotCompleteRegistration =
|
||||
"$serviceApp/getPassengersNotCompleteRegistration.php";
|
||||
static String addNotesDriver = "$serviceApp/addNotesDriver.php";
|
||||
static String getCarPlateNotEdit = "$serviceApp/getCarPlateNotEdit.php";
|
||||
static String addNotesPassenger = "$serviceApp/addNotesPassenger.php";
|
||||
static String editCarPlate = "$serviceApp/editCarPlate.php";
|
||||
static String getComplaintAllData = "$serviceApp/getComplaintAllData.php";
|
||||
static String getComplaintAllDataForDriver =
|
||||
"$serviceApp/getComplaintAllDataForDriver.php";
|
||||
static String addCriminalDocuments = "$authCaptin/addCriminalDocuments.php";
|
||||
static String ride = '$server/ride';
|
||||
static String addRegisrationCar = "$ride/RegisrationCar/add.php";
|
||||
static String getRegisrationCar = "$ride/RegisrationCar/get.php";
|
||||
static String updateRegisrationCar = "$ride/RegisrationCar/update.php";
|
||||
}
|
||||
61
lib/constant/style.dart
Normal file
61
lib/constant/style.dart
Normal file
@@ -0,0 +1,61 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import 'box_name.dart';
|
||||
import 'colors.dart';
|
||||
|
||||
class AppStyle {
|
||||
static TextStyle headTitle = const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 40,
|
||||
color: AppColor.accentColor,
|
||||
);
|
||||
static TextStyle headTitle2 = const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 26,
|
||||
color: AppColor.writeColor,
|
||||
);
|
||||
static TextStyle title = TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: box.read(BoxName.lang) == 'ar' ? 14 : 16,
|
||||
color: AppColor.writeColor,
|
||||
);
|
||||
static TextStyle subtitle = const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 13,
|
||||
color: AppColor.writeColor,
|
||||
);
|
||||
static TextStyle number = const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
color: AppColor.writeColor,
|
||||
fontFamily: 'digit');
|
||||
|
||||
static BoxDecoration boxDecoration = const BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)),
|
||||
BoxShadow(
|
||||
color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2))
|
||||
],
|
||||
color: AppColor.secondaryColor,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.elliptical(15, 30),
|
||||
));
|
||||
static BoxDecoration boxDecoration1 = const BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(255, 237, 230, 230),
|
||||
blurRadius: 5,
|
||||
offset: Offset(2, 4)),
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(255, 242, 237, 237),
|
||||
blurRadius: 5,
|
||||
offset: Offset(-2, -2))
|
||||
],
|
||||
color: AppColor.secondaryColor,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.elliptical(15, 30),
|
||||
),
|
||||
);
|
||||
}
|
||||
9
lib/constant/table_names.dart
Normal file
9
lib/constant/table_names.dart
Normal file
@@ -0,0 +1,9 @@
|
||||
class TableName {
|
||||
static const String placesFavorite = "placesFavorite";
|
||||
static const String recentLocations = "recentLocations";
|
||||
static const String carLocations = "carLocations";
|
||||
static const String driverOrdersRefuse = "driverOrdersRefuse";
|
||||
static const String rideLocation = "rideLocation";
|
||||
static const String faceDetectTimes = "faceDetectTimes";
|
||||
static const String captainNotification = "captainNotification";
|
||||
}
|
||||
117
lib/controller/firebase.dart
Normal file
117
lib/controller/firebase.dart
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
216
lib/controller/functions/crud.dart
Normal file
216
lib/controller/functions/crud.dart
Normal 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) {}
|
||||
}
|
||||
335
lib/controller/functions/image.dart
Normal file
335
lib/controller/functions/image.dart
Normal 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);
|
||||
}
|
||||
156
lib/controller/local/local_controller.dart
Normal file
156
lib/controller/local/local_controller.dart
Normal 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();
|
||||
}
|
||||
}
|
||||
9160
lib/controller/local/translations.dart
Normal file
9160
lib/controller/local/translations.dart
Normal file
File diff suppressed because it is too large
Load Diff
38
lib/controller/login_controller.dart
Normal file
38
lib/controller/login_controller.dart
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 {}
|
||||
}
|
||||
}
|
||||
59
lib/controller/themes/themes.dart
Normal file
59
lib/controller/themes/themes.dart
Normal 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,
|
||||
);
|
||||
185
lib/env/env.dart
vendored
Normal file
185
lib/env/env.dart
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
import 'package:envied/envied.dart';
|
||||
|
||||
part 'env.g.dart';
|
||||
|
||||
@Envied()
|
||||
abstract class Env {
|
||||
@EnviedField(varName: 'basicAuthCredentials', obfuscate: true)
|
||||
static final String basicAuthCredentials = _Env.basicAuthCredentials;
|
||||
|
||||
@EnviedField(varName: 'visionApi', obfuscate: true)
|
||||
static final String visionApi = _Env.visionApi;
|
||||
|
||||
@EnviedField(varName: 'smsPasswordEgypt', obfuscate: true)
|
||||
static final String smsPasswordEgypt = _Env.smsPasswordEgypt;
|
||||
|
||||
@EnviedField(varName: 'ocpApimSubscriptionKey', obfuscate: true)
|
||||
static final String ocpApimSubscriptionKey = _Env.ocpApimSubscriptionKey;
|
||||
|
||||
@EnviedField(varName: 'serverPHP', obfuscate: true)
|
||||
static final String serverPHP = _Env.serverPHP;
|
||||
|
||||
@EnviedField(varName: 'anthropicAIkeySeferNew', obfuscate: true)
|
||||
static final String anthropicAIkeySeferNew = _Env.anthropicAIkeySeferNew;
|
||||
|
||||
@EnviedField(varName: 'A', obfuscate: true)
|
||||
static final String A = _Env.A;
|
||||
|
||||
@EnviedField(varName: 'B', obfuscate: true)
|
||||
static final String B = _Env.B;
|
||||
|
||||
@EnviedField(varName: 'C', obfuscate: true)
|
||||
static final String C = _Env.C;
|
||||
|
||||
@EnviedField(varName: 'D', obfuscate: true)
|
||||
static final String D = _Env.D;
|
||||
|
||||
@EnviedField(varName: 'E', obfuscate: true)
|
||||
static final String E = _Env.E;
|
||||
|
||||
@EnviedField(varName: 'F', obfuscate: true)
|
||||
static final String F = _Env.F;
|
||||
|
||||
@EnviedField(varName: 'G', obfuscate: true)
|
||||
static final String G = _Env.G;
|
||||
|
||||
@EnviedField(varName: 'H', obfuscate: true)
|
||||
static final String H = _Env.H;
|
||||
|
||||
@EnviedField(varName: 'I', obfuscate: true)
|
||||
static final String I = _Env.I;
|
||||
|
||||
@EnviedField(varName: 'J', obfuscate: true)
|
||||
static final String J = _Env.J;
|
||||
|
||||
@EnviedField(varName: 'K', obfuscate: true)
|
||||
static final String K = _Env.K;
|
||||
|
||||
@EnviedField(varName: 'L', obfuscate: true)
|
||||
static final String L = _Env.L;
|
||||
|
||||
@EnviedField(varName: 'M', obfuscate: true)
|
||||
static final String M = _Env.M;
|
||||
|
||||
@EnviedField(varName: 'N', obfuscate: true)
|
||||
static final String N = _Env.N;
|
||||
|
||||
@EnviedField(varName: 'O', obfuscate: true)
|
||||
static final String O = _Env.O;
|
||||
|
||||
@EnviedField(varName: 'P', obfuscate: true)
|
||||
static final String P = _Env.P;
|
||||
|
||||
@EnviedField(varName: 'Q', obfuscate: true)
|
||||
static final String Q = _Env.Q;
|
||||
|
||||
@EnviedField(varName: 'R', obfuscate: true)
|
||||
static final String R = _Env.R;
|
||||
|
||||
@EnviedField(varName: 'S', obfuscate: true)
|
||||
static final String S = _Env.S;
|
||||
|
||||
@EnviedField(varName: 'T', obfuscate: true)
|
||||
static final String T = _Env.T;
|
||||
|
||||
@EnviedField(varName: 'U', obfuscate: true)
|
||||
static final String U = _Env.U;
|
||||
|
||||
@EnviedField(varName: 'V', obfuscate: true)
|
||||
static final String V = _Env.V;
|
||||
|
||||
@EnviedField(varName: 'W', obfuscate: true)
|
||||
static final String W = _Env.W;
|
||||
|
||||
@EnviedField(varName: 'X', obfuscate: true)
|
||||
static final String X = _Env.X;
|
||||
|
||||
@EnviedField(varName: 'Y', obfuscate: true)
|
||||
static final String Y = _Env.Y;
|
||||
|
||||
@EnviedField(varName: 'Z', obfuscate: true)
|
||||
static final String Z = _Env.Z;
|
||||
@EnviedField(varName: 'a', obfuscate: true)
|
||||
static final String a = _Env.a;
|
||||
|
||||
@EnviedField(varName: 'b', obfuscate: true)
|
||||
static final String b = _Env.b;
|
||||
|
||||
@EnviedField(varName: 'c', obfuscate: true)
|
||||
static final String c = _Env.c;
|
||||
|
||||
@EnviedField(varName: 'd', obfuscate: true)
|
||||
static final String d = _Env.d;
|
||||
|
||||
@EnviedField(varName: 'e', obfuscate: true)
|
||||
static final String e = _Env.e;
|
||||
|
||||
@EnviedField(varName: 'f', obfuscate: true)
|
||||
static final String f = _Env.f;
|
||||
|
||||
@EnviedField(varName: 'g', obfuscate: true)
|
||||
static final String g = _Env.g;
|
||||
|
||||
@EnviedField(varName: 'h', obfuscate: true)
|
||||
static final String h = _Env.h;
|
||||
|
||||
@EnviedField(varName: 'i', obfuscate: true)
|
||||
static final String i = _Env.i;
|
||||
|
||||
@EnviedField(varName: 'j', obfuscate: true)
|
||||
static final String j = _Env.j;
|
||||
|
||||
@EnviedField(varName: 'k', obfuscate: true)
|
||||
static final String k = _Env.k;
|
||||
|
||||
@EnviedField(varName: 'l', obfuscate: true)
|
||||
static final String l = _Env.l;
|
||||
|
||||
@EnviedField(varName: 'm', obfuscate: true)
|
||||
static final String m = _Env.m;
|
||||
|
||||
@EnviedField(varName: 'n', obfuscate: true)
|
||||
static final String n = _Env.n;
|
||||
|
||||
@EnviedField(varName: 'o', obfuscate: true)
|
||||
static final String o = _Env.o;
|
||||
|
||||
@EnviedField(varName: 'p', obfuscate: true)
|
||||
static final String p = _Env.p;
|
||||
|
||||
@EnviedField(varName: 'q', obfuscate: true)
|
||||
static final String q = _Env.q;
|
||||
|
||||
@EnviedField(varName: 'r', obfuscate: true)
|
||||
static final String r = _Env.r;
|
||||
|
||||
@EnviedField(varName: 's', obfuscate: true)
|
||||
static final String s = _Env.s;
|
||||
|
||||
@EnviedField(varName: 't', obfuscate: true)
|
||||
static final String t = _Env.t;
|
||||
|
||||
@EnviedField(varName: 'u', obfuscate: true)
|
||||
static final String u = _Env.u;
|
||||
|
||||
@EnviedField(varName: 'v', obfuscate: true)
|
||||
static final String v = _Env.v;
|
||||
|
||||
@EnviedField(varName: 'w', obfuscate: true)
|
||||
static final String w = _Env.w;
|
||||
|
||||
@EnviedField(varName: 'x', obfuscate: true)
|
||||
static final String x = _Env.x;
|
||||
|
||||
@EnviedField(varName: 'y', obfuscate: true)
|
||||
static final String y = _Env.y;
|
||||
|
||||
@EnviedField(varName: 'z', obfuscate: true)
|
||||
static final String z = _Env.z;
|
||||
|
||||
@EnviedField(varName: 'emailService', obfuscate: true)
|
||||
static final String emailService = _Env.emailService;
|
||||
|
||||
@EnviedField(varName: 'keyOfApp', obfuscate: true)
|
||||
static final String keyOfApp = _Env.keyOfApp;
|
||||
}
|
||||
1276
lib/env/env.g.dart
vendored
Normal file
1276
lib/env/env.g.dart
vendored
Normal file
File diff suppressed because it is too large
Load Diff
62
lib/firebase_options.dart
Normal file
62
lib/firebase_options.dart
Normal file
@@ -0,0 +1,62 @@
|
||||
// File generated by FlutterFire CLI.
|
||||
// ignore_for_file: type=lint
|
||||
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||
import 'package:flutter/foundation.dart'
|
||||
show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||
|
||||
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// import 'firebase_options.dart';
|
||||
/// // ...
|
||||
/// await Firebase.initializeApp(
|
||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||
/// );
|
||||
/// ```
|
||||
class DefaultFirebaseOptions {
|
||||
static FirebaseOptions get currentPlatform {
|
||||
if (kIsWeb) {
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for web - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
}
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return android;
|
||||
case TargetPlatform.iOS:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for ios - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.macOS:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for macos - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.windows:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for windows - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.linux:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for linux - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
default:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions are not supported for this platform.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static const FirebaseOptions android = FirebaseOptions(
|
||||
apiKey: 'AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0',
|
||||
appId: '1:594687661098:android:f81fcce13962121a595f53',
|
||||
messagingSenderId: '594687661098',
|
||||
projectId: 'ride-b1bd8',
|
||||
storageBucket: 'ride-b1bd8.appspot.com',
|
||||
);
|
||||
}
|
||||
50
lib/login_page.dart
Normal file
50
lib/login_page.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/views/widgets/my_textField.dart';
|
||||
import 'controller/login_controller.dart';
|
||||
|
||||
class LoginPage extends StatelessWidget {
|
||||
final LoginController controller = Get.put(LoginController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const CupertinoNavigationBar(
|
||||
middle: Text('Login'),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
MyTextForm(
|
||||
controller: controller.email,
|
||||
label: 'email',
|
||||
hint: 'email',
|
||||
type: TextInputType.emailAddress),
|
||||
const SizedBox(height: 20),
|
||||
MyTextForm(
|
||||
controller: controller.password,
|
||||
label: 'Password',
|
||||
hint: 'Password',
|
||||
type: TextInputType.name),
|
||||
const SizedBox(height: 40),
|
||||
CupertinoButton.filled(
|
||||
child: const Text('Login'),
|
||||
onPressed: () {
|
||||
controller.login();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
60
lib/main.dart
Normal file
60
lib/main.dart
Normal file
@@ -0,0 +1,60 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
|
||||
import 'controller/firebase.dart';
|
||||
import 'controller/local/local_controller.dart';
|
||||
import 'controller/local/translations.dart';
|
||||
import 'firebase_options.dart';
|
||||
import 'login_page.dart';
|
||||
import 'views/home/main.dart';
|
||||
|
||||
final box = GetStorage();
|
||||
const storage = FlutterSecureStorage();
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
if (Platform.isAndroid || Platform.isIOS) {
|
||||
await Firebase.initializeApp(
|
||||
options: DefaultFirebaseOptions.currentPlatform,
|
||||
);
|
||||
await FirebaseMessagesController().requestFirebaseMessagingPermission();
|
||||
|
||||
// FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
|
||||
|
||||
List<Future> initializationTasks = [
|
||||
FirebaseMessagesController().getNotificationSettings(),
|
||||
FirebaseMessagesController().getToken(),
|
||||
];
|
||||
// cameras = await availableCameras();
|
||||
await Future.wait(initializationTasks);
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
DeviceOrientation.portraitDown,
|
||||
]);
|
||||
}
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
MyApp({super.key});
|
||||
LocaleController localController = Get.put(LocaleController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetMaterialApp(
|
||||
title: 'Sefer Service'.tr,
|
||||
debugShowCheckedModeBanner: false,
|
||||
translations: MyTranslation(),
|
||||
locale: localController.language,
|
||||
theme: localController.appTheme,
|
||||
key: UniqueKey(),
|
||||
home: LoginPage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
13
lib/print.dart
Normal file
13
lib/print.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'dart:developer' as developer;
|
||||
|
||||
class Log {
|
||||
Log._();
|
||||
|
||||
static void print(String value, {StackTrace? stackTrace}) {
|
||||
developer.log(value, name: 'LOG', stackTrace: stackTrace);
|
||||
}
|
||||
|
||||
static Object? inspect(Object? object) {
|
||||
return developer.inspect(object);
|
||||
}
|
||||
}
|
||||
204
lib/views/home/main.dart
Normal file
204
lib/views/home/main.dart
Normal file
@@ -0,0 +1,204 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:service/controller/mainController/main_controller.dart';
|
||||
import 'package:service/controller/mainController/pages/complaint.dart';
|
||||
import 'package:service/controller/mainController/pages/edit_car_plate.dart';
|
||||
import 'package:service/controller/mainController/pages/passengers_cant_regster.dart';
|
||||
import 'package:service/views/widgets/my_dialog.dart';
|
||||
import 'package:service/views/widgets/my_textField.dart';
|
||||
|
||||
import '../../constant/style.dart';
|
||||
import '../../controller/mainController/pages/drivers_cant_register.dart';
|
||||
import '../../controller/mainController/pages/welcome_call.dart';
|
||||
import '../widgets/my_scafold.dart';
|
||||
|
||||
class Main extends StatelessWidget {
|
||||
Main({super.key});
|
||||
MainController mainController = Get.put(MainController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MyScaffold(title: 'Sefer Service'.tr, isleading: false, body: [
|
||||
ListView(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
MyDialog().getDialog(
|
||||
'insert passenger phone'.tr,
|
||||
'midTitle',
|
||||
Column(
|
||||
children: [
|
||||
Form(
|
||||
key: mainController.formKey,
|
||||
child: MyTextForm(
|
||||
controller: mainController.passengerPhoneController,
|
||||
label: 'insert passenger phone'.tr,
|
||||
hint: 'insert passenger phone'.tr,
|
||||
type: TextInputType.phone,
|
||||
)),
|
||||
],
|
||||
),
|
||||
() {
|
||||
mainController.searchPassengerByPhone();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'passenger details by phone'.tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
MyDialog().getDialog(
|
||||
'insert Driver phone'.tr,
|
||||
'midTitle',
|
||||
Column(
|
||||
children: [
|
||||
Form(
|
||||
key: mainController.formKey,
|
||||
child: MyTextForm(
|
||||
controller: mainController.driverPhoneController,
|
||||
label: 'insert Driver phone'.tr,
|
||||
hint: 'insert Driver phone'.tr,
|
||||
type: TextInputType.phone,
|
||||
)),
|
||||
],
|
||||
),
|
||||
() {
|
||||
mainController.searchDriverByPhone();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'Driver details by phone'.tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
await mainController.getDriverNotCompleteRegistration();
|
||||
Get.to(() => DriversCantRegister());
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'Drivers Cant Register'.tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
await mainController.getPassengerNotCompleteRegistration();
|
||||
Get.to(() => PassengersCantRegister());
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'Passengers Cant Register'.tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
await mainController.getCarPlateNotEdit();
|
||||
if (mainController.carPlateNotEdit.isNotEmpty) {
|
||||
Get.to(() => EditCarPlate());
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'Edit car plate'.tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
// await mainController.getCarPlateNotEdit();
|
||||
// if (mainController.carPlateNotEdit.isNotEmpty) {
|
||||
Get.to(() => Complaint());
|
||||
// }
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"View complaint".tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
await mainController.getNewDriverRegister();
|
||||
// if (mainController.carPlateNotEdit.isNotEmpty) {
|
||||
Get.to(() => const WelcomeCall());
|
||||
// }
|
||||
},
|
||||
child: Container(
|
||||
decoration: AppStyle.boxDecoration,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"Welcome call".tr,
|
||||
style: AppStyle.title,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
63
lib/views/widgets/circle_container.dart
Normal file
63
lib/views/widgets/circle_container.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../constant/colors.dart';
|
||||
|
||||
class MyCircleContainer extends StatelessWidget {
|
||||
final Widget child;
|
||||
final Color backgroundColor;
|
||||
final Color borderColor;
|
||||
|
||||
MyCircleContainer({
|
||||
Key? key,
|
||||
required this.child,
|
||||
this.backgroundColor = AppColor.secondaryColor,
|
||||
this.borderColor = AppColor.accentColor,
|
||||
}) : super(key: key);
|
||||
|
||||
final controller = Get.put(CircleController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<CircleController>(
|
||||
builder: ((controller) => GestureDetector(
|
||||
onTap: () {
|
||||
controller.changeColor();
|
||||
},
|
||||
child: AnimatedContainer(
|
||||
onEnd: () {
|
||||
controller.onEnd();
|
||||
},
|
||||
duration: const Duration(milliseconds: 300),
|
||||
width: controller.size,
|
||||
height: controller.size,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: controller.backgroundColor,
|
||||
border: Border.all(
|
||||
color: borderColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Center(child: child),
|
||||
),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
class CircleController extends GetxController {
|
||||
Color backgroundColor = AppColor.secondaryColor;
|
||||
double size = 40;
|
||||
void changeColor() {
|
||||
backgroundColor = backgroundColor == AppColor.secondaryColor
|
||||
? AppColor.accentColor
|
||||
: AppColor.secondaryColor;
|
||||
size = 60;
|
||||
update();
|
||||
}
|
||||
|
||||
void onEnd() {
|
||||
size = 40;
|
||||
update();
|
||||
}
|
||||
}
|
||||
53
lib/views/widgets/elevated_btn.dart
Normal file
53
lib/views/widgets/elevated_btn.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:vibration/vibration.dart';
|
||||
|
||||
import '../../constant/box_name.dart';
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/style.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MyElevatedButton extends StatelessWidget {
|
||||
final String title;
|
||||
final VoidCallback onPressed;
|
||||
final Color kolor;
|
||||
final int vibrateDuration;
|
||||
|
||||
const MyElevatedButton({
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.onPressed,
|
||||
this.kolor = AppColor.primaryColor,
|
||||
this.vibrateDuration = 100,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool vibrate = box.read(BoxName.isvibrate) ?? true;
|
||||
|
||||
return ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: kolor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
if (vibrate == true) {
|
||||
if (Platform.isIOS) {
|
||||
HapticFeedback.selectionClick();
|
||||
} else if (Platform.isAndroid) {
|
||||
await Vibration.vibrate(duration: vibrateDuration);
|
||||
} else {}
|
||||
}
|
||||
onPressed();
|
||||
},
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.title.copyWith(color: AppColor.secondaryColor),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
66
lib/views/widgets/icon_widget_menu.dart
Normal file
66
lib/views/widgets/icon_widget_menu.dart
Normal file
@@ -0,0 +1,66 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/style.dart';
|
||||
|
||||
class IconWidgetMenu extends StatelessWidget {
|
||||
const IconWidgetMenu({
|
||||
Key? key,
|
||||
required this.onpressed,
|
||||
required this.icon,
|
||||
required this.title,
|
||||
}) : super(key: key);
|
||||
|
||||
final VoidCallback onpressed;
|
||||
final IconData icon;
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: onpressed,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 1),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 50,
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColor.secondaryColor,
|
||||
shape: BoxShape.circle,
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: AppColor.secondaryColor,
|
||||
// offset: Offset(-2, -2),
|
||||
// blurRadius: 0,
|
||||
// spreadRadius: 0,
|
||||
// blurStyle: BlurStyle.outer,
|
||||
// ),
|
||||
// BoxShadow(
|
||||
// color: AppColor.accentColor,
|
||||
// offset: Offset(3, 3),
|
||||
// blurRadius: 0,
|
||||
// spreadRadius: 0,
|
||||
// blurStyle: BlurStyle.outer,
|
||||
// ),
|
||||
// ],
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 30,
|
||||
color: AppColor.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: AppStyle.subtitle.copyWith(color: AppColor.secondaryColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
40
lib/views/widgets/my_dialog.dart
Normal file
40
lib/views/widgets/my_dialog.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/style.dart';
|
||||
import 'elevated_btn.dart';
|
||||
|
||||
class MyDialog extends GetxController {
|
||||
void getDialog(
|
||||
String title, String? midTitle, Widget widget, VoidCallback onPressed) {
|
||||
// final textToSpeechController = Get.put(TextToSpeechController());
|
||||
Get.defaultDialog(
|
||||
title: title,
|
||||
titleStyle: AppStyle.title,
|
||||
middleTextStyle: AppStyle.title,
|
||||
content: Column(
|
||||
children: [
|
||||
// IconButton(
|
||||
// onPressed: () async {
|
||||
// // await textToSpeechController.speakText(title ?? midTitle!);
|
||||
// },
|
||||
// icon: const Icon(Icons.headphones)),
|
||||
widget
|
||||
],
|
||||
),
|
||||
confirm: MyElevatedButton(
|
||||
title: 'Ok'.tr,
|
||||
onPressed: onPressed,
|
||||
kolor: AppColor.greenColor,
|
||||
),
|
||||
cancel: MyElevatedButton(
|
||||
title: 'Cancel',
|
||||
kolor: AppColor.redColor,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
}));
|
||||
}
|
||||
}
|
||||
50
lib/views/widgets/my_scafold.dart
Normal file
50
lib/views/widgets/my_scafold.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/style.dart';
|
||||
|
||||
class MyScaffold extends StatelessWidget {
|
||||
const MyScaffold({
|
||||
super.key,
|
||||
required this.title,
|
||||
this.action = const Icon(
|
||||
Icons.clear,
|
||||
color: AppColor.secondaryColor,
|
||||
),
|
||||
required this.isleading,
|
||||
required this.body,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final List<Widget> body;
|
||||
final Widget action;
|
||||
final bool isleading;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColor.secondaryColor,
|
||||
appBar: AppBar(
|
||||
backgroundColor: AppColor.secondaryColor,
|
||||
elevation: 0,
|
||||
leading: isleading
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_back_ios_new,
|
||||
color: AppColor.primaryColor,
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
actions: [action],
|
||||
title: Text(
|
||||
title,
|
||||
style: AppStyle.title.copyWith(fontSize: 30),
|
||||
),
|
||||
),
|
||||
body: SafeArea(child: Stack(children: body)));
|
||||
}
|
||||
}
|
||||
74
lib/views/widgets/my_textField.dart
Normal file
74
lib/views/widgets/my_textField.dart
Normal file
@@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../constant/box_name.dart';
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/style.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MyTextForm extends StatelessWidget {
|
||||
const MyTextForm({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.label,
|
||||
required this.hint,
|
||||
required this.type,
|
||||
});
|
||||
final TextEditingController controller;
|
||||
final String label, hint;
|
||||
final TextInputType type;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: SizedBox(
|
||||
width: Get.width * .8,
|
||||
child: TextFormField(
|
||||
keyboardType: type,
|
||||
cursorColor: AppColor.accentColor,
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(
|
||||
color: AppColor.primaryColor,
|
||||
width: 2.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
focusColor: AppColor.accentColor,
|
||||
fillColor: AppColor.accentColor,
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
labelText: label.tr,
|
||||
hintText: hint.tr,
|
||||
hintStyle: AppStyle.title,
|
||||
labelStyle: AppStyle.title,
|
||||
),
|
||||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
return '${'Please enter'.tr} $label.'.tr;
|
||||
}
|
||||
|
||||
if (type == TextInputType.emailAddress) {
|
||||
if (!value.contains('@')) {
|
||||
return 'Please enter a valid email.'.tr;
|
||||
}
|
||||
} else if (type == TextInputType.phone) {
|
||||
if (box.read(BoxName.countryCode) == 'Egypt') {
|
||||
if (value.length != 11) {
|
||||
return 'Please enter a valid phone number.'.tr;
|
||||
}
|
||||
} else if (value.length != 11) {
|
||||
//for this you will return to 10 but now for service egypt
|
||||
return 'Please enter a valid phone number.'.tr;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
37
lib/views/widgets/mycircular.dart
Normal file
37
lib/views/widgets/mycircular.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MyCircularProgressIndicator extends StatelessWidget {
|
||||
final Color backgroundColor;
|
||||
|
||||
const MyCircularProgressIndicator({
|
||||
super.key,
|
||||
this.backgroundColor = Colors.transparent,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Container(
|
||||
width: 110,
|
||||
height: 110,
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Image.asset('assets/images/logo.png'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user