This commit is contained in:
Hamza-Ayed
2024-11-10 18:38:07 +02:00
parent c9ac8da2ec
commit e8c72d79a9
25 changed files with 1211 additions and 329 deletions

View File

@@ -0,0 +1,76 @@
import 'dart:convert';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/main.dart';
import 'package:get/get.dart';
class DriverCarController extends GetxController {
bool isLoading = false;
List cars = [];
int? carId;
fetchCatrsForDrivers() async {
isLoading = true;
update();
var res = await CRUD().get(link: AppLink.getNewCarsDrivers, payload: {
"driverID": box.read(BoxName.driverID).toString(),
});
if (res != 'failure') {
var d = jsonDecode(res)['message'];
cars = d;
carId = cars.isEmpty ? 1 : cars.length + 1;
}
isLoading = false;
update();
}
addCarsForDrivers(
String vin,
String car_plate,
String make,
String model,
String year,
String expiration_date,
String color,
String color_hex,
String address,
String owner,
String registration_date,
String displacement,
String fuel) async {
var res = await CRUD().post(
link: AppLink.addNewCarsDrivers,
payload: {
"driverID": box.read(BoxName.driverID).toString(),
"vin": vin,
"car_plate": car_plate,
"make": make,
"model": model,
"year": year,
"expiration_date": expiration_date,
"color": color,
"owner": owner,
"color_hex": color_hex,
"address": address,
"displacement": displacement,
"fuel": fuel,
"registration_date": registration_date,
},
);
if (res != 'failure') {
Get.snackbar('Success'.tr, '', backgroundColor: AppColor.greenColor);
fetchCatrsForDrivers();
} else {
Get.snackbar('Error'.tr, '', backgroundColor: AppColor.redColor);
}
}
removeCar(String car) async {}
@override
void onInit() {
fetchCatrsForDrivers();
super.onInit();
}
}

View File

