diff --git a/android/app/build.gradle b/android/app/build.gradle index 8b1d72d..1492889 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -55,8 +55,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 23 targetSdkVersion flutter.targetSdkVersion - versionCode 30 - versionName '1.5.30' + versionCode 33 + versionName '1.5.33' // manifestPlaceholders = [mapsApiKey: 'android/app/src/main/AndroidManifest.xml'] } diff --git a/android/app/src/main/res/drawable/app_icon.png b/android/app/src/main/res/drawable/app_icon.png index 2da09bd..624b71d 100644 Binary files a/android/app/src/main/res/drawable/app_icon.png and b/android/app/src/main/res/drawable/app_icon.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png index 0fee87f..843b118 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/launcher_icon.png and b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png index 798ceca..7733536 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/launcher_icon.png and b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png index 13e65dd..239ad3d 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png and b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png index 9c869e6..8351f49 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png and b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png index 107e543..2c5fd48 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png and b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/lib/constant/box_name.dart b/lib/constant/box_name.dart index b0aed6e..8705145 100644 --- a/lib/constant/box_name.dart +++ b/lib/constant/box_name.dart @@ -3,6 +3,7 @@ class BoxName { static const String countryCode = "countryCode"; static const String googlaMapApp = "googlaMapApp"; + static const String tokenParent = "tokenParent"; static const String lang = "lang"; static const String carType = "carType"; static const String carPlate = "carPlate"; @@ -71,4 +72,5 @@ class BoxName { static const String registrationDate = "registrationDate"; static const String recentLocations = 'recentLocations'; static const String tripData = 'tripData'; + static const String parentTripSelected = 'parentTripSelected'; } diff --git a/lib/constant/links.dart b/lib/constant/links.dart index b247da4..8e4fd90 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -10,6 +10,7 @@ class AppLink { static String test = "$server/test.php"; //===============firebase========================== static String getTokens = "$server/ride/firebase/get.php"; + static String getTokenParent = "$server/ride/firebase/getTokenParent.php"; static String addTokens = "$server/ride/firebase/add.php"; static String addTokensDriver = "$server/ride/firebase/addDriver.php"; @@ -67,6 +68,8 @@ class AppLink { ////-----------------DriverPayment------------------ static String addDriverpayment = "$ride/payment/add.php"; static String addDriverPaymentPoints = "$ride/driverPayment/add.php"; + static String addPaymentToken = + "$ride/passengerWallet/addPaymentTokenPassenger.php"; static String getDriverPaymentPoints = "$ride/driverWallet/get.php"; static String getDriverpaymentToday = "$ride/payment/get.php"; static String getCountRide = "$ride/payment/getCountRide.php"; @@ -155,6 +158,7 @@ class AppLink { //==================certifcate========== static String location = '$server/ride/location'; static String getCarsLocationByPassenger = "$location/get.php"; + static String getLocationParents = "$location/getLocationParents.php"; static String getFemalDriverLocationByPassenger = "$location/getFemalDriver.php"; static String getDriverCarsLocationToPassengerAfterApplied = diff --git a/lib/constant/style.dart b/lib/constant/style.dart index 63cf478..963bbb4 100644 --- a/lib/constant/style.dart +++ b/lib/constant/style.dart @@ -44,7 +44,7 @@ class AppStyle { BoxShadow( color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)), BoxShadow( - color: AppColor.twitterColor, blurRadius: 5, offset: Offset(-2, -2)) + color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2)) ], color: AppColor.secondaryColor, borderRadius: BorderRadius.all( diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index 4a48de0..f8e7ee7 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'package:SEFER/views/home/HomePage/trip_monitor/trip_monitor.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -138,6 +139,15 @@ class FirebaseMessagesController extends GetxController { NotificationController() .showNotification('Promo', 'Show latest promo'.tr, 'promo'); Get.to(const PromosPassengerPage()); + } else if (message.notification!.title! == 'Trip Monitoring') { + NotificationController().showNotification( + 'Trip Monitoring'.tr, 'Show latest promo'.tr, 'iphone_ringtone'); + var myListString = message.data['passengerList']; + var myList = jsonDecode(myListString) as List; + Get.to(const TripMonitor(), arguments: { + 'rideId': myList[0].toString(), + 'driverId': myList[1].toString(), + }); } else if (message.notification!.title! == 'token change') { NotificationController() .showNotification('token change', 'token change', 'cancel'); @@ -186,16 +196,23 @@ class FirebaseMessagesController extends GetxController { box.write(BoxName.passengerWalletTotal, 0); } Get.find().tripFinishedFromDriver(); - // if (Get.find().isCashChecked == false && - // Get.find().isWalletChecked == true) { - // // driverFinishTripDialoge(driverList); - // } else { + Get.to(() => RateDriverFromPassenger(), arguments: { 'driverId': driverList[0].toString(), 'rideId': driverList[1].toString(), 'price': driverList[3].toString() }); // } + } else if (message.notification!.title! == "Finish Monitor") { + Get.defaultDialog( + titleStyle: AppStyle.title, + title: 'Trip finished '.tr, + middleText: '', + confirm: MyElevatedButton( + title: 'Ok'.tr, + onPressed: () { + Get.offAll(() => const MapPagePassenger()); + })); } else if (message.notification!.title! == 'Call Income') { try { var myListString = message.data['passengerList']; @@ -265,6 +282,8 @@ class FirebaseMessagesController extends GetxController { .tr, 'cancel'); } + box.write(BoxName.parentTripSelected, false); + box.remove(BoxName.tokenParent); Get.find().restCounter(); Get.offAll(const MapPagePassenger()); diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart index c6ced38..26863c0 100644 --- a/lib/controller/functions/crud.dart +++ b/lib/controller/functions/crud.dart @@ -41,7 +41,39 @@ class CRUD { return jsonData['status']; } + // } + Future getTokenParent({ + required String link, + Map? payload, + }) async { + var url = Uri.parse( + link, + ); + var response = await http.post( + url, + body: payload, + headers: { + "Content-Type": "application/x-www-form-urlencoded", + 'Authorization': + 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}', + }, + ); + print("-----request----" + response.request.toString()); + // print("-----headers-----" + response.headers.toString()); + print("-----payload-----" + payload.toString()); + if (response.statusCode == 200) { + print(response.body); + var jsonData = jsonDecode(response.body); + // if (jsonData['status'] == 'success') { + // print(jsonData); + + return jsonData; + // } + + // return jsonData['status']; + } + } Future getAgoraToken({ required String channelName, diff --git a/lib/controller/functions/sms_controller.dart b/lib/controller/functions/sms_controller.dart index 0e1726f..ccb7502 100644 --- a/lib/controller/functions/sms_controller.dart +++ b/lib/controller/functions/sms_controller.dart @@ -18,7 +18,7 @@ class SmsEgyptController extends GetxController { "password": AK.smsPasswordEgypt, "message": "${AppInformation.appName} app code is $otp\ncopy it to app", "language": box.read(BoxName.lang) == 'en' ? "e" : 'r', - "sender": "SEFER EGY", // todo add sefer sender name + "sender": "Sefer Egy", "receiver": "2$phone" }); diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart index a33cc8f..aca524f 100644 --- a/lib/controller/home/map_passenger_controller.dart +++ b/lib/controller/home/map_passenger_controller.dart @@ -5,6 +5,7 @@ import 'dart:math' as math; import 'package:SEFER/controller/functions/tts.dart'; import 'package:SEFER/views/home/map_page_passenger.dart'; +import 'package:SEFER/views/widgets/my_textField.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; @@ -44,7 +45,7 @@ class MapPassengerController extends GetxController { TextEditingController wayPoint4Controller = TextEditingController(); TextEditingController sosPhonePassengerProfile = TextEditingController(); final sosFormKey = GlobalKey(); - final increasFeeFormKey = GlobalKey(); + final increaseFeeFormKey = GlobalKey(); List data = []; List bounds = []; List placesStart = []; @@ -338,7 +339,7 @@ class MapPassengerController extends GetxController { } increaseFeeByPassengerAndReOrder() async { - if (increasFeeFormKey.currentState!.validate()) { + if (increaseFeeFormKey.currentState!.validate()) { if (double.parse(increasFeeFromPassenger.text) > totalPassenger) { totalPassenger = double.parse(increasFeeFromPassenger.text); Get.back(); @@ -675,6 +676,16 @@ class MapPassengerController extends GetxController { box.write(BoxName.arrivalTime, ''); remainingTimeTimerRideBegin = 0; box.write(BoxName.passengerWalletTotal, '0'); + if (box.read(BoxName.parentTripSelected) == true) { + FirebaseMessagesController().sendNotificationToPassengerToken( + "Finish Monitor", + "Finish Monitor".tr, + box.read(BoxName.tokenParent), + [], + ); + box.write(BoxName.parentTripSelected, false); + box.remove(BoxName.tokenParent); + } update(); } @@ -1088,32 +1099,35 @@ class MapPassengerController extends GetxController { Timer(const Duration(milliseconds: 200), () async { if (shouldFetch) { // //print('shouldFetch is =$shouldFetch'); - var res = await getRideStatus(rideId); - // print(res); - // var decod = jsonDecode(res); - print( - ' 000000000000000000delayAndFetchRideStatus0000000000000000000000000000000'); - print(res); - if (res.toString() == 'Apply') { - // getUpdatedRideForDriverApply(rideId); - shouldFetch = false; // Stop further fetches - statusRide = 'Apply'; - rideConfirm = false; - isSearchingWindow = false; - update(); - startTimerFromDriverToPassengerAfterApplied(); - // startTimer(); - } else if (res.toString() == 'Refused') { - statusRide = 'Refused'; - // isDriversTokensSend = false; - if (isDriversTokensSend == false) { - confirmRideForAllDriverAvailable(); - isDriversTokensSend = true; + if (remainingTimeToPassengerFromDriverAfterApplied > 0) { + var res = await getRideStatus(rideId); + + // print(res); + // var decod = jsonDecode(res); + print( + ' 000000000000000000delayAndFetchRideStatus0000000000000000000000000000000'); + print(res); + if (res.toString() == 'Apply') { + // getUpdatedRideForDriverApply(rideId); + shouldFetch = false; // Stop further fetches + statusRide = 'Apply'; + rideConfirm = false; + isSearchingWindow = false; + update(); + startTimerFromDriverToPassengerAfterApplied(); + // startTimer(); + } else if (res.toString() == 'Refused') { + statusRide = 'Refused'; + // isDriversTokensSend = false; + if (isDriversTokensSend == false) { + confirmRideForAllDriverAvailable(); + isDriversTokensSend = true; + } + } else if (isDriversTokensSend == false) { + delayAndFetchRideStatus( + rideId); // Repeat the delay and fetch operation + update(); } - } else if (isDriversTokensSend == false) { - delayAndFetchRideStatus( - rideId); // Repeat the delay and fetch operation - update(); } } }); @@ -1210,7 +1224,7 @@ class MapPassengerController extends GetxController { driverRate = response['data']['ratingDriver']; } driversToken.remove(driverToken); - for (var i = 0; i < driversToken.length; i++) { + for (var i = 1; i < driversToken.length; i++) { FirebaseMessagesController().sendNotificationToAnyWithoutData( 'Order Applied', '$driverName Apply order\nTake attention in other order'.tr, @@ -1310,6 +1324,107 @@ class MapPassengerController extends GetxController { } } + Future getTokenForParent() async { + if (box.read(BoxName.sosPhonePassenger) == null) { + Get.defaultDialog( + title: 'Add SOS Phone'.tr, + titleStyle: AppStyle.title, + content: Form( + key: sosFormKey, + child: MyTextForm( + controller: sosPhonePassengerProfile, + label: 'insert sos phone'.tr, + hint: 'insert sos phone'.tr, + type: TextInputType.phone, + ), + ), + confirm: MyElevatedButton( + title: 'Add SOS Phone'.tr, + onPressed: () async { + if (sosFormKey.currentState!.validate()) { + Get.back(); + await CRUD().post( + link: AppLink.updateprofile, + payload: { + 'id': box.read(BoxName.passengerID), + 'sosPhone': sosPhonePassengerProfile.text, + }, + ); + } + })); + } + + var res = await CRUD().getTokenParent( + link: AppLink.getTokenParent, + payload: {'phone': '+2' + box.read(BoxName.sosPhonePassenger)}); + + // Check if `res` is already a map + if (res is Map) { + var res1 = res; + handleResponse(res1); + } else { + // If it's a string, decode it + var res1 = jsonDecode(res); + handleResponse(res1); + } + } + + void handleResponse(Map res1) { + if (res1['message'] == "No passenger found for the given phone number") { + print(res1); + Get.defaultDialog( + title: "No user found for the given phone number".tr, + titleStyle: AppStyle.title, + content: Column( + children: [ + Text( + "No passenger found for the given phone number".tr, + style: AppStyle.title, + ), + Text( + "Send Sefer app to him".tr, + style: AppStyle.title.copyWith(color: AppColor.greenColor), + ) + ], + ), + confirm: MyElevatedButton( + title: 'Ok'.tr, + onPressed: () { + Get.back(); + var phone = box.read(BoxName.countryCode) == 'Egypt' + ? '+2${box.read(BoxName.sosPhonePassenger)}' + : '+962${box.read(BoxName.sosPhonePassenger)}'; + var message = '''Dear , + + 🚀 I have just started an exciting trip and I would like to share the details of my journey and my current location with you in real-time! Please download the SEFER app. It will allow you to view my trip details and my latest location. + + 👉 Download link: + Android [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride] + iOS [https://getapp.cc/app/6458734951] + + I look forward to keeping you close during my adventure! + + SEFER ,''' + .tr; + launchCommunication('whatsapp', phone, message); + }), + cancel: MyElevatedButton( + title: 'No'.tr, + onPressed: () { + Get.back(); + })); + } else if (res1['status'] == 'success') { + var tokenParent = res1['data'][0]['token']; + FirebaseMessagesController().sendNotificationToPassengerToken( + "Trip Monitoring", + "Trip Monitoring".tr, + tokenParent, + [rideId, driverId]); + box.write(BoxName.parentTripSelected, true); + box.write(BoxName.tokenParent, tokenParent); + } + } + LatLng driverLocationToPassenger = const LatLng(32, 35); Future getDriverCarsLocationToPassengerAfterApplied() async { driverCarsLocationToPassengerAfterApplied = []; diff --git a/lib/controller/home/profile/complaint_controller.dart b/lib/controller/home/profile/complaint_controller.dart index 2d65be8..86096da 100644 --- a/lib/controller/home/profile/complaint_controller.dart +++ b/lib/controller/home/profile/complaint_controller.dart @@ -28,7 +28,7 @@ class ComplaintController extends GetxController { Get.defaultDialog( title: 'Success'.tr, titleStyle: AppStyle.title, - middleText: 'Feedback data saved successfully'.tr, + middleText: 'Complaint data saved successfully'.tr, middleTextStyle: AppStyle.title, confirm: MyElevatedButton( kolor: AppColor.greenColor, diff --git a/lib/controller/home/profile/promos_controller.dart b/lib/controller/home/profile/promos_controller.dart index 3e44727..0298c6f 100644 --- a/lib/controller/home/profile/promos_controller.dart +++ b/lib/controller/home/profile/promos_controller.dart @@ -19,16 +19,16 @@ class PromosController extends GetxController { Future getPromoByToday() async { var res = await CRUD().get(link: AppLink.getPromoBytody, payload: {}); if (res.toString() == 'failure') { - Get.defaultDialog( - title: 'No Promo for today .'.tr, - middleText: '', - titleStyle: AppStyle.title, - confirm: MyElevatedButton( - title: 'Back'.tr, - onPressed: () { - Get.back(); - Get.back(); - })); + // Get.defaultDialog( + // title: 'No Promo for today .'.tr, + // middleText: '', + // titleStyle: AppStyle.title, + // confirm: MyElevatedButton( + // title: 'Back'.tr, + // onPressed: () { + // Get.back(); + // Get.back(); + // })); isLoading = false; update(); } else { diff --git a/lib/controller/home/trip_monitor_controller.dart b/lib/controller/home/trip_monitor_controller.dart index e69de29..6ab1719 100644 --- a/lib/controller/home/trip_monitor_controller.dart +++ b/lib/controller/home/trip_monitor_controller.dart @@ -0,0 +1,83 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:SEFER/constant/links.dart'; +import 'package:SEFER/controller/functions/crud.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; + +class TripMonitorController extends GetxController { + bool isLoading = false; + Map tripData = {}; + late String rideId; + late String driverId; + GoogleMapController? mapController; + List myListString = []; + late Timer timer; + late LatLng parentLocation; + BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker; + double rotation = 0; + double speed = 0; + + getLocationParent() async { + var res = await CRUD().get( + link: AppLink.getLocationParents, payload: {"driver_id": driverId}); + if (res != 'failure') { + tripData = jsonDecode(res); + parentLocation = LatLng( + double.parse(tripData['message'][0]['latitude'].toString()), + double.parse(tripData['message'][0]['longitude'].toString())); + rotation = double.parse(tripData['message'][0]['heading'].toString()); + speed = double.parse(tripData['message'][0]['speed'].toString()); + update(); + } + } + + void onMapCreated(GoogleMapController controller) async { + mapController = controller; + controller.getVisibleRegion(); + controller.animateCamera( + CameraUpdate.newLatLng(parentLocation), + ); + update(); + // Set up a timer or interval to trigger the marker update every 3 seconds. + timer = Timer.periodic(const Duration(seconds: 10), (_) async { + await getLocationParent(); + mapController?.animateCamera(CameraUpdate.newLatLng(parentLocation)); + update(); + }); + } + + init() async { + final arguments = Get.arguments; + driverId = arguments['driverId']; + rideId = arguments['rideId']; + await getLocationParent(); + } + + void addCustomCarIcon() { + ImageConfiguration config = ImageConfiguration( + size: const Size(30, 30), devicePixelRatio: Get.pixelRatio); + BitmapDescriptor.fromAssetImage(config, 'assets/images/car.png', + mipmaps: false) + .then((value) { + carIcon = value; + update(); + }); + } + + @override + void onInit() { + addCustomCarIcon(); + super.onInit(); + } + + @override + void onClose() { + timer.cancel(); + mapController?.dispose(); + + super.onClose(); + } +} diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index 35abd55..b4d0958 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -4,6 +4,48 @@ class MyTranslation extends Translations { @override Map> get keys => { "ar": { + "Enter your complaint here": "أدخل شكواك هنا", + "Complaint": "شكوى", + "Please enter your complaint.": "الرجاء إدخال شكواك.", + "Submit": "إرسال", + "Complaint data saved successfully": "تم حفظ بيانات الشكوى بنجاح", + "Trip Monitor": "مراقبة الرحلة", + "Insert SOS Phone": "أدخل رقم الهاتف للطوارئ", + "Add SOS Phone": "أضف رقم الهاتف للطوارئ", + "Trip Monitoring": "مراقبة الرحلة", + '''Dear , + + 🚀 I have just started an exciting trip and I would like to share the details of my journey and my current location with you in real-time! Please download the SEFER app. It will allow you to view my trip details and my latest location. + + 👉 Download link: + Android [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride] + iOS [https://getapp.cc/app/6458734951] + + I look forward to keeping you close during my adventure! + + SEFER ,''': '''عزيزي ، + + +🚀 لقد بدأت للتو رحلة مثيرة وأود مشاركة تفاصيل رحلتي وموقعي الحالي معك في الوقت الفعلي! يرجى تنزيل تطبيق سفر. سيمكنك ذلك من عرض تفاصيل رحلتي وموقعي الأخير. + + +👉 رابط التحميل: +Android [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride] +iOS [https://getapp.cc/app/6458734951] + + +أتطلع إلى إبقائك قريبًا خلال مغامرتي! + + +سفر ،''', + "Send Sefer app to him": "أرسل له تطبيق سفر", + "No passenger found for the given phone number": + "لم يتم العثور على راكب لرقم الهاتف المعطى", + "No user found for the given phone number": + "لم يتم العثور على مستخدم لرقم الهاتف المعطى", + "This price is": "هذا السعر هو", + "Work": "عمل", + "Add Home": "أضف منزل", "Notifications": "إشعارات", '💳 Pay with Credit Card': "ادفع باستخدام بطاقة الائتمان💳", "⚠️ You need to choose an amount!": "⚠️ يجب عليك اختيار مبلغ!", diff --git a/lib/controller/payment/payment_controller.dart b/lib/controller/payment/payment_controller.dart index 8687d7c..29d83ad 100644 --- a/lib/controller/payment/payment_controller.dart +++ b/lib/controller/payment/payment_controller.dart @@ -61,14 +61,27 @@ class PaymentController extends GetxController { update(); } + String paymentToken = ''; + Future generateToken(String amount) async { + var res = await CRUD().post(link: AppLink.addPaymentToken, payload: { + 'passengerId': box.read(BoxName.passengerID).toString(), + 'amount': amount.toString(), + }); + var d = jsonDecode(res); + print('paymentToken ${d['message']}'); + return d['message']; + } + addPassengerWallet() async { isLoading = true; update(); + paymentToken = await generateToken(selectedAmount.toString()); // double sallaryAccountNowBeforeAdding = // double.parse(box.read(BoxName.passengerWalletTotal).toString()); await CRUD().post(link: AppLink.addPassengersWallet, payload: { 'passenger_id': box.read(BoxName.passengerID).toString(), - 'balance': selectedAmount.toString() + 'balance': selectedAmount.toString(), + 'token': paymentToken, }).then((value) { getPassengerWallet(); // sallaryAccountNowBeforeAdding = sallaryAccountNowBeforeAdding + diff --git a/lib/controller/profile/profile_controller.dart b/lib/controller/profile/profile_controller.dart index 3bb1329..73e92e3 100644 --- a/lib/controller/profile/profile_controller.dart +++ b/lib/controller/profile/profile_controller.dart @@ -68,8 +68,8 @@ class ProfileController extends GetxController { ), MyElevatedButton( title: 'Update'.tr, - onPressed: () { - updateColumn({ + onPressed: () async { + await updateColumn({ 'id': box.read(BoxName.passengerID), columnName: txtController.text, }); diff --git a/lib/views/home/HomePage/trip_monitor/trip_monitor.dart b/lib/views/home/HomePage/trip_monitor/trip_monitor.dart index e69de29..4c86135 100644 --- a/lib/views/home/HomePage/trip_monitor/trip_monitor.dart +++ b/lib/views/home/HomePage/trip_monitor/trip_monitor.dart @@ -0,0 +1,96 @@ +import 'dart:io'; + +import 'package:SEFER/controller/home/trip_monitor_controller.dart'; +import 'package:SEFER/views/widgets/my_scafold.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:vibration/vibration.dart'; + +import '../../../../constant/colors.dart'; +import '../../../../constant/style.dart'; +import '../../../widgets/elevated_btn.dart'; + +class TripMonitor extends StatelessWidget { + const TripMonitor({super.key}); + + @override + Widget build(BuildContext context) { + Get.put(TripMonitorController()).init(); + return GetBuilder(builder: (tripMonitorController) { + return MyScafolld( + title: 'Trip Monitor'.tr, + body: [ + GoogleMap( + onMapCreated: tripMonitorController.onMapCreated, + initialCameraPosition: CameraPosition( + // bearing: 45, + target: tripMonitorController.parentLocation, + zoom: 16, + tilt: 40, + ), + // onCameraMove: (position) {}, + markers: { + Marker( + markerId: MarkerId('start'.tr), + position: tripMonitorController.parentLocation, + draggable: true, + icon: tripMonitorController.carIcon, + rotation: tripMonitorController.rotation, + ), + }, + ), + speedCircle() + ], + isleading: true, + ); + }); + } +} + +GetBuilder speedCircle() { + if (Get.find().speed > 100) { + if (Platform.isIOS) { + HapticFeedback.selectionClick(); + } else { + Vibration.vibrate(duration: 1000); + } + Get.defaultDialog( + barrierDismissible: false, + titleStyle: AppStyle.title, + title: 'Speed Over'.tr, + middleText: 'Please slow down'.tr, + middleTextStyle: AppStyle.title, + confirm: MyElevatedButton( + title: 'I will slow down'.tr, + onPressed: () => Get.back(), + ), + ); + } + return GetBuilder( + builder: (tripMonitorController) { + return Positioned( + bottom: 25, + right: 100, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: tripMonitorController.speed > 100 + ? Colors.red + : AppColor.secondaryColor, + border: Border.all(width: 3, color: AppColor.redColor), + ), + height: 60, + width: 60, + child: Center( + child: Text( + tripMonitorController.speed.toStringAsFixed(0), + style: AppStyle.number, + ), + ), + ), + ); + }, + ); +} diff --git a/lib/views/home/map_widget.dart/apply_order_widget.dart b/lib/views/home/map_widget.dart/apply_order_widget.dart index 0910c20..b398f96 100644 --- a/lib/views/home/map_widget.dart/apply_order_widget.dart +++ b/lib/views/home/map_widget.dart/apply_order_widget.dart @@ -33,8 +33,9 @@ class ApplyOrderWidget extends StatelessWidget { if (box.read(BoxName.carType) == 'Speed' || box.read(BoxName.carType) == 'Delivery') { Get.snackbar( - 'This price is ${controller.totalPassenger.toStringAsFixed(2)}' - .tr, + 'This price is'.tr + + ' ${controller.totalPassenger.toStringAsFixed(2)}' + .tr, 'This ride type does not allow changes to the destination or additional stops' .tr, snackPosition: SnackPosition.BOTTOM, @@ -108,7 +109,7 @@ class ApplyOrderWidget extends StatelessWidget { children: [ Image.asset( 'assets/images/blob.png', - width: 100, + width: 80, ), Column( children: [ @@ -165,7 +166,7 @@ class ApplyOrderWidget extends StatelessWidget { Get.defaultDialog( title: 'Select one message'.tr, titleStyle: AppStyle.title, - content: Container( + content: SizedBox( height: Get.height * .5, child: Column( mainAxisAlignment: @@ -391,6 +392,8 @@ class TimeDriverToPassenger extends StatelessWidget { children: [ Text( 'The driver on your way'.tr, + style: AppStyle.title + .copyWith(color: AppColor.yellowColor), textAlign: TextAlign.center, ), const SizedBox( diff --git a/lib/views/home/map_widget.dart/map_menu_widget.dart b/lib/views/home/map_widget.dart/map_menu_widget.dart index bc77b09..7d888c4 100644 --- a/lib/views/home/map_widget.dart/map_menu_widget.dart +++ b/lib/views/home/map_widget.dart/map_menu_widget.dart @@ -7,7 +7,7 @@ import 'package:get/get.dart'; import 'package:get/get_rx/src/rx_typedefs/rx_typedefs.dart'; import 'package:SEFER/constant/style.dart'; import 'package:SEFER/views/home/my_wallet/passenger_wallet.dart'; -import 'package:SEFER/views/home/profile/feed_back_page.dart'; +import 'package:SEFER/views/home/profile/complaint_page.dart'; import 'package:SEFER/views/home/profile/order_history.dart'; import 'package:SEFER/views/home/profile/promos_passenger_page.dart'; import 'package:SEFER/views/home/profile/taarif_page.dart'; @@ -188,9 +188,9 @@ class MapMenuWidget extends StatelessWidget { ), IconMainPageMap( onTap: () { - Get.to(() => FeedBackPage()); + Get.to(() => ComplaintPage()); }, - title: 'Feed Back'.tr, + title: 'Complaint'.tr, icon: Icons.feedback, ), IconMainPageMap( diff --git a/lib/views/home/map_widget.dart/ride_begin_passenger.dart b/lib/views/home/map_widget.dart/ride_begin_passenger.dart index 5cb2d11..4bf67bd 100644 --- a/lib/views/home/map_widget.dart/ride_begin_passenger.dart +++ b/lib/views/home/map_widget.dart/ride_begin_passenger.dart @@ -1,5 +1,5 @@ import 'package:SEFER/constant/links.dart'; -import 'package:SEFER/views/home/profile/feed_back_page.dart'; +import 'package:SEFER/views/home/profile/complaint_page.dart'; import 'package:SEFER/views/widgets/elevated_btn.dart'; import 'package:flutter/material.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; @@ -32,7 +32,7 @@ class RideBeginPassenger extends StatelessWidget { right: 10, bottom: 4, child: Container( - decoration: AppStyle.boxDecoration, + decoration: AppStyle.boxDecoration1, height: controller.statusRide == 'Begin' ? Get.height * .33 : 0, // width: 100, child: Padding( @@ -51,14 +51,14 @@ class RideBeginPassenger extends StatelessWidget { Column( children: [ Container( - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: Text( controller.firstName, style: AppStyle.title, ), ), Container( - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -79,7 +79,7 @@ class RideBeginPassenger extends StatelessWidget { children: [ const Text(''), Container( - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4), @@ -94,7 +94,7 @@ class RideBeginPassenger extends StatelessWidget { Column( children: [ Container( - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: Padding( padding: const EdgeInsets.all(3), child: Text( @@ -124,7 +124,7 @@ class RideBeginPassenger extends StatelessWidget { }, child: Container( width: Get.width * .15, - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: Column( children: [ Text( @@ -150,7 +150,7 @@ class RideBeginPassenger extends StatelessWidget { }, child: Container( width: Get.width * .15, - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: Column( children: [ Text( @@ -167,10 +167,10 @@ class RideBeginPassenger extends StatelessWidget { ), Container( width: Get.width * .15, - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: IconButton( onPressed: () => Get.to( - () => FeedBackPage(), + () => ComplaintPage(), transition: Transition.downToUp, ), icon: const Icon( @@ -182,7 +182,7 @@ class RideBeginPassenger extends StatelessWidget { ), Container( width: Get.width * .15, - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, child: audioController.isRecording == false ? IconButton( onPressed: () async { @@ -237,7 +237,7 @@ class RideBeginPassenger extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Container( - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, width: Get.width * .15, child: IconButton( onPressed: () async { @@ -260,7 +260,7 @@ class RideBeginPassenger extends StatelessWidget { ), ), Container( - decoration: AppStyle.boxDecoration1, + decoration: AppStyle.boxDecoration, width: Get.width * .15, child: IconButton( onPressed: () async { @@ -292,6 +292,19 @@ class RideBeginPassenger extends StatelessWidget { ), ), ), + Container( + decoration: AppStyle.boxDecoration, + width: Get.width * .15, + child: IconButton( + onPressed: () async { + await controller.getTokenForParent(); + }, + icon: const Icon( + Foundation.record, + color: AppColor.yellowColor, + ), + ), + ), ], ) ], diff --git a/lib/views/home/map_widget.dart/searching_captain_window.dart b/lib/views/home/map_widget.dart/searching_captain_window.dart index 7e96030..cf3e7be 100644 --- a/lib/views/home/map_widget.dart/searching_captain_window.dart +++ b/lib/views/home/map_widget.dart/searching_captain_window.dart @@ -115,7 +115,7 @@ Widget _buildTimer(MapPassengerController mapPassengerController) { SizedBox( width: 100, child: Form( - key: mapPassengerController.increasFeeFormKey, + key: mapPassengerController.increaseFeeFormKey, child: MyTextForm( controller: mapPassengerController .increasFeeFromPassenger, diff --git a/lib/views/home/my_wallet/passenger_wallet.dart b/lib/views/home/my_wallet/passenger_wallet.dart index 5815cfd..d3e9f3c 100644 --- a/lib/views/home/my_wallet/passenger_wallet.dart +++ b/lib/views/home/my_wallet/passenger_wallet.dart @@ -69,7 +69,7 @@ class PassengerWallet extends StatelessWidget { }, ), )), - const PassengerWalletDialoge(), + const PassengerWalletDialog(), ], ); } diff --git a/lib/views/home/my_wallet/passenger_wallet_dialoge.dart b/lib/views/home/my_wallet/passenger_wallet_dialoge.dart index fa8cf9e..bb11e11 100644 --- a/lib/views/home/my_wallet/passenger_wallet_dialoge.dart +++ b/lib/views/home/my_wallet/passenger_wallet_dialoge.dart @@ -9,8 +9,8 @@ import 'package:SEFER/views/widgets/elevated_btn.dart'; import '../../../main.dart'; -class PassengerWalletDialoge extends StatelessWidget { - const PassengerWalletDialoge({ +class PassengerWalletDialog extends StatelessWidget { + const PassengerWalletDialog({ super.key, }); diff --git a/lib/views/home/profile/budgets_ads.dart b/lib/views/home/profile/budgets_ads.dart index e69de29..aa98be4 100644 --- a/lib/views/home/profile/budgets_ads.dart +++ b/lib/views/home/profile/budgets_ads.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:SEFER/constant/colors.dart'; +import 'package:SEFER/constant/style.dart'; +import 'package:SEFER/controller/payment/payment_controller.dart'; + +import '../../../constant/box_name.dart'; +import '../../../main.dart'; +import '../my_wallet/passenger_wallet.dart'; + +class PointsCaptain extends StatelessWidget { + PaymentController paymentController = Get.put(PaymentController()); + + PointsCaptain({ + super.key, + required this.kolor, + required this.countPoint, + required this.pricePoint, + }); + final Color kolor; + final String countPoint; + double pricePoint; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () async { + Get.to(() => const PassengerWallet()); + paymentController.changePromoSheetDialogue(); + }, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 3, vertical: 8), + child: Container( + width: Get.width * .21, + height: Get.width * .29, + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: kolor, + border: Border.all(color: AppColor.accentColor), + borderRadius: BorderRadius.circular(12), + shape: BoxShape.rectangle, + ), + child: Center( + child: Column( + children: [ + Text( + '$countPoint ${'Point'.tr}', + style: AppStyle.subtitle, + ), + Text( + '$pricePoint ${box.read(BoxName.countryCode) == 'Jordan' ? 'JOD'.tr : 'LE'.tr}', + style: AppStyle.title, + textAlign: TextAlign.center, + ), + ], + ), + )), + ), + ); + } +} diff --git a/lib/views/home/profile/complaint_page.dart b/lib/views/home/profile/complaint_page.dart index 4368f49..a9f137b 100644 --- a/lib/views/home/profile/complaint_page.dart +++ b/lib/views/home/profile/complaint_page.dart @@ -3,7 +3,7 @@ import 'package:get/get.dart'; import 'package:SEFER/views/widgets/my_scafold.dart'; import 'package:SEFER/views/widgets/mycircular.dart'; -import '../../../controller/home/profile/feed_back_controller.dart'; +import '../../../controller/home/profile/complaint_controller.dart'; import '../../widgets/elevated_btn.dart'; class ComplaintPage extends StatelessWidget { @@ -28,11 +28,11 @@ class ComplaintPage extends StatelessWidget { decoration: InputDecoration( border: const OutlineInputBorder(), hintText: 'Enter your complaint here'.tr, - labelText: 'Complaint', // Update label + labelText: 'Complaint'.tr, // Update label ), validator: (value) { if (value == null || value.isEmpty) { - return 'Please enter your complaint.'; + return 'Please enter your complaint.'.tr; } return null; }, @@ -51,7 +51,7 @@ class ComplaintPage extends StatelessWidget { complaintController.formKey.currentState!.reset(); } }, - title: 'Submit '.tr, + title: 'Submit'.tr, ), ], ), diff --git a/lib/views/home/profile/promos_passenger_page.dart b/lib/views/home/profile/promos_passenger_page.dart index ced92dd..dc3e632 100644 --- a/lib/views/home/profile/promos_passenger_page.dart +++ b/lib/views/home/profile/promos_passenger_page.dart @@ -4,9 +4,12 @@ import 'package:get/get.dart'; import 'package:SEFER/controller/home/profile/promos_controller.dart'; import 'package:SEFER/views/widgets/my_scafold.dart'; +import '../../../constant/box_name.dart'; import '../../../constant/colors.dart'; import '../../../constant/style.dart'; +import '../../../main.dart'; import '../../widgets/mycircular.dart'; +import 'budgets_ads.dart'; class PromosPassengerPage extends StatelessWidget { const PromosPassengerPage({super.key}); @@ -22,89 +25,155 @@ class PromosPassengerPage extends StatelessWidget { builder: (orderHistoryController) => orderHistoryController.isLoading ? const MyCircularProgressIndicator() : ListView.builder( - itemCount: orderHistoryController.promoList.length, + itemCount: orderHistoryController.promoList.length + + 1, // Adding 1 for the ad itemBuilder: (BuildContext context, int index) { - final rides = orderHistoryController.promoList[index]; - return Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(12)), - color: AppColor.secondaryColor, - boxShadow: [ - BoxShadow( - color: AppColor.accentColor, - offset: Offset(-3, -3), - blurRadius: 0, - spreadRadius: 0, - blurStyle: BlurStyle.outer), - BoxShadow( - color: AppColor.accentColor, - offset: Offset(3, 3), - blurRadius: 0, - spreadRadius: 0, - blurStyle: BlurStyle.outer) - ]), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AnimatedTextKit( - animatedTexts: [ - ScaleAnimatedText(rides['promo_code'], - textStyle: AppStyle.title), - WavyAnimatedText(rides['promo_code'], - textStyle: AppStyle.title), - FlickerAnimatedText( - rides['promo_code'], - textStyle: AppStyle.title), - WavyAnimatedText(rides['promo_code'], - textStyle: AppStyle.title), - ], - isRepeatingAnimation: true, - onTap: () { - print("Tap Event"); - }, - ), - Text( - rides['description'], - style: AppStyle.title, - ), - ], - ), - Column( - children: [ - Text( - rides['validity_start_date'], - style: AppStyle.title, - ), - Text( - rides['validity_end_date'], - style: AppStyle.title, - ), - ], - ), - ], - ), - Text( - 'Copy this Promo to use it in your Ride!'.tr, - textAlign: TextAlign.center, - style: AppStyle.headTitle2 - .copyWith(color: AppColor.accentColor), - ) - ], + if (index == 0) { + // Ad at the beginning + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: 120, // Adjust the height of the ad container + decoration: BoxDecoration( + color: + Colors.grey[200], // Background color for the ad + borderRadius: BorderRadius.circular(10), + ), + child: Center( + child: Container( + decoration: AppStyle.boxDecoration, + height: Get.height * .19, + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + PointsCaptain( + kolor: AppColor.blueColor, + pricePoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? 5 + : 100, + countPoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? '300' + : '100', + ), + PointsCaptain( + kolor: Colors.green, + pricePoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? 10 + : 200, + countPoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? '1040' + : '210', + ), + PointsCaptain( + kolor: Colors.amberAccent, + pricePoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? 22 + : 400, + countPoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? '2300' + : '450', + ), + PointsCaptain( + kolor: AppColor.yellowColor, + pricePoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? 50 + : 1000, + countPoint: + box.read(BoxName.countryCode) == + 'Jordan' + ? '55000' + : '1200', + ), + ], + )), ), ), - ), - ); + ); + } else { + // Promo items + final rides = orderHistoryController.promoList[index - 1]; + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration: AppStyle.boxDecoration, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + AnimatedTextKit( + animatedTexts: [ + ScaleAnimatedText( + rides['promo_code'], + textStyle: AppStyle.title), + WavyAnimatedText( + rides['promo_code'], + textStyle: AppStyle.title), + FlickerAnimatedText( + rides['promo_code'], + textStyle: AppStyle.title), + WavyAnimatedText( + rides['promo_code'], + textStyle: AppStyle.title), + ], + isRepeatingAnimation: true, + onTap: () { + print("Tap Event"); + }, + ), + Text( + rides['description'], + style: AppStyle.title, + ), + ], + ), + Column( + children: [ + Text( + rides['validity_start_date'], + style: AppStyle.title, + ), + Text( + rides['validity_end_date'], + style: AppStyle.title, + ), + ], + ), + ], + ), + Text( + 'Copy this Promo to use it in your Ride!'.tr, + textAlign: TextAlign.center, + style: AppStyle.headTitle2 + .copyWith(color: AppColor.accentColor), + ) + ], + ), + ), + ), + ); + } }, ), )