This commit is contained in:
Hamza-Ayed
2024-10-10 16:22:30 +03:00
parent ebb57a699b
commit 9b0caf3bed
21 changed files with 1142 additions and 630 deletions

View File

@@ -244,10 +244,18 @@ class AppLink {
//===================Auth============
static String addInviteDriver = "$server/ride/invitor/add.php";
static String addInvitationPassenger =
"$server/ride/invitor/addInvitationPassenger.php";
static String getInviteDriver = "$server/ride/invitor/get.php";
static String getDriverInvitationToPassengers =
"$server/ride/invitor/getDriverInvitationToPassengers.php";
static String updateInviteDriver = "$server/ride/invitor/update.php";
static String updatePassengerGift =
"$server/ride/invitor/updatePassengerGift.php";
static String updateInvitationCodeFromRegister =
"$server/ride/invitor/updateInvitationCodeFromRegister.php";
static String updatePassengersInvitation =
"$server/ride/invitor/updatePassengersInvitation.php";
//===================Auth============

View File

@@ -7,7 +7,7 @@ import 'colors.dart';
class AppStyle {
static TextStyle headTitle = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 40,
fontSize: 36,
color: AppColor.accentColor,
fontFamily: box.read(BoxName.lang) == 'ar'
// ?GoogleFonts.notoNaskhArabic().fontFamily
@@ -15,21 +15,21 @@ class AppStyle {
: GoogleFonts.roboto().fontFamily);
static TextStyle headTitle2 = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 26,
fontSize: 24,
color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? GoogleFonts.notoNaskhArabic().fontFamily
: GoogleFonts.roboto().fontFamily);
static TextStyle title = TextStyle(
fontWeight: FontWeight.normal,
fontSize: box.read(BoxName.lang) == 'ar' ? 14 : 16,
fontSize: 14,
color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? GoogleFonts.notoNaskhArabic().fontFamily
: GoogleFonts.roboto().fontFamily);
static TextStyle subtitle = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
fontSize: 12,
color: AppColor.writeColor,
fontFamily: box.read(BoxName.lang) == 'ar'
? GoogleFonts.notoNaskhArabic().fontFamily

View File

@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_contacts/contact.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:get/get.dart';
import 'package:share/share.dart';
import '../../../main.dart';
import '../../../print.dart';
@@ -19,6 +20,42 @@ import '../../notification/notification_captain_controller.dart';
class InviteController extends GetxController {
final TextEditingController invitePhoneController = TextEditingController();
List driverInvitationData = [];
List driverInvitationDataToPassengers = [];
String? couponCode;
String? driverCouponCode;
int selectedTab = 0;
PassengerStats passengerStats = PassengerStats();
void updateSelectedTab(int index) {
selectedTab = index;
update();
}
Future<void> shareCouponCode() async {
// TODO: Implement sharing functionality
// You can use share_plus package to share the coupon code
}
Future<void> shareDriverCode() async {
if (driverCouponCode != null) {
final String shareText = '''
Join SEFER as a driver using my referral code!
Use code: $driverCouponCode
Download the SEFER Driver app now and earn rewards!
''';
await Share.share(shareText);
}
}
Future<void> sharePassengerCode() async {
if (couponCode != null) {
final String shareText = '''
Get a discount on your first SEFER ride!
Use my referral code: $couponCode
Download the SEFER app now and enjoy your ride!
''';
await Share.share(shareText);
}
}
@override
void onInit() {
@@ -39,6 +76,20 @@ class InviteController extends GetxController {
} catch (e) {}
}
void fetchDriverStatsPassengers() async {
try {
var response = await CRUD()
.get(link: AppLink.getDriverInvitationToPassengers, payload: {
"driverId": box.read(BoxName.driverID),
});
if (response != 'failure') {
var data = jsonDecode(response);
driverInvitationDataToPassengers = data['message'];
update();
}
} catch (e) {}
}
void selectPhone(String phone) {
if (box.read(BoxName.countryCode) == 'Egypt') {
invitePhoneController.text = phone;
@@ -136,6 +187,57 @@ class InviteController extends GetxController {
);
}
void onSelectPassengerInvitation(int index) async {
MyDialog().getDialog(
driverInvitationDataToPassengers[index]['countOfInvitDriver'] < 6
? '${'When'.tr} ${driverInvitationDataToPassengers[index]['passengerName']} ${"complete, you can claim your gift".tr} '
: 'You deserve the gift'.tr,
'${driverInvitationDataToPassengers[index]['passengerName']} ${driverInvitationDataToPassengers[index]['countOfInvitDriver']} / 6 ${'Trip'.tr}',
() async {
if (driverInvitationDataToPassengers[index]['countOfInvitDriver'] < 6) {
Get.back();
} else {
// Claim the gift if 100 trips are completed
if (driverInvitationDataToPassengers[index]['isGiftToken']
.toString() ==
'0') {
Get.back();
// Add wallet to the inviter
await Get.find<CaptainWalletController>()
.addDriverWallet('paymentMethod', '50');
// add for invitor too
await Get.find<CaptainWalletController>().addDriverWalletToInvitor(
'paymentMethod',
driverInvitationData[index]['driverInviterId'],
'50');
// Update invitation as claimed
await CRUD().post(
link: AppLink.updatePassengerGift,
payload: {'id': driverInvitationDataToPassengers[index]['id']},
);
// Notify the inviter
NotificationCaptainController().addNotificationCaptain(
driverInvitationDataToPassengers[index]['passengerInviterId']
.toString(),
"You have got a gift for invitation".tr,
'${"You have 50".tr} ${'LE'}',
false,
);
} else {
Get.back();
MyDialog().getDialog(
"You have got a gift".tr,
"Share the app with another new passenger".tr,
() {
Get.back();
},
);
}
}
},
);
}
savePhoneToServer() async {
for (var i = 0; i < contactMaps.length; i++) {
var phones = contactMaps[i]['phones'];
@@ -174,7 +276,7 @@ class InviteController extends GetxController {
var response = await CRUD().post(link: AppLink.addInviteDriver, payload: {
"driverId": box.read(BoxName.driverID),
"inviterDriverPhone": phoneNumber
"inviterDriverPhone": '+2$phoneNumber'
});
if (response != 'failure') {
@@ -203,4 +305,58 @@ class InviteController extends GetxController {
// Get.snackbar('Error', 'An error occurred'.tr);
// }
}
void sendInviteToPassenger() async {
if (invitePhoneController.text.isEmpty) {
Get.snackbar('Error', 'Please enter an phone address'.tr);
return;
}
// try {
String phoneNumber = formatPhoneNumber(invitePhoneController.text);
var response =
await CRUD().post(link: AppLink.addInvitationPassenger, payload: {
"driverId": box.read(BoxName.driverID),
"inviterPassengerPhone": '+2$phoneNumber'
});
if (response != 'failure') {
var d = jsonDecode(response);
Get.snackbar('Success', 'Invite sent successfully'.tr);
String message = '${'*SEFER APP CODE*'.tr}\n\n'
'${"Use this code in registration".tr}\n'
'${"To get a gift for both".tr}\n\n'
'${"The period of this code is 1 hour".tr}\n\n'
'${'before'.tr} *${d['message']['expirationTime'].toString()}*\n\n'
'_*${d['message']['inviteCode'].toString()}*_\n\n'
'${"Install our app:".tr}\n'
'*Android:* https://play.google.com/store/apps/details?id=com.mobileapp.store.ride\n\n\n'
'*iOS:* https://apps.apple.com/us/app/sefer/id6458734951';
launchCommunication('whatsapp', '+2$phoneNumber', message);
invitePhoneController.clear();
} else {
Get.snackbar('Error'.tr, "Invite code already used".tr,
backgroundColor: AppColor.redColor,
duration: const Duration(seconds: 4));
}
// } catch (e) {
// Get.snackbar('Error', 'An error occurred'.tr);
// }
}
}
class PassengerStats {
final int totalInvites;
final int activeUsers;
final double totalEarnings;
PassengerStats({
this.totalInvites = 0,
this.activeUsers = 0,
this.totalEarnings = 0.0,
});
}

View File

@@ -88,6 +88,31 @@ class LoginDriverController extends GetxController {
BoxName.nameDriver,
'${jsonDecoeded['data'][0]['first_name']}'
' ${jsonDecoeded['data'][0]['last_name']}');
if ((jsonDecoeded['data'][0]['model'].toString().contains('دراجه') ||
jsonDecoeded['data'][0]['make'].toString().contains('دراجه '))) {
if (jsonDecoeded['data'][0]['gender'].toString() == 'Male') {
box.write(BoxName.carTypeOfDriver, 'Scooter');
} else {
box.write(BoxName.carTypeOfDriver, 'Pink Bike');
}
} else if (int.parse(jsonDecoeded['data'][0]['year'].toString()) >
2017) {
if (jsonDecoeded['data'][0]['gender'].toString() != 'Male') {
box.write(BoxName.carTypeOfDriver, 'Lady');
} else {
box.write(BoxName.carTypeOfDriver, 'Comfort');
}
} else if (int.parse(jsonDecoeded['data'][0]['year'].toString()) >
2002 &&
int.parse(jsonDecoeded['data'][0]['year'].toString()) < 2017) {
box.write(BoxName.carTypeOfDriver, 'Speed');
} else if (int.parse(jsonDecoeded['data'][0]['year'].toString()) <
2002) {
box.write(BoxName.carTypeOfDriver, 'Awfar Car');
}
Log.print(
' box.write(BoxName.carTypeOfDriver: ${box.read(BoxName.carTypeOfDriver)}');
var token = await CRUD().get(
link: AppLink.getDriverToken,

View File

@@ -158,8 +158,16 @@ class FirebaseMessagesController extends GetxController {
// Get.to(const VipOrderPage());
} else if (message.notification!.title! == 'message From passenger'.tr) {
passengerDialog(message.notification!.body!);
if (Platform.isAndroid) {
NotificationController()
.showNotification('message From passenger'.tr, ''.tr, 'ding', '');
}
} else if (message.notification!.title == 'Cancel') {
cancelTripDialog1();
if (Platform.isAndroid) {
NotificationController()
.showNotification('Cancel'.tr, ''.tr, 'cancel', '');
}
} else if (message.notification!.title! == 'token change') {
// NotificationController1()
// .showNotification('token change'.tr, 'token change', 'cancel');
@@ -167,7 +175,7 @@ class FirebaseMessagesController extends GetxController {
GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'face detect') {
if (Platform.isAndroid) {
NotificationController1()
NotificationController()
.showNotification('face detect'.tr, ''.tr, 'tone2', '');
}
String result0 = await faceDetector();

View File

@@ -70,6 +70,23 @@ class AI extends GetxController {
}
}
Future updatePassengersInvitation() async {
if (formKey.currentState!.validate()) {
var res = await CRUD().post(
link: AppLink.updatePassengersInvitation,
payload: {"inviteCode": invitationCodeController.text});
if (res != 'failure') {
isInviteDriverFound = true;
update();
Get.snackbar("Code approved".tr, '',
backgroundColor: AppColor.greenColor);
} else {
Get.snackbar("Code not approved".tr, '',
backgroundColor: AppColor.redColor);
}
}
}
final today = DateTime.now();
Future<void> addDriverAndCarEgypt() async {

View File

@@ -28,25 +28,13 @@ Future<void> getPermissionOverlay() async {
}
}
// Future<void> getPermissionLocation() async {
// // final PermissionStatus status = await Permission.location.status;
// // if (!status.isGranted) {
// // Log.print('status.isGranted: ${status.isGranted}');
// // // box.write(BoxName.locationPermission, 'true');
// // await Permission.location.request();
// // Get.find<LoginDriverController>().update();
// // MyDialog().getDialog(
// // 'Enable Location Permission'.tr, // {en:ar}
// // 'Allowing location access will help us display orders near you. Please enable it now.'
// // .tr, // {en:ar}
// // () async {
// // Get.back();
// // box.write(BoxName.locationPermission, 'true');
// // await Permission.location.request();
// // },
// // );
// // }
// }
Future<void> closeOverlayIfFound() async {
bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
}
final location = Location();
Future<void> getLocationPermission() async {
bool serviceEnabled;

View File

@@ -462,6 +462,7 @@ class MapDriverController extends GetxController {
mapController!.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
bearing: Get.find<LocationController>().heading,
target: myLocation,
zoom: 17, // Adjust zoom level as needed
),
@@ -527,6 +528,25 @@ class MapDriverController extends GetxController {
? (distanceBetweenDriverAndPassengerWhenConfirm * .08) + (5 * 1)
: (distanceBetweenDriverAndPassengerWhenConfirm * .06) +
(5 * .06); //for Eygpt other like jordan .06 per minute
await CRUD().post(link: AppLink.updateRides, payload: {
'id': rideId,
'rideTimeStart': DateTime.now().toString(),
'status': 'CancelAfterWait',
});
CRUD().post(
link: "${AppLink.seferAlexandriaServer}/rides/update.php",
payload: {
'id': rideId,
'rideTimeStart': DateTime.now().toString(),
'status': 'CancelAfterWait',
});
CRUD()
.post(link: "${AppLink.seferGizaServer}/rides/update.php", payload: {
'id': rideId,
'rideTimeStart': DateTime.now().toString(),
'status': 'CancelAfterWait',
});
var paymentTokenWait =
await generateTokenDriver(costOfWaiting5Minute.toString());
var res = await CRUD().post(link: AppLink.addDrivePayment, payload: {

View File

@@ -165,6 +165,32 @@ class MyTranslation extends Translations {
'Rejected Orders Count': "عدد الطلبات المرفوضة",
'This is the total number of rejected orders per day after accepting the orders':
'هذا هو العدد الإجمالي للطلبات المرفوضة يوميًا بعد قبول الطلبات',
"Invite": "دعوة",
"Drivers": "السائقين",
"Passengers": "الركاب",
"Your Driver Referral Code": "رمز الإحالة الخاص بالسائق",
"DRIVER123": "سائق123",
"Share this code with other drivers. Both of you will receive rewards!":
"شارك هذا الرمز مع السائقين الآخرين. سيحصل كل منكما على مكافآت!",
"Share Code": "مشاركة الرمز",
"Invite another driver and both get a gift after he completes 100 trips!":
"ادع سائقًا آخر وسيحصل كلاكما على هدية بعد أن يكمل 100 رحلة!",
"Enter phone": "أدخل رقم الهاتف",
"Send Invite": "إرسال دعوة",
"Show Invitations": "عرض الدعوات",
"No invitation found yet!": "لم يتم العثور على دعوات حتى الآن!",
"Trip": "رحلة",
"Your Passenger Referral Code": "رمز الإحالة الخاص بالراكب",
"SEFER123": "سفر123",
"Share this code with passengers and earn rewards when they use it!":
"شارك هذا الرمز مع الركاب واكسب مكافآت عند استخدامه!",
"Your Rewards": "مكافآتك",
"Total Invites": "إجمالي الدعوات",
"Active Users": "المستخدمون النشطون",
"Total Earnings": "إجمالي الأرباح",
"Choose from contact": "اختر من جهات الاتصال",
"Cancel": "إلغاء",
"No invitation found": "لم يتم العثور على دعوة",
'You are not near the passenger location':
"أنت لست بالقرب من موقع الراكب",
'If you need assistance, contact us':

View File

@@ -44,7 +44,7 @@ class RideAvailableController extends GetxController {
var res = await CRUD().get(
link: AppLink.getRideWaiting,
payload: {
"carType": box.read(BoxName.carTypeOfDriver),
"carType": box.read(BoxName.carTypeOfDriver).toString(),
'southwestLat': bounds.southwest.latitude.toString(),
'southwestLon': bounds.southwest.longitude.toString(),
'northeastLat': bounds.northeast.latitude.toString(),

View File

@@ -662,25 +662,28 @@ class PaymentController extends GetxController {
onPayment: (PaymobResponse response) {},
);
if (response!.responseCode == 'APPROVED') {
Get.defaultDialog(
barrierDismissible: false,
title: 'Payment Successful'.tr,
titleStyle: AppStyle.title,
// backgroundColor: AppColor.greenColor,
content: Text(
'The payment was approved.'.tr,
style: AppStyle.title,
),
confirm: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'OK'.tr,
onPressed: () async {
Get.back();
method();
},
),
);
// if (response!.responseCode == 'APPROVED') {
if (response!.responseCode == '200' && response.success == true) {
Toast.show(context, 'Payment Successful'.tr, AppColor.greenColor);
method();
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'Payment Successful'.tr,
// titleStyle: AppStyle.title,
// // backgroundColor: AppColor.greenColor,
// content: Text(
// 'The payment was approved.'.tr,
// style: AppStyle.title,
// ),
// confirm: MyElevatedButton(
// kolor: AppColor.greenColor,
// title: 'OK'.tr,
// onPressed: () async {
// Get.back();
// method();
// },
// ),
// );
} else {
Get.defaultDialog(
barrierDismissible: false,

View File

@@ -1,156 +1,544 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../controller/auth/captin/invit_controller.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import '../../../controller/auth/captin/invit_controller.dart';
import '../../widgets/elevated_btn.dart';
class InviteDriverScreen extends StatelessWidget {
class InviteScreen extends StatelessWidget {
final InviteController controller = Get.put(InviteController());
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Invite a Driver'.tr),
leading: CupertinoNavigationBarBackButton(
return Scaffold(
backgroundColor: CupertinoColors.systemBackground,
appBar: AppBar(
backgroundColor: CupertinoColors.systemBackground,
elevation: 0,
title: Text(
'Invite'.tr,
style: const TextStyle(color: CupertinoColors.label),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: AppColor.blueColor),
onPressed: () => Get.back(),
),
),
child: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Invite another driver and both get a gift after he completes 100 trips!"
.tr,
style: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
),
const SizedBox(height: 20),
Row(
children: [
Expanded(
child: CupertinoTextField(
controller: controller.invitePhoneController,
placeholder: 'Enter driver\'s phone'.tr,
keyboardType: TextInputType.phone,
body: SafeArea(
child: GetBuilder<InviteController>(
builder: (controller) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(8),
),
child: SegmentedButton<int>(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.resolveWith<Color>(
(states) => states.contains(MaterialState.selected)
? CupertinoColors.white
: Colors.transparent,
),
foregroundColor:
MaterialStateProperty.resolveWith<Color>(
(states) => states.contains(MaterialState.selected)
? AppColor.blueColor
: CupertinoColors.label,
),
),
segments: [
ButtonSegment(
value: 0,
label: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Drivers'.tr),
),
),
ButtonSegment(
value: 1,
label: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Passengers'.tr),
),
),
],
selected: {controller.selectedTab},
onSelectionChanged: (Set<int> newSelection) {
controller.updateSelectedTab(newSelection.first);
},
),
),
CupertinoButton(
child: const Icon(CupertinoIcons.person_2),
onPressed: () async {
await controller.pickContacts();
if (controller.contacts.isNotEmpty) {
if (box.read(BoxName.IsSavedPhones) == null) {
controller.savePhoneToServer();
box.write(BoxName.IsSavedPhones, true);
}
_showContactsDialog(context);
}
},
),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: controller.selectedTab == 0
? _buildDriverTab(context)
: _buildPassengerTab(context),
),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
MyElevatedButton(
title: 'Send Invite'.tr,
onPressed: controller.sendInvite,
),
MyElevatedButton(
title: 'Show Invitations'.tr,
onPressed: () async {
controller.fetchDriverStats();
},
),
],
),
const SizedBox(height: 20),
GetBuilder<InviteController>(
builder: (controller) {
return SizedBox(
height: Get.height * .4,
child: controller.driverInvitationData.isEmpty
? Center(
child: Text(
"No invitation found yet!".tr,
style: CupertinoTheme.of(context)
.textTheme
.navTitleTextStyle,
),
)
: ListView.builder(
itemCount: controller.driverInvitationData.length,
itemBuilder: (context, index) {
int countOfInvitDriver = int.tryParse(controller
.driverInvitationData[index]
['countOfInvitDriver']
?.toString() ??
'0') ??
0;
),
],
);
},
),
),
);
}
double progressValue = countOfInvitDriver / 100.0;
progressValue = progressValue.clamp(0.0, 1.0);
Widget _buildDriverTab(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
Text(
"Invite another driver and both get a gift after he completes 100 trips!"
.tr,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: CupertinoColors.label,
),
),
const SizedBox(height: 20),
_buildPhoneInput(),
const SizedBox(height: 20),
_buildActionButtons(),
const SizedBox(height: 20),
_buildInvitationsList(context),
],
);
}
return GestureDetector(
onTap: () async {
controller.onSelectDriverInvitation(index);
},
child: Container(
margin:
const EdgeInsets.symmetric(vertical: 8.0),
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(12),
color: CupertinoColors.systemGrey5,
),
width: Get.width * .85,
height: 35,
child: ClipRRect(
borderRadius:
BorderRadius.circular(12),
child: LinearProgressIndicator(
value: progressValue,
backgroundColor:
CupertinoColors.systemGrey3,
valueColor:
const AlwaysStoppedAnimation<
Color>(
CupertinoColors.activeBlue),
),
),
),
Text(
'${controller.driverInvitationData[index]['invitorName']} ${countOfInvitDriver} / 100 ${'Trip'.tr}',
style: CupertinoTheme.of(context)
.textTheme
.textStyle,
),
],
),
),
);
},
),
);
},
)
Widget _buildPassengerTab(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Text(
"Share this code with passengers and earn rewards when they use it!"
.tr,
textAlign: TextAlign.center,
style: const TextStyle(
color: CupertinoColors.secondaryLabel,
fontSize: 13,
),
),
],
),
),
const SizedBox(height: 20),
_buildPhoneInput(),
const SizedBox(height: 20),
_buildActionButtonsPassengers(),
const SizedBox(height: 20),
const SizedBox(height: 20),
_buildInvitationsListPassengers(context),
],
);
}
Widget _buildPhoneInput() {
return Container(
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Expanded(
child: CupertinoTextField.borderless(
controller: controller.invitePhoneController,
placeholder: 'Enter phone'.tr,
padding: const EdgeInsets.all(12),
keyboardType: TextInputType.phone,
),
),
CupertinoButton(
child: const Icon(CupertinoIcons.person_badge_plus,
color: AppColor.blueColor),
onPressed: () async {
await controller.pickContacts();
if (controller.contacts.isNotEmpty) {
if (box.read(BoxName.IsSavedPhones) == null) {
controller.savePhoneToServer();
box.write(BoxName.IsSavedPhones, true);
}
_showContactsDialog(Get.context!);
}
},
),
],
),
);
}
Widget _buildActionButtons() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
child: CupertinoButton(
color: AppColor.blueColor,
borderRadius: BorderRadius.circular(10),
padding: const EdgeInsets.symmetric(vertical: 14),
onPressed: controller.sendInvite,
child: Text(
'Send Invite'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: CupertinoColors.white,
),
),
),
),
),
const SizedBox(width: 16),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
child: CupertinoButton(
color: AppColor.blueColor,
borderRadius: BorderRadius.circular(10),
padding: const EdgeInsets.symmetric(vertical: 14),
child: Text(
'Show Invitations'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: CupertinoColors.white,
),
),
onPressed: () async {
controller.fetchDriverStats();
},
),
),
),
],
),
);
}
Widget _buildActionButtonsPassengers() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
child: CupertinoButton(
color: AppColor.blueColor,
borderRadius: BorderRadius.circular(10),
padding: const EdgeInsets.symmetric(vertical: 14),
onPressed: controller.sendInviteToPassenger,
child: Text(
'Send Invite'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: CupertinoColors.white,
),
),
),
),
),
const SizedBox(width: 16),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 6,
offset: const Offset(0, 3),
),
],
),
child: CupertinoButton(
color: AppColor.blueColor,
borderRadius: BorderRadius.circular(10),
padding: const EdgeInsets.symmetric(vertical: 14),
child: Text(
'Show Invitations'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: CupertinoColors.white,
),
),
onPressed: () async {
controller.fetchDriverStatsPassengers();
},
),
),
),
],
),
);
}
Widget _buildInvitationsList(BuildContext context) {
return SizedBox(
height: Get.height * .4,
child: controller.driverInvitationData.isEmpty
? Center(
child: Text(
"No invitation found yet!".tr,
style: const TextStyle(
color: CupertinoColors.secondaryLabel,
fontSize: 17,
),
),
)
: ListView.builder(
itemCount: controller.driverInvitationData.length,
itemBuilder: (context, index) {
return _buildInvitationItem(context, index);
},
),
);
}
Widget _buildInvitationsListPassengers(BuildContext context) {
return SizedBox(
height: Get.height * .4,
child: controller.driverInvitationDataToPassengers.isEmpty
? Center(
child: Text(
"No invitation found yet!".tr,
style: const TextStyle(
color: CupertinoColors.secondaryLabel,
fontSize: 17,
),
),
)
: ListView.builder(
itemCount: controller.driverInvitationDataToPassengers.length,
itemBuilder: (context, index) {
return _buildInvitationItemPassengers(context, index);
},
),
);
}
Widget _buildInvitationItem(BuildContext context, int index) {
int countOfInvitDriver = int.tryParse(controller.driverInvitationData[index]
['countOfInvitDriver']
?.toString() ??
'0') ??
0;
double progressValue = (countOfInvitDriver / 100.0).clamp(0.0, 1.0);
return GestureDetector(
onTap: () {
controller.onSelectDriverInvitation(index);
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
controller.driverInvitationData[index]['invitorName'],
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: CupertinoColors.label,
),
),
const SizedBox(height: 8),
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: LinearProgressIndicator(
value: progressValue,
backgroundColor: CupertinoColors.systemGrey4,
valueColor:
const AlwaysStoppedAnimation<Color>(AppColor.blueColor),
minHeight: 6,
),
),
const SizedBox(height: 4),
Text(
'$countOfInvitDriver / 100 ${'Trip'.tr}',
style: const TextStyle(
fontSize: 13,
color: CupertinoColors.secondaryLabel,
),
),
],
),
),
);
}
Widget _buildInvitationItemPassengers(BuildContext context, int index) {
// Extracting the data from the sample JSON-like structure
var invitation = controller.driverInvitationDataToPassengers[index];
int countOfInvitDriver =
int.tryParse(invitation['countOfInvitDriver']?.toString() ?? '0') ?? 0;
double progressValue = (countOfInvitDriver / 10.0).clamp(0.0, 1.0);
return GestureDetector(
onTap: () {
controller.onSelectPassengerInvitation(index);
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
invitation['passengerName']
.toString(), // Handle null or missing data
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: CupertinoColors.label,
),
),
const SizedBox(height: 8),
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: LinearProgressIndicator(
value: progressValue,
backgroundColor: CupertinoColors.systemGrey4,
valueColor:
const AlwaysStoppedAnimation<Color>(AppColor.blueColor),
minHeight: 6,
),
),
const SizedBox(height: 4),
Text(
'$countOfInvitDriver / 6 ${'Trip'.tr}', // Show trips completed
style: const TextStyle(
fontSize: 13,
color: CupertinoColors.secondaryLabel,
),
),
],
),
),
);
}
Widget _buildPassengerStats(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Your Rewards".tr,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: CupertinoColors.label,
),
),
const SizedBox(height: 16),
_buildStatItem(
context,
"Total Invites".tr,
controller.driverInvitationDataToPassengers[0]['countOfInvitDriver']
.toString(),
),
_buildStatItem(
context,
"Active Users".tr,
controller.driverInvitationDataToPassengers[0]['passengerName']
.toString(),
),
],
),
);
}
Widget _buildStatItem(BuildContext context, String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: const TextStyle(
color: CupertinoColors.label,
fontSize: 15,
),
),
Text(
value,
style: const TextStyle(
fontWeight: FontWeight.w600,
color: AppColor.blueColor,
fontSize: 15,
),
),
],
),
);
}
@@ -158,34 +546,94 @@ class InviteDriverScreen extends StatelessWidget {
void _showContactsDialog(BuildContext context) {
showCupertinoModalPopup(
context: context,
builder: (BuildContext context) => CupertinoActionSheet(
title: Text('Choose from contact'.tr),
actions: [
SizedBox(
height: 300,
child: CupertinoScrollbar(
builder: (BuildContext context) => Container(
height: 400,
color: CupertinoColors.systemBackground,
child: Column(
children: [
Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: CupertinoColors.separator.withOpacity(0.5)),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CupertinoButton(
padding: EdgeInsets.zero,
child: Text('Cancel'.tr),
onPressed: () => Navigator.pop(context),
),
Text(
'Choose from contact'.tr,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
),
),
const SizedBox(width: 60), // For balance
],
),
),
Expanded(
child: ListView.builder(
itemCount: controller.contactMaps.length,
itemBuilder: (context, index) {
final contact = controller.contactMaps[index];
return CupertinoActionSheetAction(
child: Text(
'${contact['name']} - ${controller.formatPhoneNumber(contact['phones'][0].toString())}'),
onPressed: () {
controller.selectPhone(contact['phones'].toString());
// Navigator.pop(context);
},
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: CupertinoColors.separator.withOpacity(0.5),
),
),
),
child: CupertinoButton(
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 12),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
contact['name'],
style: const TextStyle(
color: CupertinoColors.label,
fontSize: 17,
),
),
Text(
controller.formatPhoneNumber(
contact['phones'][0].toString()),
style: const TextStyle(
color: CupertinoColors.secondaryLabel,
fontSize: 15,
),
),
],
),
),
const Icon(
CupertinoIcons.chevron_right,
color: CupertinoColors.secondaryLabel,
),
],
),
onPressed: () {
controller.selectPhone(contact['phones'].toString());
// Navigator.pop(context);
},
),
);
},
),
),
),
],
cancelButton: CupertinoActionSheetAction(
child: Text('Cancel'.tr),
onPressed: () {
Navigator.pop(context);
},
],
),
),
);