@@ -98,7 +98,7 @@ class CupertinoDrawerCaptain extends StatelessWidget {
_buildDrawerItem(
icon: CupertinoIcons.mail,
text: "Contact Us".tr,
onTap: () => Get.to(() => const SettingsCaptain()),
onTap: () => Get.to(() => ContactUsPage()),
),
_buildDivider(),
_buildDrawerItem(

View File

@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:math';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/firebase/local_notification.dart';
@@ -10,8 +11,12 @@ import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import '../../../../../constant/colors.dart';
import '../../../../../constant/notification.dart';
import '../../../../../controller/functions/audio_controller.dart';
import '../../../../../print.dart';
import '../../../../Rate/ride_calculate_driver.dart';
import '../../../../../controller/functions/location_controller.dart';
import '../../driver_map_page.dart';
@@ -180,30 +185,53 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
),
// Platform.isAndroid
// ?
// AnimatedContainer(
// duration: const Duration(microseconds: 200),
// width: controller.widthMapTypeAndTraffic,
// decoration: BoxDecoration(
// color: AppColor.secondaryColor,
// border: Border.all(color: AppColor.blueColor),
// borderRadius: BorderRadius.circular(15)),
// child: Builder(builder: (context) {
// return IconButton(
// onPressed: () async {
// // NotificationController().showNotification(
// // ' message.notification!.title.toString()',
// // ' message.notification!.body.toString()',
// // 'order',
// // '');
// },
// icon: const Icon(
// FontAwesome5.window_close,
// size: 29,
// color: AppColor.blueColor,
// ),
// );
// }),
// ),
AnimatedContainer(
duration: const Duration(microseconds: 200),
width: controller.widthMapTypeAndTraffic,
decoration: BoxDecoration(
color: AppColor.secondaryColor,
border: Border.all(color: AppColor.blueColor),
borderRadius: BorderRadius.circular(15)),
child: Builder(builder: (context) {
return IconButton(
onPressed: () async {
// NotificationController().showNotification(
// ' message.notification!.title.toString()',
// ' message.notification!.body.toString()',
// 'order',
// '');
NotificationController notificationController =
Get.put(NotificationController());
await notificationController.initNotifications();
final random = Random();
final randomMessage =
driverMessages[random.nextInt(driverMessages.length)];
Log.print(
' randomMessage.split[0]: ${randomMessage.split(':')[0]}');
Log.print(
' randomMessage.split([1]: ${randomMessage.split(':')[1]}');
// Schedule the notification with the random message
notificationController.showNotification(
randomMessage.split(':')[0],
randomMessage.split(':')[1],
"ding",
'');
// notificationController.scheduleNotificationEvery10Hours(
// "افتح التطبيق".tr,
// "افتح التطبيق لتبقى على اطلاع واستعداد للمهام القادمة.".tr,
// "ding",
// );
},
icon: const Icon(
FontAwesome5.window_close,
size: 29,
color: AppColor.blueColor,
),
);
}),
),
// : const SizedBox(),
// AnimatedContainer(
// duration: const Duration(microseconds: 200),

View File

@@ -101,12 +101,13 @@ class PassengerInfoWindow extends StatelessWidget {
children: [
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToAnyWithoutData(
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Where are you, sir?"
.tr,
controller
.tokenPassenger,
[],
'ding.wav');
Get.back();
},
@@ -132,12 +133,13 @@ class PassengerInfoWindow extends StatelessWidget {
),
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToAnyWithoutData(
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"I've been trying to reach you but your phone is off."
.tr,
controller
.tokenPassenger,
[],
'ding.wav');
Get.back();
},
@@ -163,12 +165,13 @@ class PassengerInfoWindow extends StatelessWidget {
),
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToAnyWithoutData(
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late, I'm waiting for you at the specified location."
.tr,
controller
.tokenPassenger,
[],
'ding.wav');
Get.back();
},
@@ -194,13 +197,14 @@ class PassengerInfoWindow extends StatelessWidget {
),
InkWell(
onTap: () {
FirebaseMessagesController().sendNotificationToAnyWithoutData(
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
"Please don't be late"
.tr,
controller
.tokenPassenger,
'ding.wav');
[],
'cancel.wav');
Get.back();
},
child: Container(
@@ -247,10 +251,11 @@ class PassengerInfoWindow extends StatelessWidget {
IconButton(
onPressed:
() {
FirebaseMessagesController().sendNotificationToAnyWithoutData(
'message From Driver'.tr,
FirebaseMessagesController().sendNotificationToDriverMAP(
'message From Driver',
controller.messageToPassenger.text,
controller.tokenPassenger,
[],
'ding.wav');
controller
.messageToPassenger
@@ -471,13 +476,13 @@ class PassengerInfoWindow extends StatelessWidget {
140) {
// Notify Passenger
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Hi, I Arrive at your site',
.sendNotificationToDriverMAP(
'Hi ,I Arrive your site',
'I Arrive at your site'
.tr,
controller.tokenPassenger,
[],
'start.wav',
'ding.wav',
);
controller
.startTimerToShowDriverWaitPassengerDuration();
@@ -553,7 +558,7 @@ class PassengerInfoWindow extends StatelessWidget {
'Are you sure to cancel?'.tr,
'', () async {
FirebaseMessagesController()
.sendNotificationToPassengerToken(
.sendNotificationToDriverMAP(
'Driver Cancelled Your Trip',
'You will need to pay the cost to the driver, or it will be deducted from your next trip'
.tr,

View File

@@ -330,7 +330,7 @@ class OrderSpeedRequest extends StatelessWidget {
if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
link:
"${AppLink.endPoint}/rides/updateStausFromSpeed.php",
"${AppLink.endPoint}/ride/rides/updateStausFromSpeed.php",
payload: {
'id': orderRequestController.myList[16],
'rideTimeStart': DateTime.now().toString(),
@@ -364,6 +364,17 @@ class OrderSpeedRequest extends StatelessWidget {
box.read(BoxName.nameDriver).toString(),
box.read(BoxName.tokenDriver).toString(),
];
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Accepted Ride',
'your ride is applied'.tr,
// arguments['DriverList'][9].toString(),
orderRequestController
.arguments['DriverList'][9]
.toString(),
// box.read(BoxName.tokenDriver).toString(),
bodyToPassenger,
'start.wav');
await CRUD().postFromDialogue(
link: AppLink.addDriverOrder,
payload: {
@@ -388,7 +399,7 @@ class OrderSpeedRequest extends StatelessWidget {
if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
link:
"${AppLink.endPoint}/driver_order/add.php",
"${AppLink.endPoint}/ride/driver_order/add.php",
payload: {
'driver_id': orderRequestController
.myList[6]
@@ -400,17 +411,7 @@ class OrderSpeedRequest extends StatelessWidget {
'status': 'Apply'
});
}
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Apply Ride',
'your ride is applied'.tr,
// arguments['DriverList'][9].toString(),
orderRequestController
.arguments['DriverList'][9]
.toString(),
// box.read(BoxName.tokenDriver).toString(),
bodyToPassenger,
'start.wav');
Get.back();
// 'Arguments passed to PassengerLocationMapPage:');

View File

@@ -1,16 +1,69 @@
import 'dart:convert';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../main.dart';
class VipOrderPage extends StatelessWidget {
const VipOrderPage({super.key});
@override
Widget build(BuildContext context) {
Get.put(VipOrderController());
return MyScafolld(
title: 'VIP Order'.tr,
body: [],
body: [
GetBuilder<VipOrderController>(builder: (vipOrderController) {
return SafeArea(
child: Column(
children: [],
));
})
],
isleading: true,
);
}
}
class VipOrderController extends GetxController {
bool isLoading = false;
final arguments = Get.arguments;
late String body;
List tripData = [];
var myList;
initilize() {
final myListString = arguments['myListString'];
if (arguments['DriverList'] == null || arguments['DriverList'].isEmpty) {
myList = jsonDecode(myListString);
} else {
myList = arguments['DriverList'];
}
body = arguments['body'];
update();
}
fetchOrder() async {
var res = await CRUD().get(link: AppLink.getMishwari, payload: {
'driverId': box.read(BoxName.driverID).toString(),
});
if (res != 'failure') {
tripData = jsonDecode(res)['message'];
update();
}
}
@override
void onInit() async {
await initilize();
fetchOrder();
super.onInit();
}
}

View File

@@ -0,0 +1,105 @@
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import '../../auth/captin/driver_car_controller.dart';
import '../../widgets/elevated_btn.dart';
import 'cars_inserting_page.dart';
class CaptainsCars extends StatelessWidget {
const CaptainsCars({super.key});
@override
Widget build(BuildContext context) {
Get.put(DriverCarController());
return MyScafolld(
title: "Add new car".tr,
body: [
Column(
children: [
MyElevatedButton(
title: "Add new car".tr,
onPressed: () async {
Get.to(() => CarsInsertingPage());
},
),
Expanded(
child: GetBuilder<DriverCarController>(
builder: (controller) {
return controller.isLoading
? const MyCircularProgressIndicator()
: ListView.builder(
itemCount: controller.cars.length,
itemBuilder: (context, index) {
final car = controller.cars[index];
return Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 2,
child: ListTile(
leading: Icon(
Fontisto.car,
size: 50,
color: Color(int.parse(car['color_hex']
.replaceFirst('#', '0xff'))),
),
title: Text(
car['make'],
style: AppStyle.title,
), // Assuming `make` is a field in each car item
subtitle: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
car['model'],
style: AppStyle.title,
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: AppColor.blueColor)),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4),
child: Text(
car['car_plate'],
style: AppStyle.title,
),
),
),
Text(
car['year'],
style: AppStyle.title,
),
],
), // Assuming `model` is a field in each car item
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
// Add logic here to remove a car
controller
.removeCar(car['id'].toString());
},
),
onTap: () {
// Add logic to view or edit the car details
},
),
),
);
},
);
},
),
),
],
)
],
isleading: true);
}
}

View File

@@ -0,0 +1,300 @@
import 'package:SEFER/splash_screen_page.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../constant/colors.dart';
import '../../../constant/links.dart';
import '../../../constant/style.dart';
import '../../../controller/functions/gemeni.dart';
import '../../auth/captin/driver_car_controller.dart';
class CarsInsertingPage extends StatelessWidget {
CarsInsertingPage({super.key});
final driverCarController = Get.put(DriverCarController());
@override
Widget build(BuildContext context) {
Get.put(AI());
return MyScafolld(
title: 'Insert New Car'.tr,
body: [
Container(
color: AppColor.accentColor.withOpacity(.2),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
egyptCarLicenceFront(),
egyptCarLicenceBack(),
const SizedBox(height: 10),
Text('Please make sure to read the license carefully.'.tr),
Text(
'If your car license has the new design, upload the front side with two images.'
.tr),
const SizedBox(height: 10),
MyElevatedButton(
title: 'Please upload this license.'.tr,
onPressed: () {
final aiFront =
Get.find<AI>().responseIdCardDriverEgyptFront;
final aiBack =
Get.find<AI>().responseIdCardDriverEgyptBack;
driverCarController.addCarsForDrivers(
aiBack['vin'].toString(),
aiBack['car_plate'].toString(),
aiBack['make'].toString(),
aiBack['model'].toString(),
aiBack['year'].toString(),
aiFront['expiration_date'].toString(),
aiBack['color'].toString(),
aiBack['color_hex'].toString(),
aiFront['address'].toString(),
aiFront['owner'].toString(),
aiBack['registration_date'].toString(),
aiBack['displacement'].toString(),
aiBack['fuel'].toString(),
);
})
],
),
),
)
],
isleading: true);
}
}
GetBuilder<AI> egyptCarLicenceFront() {
return GetBuilder<AI>(
builder: (ai) {
if (ai.responseIdCardDriverEgyptFront.isNotEmpty) {
// No need to access ai.responseIdCardDriverEgyptBack anymore
final licenseExpiryDate = DateTime.parse(
ai.responseIdCardDriverEgyptFront['LicenseExpirationDate']);
// Check if license has expired
final today = DateTime.now();
final isLicenseExpired = licenseExpiryDate.isBefore(today);
return Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('Vehicle Details Front'.tr,
style: AppStyle.headTitle2),
IconButton(
onPressed: () async {
ai.allMethodForAI(ai.prompts[3]['prompt'].toString(),
AppLink.uploadEgypt, 'car_front');
},
icon: const Icon(Icons.refresh),
),
],
),
const SizedBox(height: 8.0),
const Divider(color: AppColor.accentColor),
const SizedBox(height: 8.0),
// Removed Make, Model, etc. as they are not available
Text(
'${'Plate Number'.tr}: ${ai.responseIdCardDriverEgyptFront['car_plate']}',
),
const SizedBox(height: 8.0),
Text(
'${'Owner Name'.tr}: ${ai.responseIdCardDriverEgyptFront['owner']}',
),
const SizedBox(height: 8.0),
Text(
'${'Address'.tr}: ${ai.responseIdCardDriverEgyptFront['address']}',
),
const SizedBox(height: 8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${'License Expiry Date'.tr}: ${licenseExpiryDate.toString().substring(0, 10)}',
style: TextStyle(
color: isLicenseExpired ? Colors.red : Colors.green,
),
),
// Removed Fuel as it's not available
],
),
// Removed Inspection Date as it's not available
],
),
),
);
}
return Card(
child: InkWell(
onTap: () async {
ai.allMethodForAINewCar(ai.prompts[3]['prompt'].toString(),
AppLink.uploadEgypt, 'car_front', 'carId'); //todo
},
child: Column(
children: [
Image.asset(
'assets/images/3.png',
height: Get.height * .25,
width: double.maxFinite,
fit: BoxFit.fitHeight,
),
Text(
'Capture an Image of Your car license front '.tr,
style: AppStyle.title,
),
],
),
),
);
},
);
}
GetBuilder<AI> egyptCarLicenceBack() {
return GetBuilder<AI>(
builder: (ai) {
if (ai.responseIdCardDriverEgyptBack.isNotEmpty) {
// Get the tax expiry date from the response
final taxExpiryDate =
ai.responseIdCardDriverEgyptBack['tax_expiry'].toString();
// final displacement = ai.responseIdCardDriverEgyptBack['displacement'];
// if (int.parse(displacement) < 1000) {}
// Get the inspection date from the response
final inspectionDate =
ai.responseIdCardDriverEgyptBack['inspection_date'].toString();
final year = int.parse(inspectionDate.toString().split('-')[0]);
// Set inspectionDateTime to December 31st of the given year
final inspectionDateTime = DateTime(year, 12, 31);
String carBackLicenseExpired =
inspectionDateTime.toString().split(' ')[0];
// Get the current date
final today = DateTime.now();
// Try parsing the tax expiry date. If it fails, set it to null.
final taxExpiryDateTime = DateTime.tryParse(taxExpiryDate ?? '');
final isExpired =
taxExpiryDateTime != null && taxExpiryDateTime.isBefore(today);
// Check if the inspection date is before today
bool isInspectionExpired = inspectionDateTime.isBefore(today);
return Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Vehicle Details Back'.tr, style: AppStyle.headTitle2),
IconButton(
onPressed: () async {
ai.allMethodForAI(ai.prompts[4]['prompt'].toString(),
AppLink.uploadEgypt, 'car_back');
},
icon: const Icon(Icons.refresh),
),
],
),
const SizedBox(height: 8.0),
const Divider(color: AppColor.accentColor),
const SizedBox(height: 8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Make'.tr}: ${ai.responseIdCardDriverEgyptBack['make']}'),
Text(
'${'Model'.tr}: ${ai.responseIdCardDriverEgyptBack['model']}'),
],
),
const SizedBox(height: 8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Year'.tr}: ${ai.responseIdCardDriverEgyptBack['year']}'),
Text(
'${'Chassis'.tr}: ${ai.responseIdCardDriverEgyptBack['chassis']}'),
],
),
const SizedBox(height: 8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Color'.tr}: ${ai.responseIdCardDriverEgyptBack['color']}'),
Text(
'${'Displacement'.tr}: ${ai.responseIdCardDriverEgyptBack['displacement']} cc'),
],
),
const SizedBox(height: 8.0),
Text(
'${'Fuel'.tr}: ${ai.responseIdCardDriverEgyptBack['fuel']}'),
const SizedBox(height: 8.0),
if (taxExpiryDateTime != null)
Text(
'${'Tax Expiry Date'.tr}: $taxExpiryDate',
style: TextStyle(
color: isExpired ? Colors.red : Colors.green,
),
),
const SizedBox(height: 8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${'Inspection Date'.tr}: $carBackLicenseExpired',
style: TextStyle(
color: isInspectionExpired ? Colors.red : Colors.green,
),
),
],
),
],
),
),
);
}
return Card(
child: InkWell(
onTap: () async {
ai.allMethodForAI(ai.prompts[4]['prompt'].toString(),
AppLink.uploadEgypt, 'car_back');
},
child: Column(
children: [
Image.asset(
'assets/images/4.png',
height: Get.height * .25,
width: double.maxFinite,
fit: BoxFit.fitHeight,
),
Text(
'Capture an Image of Your car license back'.tr,
style: AppStyle.title,
),
],
),
),
);
},
);
}

View File

@@ -1,5 +1,6 @@
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/payment/captain_wallet_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -7,6 +8,7 @@ import 'package:SEFER/controller/profile/captain_profile_controller.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import '../my_wallet/walet_captain.dart';
import 'captains_cars.dart';
class ProfileCaptain extends StatelessWidget {
ProfileCaptain({super.key});
@@ -41,6 +43,15 @@ class ProfileCaptain extends StatelessWidget {
),
),
),
const SizedBox(
height: 5,
),
MyElevatedButton(
title: 'Show my Cars'.tr,
onPressed: () async {
Get.to(() => CaptainsCars());
},
),
SizedBox(
height: Get.height * .8,
child: DriverProfileCard(