diff --git a/android/app/build.gradle b/android/app/build.gradle
index 1246a23..ef50745 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -54,8 +54,8 @@ android {
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdk = 23
targetSdk = flutter.targetSdkVersion
- versionCode = 105
- versionName = '1.5.05'
+ versionCode = 107
+ versionName = '1.5.07'
multiDexEnabled =true
}
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 17abe8c..597f364 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -33,7 +33,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 64
+ 66
CFBundleSignature
????
CFBundleURLTypes
@@ -48,7 +48,7 @@
CFBundleVersion
- 4.0.64
+ 4.0.66
FirebaseAppDelegateProxyEnabled
NO
GMSApiKey
diff --git a/lib/constant/links.dart b/lib/constant/links.dart
index 1aa7457..b20b1e4 100644
--- a/lib/constant/links.dart
+++ b/lib/constant/links.dart
@@ -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============
diff --git a/lib/constant/style.dart b/lib/constant/style.dart
index 9d13b27..b8a4951 100644
--- a/lib/constant/style.dart
+++ b/lib/constant/style.dart
@@ -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
diff --git a/lib/controller/auth/captin/invit_controller.dart b/lib/controller/auth/captin/invit_controller.dart
index 96c956a..bae4564 100644
--- a/lib/controller/auth/captin/invit_controller.dart
+++ b/lib/controller/auth/captin/invit_controller.dart
@@ -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 shareCouponCode() async {
+ // TODO: Implement sharing functionality
+ // You can use share_plus package to share the coupon code
+ }
+ Future 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 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()
+ .addDriverWallet('paymentMethod', '50');
+ // add for invitor too
+ await Get.find().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,
+ });
}
diff --git a/lib/controller/auth/captin/login_captin_controller.dart b/lib/controller/auth/captin/login_captin_controller.dart
index 9367d0f..1a08bc4 100644
--- a/lib/controller/auth/captin/login_captin_controller.dart
+++ b/lib/controller/auth/captin/login_captin_controller.dart
@@ -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,
diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart
index bcd9342..5f8b809 100644
--- a/lib/controller/firebase/firbase_messge.dart
+++ b/lib/controller/firebase/firbase_messge.dart
@@ -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();
diff --git a/lib/controller/functions/gemeni.dart b/lib/controller/functions/gemeni.dart
index ae6abd2..25d8966 100644
--- a/lib/controller/functions/gemeni.dart
+++ b/lib/controller/functions/gemeni.dart
@@ -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 addDriverAndCarEgypt() async {
diff --git a/lib/controller/functions/overlay_permisssion.dart b/lib/controller/functions/overlay_permisssion.dart
index 4088f93..5e65557 100644
--- a/lib/controller/functions/overlay_permisssion.dart
+++ b/lib/controller/functions/overlay_permisssion.dart
@@ -28,25 +28,13 @@ Future getPermissionOverlay() async {
}
}
-// Future 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().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 closeOverlayIfFound() async {
+ bool isOverlayActive = await FlutterOverlayWindow.isActive();
+ if (isOverlayActive) {
+ await FlutterOverlayWindow.closeOverlay();
+ }
+}
+
final location = Location();
Future getLocationPermission() async {
bool serviceEnabled;
diff --git a/lib/controller/home/captin/map_driver_controller.dart b/lib/controller/home/captin/map_driver_controller.dart
index ca5d50a..b88e588 100644
--- a/lib/controller/home/captin/map_driver_controller.dart
+++ b/lib/controller/home/captin/map_driver_controller.dart
@@ -462,6 +462,7 @@ class MapDriverController extends GetxController {
mapController!.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
+ bearing: Get.find().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: {
diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart
index adc012a..5df57a0 100644
--- a/lib/controller/local/translations.dart
+++ b/lib/controller/local/translations.dart
@@ -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':
diff --git a/lib/controller/notification/ride_available_controller.dart b/lib/controller/notification/ride_available_controller.dart
index 37c9b46..1801e3b 100644
--- a/lib/controller/notification/ride_available_controller.dart
+++ b/lib/controller/notification/ride_available_controller.dart
@@ -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(),
diff --git a/lib/controller/payment/payment_controller.dart b/lib/controller/payment/payment_controller.dart
index dcb2451..04a33d2 100644
--- a/lib/controller/payment/payment_controller.dart
+++ b/lib/controller/payment/payment_controller.dart
@@ -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,
diff --git a/lib/views/auth/captin/invite_driver_screen.dart b/lib/views/auth/captin/invite_driver_screen.dart
index 8775d63..e108713 100644
--- a/lib/views/auth/captin/invite_driver_screen.dart
+++ b/lib/views/auth/captin/invite_driver_screen.dart
@@ -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(
+ 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(
+ style: ButtonStyle(
+ backgroundColor:
+ MaterialStateProperty.resolveWith(
+ (states) => states.contains(MaterialState.selected)
+ ? CupertinoColors.white
+ : Colors.transparent,
+ ),
+ foregroundColor:
+ MaterialStateProperty.resolveWith(
+ (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 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(
- 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(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(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);
- },
+ ],
),
),
);
diff --git a/lib/views/home/Captin/driver_map_page.dart b/lib/views/home/Captin/driver_map_page.dart
index 949fb3b..fff673e 100644
--- a/lib/views/home/Captin/driver_map_page.dart
+++ b/lib/views/home/Captin/driver_map_page.dart
@@ -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,
diff --git a/lib/views/home/Captin/home_captain/drawer_captain.dart b/lib/views/home/Captin/home_captain/drawer_captain.dart
index 3a768e3..1ae48cf 100644
--- a/lib/views/home/Captin/home_captain/drawer_captain.dart
+++ b/lib/views/home/Captin/home_captain/drawer_captain.dart
@@ -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(
diff --git a/lib/views/home/Captin/home_captain/home_captin.dart b/lib/views/home/Captin/home_captain/home_captin.dart
index c989c1d..b6b2c20 100644
--- a/lib/views/home/Captin/home_captain/home_captin.dart
+++ b/lib/views/home/Captin/home_captain/home_captin.dart
@@ -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().getSQL(),
- // onPressed: () => sql.deleteAllData(TableName.driverOrdersRefuse),
- // icon: const Icon(Icons.remove)),
- // GetBuilder(
- // 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) {
diff --git a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart
index 9da28a8..c54f651 100644
--- a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart
+++ b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart
@@ -185,33 +185,33 @@ GetBuilder 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,
diff --git a/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart b/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart
index 56d27eb..e7402de 100644
--- a/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart
+++ b/lib/views/home/Captin/mapDriverWidgets/google_driver_map_page.dart
@@ -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,
diff --git a/lib/views/home/Captin/orderCaptin/order_speed_request.dart b/lib/views/home/Captin/orderCaptin/order_speed_request.dart
index 22f102c..027bf40 100644
--- a/lib/views/home/Captin/orderCaptin/order_speed_request.dart
+++ b/lib/views/home/Captin/orderCaptin/order_speed_request.dart
@@ -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()
- .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()
+ // .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,
),
diff --git a/lib/views/notification/available_rides_page.dart b/lib/views/notification/available_rides_page.dart
index 0fe7932..74338d3 100644
--- a/lib/views/notification/available_rides_page.dart
+++ b/lib/views/notification/available_rides_page.dart
@@ -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 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 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
+ // ...
+ }
+}