View File

@@ -20,18 +20,21 @@ class PassengerLocationMapPage extends StatelessWidget {
final LocationController locationController = Get.put(LocationController());
final MapDriverController mapDriverController =
Get.put(MapDriverController());
@override
Widget build(BuildContext context) {
if (!mapDriverController.initialized) {
// Call a method to initialize the controller
// if (!mapDriverController.initialized) {
// // Call a method to initialize the controller
mapDriverController.initialized;
} else {
Get.put(MapDriverController()).argumentLoading();
// mapDriverController.initialized;
// } else {
// Get.put(MapDriverController()).argumentLoading();
Get.put(MapDriverController())
.startTimerToShowPassengerInfoWindowFromDriver();
}
// Get.put(MapDriverController())
// .startTimerToShowPassengerInfoWindowFromDriver();
// }
mapDriverController.argumentLoading();
mapDriverController.startTimerToShowPassengerInfoWindowFromDriver();
return Scaffold(
// title: 'Map Passenger'.tr,

View File

@@ -78,7 +78,7 @@ class CupertinoDrawerCaptain extends StatelessWidget {
_buildDrawerItem(
icon: CupertinoIcons.share,
text: 'Share App'.tr,
onTap: () => Get.to(() => InviteDriverScreen()),
onTap: () => Get.to(() => InviteScreen()),
),
_buildDivider(),
_buildDrawerItem(

View File

@@ -3,9 +3,9 @@ import 'dart:io';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/views/notification/available_rides_page.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
@@ -17,7 +17,6 @@ import '../../../../constant/colors.dart';
import '../../../../constant/info.dart';
import '../../../../constant/style.dart';
import '../../../../controller/functions/location_controller.dart';
import '../../../../controller/functions/location_permission.dart';
import '../../../../controller/functions/overlay_permisssion.dart';
import '../../../../controller/functions/package_info.dart';
import '../../../../controller/home/captin/home_captain_controller.dart';
@@ -38,13 +37,15 @@ class HomeCaptain extends StatelessWidget {
@override
Widget build(BuildContext context) {
Get.put(OrderRequestController());
Get.put(HomeCaptainController());
// Get.put(HomeCaptainController());
Get.put(CaptainWalletController());
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
closeOverlayIfFound();
checkForUpdate(context);
getPermissionOverlay();
// getPermissionLocation1();
_showFirstTimeOfferNotification(context);
await showFirstTimeOfferNotification(context);
});
return Scaffold(
appBar: AppBar(
@@ -59,16 +60,6 @@ class HomeCaptain extends StatelessWidget {
style: AppStyle.title,
)),
),
// IconButton(
// // onPressed: () => Get.find<OrderRequestController>().getSQL(),
// onPressed: () => sql.deleteAllData(TableName.driverOrdersRefuse),
// icon: const Icon(Icons.remove)),
// GetBuilder<OrderRequestController>(
// builder: (orderRequestController) => IconButton(
// onPressed: () =>
// orderRequestController.getRefusedOrderByCaptain(),
// icon: const Icon(Icons.get_app)),
// ),
],
),
drawer: CupertinoDrawerCaptain(),
@@ -381,7 +372,7 @@ class HomeCaptain extends StatelessWidget {
}
}
void _showFirstTimeOfferNotification(BuildContext context) {
showFirstTimeOfferNotification(BuildContext context) async {
bool isFirstTime = _checkIfFirstTime();
if (isFirstTime) {

View File

@@ -185,33 +185,33 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
const SizedBox(
height: 5,
),
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 {
bool isOverlayActive =
await FlutterOverlayWindow.isActive();
if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
// print(box.read(BoxName.tokenDriver));
},
icon: const Icon(
FontAwesome5.window_close,
size: 29,
color: AppColor.blueColor,
),
);
}),
)
: const SizedBox(),
// 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 {
// bool isOverlayActive =
// await FlutterOverlayWindow.isActive();
// if (isOverlayActive) {
// await FlutterOverlayWindow.closeOverlay();
// }
// // print(box.read(BoxName.tokenDriver));
// },
// icon: const Icon(
// FontAwesome5.window_close,
// size: 29,
// color: AppColor.blueColor,
// ),
// );
// }),
// )
// : const SizedBox(),
// AnimatedContainer(
// duration: const Duration(microseconds: 200),
// width: controller.widthMapTypeAndTraffic,

View File

@@ -28,39 +28,34 @@ class GoogleDriverMap extends StatelessWidget {
onMapCreated: controller.onMapCreated,
zoomControlsEnabled: true,
initialCameraPosition: CameraPosition(
// bearing: 45,
target: locationController.myLocation,
zoom: 13,
bearing: locationController.heading,
tilt: 40,
),
// onCameraMoveStarted: () {},
cameraTargetBounds: CameraTargetBounds(controller.boundsData),
cameraTargetBounds:
CameraTargetBounds.unbounded, // Allow unrestricted movement
onCameraMove: (position) {
locationController.myLocation = position.target;
controller.mapController!
.animateCamera(CameraUpdate.newCameraPosition(position));
// controller.mapController
// ?.animateCamera(CameraUpdate.newCameraPosition(position));
},
minMaxZoomPreference: const MinMaxZoomPreference(8, 15),
myLocationEnabled: true, myLocationButtonEnabled: true,
myLocationEnabled: true,
myLocationButtonEnabled: true,
compassEnabled: true,
mapType: MapType.terrain,
rotateGesturesEnabled: true,
scrollGesturesEnabled: true,
trafficEnabled: false,
// liteModeEnabled: true,
buildingsEnabled: true,
mapToolbarEnabled: true,
// zoomControlsEnabled: true,
fortyFiveDegreeImageryEnabled: true,
zoomGesturesEnabled: true,
polylines: {
Polyline(
zIndex: 2,
consumeTapEvents: true,
geodesic: true,
endCap: Cap.buttCap,
startCap: Cap.buttCap,
visible: true,
polylineId: const PolylineId('route1'),
points: controller.polylineCoordinates,
color: const Color.fromARGB(255, 163, 81, 246),
@@ -68,11 +63,7 @@ class GoogleDriverMap extends StatelessWidget {
),
Polyline(
zIndex: 2,
consumeTapEvents: true,
geodesic: true,
endCap: Cap.buttCap,
startCap: Cap.buttCap,
visible: true,
polylineId: const PolylineId('route'),
points: controller.polylineCoordinatesDestination,
color: const Color.fromARGB(255, 10, 29, 126),
@@ -81,11 +72,12 @@ class GoogleDriverMap extends StatelessWidget {
},
markers: {
Marker(
markerId: MarkerId('MyLocation'.tr),
position: locationController.myLocation,
draggable: true,
icon: controller.carIcon,
rotation: locationController.heading),
markerId: MarkerId('MyLocation'.tr),
position: locationController.myLocation,
draggable: true,
icon: controller.carIcon,
rotation: locationController.heading,
),
Marker(
markerId: MarkerId('start'.tr),
position: controller.latLngPassengerLocation,

View File

@@ -220,7 +220,7 @@ class OrderSpeedRequest extends StatelessWidget {
height: 5,
),
Container(
height: Get.height * .15,
height: Get.height * .2,
width: Get.width * .9,
decoration: AppStyle.boxDecoration1,
child: Padding(
@@ -301,40 +301,40 @@ class OrderSpeedRequest extends StatelessWidget {
),
),
Padding(
padding: const EdgeInsets.all(4),
child: Container(
color: AppColor.greenColor.withOpacity(.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RichText(
text: TextSpan(
text: 'Cost Of Trip IS '.tr,
style: AppStyle.title,
children: [
TextSpan(
text: myList[26], style: AppStyle.headTitle2),
],
),
),
RichText(
text: TextSpan(
text: 'Total net'.tr,
style: AppStyle.title,
children: [
TextSpan(
text: (double.parse(myList[2]) -
double.parse(myList[32]))
.toStringAsFixed(2),
style: AppStyle.headTitle2),
],
),
),
],
),
),
),
// Padding(
// padding: const EdgeInsets.all(4),
// child: Container(
// color: AppColor.greenColor.withOpacity(.5),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// RichText(
// text: TextSpan(
// text: 'Cost Of Trip IS '.tr,
// style: AppStyle.title,
// children: [
// TextSpan(
// text: myList[26], style: AppStyle.headTitle2),
// ],
// ),
// ),
// RichText(
// text: TextSpan(
// text: 'Total net'.tr,
// style: AppStyle.title,
// children: [
// TextSpan(
// text: (double.parse(myList[2]) -
// double.parse(myList[32]))
// .toStringAsFixed(2),
// style: AppStyle.headTitle2),
// ],
// ),
// ),
// ],
// ),
// ),
// ),
Padding(
padding: const EdgeInsets.all(8.0),
@@ -531,33 +531,52 @@ class OrderSpeedRequest extends StatelessWidget {
MyElevatedButton(
title: 'Refuse Order'.tr,
onPressed: () async {
Get.defaultDialog(
title: 'Reject Order'.tr,
titleStyle: AppStyle.title,
content: Column(
children: [
IconButton(
onPressed: () async {
await Get.find<TextToSpeechController>()
.speakText(
'You can decline a request without any cost'
.tr);
},
icon: const Icon(Icons.headphones),
),
Text(
'You can decline a request without any cost'
.tr,
style: AppStyle.title,
)
],
),
confirm: MyElevatedButton(
title: 'Ok'.tr,
onPressed: () {
Get.back();
Get.back();
}));
// Get.defaultDialog(
// title: 'Reject Order'.tr,
// titleStyle: AppStyle.title,
// content: Column(
// children: [
// IconButton(
// onPressed: () async {
// await Get.find<TextToSpeechController>()
// .speakText(
// 'You can decline a request without any cost'
// .tr);
// },
// icon: const Icon(Icons.headphones),
// ),
// Text(
// 'You can decline a request without any cost'
// .tr,
// style: AppStyle.title,
// )
// ],
// ),
// confirm: MyElevatedButton(
// title: 'Ok'.tr,
// onPressed: () {
// Get.back();
// Get.back();
// }));
orderRequestController.endTimer();
orderRequestController.refuseOrder(
myList[16].toString(),
);
orderRequestController.addRideToNotificationDriverString(
myList[16].toString(),
myList[29].toString(),
myList[30].toString(),
'${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}',
'${DateTime.now().hour}:${DateTime.now().minute}',
myList[2].toString(),
myList[7].toString(),
'wait',
myList[31].toString(),
myList[33].toString(),
myList[2].toString(),
myList[5].toString(),
myList[4].toString());
},
kolor: AppColor.redColor,
),

View File

@@ -1,23 +1,11 @@
import 'dart:convert';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:SEFER/controller/notification/ride_available_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../controller/firebase/firbase_messge.dart';
import '../../controller/functions/crud.dart';
import '../../main.dart';
import '../home/Captin/driver_map_page.dart';
class AvailableRidesPage extends StatelessWidget {
const AvailableRidesPage({super.key});
@@ -34,293 +22,113 @@ class AvailableRidesPage extends StatelessWidget {
: ListView.builder(
itemCount: rideAvailableController
.rideAvailableMap['message'].length,
itemBuilder: (BuildContext context, int index) {
var list = rideAvailableController
.rideAvailableMap['message'][index];
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: Get.width * .9,
decoration: AppStyle.boxDecoration1,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'🟢 ',
style: AppStyle.subtitle,
),
SizedBox(
height: Get.height * .06,
width: Get.width * .8,
child: Text(
'${list['startName']}',
style: AppStyle.subtitle,
),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'🔴 ',
style: AppStyle.subtitle,
),
SizedBox(
height: Get.height * .06,
width: Get.width * .8,
child: Text(
'${list['endName']}',
style: AppStyle.subtitle,
),
),
],
),
const SizedBox(height: 4),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Text('${'Price: '.tr}${list['price']} \$'),
const SizedBox(height: 4),
Text(
'${list['carType']}',
style: AppStyle.title
.copyWith(color: AppColor.greenColor),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: [
Text('📈 ${list['passengerRate']}',
style: AppStyle.title),
MyElevatedButton(
title: 'Accept'.tr,
onPressed: () async {
box.write(
BoxName.statusDriverLocation, 'on');
var res = await CRUD().post(
link: AppLink.updateStausFromSpeed,
payload: {
'id': list['id'],
'rideTimeStart':
DateTime.now().toString(),
'status': 'Apply',
'driver_id':
box.read(BoxName.driverID),
});
CRUD().post(
link:
'${AppLink.seferAlexandriaServer}rides/updateStausFromSpeed.php',
payload: {
'id': list['id'],
'rideTimeStart':
DateTime.now().toString(),
'status': 'Apply',
'driver_id':
box.read(BoxName.driverID),
});
CRUD().post(
link:
'${AppLink.seferGizaServer}rides/updateStausFromSpeed.php',
payload: {
'id': list['id'],
'rideTimeStart':
DateTime.now().toString(),
'status': 'Apply',
'driver_id':
box.read(BoxName.driverID),
});
// .then((value) {
// var json = jsonDecode(res);
if (res == "failure") {
MyDialog().getDialog(
"This ride is already taken by another driver."
.tr,
'', () {
CRUD().post(
link: AppLink.deleteAvailableRide,
payload: {'id': list['id']});
CRUD().post(
link:
'${AppLink.endPoint}/ride/notificationCaptain/deleteAvailableRide.php',
payload: {'id': list['id']});
Get.back();
});
} else if (jsonDecode(res)['status'] ==
"success") {
List<String> bodyToPassenger = [
box.read(BoxName.driverID).toString(),
box
.read(BoxName.nameDriver)
.toString(),
box
.read(BoxName.tokenDriver)
.toString(),
];
await CRUD().postFromDialogue(
link: AppLink.addDriverOrder,
payload: {
'driver_id':
box.read(BoxName.driverID),
// box.read(BoxName.driverID).toString(),
'order_id': list['id'],
'status': 'Apply'
});
CRUD().postFromDialogue(
link:
'${AppLink.seferAlexandriaServer}/driver_order/add.php',
payload: {
'driver_id':
box.read(BoxName.driverID),
// box.read(BoxName.driverID).toString(),
'order_id': list['id'],
'status': 'Apply'
});
CRUD().postFromDialogue(
link:
'${AppLink.seferGizaServer}/driver_order/add.php',
payload: {
'driver_id':
box.read(BoxName.driverID),
// box.read(BoxName.driverID).toString(),
'order_id': list['id'],
'status': 'Apply'
});
await CRUD().post(
link: AppLink.updateRides,
payload: {
'id': list['id'],
'DriverIsGoingToPassenger':
DateTime.now().toString(),
'status': 'Applied'
});
CRUD().post(
link:
'${AppLink.seferAlexandriaServer}/rides/update.php',
payload: {
'id': list['id'],
'DriverIsGoingToPassenger':
DateTime.now().toString(),
'status': 'Applied'
});
CRUD().post(
link:
'${AppLink.seferGizaServer}/rides/update.php',
payload: {
'id': list['id'],
'DriverIsGoingToPassenger':
DateTime.now().toString(),
'status': 'Applied'
});
await CRUD().post(
link: AppLink.updateWaitingRide,
payload: {
'id': list['id'],
'status': 'Applied'
});
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Apply Ride',
'your ride is applied'.tr,
// arguments['DriverList'][9].toString(),
list['passengerToken']
.toString(),
// box.read(BoxName.tokenDriver).toString(),
bodyToPassenger,
'start.wav');
Get.back();
Get.to(() => PassengerLocationMapPage(),
arguments: {
'passengerLocation':
list['start_location']
.toString(),
'passengerDestination':
list['end_location']
.toString(),
'Duration':
list['duration'].toString(),
'totalCost':
list['price'].toString(),
'Distance':
list['distance'].toString(),
'name':
list['first_name'].toString(),
'phone': list['phone'].toString(),
'email': list['email'].toString(),
'WalletChecked':
list['payment_method']
.toString(),
'tokenPassenger':
list['passengerToken']
.toString(),
'direction':
'https://www.google.com/maps/dir/${list['start_location']}/${list['end_location']}/',
'DurationToPassenger':
list['duration'].toString(),
'rideId': list['id'].toString(),
'passengerId':
list['passenger_id']
.toString(),
'driverId': box
.read(BoxName.driverID)
.toString(),
'durationOfRideValue':
list['duration'].toString(),
'paymentAmount':
list['price'].toString(),
'paymentMethod':
'cash'.toString() == //todo fix payment method
'true'
? 'visa'
: 'cash',
'isHaveSteps':
'startEnd'.toString(),
'step0': ''.toString(),
'step1': ''.toString(),
'step2': ''.toString(),
'step3': ''.toString(),
'step4': ''.toString(),
'passengerWalletBurc':
list['bruc'].toString(),
'timeOfOrder':
DateTime.now().toString(),
'totalPassenger':
list['price'].toString(),
'carType':
list['carType'].toString(),
'kazan': Get.find<
HomeCaptainController>()
.kazan
.toString(),
});
}
},
kolor: AppColor.greenColor,
),
Text(
'📍 ${list['distance']} ${'KM'.tr}',
style: AppStyle.title
.copyWith(color: AppColor.greenColor),
),
],
)
],
),
),
);
})
itemBuilder: (context, index) => RideAvailableCard(
rideInfo: rideAvailableController
.rideAvailableMap['message'][index],
),
)
],
isleading: true);
});
}
}
class RideAvailableCard extends StatelessWidget {
final Map<String, dynamic> rideInfo;
const RideAvailableCard({Key? key, required this.rideInfo}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(8.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// _buildLocationRow('🟢', rideInfo['startName']),
// const SizedBox(height: 8),
// _buildLocationRow('🔴', rideInfo['endName']),
_buildLocationRow('', rideInfo['startName'], AppColor.greenColor),
const SizedBox(height: 8),
_buildLocationRow('', rideInfo['endName'], Colors.red),
const SizedBox(height: 16),
_buildInfoRow(),
const SizedBox(height: 16),
_buildActionRow(),
],
),
),
);
}
Widget _buildLocationRow(String icon, String location, Color iconColor) {
return Row(
children: [
Text(
icon,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold, color: iconColor),
),
const SizedBox(width: 8),
Expanded(
child: Text(
location,
style: AppStyle.subtitle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
],
);
}
Widget _buildInfoRow() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('${'Price:'.tr} ${rideInfo['price']} \$', style: AppStyle.title),
Text(
rideInfo['carType'],
style: AppStyle.title.copyWith(color: AppColor.greenColor),
),
],
);
}
Widget _buildActionRow() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('📈 ${rideInfo['passengerRate']}', style: AppStyle.title),
const SizedBox(height: 4),
Text(
'📍 ${rideInfo['distance']} ${'KM'.tr}',
style: AppStyle.title.copyWith(color: AppColor.greenColor),
),
],
),
ElevatedButton(
onPressed: () => _acceptRide(),
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.greenColor,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
child: Text('Accept'.tr),
),
],
);
}
void _acceptRide() async {
// Your existing accept ride logic here
// ...
}
}