Initial commit

This commit is contained in:
Hamza-Ayed
2024-10-12 19:19:26 +03:00
parent 2e3ce78fe8
commit aca697578d
41 changed files with 2976 additions and 1188 deletions

View File

@@ -10,9 +10,14 @@ class BoxName {
static const String carType = "carType";
static const String carPlate = "carPlate";
static const String packagInfo = "packagInfo";
static const String isVerified = '0';
static const String isVerified = 'isVerified';
static const String isFirstTime = 'isFirstTime';
static const String statusDriverLocation = "statusDriverLocation";
static const String isTest = "isTest";
static const String password = "password";
static const String validity = "validity";
static const String promo = "promo";
static const String discount = "discount";
static const String arrivalTime = "arrivalTime";
static const String passwordDriver = "passwordDriver";
static const String agreeTerms = "agreeTerms";
@@ -25,6 +30,10 @@ class BoxName {
static const String sosPhoneDriver = "sosPhoneDriver";
static const String passengerID = "pasengerID";
static const String phone = "phone";
static const String package = "package";
static const String isInstall = "isInstall";
static const String isGiftToken = "isGiftToken";
static const String inviteCode = "inviteCode";
static const String phoneWallet = "phoneWallet";
static const String phoneDriver = "phoneDriver";
static const String dobDriver = "dobDriver";

View File

@@ -59,21 +59,27 @@ class AppLink {
////=======================cancelRide===================
static String ride = '$server/ride';
static String addCancelRideFromPassenger =
"$endPoint/ride/cancelRide/add.php";
static String cancelRide = "$endPoint/ride/cancelRide/get.php";
"${box.read(BoxName.serverChosen)}/ride/cancelRide/add.php";
static String cancelRide =
"${box.read(BoxName.serverChosen)}/ride/cancelRide/get.php";
//-----------------ridessss------------------
static String addRides = "$ride/rides/add.php";
static String getRides = "$endPoint/ride/rides/get.php";
static String getRideOrderID = "$endPoint/ride/rides/getRideOrderID.php";
static String getRideStatus = "$endPoint/ride/rides/getRideStatus.php";
static String getRides =
"${box.read(BoxName.serverChosen)}/ride/rides/get.php";
static String getRideOrderID =
"${box.read(BoxName.serverChosen)}/ride/rides/getRideOrderID.php";
static String getRideStatus =
"${box.read(BoxName.serverChosen)}/ride/rides/getRideStatus.php";
static String getRideStatusBegin =
"$endPoint/ride/rides/getRideStatusBegin.php";
"${box.read(BoxName.serverChosen)}/ride/rides/getRideStatusBegin.php";
static String getRideStatusFromStartApp =
"$ride/rides/getRideStatusFromStartApp.php";
static String updateRides = "$endPoint/ride/rides/update.php";
static String updateRides =
"${box.read(BoxName.serverChosen)}/ride/rides/update.php";
static String updateStausFromSpeed =
"$endPoint/ride/rides/updateStausFromSpeed.php";
static String deleteRides = "$endPoint/ride/rides/delete.php";
"${box.read(BoxName.serverChosen)}/ride/rides/updateStausFromSpeed.php";
static String deleteRides =
"${box.read(BoxName.serverChosen)}/ride/rides/delete.php";
//-----------------DriverPayment------------------
static String adddriverScam = "$ride/driver_scam/add.php";
@@ -105,8 +111,12 @@ class AppLink {
"$ride/notificationPassenger/update.php";
//-----------------Driver NotificationCaptain------------------
static String addNotificationCaptain = "$ride/notificationCaptain/add.php";
static String addWaitingRide = "$ride/notificationCaptain/addWaitingRide.php";
static String getRideWaiting = "$ride/notificationCaptain/getRideWaiting.php";
static String addWaitingRide =
"$endPoint/ride/notificationCaptain/addWaitingRide.php";
static String updateWaitingTrip =
"$endPoint/ride/notificationCaptain/updateWaitingTrip.php";
static String getRideWaiting =
"$endPoint/ride/notificationCaptain/getRideWaiting.php";
static String getNotificationCaptain = "$ride/notificationCaptain/get.php";
static String updateNotificationCaptain =
"$ride/notificationCaptain/update.php";
@@ -142,7 +152,8 @@ class AppLink {
static String updateLicense = "$ride/license/updateFeedBack.php";
//-----------------RegisrationCar------------------
static String addRegisrationCar = "$ride/RegisrationCar/add.php";
static String getRegisrationCar = "$endPoint/ride/RegisrationCar/get.php";
static String getRegisrationCar =
"${box.read(BoxName.serverChosen)}/ride/RegisrationCar/get.php";
static String selectDriverAndCarForMishwariTrip =
"$ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php";
static String updateRegisrationCar = "$ride/RegisrationCar/update.php";
@@ -183,7 +194,7 @@ class AppLink {
static String uploadEgypt = "$server/uploadEgypt.php";
//==================certifcate==========
static String location = '$endPoint/ride/location';
static String location = '${box.read(BoxName.serverChosen)}/ride/location';
static String getCarsLocationByPassenger = "$location/get.php";
static String addpassengerLocation = "$location/addpassengerLocation.php";
static String getCarsLocationByPassengerSpeed = "$location/getSpeed.php";
@@ -241,7 +252,8 @@ class AppLink {
static String deletecaptainAccounr = "$authCaptin/deletecaptainAccounr.php";
static String updateAccountBank = "$authCaptin/updateAccountBank.php";
static String getAccount = "$authCaptin/getAccount.php";
static String updatePassengersInvitation =
"$server/ride/invitor/updatePassengersInvitation.php";
//===================Admin Captin============
static String getPassengerDetailsByPassengerID =
@@ -250,6 +262,7 @@ class AppLink {
static String getPassengerbyEmail = "$server/Admin/getPassengerbyEmail.php";
static String addAdminUser = "$server/Admin/adminUser/add.php";
static String getAdminUser = "$server/Admin/adminUser/get.php";
static String addError = "$server/Admin/errorApp.php";
static String getCaptainDetailsByEmailOrIDOrPhone =
"$server/Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php";
static String getCaptainDetails = "$server/Admin/AdminCaptain/get.php";

View File

@@ -0,0 +1,83 @@
import 'package:google_maps_flutter/google_maps_flutter.dart';
class UniversitiesPolygons {
// AUC polygon points
static const List<List<LatLng>> universityPolygons = [
// AUC Polygon
[
LatLng(30.013431, 31.502572),
LatLng(30.018469, 31.497478),
LatLng(30.023158, 31.495870),
LatLng(30.025084, 31.496781),
LatLng(30.018701, 31.511393),
LatLng(30.015312, 31.508310),
],
// Example polygon for University 'German University in Cairo (GUC)'
[
LatLng(29.984554, 31.437829),
LatLng(29.990363, 31.438390),
LatLng(29.990560, 31.445643),
LatLng(29.984436, 31.445825),
],
//Future University in Egypt (FUE)
[
LatLng(30.025794, 31.490946),
LatLng(30.028341, 31.491014),
LatLng(30.028341, 31.492586),
LatLng(30.025844, 31.492491),
],
//'British University in Egypt (BUE)'
[
LatLng(30.117423, 31.605834),
LatLng(30.118224, 31.605543),
LatLng(30.118649, 31.607361),
LatLng(30.118932, 31.608033),
LatLng(30.119592, 31.612159),
LatLng(30.119372, 31.612958),
LatLng(30.120017, 31.617102),
LatLng(30.119435, 31.617193),
],
//Misr International University (MIU)
[
LatLng(30.166498, 31.491663),
LatLng(30.171956, 31.491060),
LatLng(30.172212, 31.495754),
LatLng(30.167112, 31.496108),
],
// Canadian International College (CIC)
[
LatLng(30.034312, 31.428963),
LatLng(30.035661, 31.429037),
LatLng(30.036074, 31.430522),
LatLng(30.036017, 31.431146),
LatLng(30.034580, 31.431117),
],
// October 6 University (O6U)
[
LatLng(29.974102, 30.946934),
LatLng(29.976620, 30.944925),
LatLng(29.979848, 30.949832),
LatLng(29.977372, 30.951950),
],
[
LatLng(30.029312, 31.210046),
LatLng(30.027124, 31.201393),
LatLng(30.014523, 31.205087),
LatLng(30.015416, 31.212218),
LatLng(30.027325, 31.210661),
],
// Add polygons for 8 more universities...
];
static const List<String> universityNames = [
"American University in Cairo (AUC)",
'German University in Cairo (GUC)',
'Future University in Egypt (FUE)',
'British University in Egypt (BUE)',
'Misr International University (MIU)',
'Canadian International College (CIC)',
'October 6 University (O6U)',
"Cairo University",
// Add names for 8 more universities...
];
}

View File

@@ -1,10 +1,17 @@
import 'dart:io';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/auth/login_controller.dart';
import 'package:SEFER/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../constant/links.dart';
import '../../onbording_page.dart';
import '../functions/crud.dart';
class GoogleSignInHelper {
static final GoogleSignIn _googleSignIn = GoogleSignIn(
@@ -32,26 +39,114 @@ class GoogleSignInHelper {
}
}
static Future<GoogleSignInAccount?> signInFromLogin() async {
Future<GoogleSignInAccount?> signInFromLogin() async {
try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
if (googleUser != null) {
await _handleSignUp(googleUser);
// if (box.read(BoxName.countryCode) == 'Egypt') {
await Get.put(LoginController()).loginUsingCredentials(
box.read(BoxName.passengerID).toString(),
box.read(BoxName.email).toString(),
);
// } else if (box.read(BoxName.countryCode) == 'Jordan') {
// // Get.to(() => AiPage());
// }
}
return googleUser;
} catch (error) {
// if (error is GoogleSignInAuthenticationException) {
// // Handle authentication errors from Google Sign-In
// addError("Google sign-in authentication error: ${error.message}",
// '<GoogleSignInAccount?> signInFromLogin()');
// } else if (error is GoogleSignInAccountNotFoundException) {
// // Handle the case where the user is not found (if applicable)
// addError("Google sign-in account not found error: ${error.message}",
// '<GoogleSignInAccount?> signInFromLogin()');
// }
// else
if (error is SocketException) {
// Handle network issues, like SSL certificate issues
addError("Network error (SSL certificate issue): ${error.message}",
'<GoogleSignInAccount?> signInFromLogin()');
} else if (error is PlatformException) {
// Handle platform-specific errors, like Google Play Services issues
if (error.code == 'sign_in_required') {
// Google Play Services are required but not installed or outdated
showGooglePlayServicesError();
} else {
addError("Platform error: ${error.message}",
'<GoogleSignInAccount?> signInFromLogin()');
}
} else {
// Catch all other unknown errors
addError("Unknown error: ${error.toString()}",
'<GoogleSignInAccount?> signInFromLogin()');
}
return null;
}
}
void showGooglePlayServicesError() async {
const playStoreUrl =
'https://play.google.com/store/apps/details?id=com.google.android.gms&hl=en_US';
if (await canLaunchUrl(Uri.parse(playStoreUrl))) {
await launchUrl(Uri.parse(playStoreUrl));
} else {
// Fallback if the URL can't be opened
showDialog(
context: Get.context!,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Error'.tr),
content: Text(
'Could not open the Google Play Store. Please update Google Play Services manually.'
.tr),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Close'.tr),
),
],
);
},
);
}
}
// Future<GoogleSignInAccount?> signInFromLogin() async {
// try {
// final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
// if (googleUser != null) {
// await _handleSignUp(googleUser);
// // if (box.read(BoxName.countryCode) == 'Egypt') {
// await Get.put(LoginController()).loginUsingCredentials(
// box.read(BoxName.passengerID).toString(),
// box.read(BoxName.email).toString(),
// );
// // } else if (box.read(BoxName.countryCode) == 'Jordan') {
// // // Get.to(() => AiPage());
// // }
// }
// return googleUser;
// } catch (error) {
// addError(error.toString(), '<GoogleSignInAccount?> signInFromLogin()');
// return null;
// }
// }
addError(String error, where) async {
CRUD().post(link: AppLink.addError, payload: {
'error': error.toString(), // Example error description
'userId': box.read(BoxName.driverID) ??
box.read(BoxName.passengerID), // Example user ID
'userType': box.read(BoxName.driverID) != null
? 'Driver'
: 'passenger', // Example user type
'phone': box.read(BoxName.phone) ??
box.read(BoxName.phoneDriver), // Example phone number
'device': where
});
}
// Method to handle Google Sign-Out
static Future<void> signOut() async {
try {

View File

@@ -1,9 +1,11 @@
import 'dart:convert';
import 'dart:io';
import 'package:SEFER/constant/info.dart';
import 'package:SEFER/controller/firebase/firbase_messge.dart';
import 'package:SEFER/views/auth/login_page.dart';
import 'package:SEFER/views/auth/sms_verfy_page.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart';
@@ -13,6 +15,8 @@ import 'package:SEFER/main.dart';
import 'package:SEFER/views/home/map_page_passenger.dart';
import 'package:location/location.dart';
import '../functions/package_info.dart';
class LoginController extends GetxController {
final formKey = GlobalKey<FormState>();
final formKeyAdmin = GlobalKey<FormState>();
@@ -29,9 +33,20 @@ class LoginController extends GetxController {
update();
}
getAppTester(String appPlatform) async {
var res = await CRUD()
.get(link: AppLink.getTesterApp, payload: {'appPlatform': appPlatform});
@override
void onInit() async {
box.read(BoxName.isTest) == null ||
box.read(BoxName.isTest).toString() == '0'
? await getAppTester()
: null;
super.onInit();
}
getAppTester() async {
var res = await CRUD().get(
link: AppLink.getTesterApp,
payload: {'appPlatform': AppInformation.appName});
if (res != 'failure') {
var d = jsonDecode(res);
@@ -64,6 +79,8 @@ class LoginController extends GetxController {
await CRUD().get(link: AppLink.loginFromGooglePassenger, payload: {
'email': email,
'id': passengerID,
"platform": Platform.isAndroid ? 'android' : 'ios',
"appName": AppInformation.appName,
});
if (res == 'Failure') {
Get.offAll(SmsSignupEgypt());
@@ -79,6 +96,17 @@ class LoginController extends GetxController {
box.write(BoxName.isVerified, '1');
box.write(BoxName.email, jsonDecoeded['data'][0]['email']);
box.write(BoxName.phone, jsonDecoeded['data'][0]['phone']);
box.write(BoxName.isTest, '1');
box.write(BoxName.package, jsonDecoeded['data'][0]['package']);
box.write(BoxName.promo, jsonDecoeded['data'][0]['promo']);
box.write(BoxName.discount, jsonDecoeded['data'][0]['discount']);
box.write(BoxName.validity, jsonDecoeded['data'][0]['validity']);
box.write(BoxName.isInstall,
jsonDecoeded['data'][0]['isInstall'] ?? 'none');
box.write(BoxName.isGiftToken,
jsonDecoeded['data'][0]['isGiftToken'] ?? 'none');
box.write(BoxName.inviteCode,
jsonDecoeded['data'][0]['inviteCode'] ?? 'none');
var token = await CRUD().get(link: AppLink.getTokens, payload: {
'passengerID': box.read(BoxName.passengerID).toString()
@@ -94,10 +122,25 @@ class LoginController extends GetxController {
'cancel.wav',
);
Future.delayed(const Duration(seconds: 1));
await CRUD().post(link: AppLink.addTokens, payload: {
'token': box.read(BoxName.tokenFCM),
'passengerID': box.read(BoxName.passengerID).toString()
});
await CRUD().post(
link: "${AppLink.server}/ride/firebase/add.php",
payload: {
'token': box.read(BoxName.tokenFCM),
'passengerID': box.read(BoxName.passengerID).toString()
});
CRUD().post(
link:
"${AppLink.seferAlexandriaServer}/ride/firebase/add.php",
payload: {
'token': box.read(BoxName.tokenFCM),
'passengerID': box.read(BoxName.passengerID).toString()
});
CRUD().post(
link: "${AppLink.seferGizaServer}/ride/firebase/add.php",
payload: {
'token': box.read(BoxName.tokenFCM),
'passengerID': box.read(BoxName.passengerID).toString()
});
Get.defaultDialog(
title: 'Device Change Detected'.tr,
middleText:
@@ -111,8 +154,31 @@ class LoginController extends GetxController {
},
);
}
} // Logging to check if inviteCode is written correctly
print("Invite Code in Box: ${box.read(BoxName.inviteCode)}");
print("Is Install: ${box.read(BoxName.isInstall)}");
if (box.read(BoxName.inviteCode).toString() != 'none' &&
box.read(BoxName.isInstall).toString() != '1') {
await CRUD()
.post(link: AppLink.updatePassengersInvitation, payload: {
"inviteCode": box.read(BoxName.inviteCode).toString(),
"passengerID": box.read(BoxName.passengerID).toString(),
});
Get.defaultDialog(
title: 'Invitation Used'
.tr, // Automatically translates based on the current locale
middleText: "Your invite code was successfully applied!"
.tr, // Automatically translates based on the current locale
onConfirm: () {
Get.offAll(() =>
const MapPagePassenger()); // Navigate to MapPagePassenger after confirmation
},
textConfirm: "OK".tr, // Confirm button text
);
} else {
Get.offAll(() => const MapPagePassenger());
}
Get.offAll(() => const MapPagePassenger());
} else {
Get.offAll(() => SmsSignupEgypt());
// Get.snackbar(jsonDecoeded['status'], jsonDecoeded['data'],
@@ -241,15 +307,4 @@ class LoginController extends GetxController {
}
update();
}
@override
void onInit() async {
// permissionLocation = await Permission.locationWhenInUse.isGranted;
await getAppTester(AppInformation.appName);
// if (isTest == 0 && box.read(BoxName.passengerID) != null) {
// await loginUsingCredentials(
// box.read(BoxName.passengerID), box.read(BoxName.email));
// }
super.onInit();
}
}

View File

@@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:math';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/controller/auth/login_controller.dart';
import 'package:SEFER/controller/local/phone_intel/phone_number.dart';
import 'package:SEFER/views/home/map_page_passenger.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
@@ -214,6 +215,8 @@ class RegisterController extends GetxController {
await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
'phone_number': phoneNumber,
'token': otp.toString(),
// 'urlImage': box.read(BoxName.passengerPhotoUrl),
// 'name': box.read(BoxName.name),
});
await controller.sendSmsEgypt(phoneNumber, otp.toString());
@@ -257,7 +260,7 @@ class RegisterController extends GetxController {
'password': 'unknown',
'gender': 'unknown',
'birthdate': '2002-01-01',
'site': 'unknown',
'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
'first_name': box.read(BoxName.name).toString().split(' ')[0],
'last_name': box.read(BoxName.name).toString().split(' ')[1],
};
@@ -276,8 +279,13 @@ class RegisterController extends GetxController {
payload: payload,
);
box.write(BoxName.isVerified, '1');
box.write(BoxName.isFirstTime, '0');
box.write(BoxName.phone, phoneController.text);
Get.offAll(const MapPagePassenger());
// Get.offAll(const MapPagePassenger());
Get.put(LoginController()).loginUsingCredentials(
box.read(BoxName.passengerID).toString(),
box.read(BoxName.email).toString(),
);
}
} else {
Get.snackbar(

View File

@@ -1,12 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:SEFER/env/env.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:googleapis_auth/auth_io.dart';
import 'package:googleapis_auth/googleapis_auth.dart';
import 'package:http/http.dart' as http;
import 'package:SEFER/controller/functions/toast.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
@@ -131,16 +127,22 @@ class FirebaseMessagesController extends GetxController {
Get.find<MapPassengerController>().statusRide == 'Apply';
Get.find<MapPassengerController>().isSearchingWindow == false;
Get.find<MapPassengerController>().update();
NotificationController().showNotification(
'Apply Order'.tr, 'Driver Applied the Ride for You'.tr, 'order1');
if (Platform.isAndroid) {
NotificationController().showNotification(
'Apply Order'.tr, 'Driver Applied the Ride for You'.tr, 'order1');
}
// driverAppliedTripSnakBar();
} else if (message.notification!.title! == 'Promo'.tr) {
NotificationController()
.showNotification('Promo', 'Show latest promo'.tr, 'promo');
if (Platform.isAndroid) {
NotificationController()
.showNotification('Promo', 'Show latest promo'.tr, 'promo');
}
Get.to(const PromosPassengerPage());
} else if (message.notification!.title! == 'Trip Monitoring'.tr) {
NotificationController()
.showNotification('Trip Monitoring'.tr, '', 'iphone_ringtone');
if (Platform.isAndroid) {
NotificationController()
.showNotification('Trip Monitoring'.tr, '', 'iphone_ringtone');
}
var myListString = message.data['passengerList'];
var myList = jsonDecode(myListString) as List<dynamic>;
Get.toNamed('/tripmonitor', arguments: {
@@ -148,46 +150,59 @@ class FirebaseMessagesController extends GetxController {
'driverId': myList[1].toString(),
});
} else if (message.notification!.title! == 'token change'.tr) {
NotificationController()
.showNotification('token change'.tr, 'token change'.tr, 'cancel');
if (Platform.isAndroid) {
NotificationController()
.showNotification('token change'.tr, 'token change'.tr, 'cancel');
}
GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'DriverIsGoingToPassenger'.tr) {
Get.find<MapPassengerController>().isDriverInPassengerWay = true;
Get.find<MapPassengerController>().update();
NotificationController().showNotification('Driver is Going To You'.tr,
'Please stay on the picked point.'.tr, 'tone1');
if (Platform.isAndroid) {
NotificationController().showNotification('Driver is Going To You'.tr,
'Please stay on the picked point.'.tr, 'tone1');
}
// Get.snackbar('Driver is Going To Passenger', '',
// backgroundColor: AppColor.greenColor);
} else if (message.notification!.title! == 'message From passenger') {
NotificationController()
.showNotification('message From passenger'.tr, ''.tr, 'tone2');
if (Platform.isAndroid) {
NotificationController()
.showNotification('message From passenger'.tr, ''.tr, 'tone2');
}
passengerDialog(message.notification!.body!);
update();
} else if (message.notification!.title! == 'message From Driver') {
NotificationController()
.showNotification('message From passenger'.tr, ''.tr, 'tone2');
passengerDialog(message.notification!.body!);
if (Platform.isAndroid) {
NotificationController()
.showNotification('message From passenger'.tr, ''.tr, 'tone2');
}
update();
} else if (message.notification!.title! == 'RideIsBegin'.tr) {
Get.find<MapPassengerController>().getBeginRideFromDriver();
// Get.snackbar('RideIsBegin', '', backgroundColor: AppColor.greenColor);
box.write(BoxName.passengerWalletTotal, '0');
NotificationController()
.showNotification('Trip is Begin'.tr, ''.tr, 'start');
update();
if (Platform.isAndroid) {
NotificationController()
.showNotification('Trip is Begin'.tr, ''.tr, 'start');
}
} else if (message.notification!.title! == 'Hi ,I will go now'.tr) {
// Get.snackbar('Hi ,I will go now', '',
// backgroundColor: AppColor.greenColor);
NotificationController().showNotification(
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2');
if (Platform.isAndroid) {
NotificationController().showNotification(
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2');
}
update();
} else if (message.notification!.title! == 'Hi ,I Arrive your site'.tr) {
NotificationController()
.showNotification('Hi ,I Arrive your site'.tr, ''.tr, 'tone2');
driverArrivePassengerDialoge();
if (Platform.isAndroid) {
NotificationController()
.showNotification('Hi ,I Arrive your site'.tr, ''.tr, 'tone2');
}
update();
} else if (message.notification!.title! == "Cancel Trip from driver".tr) {
Get.back();
@@ -214,10 +229,12 @@ class FirebaseMessagesController extends GetxController {
} else if (message.notification!.title! == 'Driver Finish Trip'.tr) {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
NotificationController().showNotification(
'Driver Finish Trip'.tr,
'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr,
'tone1');
if (Platform.isAndroid) {
NotificationController().showNotification(
'Driver Finish Trip'.tr,
'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr,
'tone1');
}
Get.find<AudioRecorderController>().stopRecording();
if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) {
box.write(BoxName.passengerWalletTotal, 0);
@@ -249,11 +266,13 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
// if (Platform.isAndroid) {
NotificationController().showNotification(
'Call Income'.tr,
message.notification!.body!,
'iphone_ringtone',
);
if (Platform.isAndroid) {
NotificationController().showNotification(
'Call Income'.tr,
message.notification!.body!,
'iphone_ringtone',
);
}
// }
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.to(() => PassengerCallPage(
@@ -267,12 +286,13 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
// if (Platform.isAndroid) {
NotificationController().showNotification(
'Call Income'.tr,
message.notification!.body!,
'iphone_ringtone',
);
// }
if (Platform.isAndroid) {
NotificationController().showNotification(
'Call Income'.tr,
message.notification!.body!,
'iphone_ringtone',
);
}
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.to(() => PassengerCallPage(
// channelName: driverList[1].toString(),
@@ -325,11 +345,13 @@ class FirebaseMessagesController extends GetxController {
// }
else if (message.notification!.title! == 'Order Applied'.tr) {
NotificationController().showNotification(
'The order Accepted by another Driver'.tr,
'We regret to inform you that another driver has accepted this order.'
.tr,
'order');
if (Platform.isAndroid) {
NotificationController().showNotification(
'The order Accepted by another Driver'.tr,
'We regret to inform you that another driver has accepted this order.'
.tr,
'order');
}
}
}
@@ -645,7 +667,7 @@ class FirebaseMessagesController extends GetxController {
if (response.statusCode == 200) {
print(
'Notification sent successfully. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
print('Response token: ${token}');
} else {
print(
'Failed to send notification. Status code: ${response.statusCode}');
@@ -696,8 +718,9 @@ class FirebaseMessagesController extends GetxController {
// }
// }
Future<void> sendNotificationToDriverMAP(String title, String body,
String token, List<String> data, String tone) async {
Future<void> sendNotificationToDriverMAP(
String title, String body, String token, List<String> data, String tone,
{int retryCount = 2}) async {
try {
String serviceAccountKeyJson = '''{
"type": "service_account",
@@ -719,7 +742,7 @@ class FirebaseMessagesController extends GetxController {
// Obtain an OAuth 2.0 access token
final accessToken = await accessTokenManager.getAccessToken();
Log.print('accessToken: ${accessToken}');
// Log.print('accessToken: ${accessToken}');
// Send the notification
final response = await http.post(
@@ -762,14 +785,28 @@ class FirebaseMessagesController extends GetxController {
if (response.statusCode == 200) {
print(
'Notification sent successfully. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
print('Response token: ${token}');
} else {
print(
'Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
if (retryCount > 0) {
print('Retrying... Attempts remaining: $retryCount');
await Future.delayed(
Duration(seconds: 2)); // Optional delay before retrying
return sendNotificationToDriverMAP(title, body, token, data, tone,
retryCount: retryCount - 1);
}
}
} catch (e) {
print('Error sending notification: $e');
if (retryCount > 0) {
print('Retrying... Attempts remaining: $retryCount');
await Future.delayed(
Duration(seconds: 2)); // Optional delay before retrying
return sendNotificationToDriverMAP(title, body, token, data, tone,
retryCount: retryCount - 1);
}
}
}

View File

@@ -17,7 +17,7 @@ class NotificationController extends GetxController {
// Displays a notification with the given title and message
void showNotification(String title, String message, String tone) async {
AndroidNotificationDetails android = AndroidNotificationDetails(
'your channel id', 'your channel name',
'high_importance_channel', 'High Importance Notifications',
importance: Importance.max,
priority: Priority.high,
showWhen: false,

View File

@@ -109,7 +109,7 @@ class CRUD {
print(await response.stream.bytesToString());
Get.defaultDialog(
title: 'You will receive a code in WhatsApp Messenger'.tr,
middleText: '',
middleText: 'wait 1 minute to recive message'.tr,
confirm: MyElevatedButton(
title: 'OK'.tr,
onPressed: () {

View File

@@ -3,7 +3,6 @@ import 'dart:io';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -17,7 +16,7 @@ Future<void> checkForUpdate(BuildContext context) async {
final version = packageInfo.version;
print('currentVersion is : $currentVersion');
// Fetch the latest version from your server
String latestVersion = await getPackageInfo();
String latestVersion = box.read(BoxName.package);
box.write(BoxName.packagInfo, version);
if (latestVersion.isNotEmpty && latestVersion != currentVersion) {
@@ -25,18 +24,22 @@ Future<void> checkForUpdate(BuildContext context) async {
}
}
Future<String> getPackageInfo() async {
final response = await CRUD().get(link: AppLink.packageInfo, payload: {
"platform": Platform.isAndroid ? 'android' : 'ios',
"appName": AppInformation.appName,
});
if (response != 'failure') {
return jsonDecode(response)['message'][0]['version'];
}
return '';
checkForBounusInvitation() {
if (box.read(BoxName.inviteCode) != null) {}
}
// Future<String> getPackageInfo() async {
// final response = await CRUD().get(link: AppLink.packageInfo, payload: {
// "platform": Platform.isAndroid ? 'android' : 'ios',
// "appName": AppInformation.appName,
// });
// if (response != 'failure') {
// return jsonDecode(response)['message'][0]['version'];
// }
// return '';
// }
void showUpdateDialog(BuildContext context) {
final String storeUrl = Platform.isAndroid
? 'https://play.google.com/store/apps/details?id=com.mobileapp.store.ride'

View File

@@ -0,0 +1,91 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/links.dart';
import '../../views/widgets/elevated_btn.dart';
import '../functions/crud.dart';
class BlinkingController extends GetxController {
final promoFormKey = GlobalKey<FormState>();
final promo = TextEditingController();
bool promoTaken = false;
void applyPromoCodeToPassenger() async {
//TAWJIHI
if (promoFormKey.currentState!.validate()) {
CRUD().get(link: AppLink.getPassengersPromo, payload: {
'promo_code': promo.text,
}).then((value) {
if (value == 'failure') {
Get.defaultDialog(
title: 'Promo End !'.tr,
confirm: MyElevatedButton(
title: 'Back',
onPressed: () {
Get.back();
Get.back();
},
));
}
var decode = jsonDecode(value);
// if (decode["status"] == "success") {
// var firstElement = decode["message"][0];
// if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) {
// totalPassenger = totalCostPassenger -
// (totalCostPassenger * int.parse(firstElement['amount']) / 100);
// update();
// } else {
// totalPassenger = totalCostPassenger -
// (totalCostPassenger * int.parse(firstElement['amount']) / 100);
// update();
// }
// totalDriver = totalDriver -
// (totalDriver * int.parse(firstElement['amount']) / 100);
// promoTaken = true;
// update();
// Get.back();
// }
});
}
}
// Reactive variable for blinking (on/off)
var isLightOn = false.obs;
// To animate the border color
var borderColor = Colors.black.obs;
Timer? _blinkingTimer;
// Method to start blinking for 5 seconds
void startBlinking() {
int count = 0;
_blinkingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
// Toggle light on/off
isLightOn.value = !isLightOn.value;
borderColor.value = isLightOn.value
? Colors.yellow
: Colors.black; // Animate border color
count++;
// Stop blinking after 5 seconds
if (count >= 35) {
timer.cancel();
isLightOn.value = false; // Ensure light turns off
borderColor.value = Colors.black; // Reset the border color
}
});
}
@override
void onClose() {
_blinkingTimer?.cancel();
super.onClose();
}
}

View File

@@ -0,0 +1,78 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import '../../../constant/colors.dart';
import '../functions/launch.dart';
class ContactUsController extends GetxController {
final String phone1 = '+201018805430';
final String phone2 = '+201080182934';
final TimeOfDay workStartTime = const TimeOfDay(hour: 12, minute: 0);
final TimeOfDay workEndTime = const TimeOfDay(hour: 19, minute: 0);
bool _isWithinWorkTime(TimeOfDay now) {
return (now.hour > workStartTime.hour ||
(now.hour == workStartTime.hour &&
now.minute >= workStartTime.minute)) &&
(now.hour < workEndTime.hour ||
(now.hour == workEndTime.hour && now.minute <= workEndTime.minute));
}
void showContactDialog(BuildContext context) {
TimeOfDay now = TimeOfDay.now();
showCupertinoModalPopup(
context: context,
builder: (context) => CupertinoActionSheet(
title: Text('Contact Us'.tr),
message: Text('Choose a contact option'.tr),
actions: <Widget>[
if (_isWithinWorkTime(now))
CupertinoActionSheetAction(
child: Text(phone1),
onPressed: () => makePhoneCall(
phone1,
),
),
if (_isWithinWorkTime(now))
CupertinoActionSheetAction(
child: Text(phone2),
onPressed: () => makePhoneCall(phone2),
),
if (!_isWithinWorkTime(now))
CupertinoActionSheetAction(
child: Text(
'Work time is from 12:00 - 19:00.\nYou can send a WhatsApp message or email.'
.tr),
onPressed: () => Navigator.pop(context),
),
CupertinoActionSheetAction(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const Icon(
FontAwesome.whatsapp,
color: AppColor.greenColor,
),
Text('Send WhatsApp Message'.tr),
],
),
onPressed: () =>
launchCommunication('whatsapp', phone1, 'Hello'.tr),
),
CupertinoActionSheetAction(
child: Text('Send Email'.tr),
onPressed: () =>
launchCommunication('email', 'support@sefer.live', 'Hello'.tr),
),
],
cancelButton: CupertinoActionSheetAction(
child: Text('Cancel'.tr),
onPressed: () => Navigator.pop(context),
),
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -606,6 +606,45 @@ iOS [https://getapp.cc/app/6458734951]
'الرَّجَاء التَّحَرُّك إِلَى السَّيَّارَة الآن',
'You will receive a code in WhatsApp Messenger':
"سوف تتلقى رمزًا في واتساب ماسنجر",
'If you need assistance, contact us':
"إذا كنت بحاجة إلى المساعدة، تواصل معنا",
"Promo Ended": "انتهى العرض",
'Enter the promo code and get': 'أدخل رمز الترويج واحصل على',
'DISCOUNT': 'خصم',
'No wallet record found': 'لم يتم العثور على سجل محفظة',
'for': 'لمدة',
"SEFER is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.":
"سفر هو التطبيق الأكثر أمانًا لمشاركة الركوب الذي يقدم العديد من الميزات لكل من السائقين والركاب. نحن نقدم أقل عمولة بنسبة 8% فقط، مما يضمن حصولك على أفضل قيمة لرحلاتك. يتضمن تطبيقنا التأمين لأفضل السائقين، الصيانة المنتظمة للسيارات مع أفضل المهندسين، والخدمات على الطريق لضمان تجربة محترمة وعالية الجودة لجميع المستخدمين.",
"You can contact us during working hours from 12:00 - 19:00.":
"يمكنك الاتصال بنا خلال ساعات العمل من 12:00 - 7:00.",
"Contact Us": "اتصل بنا",
'Choose a contact option': 'اختر خيار الاتصال',
'Work time is from 12:00 - 19:00.\nYou can send a WhatsApp message or email.':
'ساعات العمل من 12:00 - 19:00.\nيمكنك إرسال رسالة عبر واتساب أو بريد إلكتروني.',
'Promo code copied to clipboard!': "'تم نسخ رمز العرض إلى الحافظة!'",
'Copy Code': 'نسخ الرمز',
"Your invite code was successfully applied!":
"تم تطبيق رمز الدعوة بنجاح!",
"Payment Options": " خيارات الدفع",
"wait 1 minute to receive message":
"انتظر دقيقة واحدة لاستلام الرسالة",
'Promo Copied!': 'تم نسخ العرض!',
'You have copied the promo code.': 'لقد قمت بنسخ رمز العرض.',
'Valid Until:': 'لمدة:',
"Select Payment Amount": " اختر مبلغ الدفع",
"The promotion period has ended.": "انتهت فترة العرض.",
"Promo Code Accepted": "تم قبول كود العرض",
'Tap on the promo code to copy it!': 'اضغط على رمز العرض لنسخه!',
"Lowest Price Achieved": "تم الوصول إلى أدنى سعر",
"Cannot apply further discounts.":
"لا يمكن تطبيق المزيد من الخصومات.",
"Promo Already Used": "تم استخدام كود العرض بالفعل",
'Invitation Used': "تم استخدام الدعوة",
"You have already used this promo code.":
"لقد استخدمت هذا الكود بالفعل.",
"Insert Your Promo Code": "أدخل كود العرض الخاص بك",
"Enter promo code here": "أدخل كود العرض هنا",
"Please enter a valid promo code": "يرجى إدخال كود عرض صالح",
'Awfar Car': 'أوفر كار',
"Old and affordable, perfect for budget rides.":
"سيارة ميسورة التكلفة، مثالية للرحلات الاقتصادية.",

View File

@@ -1,13 +1,12 @@
import 'dart:convert';
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:get/get.dart';
import 'package:SEFER/controller/firebase/firbase_messge.dart';
import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../constant/style.dart';
import '../../main.dart';
import '../../views/widgets/elevated_btn.dart';
import '../functions/crud.dart';
class PassengerNotificationController extends GetxController {
@@ -21,22 +20,17 @@ class PassengerNotificationController extends GetxController {
link: AppLink.getNotificationPassenger,
payload: {'passenger_id': box.read(BoxName.passengerID)});
if (res == "failure") {
Get.defaultDialog(
title: 'There is no notification yet'.tr,
titleStyle: AppStyle.title,
middleText: '',
confirm: MyElevatedButton(
title: 'Back',
onPressed: () {
Get.back();
Get.back();
}));
MyDialog().getDialog('There is no notification yet'.tr, '', () {
Get.back();
Get.back();
});
} else {
notificationData = jsonDecode(res);
isloading = false;
update();
}
notificationData = jsonDecode(res);
// sql.insertData(notificationData['message'], TableName.captainNotification);
isloading = false;
update();
// sql.insertData(notificationData['message'], TableName.captainNotification);
}
updateNotification(String id) async {

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/links.dart';
@@ -23,17 +24,10 @@ class PassengerWalletHistoryController extends GetxController {
isLoading = false;
update();
} else {
Get.defaultDialog(
barrierDismissible: false,
title: 'No wallet record found'.tr,
titleStyle: AppStyle.title,
middleText: '',
confirm: MyElevatedButton(
title: 'OK'.tr,
onPressed: () {
Get.back();
Get.back();
}));
MyDialog().getDialog('No wallet record found'.tr, '', () {
Get.back();
Get.back();
});
}
}

View File

@@ -167,7 +167,7 @@ class PaymentController extends GetxController {
? '1140'
: '0');
getPassengerWallet();
// getPassengerWallet();
isLoading = false;
update();
@@ -698,24 +698,28 @@ class PaymentController extends GetxController {
onPayment: (PaymobResponseWallet response) {},
);
if (response!.success == true && response.responseCode == '200') {
Get.defaultDialog(
barrierDismissible: false,
title: 'Payment Successful'.tr,
titleStyle: AppStyle.title,
content: Text(
'The payment was approved.'.tr,
style: AppStyle.title,
),
confirm: MyElevatedButton(
title: 'OK'.tr,
kolor: AppColor.greenColor,
onPressed: () async {
Get.back();
method();
},
),
);
// if (response!.success == true && response.responseCode == '200') {
if (response!.responseCode == '200' && response.success == true) {
// Log.print('transactionID wewer: ${response.transactionID}');
Toast.show(context, 'Payment Successful'.tr, AppColor.greenColor);
method();
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'Payment Successful'.tr,
// titleStyle: AppStyle.title,
// content: Text(
// 'The payment was approved.'.tr,
// style: AppStyle.title,
// ),
// confirm: MyElevatedButton(
// title: 'OK'.tr,
// kolor: AppColor.greenColor,
// onPressed: () async {
// Get.back();
// method();
// },
// ),
// );
} else {
Get.defaultDialog(
barrierDismissible: false,
@@ -763,46 +767,49 @@ class PaymentController extends GetxController {
billingData: PaymobBillingData(),
onPayment: (PaymobResponse response) {},
);
if (response!.success == true && response.responseCode == '200') {
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();
},
),
);
} else {
Get.defaultDialog(
barrierDismissible: false,
// backgroundColor: AppColor.redColor,
title: 'Payment Failed'.tr,
content: Text(
'The payment was not approved. Please try again.'.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
confirm: MyElevatedButton(
title: 'OK'.tr,
kolor: AppColor.redColor,
onPressed: () async {
Get.back();
},
),
);
}
if (response!.responseCode == '200' && response.success == true) {
// if (response!.success == true && response.responseCode == '200') {
// if (response!.responseCode == 'APPROVED') {
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,
// backgroundColor: AppColor.redColor,
title: 'Payment Failed'.tr,
content: Text(
'The payment was not approved. Please try again.'.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
confirm: MyElevatedButton(
title: 'OK'.tr,
kolor: AppColor.redColor,
onPressed: () async {
Get.back();
},
),
);
}
// }
}
} catch (e) {
Get.defaultDialog(

View File

@@ -79,13 +79,33 @@ class RateController extends GetxController {
}
}
}
await CRUD().post(link: AppLink.addRateToDriver, payload: {
'passenger_id': box.read(BoxName.passengerID).toString(),
'driver_id': driverId,
'ride_id': rideId,
'rating': selectedRateItemId.toString(),
'comment': comment.text,
}).then((value) {
await CRUD().post(
link: "${AppLink.seferCairoServer}/rate/addRateToDriver.php",
payload: {
'passenger_id': box.read(BoxName.passengerID).toString(),
'driver_id': driverId,
'ride_id': rideId,
'rating': selectedRateItemId.toString(),
'comment': comment.text,
}).then((value) {
CRUD().post(
link: "${AppLink.seferAlexandriaServer}/rate/addRateToDriver.php",
payload: {
'passenger_id': box.read(BoxName.passengerID).toString(),
'driver_id': driverId,
'ride_id': rideId,
'rating': selectedRateItemId.toString(),
'comment': comment.text,
});
CRUD().post(
link: "${AppLink.seferGizaServer}/rate/addRateToDriver.php",
payload: {
'passenger_id': box.read(BoxName.passengerID).toString(),
'driver_id': driverId,
'ride_id': rideId,
'rating': selectedRateItemId.toString(),
'comment': comment.text,
});
Get.find<MapPassengerController>().restCounter();
Get.offAll(const MapPagePassenger());
});

View File

@@ -0,0 +1,275 @@
import 'dart:math' as math;
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/splash_screen_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
class CouponPainter extends CustomPainter {
final Color primaryColor;
final Color secondaryColor;
CouponPainter({
required this.primaryColor,
required this.secondaryColor,
});
@override
void paint(Canvas canvas, Size size) {
final Paint primaryPaint = Paint()
..color = primaryColor
..style = PaintingStyle.fill;
final Paint secondaryPaint = Paint()
..color = secondaryColor
..style = PaintingStyle.fill;
final Path path = Path();
// Draw the main ticket shape
path.moveTo(0, size.height * 0.1);
path.lineTo(size.width * 0.93, size.height * 0.1);
path.arcToPoint(
Offset(size.width, size.height * 0.2),
radius: const Radius.circular(20),
clockwise: false,
);
path.lineTo(size.width, size.height * 0.8);
path.arcToPoint(
Offset(size.width * 0.93, size.height * 0.9),
radius: const Radius.circular(20),
clockwise: false,
);
path.lineTo(0, size.height * 0.9);
path.close();
canvas.drawPath(path, primaryPaint);
// Draw decorative circles on the left side
for (int i = 0; i < 5; i++) {
canvas.drawCircle(
Offset(0, size.height * (0.2 + i * 0.15)),
10,
secondaryPaint,
);
}
// Draw a wavy pattern on the right side
final wavePaint = Paint()
..color = secondaryColor.withOpacity(0.3)
..style = PaintingStyle.stroke
..strokeWidth = 2;
for (int i = 0; i < 20; i++) {
canvas.drawLine(
Offset(size.width * 0.8, i * 10.0),
Offset(
size.width,
i * 10.0 + math.sin(i * 0.5) * 10,
),
wavePaint,
);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
class PromoBanner extends StatelessWidget {
final String promoCode;
final String discountPercentage;
final String validity;
const PromoBanner({
Key? key,
required this.promoCode,
required this.discountPercentage,
required this.validity,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: CouponPainter(
primaryColor: Colors.blue[800]!,
secondaryColor: Colors.white,
),
child: Container(
width: 320,
height: 240,
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const SizedBox(
height: 10,
),
Text(
'Enter the promo code and get'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
textAlign: TextAlign.center,
),
Text(
'${'DISCOUNT'.tr} $discountPercentage ${'for'.tr} $validity'
.toUpperCase(),
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 10),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Text(
promoCode,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.blue[800],
),
),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {
// Copy promo code to clipboard
Clipboard.setData(ClipboardData(text: promoCode));
// Show a Snackbar or other feedback to the user
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Promo code copied to clipboard!'.tr)),
);
box.write(BoxName.isGiftToken, '1');
Get.back();
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.blue[800], // Customize the color
backgroundColor: Colors.white, // Customize the background color
),
child: Text('Copy Code'.tr),
)
],
),
),
);
}
}
// import 'package:SEFER/constant/colors.dart';
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// class CouponPainter extends CustomPainter {
// @override
// void paint(Canvas canvas, Size size) {
// final Paint paint = Paint()
// ..color = AppColor.blueColor
// ..style = PaintingStyle.fill;
// final Path path = Path();
// // Draw the ticket shape (like the image)
// path.moveTo(0, 0);
// path.lineTo(size.width * 0.7, 0); // top left to top right edge
// // Draw curve for the cut on the right side (ticket look)
// path.arcToPoint(Offset(size.width, size.height * 0.15),
// radius: const Radius.circular(15), clockwise: false);
// path.lineTo(size.width, size.height * 0.85);
// path.arcToPoint(Offset(size.width * 0.7, size.height),
// radius: const Radius.circular(15), clockwise: false);
// path.lineTo(0, size.height);
// canvas.drawPath(path, paint);
// }
// @override
// bool shouldRepaint(CustomPainter oldDelegate) {
// return false;
// }
// }
// class PromoBanner extends StatelessWidget {
// final String promoCode;
// final String discountPercentage;
// final String validity;
// const PromoBanner({
// required this.promoCode,
// required this.discountPercentage,
// required this.validity,
// });
// @override
// Widget build(BuildContext context) {
// return CustomPaint(
// painter: CouponPainter(),
// child: Container(
// width: 300, // Fixed width for the promo banner
// height: 180, // Set the desired height for your banner
// padding: const EdgeInsets.all(16),
// child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// children: [
// Text(
// 'Enter the promo code and get'.toUpperCase(),
// style: const TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// textAlign: TextAlign.center,
// ),
// Text(
// '$discountPercentage OFF for $validity'.toUpperCase(),
// style: const TextStyle(
// fontSize: 18,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// textAlign: TextAlign.center,
// ),
// const SizedBox(height: 10),
// Container(
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(10),
// ),
// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
// child: Text(
// promoCode,
// style: TextStyle(
// fontSize: 20,
// fontWeight: FontWeight.bold,
// color: Colors.blue[800],
// ),
// ),
// ),
// ],
// ),
// ),
// );
// }
// }

View File

@@ -17,6 +17,7 @@ import '../../constant/info.dart';
import '../../controller/auth/apple_signin_controller.dart';
import '../../controller/auth/google_sign.dart';
import '../../controller/auth/login_controller.dart';
import '../home/HomePage/contact_us.dart';
import '../home/profile/passenger_profile_page.dart';
import '../widgets/mycircular.dart';
@@ -218,7 +219,7 @@ class LoginPage extends StatelessWidget {
// ),
InkWell(
onTap: () async {
await GoogleSignInHelper.signInFromLogin();
await GoogleSignInHelper().signInFromLogin();
},
child: Container(
padding: const EdgeInsets.symmetric(
@@ -303,6 +304,14 @@ class LoginPage extends StatelessWidget {
SizedBox(
height: Get.height * .1,
),
GestureDetector(
onTap: () => Get.to(() => ContactUsPage()),
child: Text(
'If you need assistance, contact us'
.tr, // Improved wording
style: AppStyle.subtitle,
),
),
// Text(
// 'if you dont have account'.tr,
// style: AppStyle.subtitle,

View File

@@ -0,0 +1,102 @@
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
// ignore: unused_import
import 'package:SEFER/controller/functions/launch.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import '../../../controller/functions/tts.dart';
import '../../../controller/home/contact_us_controller.dart';
class ContactUsPage extends StatelessWidget {
ContactUsPage({super.key});
@override
Widget build(BuildContext context) {
Get.put(ContactUsController());
return GetBuilder<ContactUsController>(builder: (controller) {
return MyScafolld(
title: "Contact Us".tr,
body: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
decoration: AppStyle.boxDecoration1,
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image.asset('assets/images/logo.gif')),
IconButton(
onPressed: () async {
Get.put(TextToSpeechController()).speakText(
'SEFER is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.'
.tr);
},
icon: const Icon(Icons.headphones),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'SEFER is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.'
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
),
],
),
),
const SizedBox(
height: 30,
),
Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"You can contact us during working hours from 12:00 - 19:00."
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
),
),
InkWell(
onTap: () => controller.showContactDialog(context),
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
Icons.phone,
color: AppColor.blueColor,
),
Icon(
FontAwesome.whatsapp,
color: AppColor.greenColor,
),
Icon(
Icons.email,
color: AppColor.redColor,
),
],
),
),
const SizedBox(
height: 30,
)
],
),
)
],
isleading: true);
});
}
}

View File

@@ -51,6 +51,7 @@ class MapPagePassenger extends StatelessWidget {
CarDetailsTypeToChoose(),
const HeaderDestination(),
const BurcMoney(),
const PromoCode(),
const ApplyOrderWidget(), const MapMenuWidget(),
// hexagonClipper(),
const CancelRidePageShow(),

View File

@@ -33,6 +33,7 @@ class ApplyOrderWidget extends StatelessWidget {
InkWell(
onTap: () {
if (box.read(BoxName.carType) == 'Speed' ||
box.read(BoxName.carType) == 'Awfar Car' ||
box.read(BoxName.carType) == 'Delivery') {
Get.snackbar(
'This price is'.tr +
@@ -117,16 +118,24 @@ class ApplyOrderWidget extends StatelessWidget {
: box.read(BoxName.carType) == 'Speed'
? 'assets/images/carspeed.png'
: box.read(BoxName.carType) ==
'Delivery'
'Scooter'
? 'assets/images/moto.png'
: box.read(BoxName.carType) ==
'Mashwari'
'Mishwar Vip'
? 'assets/images/freeRide.png'
: box.read(BoxName
.carType) ==
'Rayeh Gai'
? 'assets/images/roundtrip.png'
: 'assets/images/carspeed.png', // Default image if none of the above
'Awfar Car'
? 'assets/images/balash.png'
: box.read(BoxName
.carType) ==
'Pink Bike'
? 'assets/images/pinkBike.png'
: box.read(BoxName
.carType) ==
'Rayeh Gai'
? 'assets/images/roundtrip.png'
: 'assets/images/carspeed.png', // Default image if none of the above
width: 80,
),
Column(
@@ -159,11 +168,51 @@ class ApplyOrderWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
radius: 30,
radius: 25,
backgroundImage: NetworkImage(
// '',
// ),
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'),
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg',
),
child: Builder(
builder: (context) {
return Image.network(
'${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg',
fit: BoxFit.cover,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child; // Image is loaded
} else {
return Center(
child: CircularProgressIndicator(
value: loadingProgress
.expectedTotalBytes !=
null
? loadingProgress
.cumulativeBytesLoaded /
(loadingProgress
.expectedTotalBytes ??
1)
: null,
),
);
}
},
errorBuilder: (BuildContext context,
Object error,
StackTrace? stackTrace) {
return const Icon(
Icons
.person, // Icon to show when image fails to load
size:
25, // Adjust the size as needed
color: AppColor
.blueColor, // Color for the error icon
);
},
);
},
),
),
Column(
children: [
@@ -196,7 +245,8 @@ class ApplyOrderWidget extends StatelessWidget {
'message From passenger',
'Hello, I\'m at the agreed-upon location'
.tr,
controller.driverToken,
controller.driverToken
.toString(),
'ding.wav',
);
Get.back();

View File

@@ -1,11 +1,14 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/blinking_promo_controller.dart.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/home/profile/passenger_profile_page.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:SEFER/views/widgets/my_textField.dart';
import 'package:flutter/material.dart';
import 'package:flutter_confetti/flutter_confetti.dart';
import 'package:get/get.dart';
import '../../../constant/info.dart';
@@ -158,35 +161,35 @@ class CarDetailsTypeToChoose extends StatelessWidget {
carType.carType == 'Comfort'
? mapPassengerController
.totalPassengerComfort
.toStringAsFixed(2)
.toStringAsFixed(1)
: carType.carType == 'Speed'
? mapPassengerController
.totalPassengerSpeed
.toStringAsFixed(2)
.toStringAsFixed(1)
: carType.carType == 'Awfar Car'
? mapPassengerController
.totalPassengerBalash
.toStringAsFixed(2)
.toStringAsFixed(1)
: carType.carType == 'Scooter'
? mapPassengerController
.totalPassengerScooter
.toStringAsFixed(2)
.toStringAsFixed(1)
: carType.carType == 'Lady'
? mapPassengerController
.totalPassengerLady
.toStringAsFixed(2)
.toStringAsFixed(1)
: carType.carType ==
'Pink Bike'
? mapPassengerController
.totalPassengerScooter
.toStringAsFixed(
2)
1)
: carType.carType ==
'Rayeh Gai'
? mapPassengerController
.totalPassengerRayehGai
.toStringAsFixed(
2)
1)
: '50',
style:
AppStyle.title.copyWith(fontSize: 20),
@@ -203,7 +206,18 @@ class CarDetailsTypeToChoose extends StatelessWidget {
decoration:
AppStyle.boxDecoration1,
child: Text(
'-12%',
mapPassengerController
.promoTaken
? mapPassengerController
.totalPassengerComfortDiscount
.toStringAsFixed(
1)
: (mapPassengerController
.totalPassengerComfortDiscount -
mapPassengerController
.totalPassengerComfort)
.toStringAsFixed(
1),
style: AppStyle.subtitle
.copyWith(
color: AppColor
@@ -214,8 +228,15 @@ class CarDetailsTypeToChoose extends StatelessWidget {
),
Text(
mapPassengerController
.totalPassengerComfortDiscount
.toStringAsFixed(2),
.promoTaken
? (mapPassengerController
.totalPassengerComfortDiscount +
mapPassengerController
.totalPassengerComfort)
.toStringAsFixed(1)
: mapPassengerController
.totalPassengerComfortDiscount
.toStringAsFixed(1),
style:
AppStyle.title.copyWith(
color: AppColor.redColor,
@@ -235,7 +256,18 @@ class CarDetailsTypeToChoose extends StatelessWidget {
decoration: AppStyle
.boxDecoration1,
child: Text(
'-10%',
mapPassengerController
.promoTaken
? mapPassengerController
.totalPassengerSpeedDiscount
.toStringAsFixed(
1)
: (mapPassengerController
.totalPassengerSpeedDiscount -
mapPassengerController
.totalPassengerSpeed)
.toStringAsFixed(
1),
style: AppStyle
.subtitle
.copyWith(
@@ -247,8 +279,17 @@ class CarDetailsTypeToChoose extends StatelessWidget {
),
Text(
mapPassengerController
.totalPassengerSpeedDiscount
.toStringAsFixed(2),
.promoTaken
? (mapPassengerController
.totalPassengerSpeedDiscount +
mapPassengerController
.totalPassengerSpeed)
.toStringAsFixed(
1)
: mapPassengerController
.totalPassengerSpeedDiscount
.toStringAsFixed(
1),
style: AppStyle.title
.copyWith(
color:
@@ -263,14 +304,25 @@ class CarDetailsTypeToChoose extends StatelessWidget {
'Awfar Car' &&
(mapPassengerController
.totalPassengerBalash >
15)
20)
? Row(
children: [
Container(
decoration: AppStyle
.boxDecoration1,
child: Text(
'-10%',
mapPassengerController
.promoTaken
? mapPassengerController
.totalPassengerBalashDiscount
.toStringAsFixed(
1)
: (mapPassengerController
.totalPassengerBalashDiscount -
mapPassengerController
.totalPassengerBalash)
.toStringAsFixed(
1),
style: AppStyle
.subtitle
.copyWith(
@@ -282,9 +334,17 @@ class CarDetailsTypeToChoose extends StatelessWidget {
),
Text(
mapPassengerController
.totalPassengerBalashDiscount
.toStringAsFixed(
2),
.promoTaken
? (mapPassengerController
.totalPassengerBalashDiscount +
mapPassengerController
.totalPassengerBalash)
.toStringAsFixed(
1)
: mapPassengerController
.totalPassengerBalashDiscount
.toStringAsFixed(
1),
style: AppStyle.title
.copyWith(
color: AppColor
@@ -306,7 +366,15 @@ class CarDetailsTypeToChoose extends StatelessWidget {
decoration: AppStyle
.boxDecoration1,
child: Text(
'-10%',
mapPassengerController
.promoTaken
? mapPassengerController
.totalPassengerLadyDiscount
.toStringAsFixed(
1)
: (mapPassengerController.totalPassengerLadyDiscount -
mapPassengerController.totalPassengerLady)
.toStringAsFixed(0),
style: AppStyle
.subtitle
.copyWith(
@@ -318,9 +386,17 @@ class CarDetailsTypeToChoose extends StatelessWidget {
),
Text(
mapPassengerController
.totalPassengerLadyDiscount
.toStringAsFixed(
2),
.promoTaken
? (mapPassengerController
.totalPassengerLadyDiscount +
mapPassengerController
.totalPassengerLady)
.toStringAsFixed(
0)
: mapPassengerController
.totalPassengerLadyDiscount
.toStringAsFixed(
1),
style: AppStyle
.title
.copyWith(
@@ -624,11 +700,88 @@ class CarDetailsTypeToChoose extends StatelessWidget {
title: 'Next'.tr,
onPressed: () {
Get.back();
mapPassengerController
.isBottomSheetShown = false;
mapPassengerController.update();
mapPassengerController
.changeCashConfirmPageShown();
Get.defaultDialog(
barrierDismissible: false,
title:
"Select betweeen types".tr,
content: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(8.0),
child: Column(
children: [
Text('Awfar Car'
.tr),
Text(mapPassengerController
.totalPassengerRayehGaiBalash
.toStringAsFixed(
0)),
],
),
)),
Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(8.0),
child: Column(
children: [
Text('Speed'.tr),
Text(mapPassengerController
.totalPassengerRayehGai
.toStringAsFixed(
0)),
],
),
)),
Container(
decoration: AppStyle
.boxDecoration1,
child: Padding(
padding:
const EdgeInsets
.all(8.0),
child: Column(
children: [
Text(
'Comfort'.tr),
Text(mapPassengerController
.totalPassengerRayehGaiComfort
.toStringAsFixed(
0)),
],
),
))
],
),
cancel: MyElevatedButton(
kolor: AppColor.redColor,
title: 'Cancel'.tr,
onPressed: () =>
Get.back()),
confirm: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Next'.tr,
onPressed: () {
mapPassengerController
.isBottomSheetShown =
false;
mapPassengerController
.update();
mapPassengerController
.changeCashConfirmPageShown();
}));
}),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
@@ -656,6 +809,87 @@ class CarDetailsTypeToChoose extends StatelessWidget {
}
}
class PromoCode extends StatelessWidget {
const PromoCode({super.key});
@override
Widget build(BuildContext context) {
Get.put(BlinkingController());
return GetBuilder<MapPassengerController>(
builder: (mapPassengerController) {
return mapPassengerController.data.isNotEmpty &&
mapPassengerController.isBottomSheetShown &&
mapPassengerController.rideConfirm == false &&
mapPassengerController.promoTaken == false
? GetBuilder<BlinkingController>(builder: (blinkingController) {
blinkingController.startBlinking();
return Positioned(
right: 5,
bottom: Get.height * 0.5,
child: Obx(() {
return AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: 70, // Circle size
height: 70,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: blinkingController.isLightOn.value
? Colors.yellow
: Colors.grey, // Light on/off effect
border: Border.all(
color: blinkingController
.borderColor.value, // Animated border color
width: 3,
),
),
child: IconButton(
onPressed: () {
Get.defaultDialog(
title: 'Insert Your Promo Code'.tr,
content: Form(
key: mapPassengerController.promoFormKey,
child: MyTextForm(
controller: mapPassengerController.promo,
label: 'Insert Your Promo Code'.tr,
hint: 'Enter promo code here'.tr,
type: TextInputType.name,
),
),
confirm: MyElevatedButton(
title: 'Ok'.tr,
onPressed: () {
if (mapPassengerController
.promoFormKey.currentState!
.validate()) {
mapPassengerController
.applyPromoCodeToPassenger(context);
Get.back();
}
}));
},
icon: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.local_offer, size: 24), // Promo icon
SizedBox(height: 4),
Text(
"Promo",
style: TextStyle(
fontSize: 12, fontWeight: FontWeight.bold),
),
],
),
),
);
}),
);
})
: const SizedBox();
},
);
}
}
class BurcMoney extends StatelessWidget {
const BurcMoney({super.key});

View File

@@ -168,7 +168,8 @@ class CashConfirmPageShown extends StatelessWidget {
paymentController.update();
controller.changeCashConfirmPageShown();
controller.isSearchingWindow = true;
controller.confirmRideForFirstDriver();
controller
.confirmRideForAllDriverAvailable();
controller.update();
},
),
@@ -179,7 +180,7 @@ class CashConfirmPageShown extends StatelessWidget {
onPressed: () {
controller.changeCashConfirmPageShown();
controller.isSearchingWindow = true;
controller.confirmRideForFirstDriver();
controller.confirmRideForAllDriverAvailable();
controller.update();
},
), // Add a fallback widget if none of the conditions are met

View File

@@ -318,7 +318,7 @@ class GoogleMapPassengerWidget extends StatelessWidget {
// icon: controller.endIcon,
// ),
// },
polygons: controller.polygons,
polylines: {
Polyline(
zIndex: 2,

View File

@@ -9,6 +9,7 @@ import '../../../controller/firebase/firbase_messge.dart';
import '../../../controller/functions/audio_record1.dart';
import '../../../controller/functions/tts.dart';
import '../../../controller/home/map_passenger_controller.dart';
import '../../../print.dart';
GetBuilder<MapPassengerController> leftMainMenuIcons() {
final textToSpeechController = Get.put(TextToSpeechController());
@@ -121,50 +122,58 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
// borderRadius: BorderRadius.circular(15)),
// child: IconButton(
// onPressed: () async {
// // Get.to(SmsSignupEgypt());
// List<String> d = [
// "30.003028,31.2419628",
// "30.0955661,31.2665336",
// "160.00",
// "25.92",
// "1488",
// "16.93",
// "114243034311436865474",
// "113172279072358305645",
// "hamza ayed",
// "rlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3",
// "+201023248456",
// "1 min",
// "1 m",
// "false",
// "QwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9",
// "0",
// "238",
// "false",
// "114243034311436865474",
// "1488",
// "startEnd",
// "30.049307749732176,31.274291574954987",
// "",
// "",
// "",
// "",
// "17.73",
// "0",
// "hamzaayedflutter@gmail.com",
// "الفسطاط، حي مصر القديمة، مصر",
// " الزاوية الحمراء، محافظة القاهرة، مصر",
// "Speed",
// "8",
// "5.00"
// ];
// FirebaseMessagesController().sendNotificationToDriverMAP(
// 'Order'.tr,
// 'from: ',
// // jsonDecode(value)['message'].toString(),
// 'd3JaCCFAQeu8QTxRnlC1sB:APA91bFuRjbVK32obIFYXFTI4iwsZEPrrgwvPouob2bXivID-W4aXz51J_OIJ2nHpNU2ocOvGLD1Ip65rLViAFx5qHVE-c8FabBwBi5fSQ-lDTQfe36xxKsc9DU-sTyj_FoYrrMnLNVi',
// d,
// 'order.wav');
// Get.to(SmsSignupEgypt());
// List<String> d = [
// "30.003028,31.2419628",
// "30.0955661,31.2665336",
// "160.00",
// "25.92",
// "1488",
// "16.93",
// "114243034311436865474",
// "113172279072358305645",
// "hamza ayed",
// "rlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3",
// "+201023248456",
// "1 min",
// "1 m",
// "false",
// "QwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9",
// "0",
// "238",
// "false",
// "114243034311436865474",
// "1488",
// "startEnd",
// "30.049307749732176,31.274291574954987",
// "",
// "",
// "",
// "",
// "17.73",
// "0",
// "hamzaayedflutter@gmail.com",
// "الفسطاط، حي مصر القديمة، مصر",
// " الزاوية الحمراء، محافظة القاهرة، مصر",
// "Speed",
// "8",
// "5.00"
// ];
// FirebaseMessagesController()
// .sendNotificationToAnyWithoutData(
// 'Cancel'.tr,
// "How much longer will you be?".tr,
// 'fKBBB4_1R0q18-byySHUeG:APA91bHk2RmjjMt6eKr7KQnqh4CK02yW3H5E8g_beVcQFgiCG50j9KCtSU1O8PtvS_gA5xuJLhaorDV9AeslcyLFJFf302tICKMiKgsDP5pWkF5WXNw0-4NsoD-BnJxf0-Do9Vs1Zbpq',
// // d,
// 'ding.wav',
// );
// Get.to(SmsSignupEgypt());
// Log.print(
// 'getUpdatedRideForDriverApply: ${Get.find<MapPassengerController>().driverToken}');
// Get.find<MapPassengerController>()
// .firstTimeRunToGetCoupon('SEFER25', '1 WEEEK', '25%');
// },
// icon: const Icon(
// Icons.chat,

View File

@@ -1,3 +1,4 @@
import 'package:SEFER/views/home/HomePage/contact_us.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
@@ -110,10 +111,10 @@ class MapMenuWidget extends StatelessWidget {
),
IconMainPageMap(
onTap: () {
Get.to(() => const TaarifPage());
Get.to(() => ContactUsPage());
},
title: 'Tariff'.tr,
icon: Icons.money,
title: "Contact Us".tr,
icon: Icons.contact_page,
),
],
),

View File

@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../constant/api_key.dart';
import '../../../constant/links.dart';
class CupertinoDriverListWidget extends StatelessWidget {
MapPassengerController mapPassengerController =
@@ -30,9 +31,39 @@ class CupertinoDriverListWidget extends StatelessWidget {
leading: CircleAvatar(
radius: 25,
backgroundImage: NetworkImage(
'${AK.serverPHP}/portrate_captain_image/${driver['id']}.jpg',
'${AppLink.seferCairoServer}/portrate_captain_image/${driver['id']}.jpg',
),
child: Builder(
builder: (context) {
return Image.network(
'${AppLink.seferCairoServer}/portrate_captain_image/${driver['id']}.jpg',
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child; // Image is loaded
} else {
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ?? 1)
: null,
),
);
}
},
errorBuilder: (BuildContext context, Object error,
StackTrace? stackTrace) {
return const Icon(
Icons.person, // Icon to show when image fails to load
size: 25, // Adjust the size as needed
color: AppColor.blueColor, // Color for the error icon
);
},
);
},
),
backgroundColor: CupertinoColors.systemGrey5,
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -65,12 +96,12 @@ class CupertinoDriverListWidget extends StatelessWidget {
Text('${'Plate'.tr}: ${driver['car_plate']}'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('${'Education'.tr}: ${driver['education']}'),
],
),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text('${'Education'.tr}: ${driver['education']}'),
// ],
// ),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [

View File

@@ -1,3 +1,5 @@
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -10,6 +12,8 @@ import '../../../controller/functions/toast.dart';
import '../../../controller/home/payment/credit_card_controller.dart';
import '../../../controller/payment/payment_controller.dart';
import '../../../main.dart';
import '../../../models/model/painter_copoun.dart';
import '../../../print.dart';
import '../../widgets/elevated_btn.dart';
import '../../widgets/my_scafold.dart';
import '../../widgets/my_textField.dart';
@@ -29,25 +33,49 @@ class PassengerWallet extends StatelessWidget {
GetBuilder<PaymentController>(
builder: (controller) => Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const CardSeferWallet(),
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
children: [
MyElevatedButton(
kolor: AppColor.blueColor,
title: 'Payment History'.tr,
onPressed: () {
Get.to(() => const PaymentHistoryPassengerPage(),
transition: Transition.size);
},
),
],
padding:
const EdgeInsets.symmetric(horizontal: 80, vertical: 10),
child: MyElevatedButton(
kolor: AppColor.blueColor,
title: 'Payment History'.tr,
onPressed: () {
Get.to(() => const PaymentHistoryPassengerPage(),
transition: Transition.size);
},
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 80, vertical: 10),
child: MyElevatedButton(
kolor: AppColor.yellowColor,
title: 'Bounus gift'.tr,
onPressed: () {
Get.dialog(
AlertDialog(
contentPadding: EdgeInsets
.zero, // Removes the padding around the content
content: SizedBox(
width: 300, // Match the width of PromoBanner
// height: 250, // Match the height of PromoBanner
child: PromoBanner(
promoCode: box.read(BoxName.promo),
discountPercentage: box.read(BoxName.discount),
validity: box.read(BoxName.validity),
),
),
),
);
Log.print(
'box.read(BoxName.isGiftToken).toString(): ${box.read(BoxName.isGiftToken).toString()}');
},
),
)
],
@@ -65,6 +93,7 @@ class PassengerWallet extends StatelessWidget {
left: Get.width * .2,
right: Get.width * .2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
MyElevatedButton(
title: 'Show Promos to Charge'.tr,
@@ -79,36 +108,58 @@ class PassengerWallet extends StatelessWidget {
kolor: AppColor.deepPurpleAccent,
title: "Add wallet phone you use".tr,
onPressed: () {
Get.defaultDialog(
barrierDismissible: false,
title: 'Insert Wallet phone number'.tr,
content: Form(
key: controller.formKey,
child: MyTextForm(
Get.dialog(
CupertinoAlertDialog(
title: Text('Insert Wallet phone number'.tr),
content: Column(
children: [
const SizedBox(height: 10),
Form(
key: controller.formKey,
child: CupertinoTextField(
controller:
controller.walletphoneController,
label: 'Insert Wallet phone number'.tr,
hint: 'Insert Wallet phone number'.tr,
type: TextInputType.phone)),
confirm: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'OK'.tr,
onPressed: () async {
Get.back();
box.write(BoxName.phoneWallet,
controller.walletphoneController.text);
Toast.show(
context,
'Phone Wallet Saved Successfully'.tr,
AppColor.greenColor);
},
placeholder:
'Insert Wallet phone number'.tr,
keyboardType: TextInputType.phone,
padding: const EdgeInsets.symmetric(
vertical: 12, horizontal: 10),
),
),
],
),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
kolor: AppColor.redColor,
actions: <Widget>[
CupertinoDialogAction(
child: Text('Cancel'.tr,
style: const TextStyle(
color: CupertinoColors
.destructiveRed)),
onPressed: () {
Get.back();
}));
Get.back(); // Dismiss the dialog
},
),
CupertinoDialogAction(
child: Text('OK'.tr,
style: const TextStyle(
color:
CupertinoColors.activeGreen)),
onPressed: () async {
Get.back(); // Close the dialog
box.write(
BoxName.phoneWallet,
controller
.walletphoneController.text);
Toast.show(
context,
'Phone Wallet Saved Successfully'.tr,
AppColor.greenColor);
},
),
],
),
barrierDismissible:
false, // Set to prevent dismissing by tapping outside
);
})
],
),
@@ -120,70 +171,71 @@ class PassengerWallet extends StatelessWidget {
}
class CardSeferWallet extends StatelessWidget {
const CardSeferWallet({
super.key,
});
const CardSeferWallet({super.key});
@override
Widget build(BuildContext context) {
return GetBuilder<PaymentController>(builder: (paymentController) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: Get.width * .85,
height: Get.height * .3,
decoration: BoxDecoration(
color: AppColor.twitterColor.withOpacity(.8),
borderRadius: const BorderRadius.all(Radius.circular(12)),
gradient: const LinearGradient(colors: [
AppColor.redColor,
AppColor.yellowColor,
AppColor.yellowColor,
]),
),
return GetBuilder<PaymentController>(
builder: (paymentController) {
return Container(
width: Get.width * 0.9,
height: Get.height * 0.25,
margin: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: CupertinoColors.extraLightBackgroundGray,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
offset: const Offset(0, 10),
blurRadius: 20,
),
],
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text(
'${AppInformation.appName} Wallet',
style: AppStyle.headTitle
.copyWith(color: AppColor.writeColor),
)
],
// Wallet Title
Text(
'${AppInformation.appName} Wallet',
style: AppStyle.headTitle.copyWith(
color: CupertinoColors.label,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${box.read(BoxName.passengerWalletTotal)} \$' ??
'0.0 \$',
style: AppStyle.headTitle2,
)
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
box.read(BoxName.name),
style: AppStyle.title,
)
],
// Wallet Balance
Center(
child: Text(
'${box.read(BoxName.passengerWalletTotal) ?? '0.0'} ${'LE'.tr}',
style: AppStyle.headTitle2.copyWith(
color: CupertinoColors.label,
fontSize: 36,
fontWeight: FontWeight.w600,
),
),
)
),
// User Name (Bottom Right)
Align(
alignment: Alignment.bottomRight,
child: Text(
box.read(BoxName.name),
style: AppStyle.title.copyWith(
color: CupertinoColors.secondaryLabel,
fontSize: 16,
),
),
),
],
),
),
],
);
});
);
},
);
}
}

View File

@@ -1,6 +1,6 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/toast.dart';
@@ -8,7 +8,6 @@ import 'package:SEFER/controller/payment/payment_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import '../../../main.dart';
import '../../widgets/my_textField.dart';
class PassengerWalletDialog extends StatelessWidget {
const PassengerWalletDialog({
@@ -19,294 +18,198 @@ class PassengerWalletDialog extends StatelessWidget {
Widget build(BuildContext context) {
return GetBuilder<PaymentController>(
builder: (controller) => Positioned(
top: Get.height * .1,
right: Get.width * .15,
left: Get.width * .15,
bottom: Get.height * .1,
child: controller.isPromoSheetDialogue
? Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: AppColor.secondaryColor,
boxShadow: [
BoxShadow(
color: AppColor.accentColor,
offset: Offset(-1, -1),
blurRadius: 0,
spreadRadius: 0,
blurStyle: BlurStyle.normal),
BoxShadow(
color: AppColor.accentColor,
offset: Offset(3, 3),
blurRadius: 1,
spreadRadius: 0,
blurStyle: BlurStyle.normal)
]),
child: Padding(
padding: const EdgeInsets.all(6),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
controller.updateSelectedAmount(10);
},
child: Row(
children: [
Radio(
value: box.read(BoxName.countryCode) == 'Egypt'
? 100
: 10,
groupValue: controller.selectedAmount,
onChanged: (value) {
controller.updateSelectedAmount(value as int);
},
),
Text(
box.read(BoxName.countryCode) == 'Egypt'
? '100 ${'LE'.tr}'.tr
: '10 ${'JOD'.tr}'.tr,
style: AppStyle.title,
),
],
top: Get.height * .1,
right: Get.width * .15,
left: Get.width * .15,
bottom: Get.height * .1,
child: controller.isPromoSheetDialogue
? CupertinoActionSheet(
title: Text('Select Payment Amount'.tr),
actions: [
CupertinoActionSheetAction(
onPressed: () {
controller.updateSelectedAmount(
box.read(BoxName.countryCode) == 'Egypt' ? 100 : 10,
);
showPaymentOptions(context, controller);
},
child: Text(
box.read(BoxName.countryCode) == 'Egypt'
? '100 ${'LE'.tr}'
: '10 ${'JOD'.tr}',
),
),
CupertinoActionSheetAction(
onPressed: () {
controller.updateSelectedAmount(
box.read(BoxName.countryCode) == 'Egypt' ? 200 : 20,
);
showPaymentOptions(context, controller);
},
child: Text(
box.read(BoxName.countryCode) == 'Egypt'
? '200 ${'LE'.tr} = 205 ${'LE'.tr}'
: '20 ${'JOD'.tr}',
),
),
CupertinoActionSheetAction(
onPressed: () {
controller.updateSelectedAmount(
box.read(BoxName.countryCode) == 'Egypt' ? 400 : 40,
);
showPaymentOptions(context, controller);
},
child: Text(
box.read(BoxName.countryCode) == 'Egypt'
? '400 ${'LE'.tr} = 415 ${'LE'.tr}'
: '40 ${'JOD'.tr}',
),
),
CupertinoActionSheetAction(
onPressed: () {
controller.updateSelectedAmount(
box.read(BoxName.countryCode) == 'Egypt' ? 1000 : 50,
);
showPaymentOptions(context, controller);
},
child: Text(
box.read(BoxName.countryCode) == 'Egypt'
? '1000 ${'LE'.tr} = 1100 ${'LE'.tr}'
: '50 ${'JOD'.tr}',
),
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () {
controller.changePromoSheetDialogue();
},
child: Text('Cancel'.tr),
),
)
: const SizedBox(),
),
);
}
}
void showPaymentOptions(BuildContext context, PaymentController controller) {
showCupertinoModalPopup(
context: context,
builder: (context) => CupertinoActionSheet(
title: Text('Payment Options'.tr),
actions: [
box.read(BoxName.countryCode) == 'Egypt'
? CupertinoActionSheetAction(
child: Text('💳 Pay with Credit Card'.tr),
onPressed: () {
if (controller.selectedAmount != 0) {
controller.payWithPayMob(
context,
controller.selectedAmount.toString(),
box.read(BoxName.countryCode) == 'Egypt' ? 'EGP' : 'JOD',
() async {
await controller.addPassengerWallet();
controller.changePromoSheetDialogue();
await controller.getPassengerWallet();
},
);
} else {
Toast.show(context, '⚠️ You need to choose an amount!'.tr,
AppColor.redColor);
}
},
)
: const SizedBox(),
box.read(BoxName.countryCode) != 'Egypt'
? CupertinoActionSheetAction(
child: Text('Pay with PayPal'.tr),
onPressed: () {
if (controller.selectedAmount != 0) {
controller.makePaymentPayPal(context);
} else {
Toast.show(context, 'You will choose one of above!'.tr,
AppColor.redColor);
}
},
)
: const SizedBox(),
box.read(BoxName.phoneWallet) != null
? CupertinoActionSheetAction(
child: Text('💰 Pay with Wallet'.tr),
onPressed: () {
if (controller.selectedAmount != 0) {
controller.payWithPayMobWallet(
context,
controller.selectedAmount.toString(),
box.read(BoxName.countryCode) == 'Egypt' ? 'EGP' : 'JOD',
() async {
await controller.addPassengerWallet();
controller.changePromoSheetDialogue();
await controller.getPassengerWallet();
},
);
} else {
Toast.show(context, '⚠️ You need to choose an amount!'.tr,
AppColor.redColor);
}
},
)
: CupertinoActionSheetAction(
child: Text('Add wallet phone you use'.tr),
onPressed: () {
Get.dialog(
CupertinoAlertDialog(
title: Text('Insert Wallet phone number'.tr),
content: Column(
children: [
const SizedBox(height: 10),
CupertinoTextField(
controller: controller.walletphoneController,
placeholder: 'Insert Wallet phone number'.tr,
keyboardType: TextInputType.phone,
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 10,
),
),
),
GestureDetector(
onTap: () {
controller.updateSelectedAmount(20);
},
child: Row(
children: [
Radio(
value:
box.read(BoxName.countryCode) == 'Egypt'
? 210
: 20,
groupValue: controller.selectedAmount,
onChanged: (value) {
controller
.updateSelectedAmount(value as int);
},
),
Text(
box.read(BoxName.countryCode) == 'Egypt'
? '${'200 ${'LE'.tr} '.tr} = 205 ${'LE'.tr}'
: '20 ${'JOD'.tr}'.tr,
style: AppStyle.title,
),
],
)),
GestureDetector(
onTap: () {
controller.updateSelectedAmount(40);
},
child: Row(
children: [
Radio(
value:
box.read(BoxName.countryCode) == 'Egypt'
? 415
: 40,
groupValue: controller.selectedAmount,
onChanged: (value) {
controller
.updateSelectedAmount(value as int);
},
),
Text(
box.read(BoxName.countryCode) == 'Egypt'
? '${'400 ${'LE'.tr} '.tr} = 415 ${'LE'.tr}'
: '40 ${'JOD'.tr}'.tr,
style: AppStyle.title,
),
],
)),
GestureDetector(
onTap: () {
controller.updateSelectedAmount(100);
},
child: Row(
children: [
Radio(
value:
box.read(BoxName.countryCode) == 'Egypt'
? 1100
: 50,
groupValue: controller.selectedAmount,
onChanged: (value) {
controller
.updateSelectedAmount(value as int);
},
),
Text(
box.read(BoxName.countryCode) == 'Egypt'
? '${'1000 ${'LE'.tr} '.tr} = 1100 ${'LE'.tr}'
: '50 ${'JOD'.tr}'.tr,
style: AppStyle.title,
),
],
)),
const Spacer(),
box.read(BoxName.countryCode) == 'Egypt'
? const SizedBox()
: MyElevatedButton(
kolor: AppColor.blueColor,
title: '${'Pay with Your'.tr} PayPal',
onPressed: () {
if (controller.selectedAmount != 0) {
controller.makePaymentPayPal(context);
} else {
Toast.show(
context,
'You will choose one of above !'.tr,
AppColor.redColor);
}
},
),
box.read(BoxName.countryCode) == 'Egypt'
? box.read(BoxName.phoneWallet) != null
? Column(
children: [
MyElevatedButton(
title: '💳 Pay with Credit Card'.tr,
onPressed: () {
if (controller.selectedAmount != 0) {
controller.payWithPayMob(
context,
controller.selectedAmount
.toString(), // Convert int to double
box.read(BoxName.countryCode) ==
'Egypt'
? 'EGP'
: 'JOD',
() async {
await controller
.addPassengerWallet();
controller
.changePromoSheetDialogue();
await controller
.getPassengerWallet();
},
);
} else {
Toast.show(
context,
'⚠️ You need to choose an amount!'
.tr,
AppColor.redColor,
);
}
},
),
// Add some spacing between buttons
MyElevatedButton(
kolor: AppColor.yellowColor,
title: '💰 Pay with Wallet'.tr,
onPressed: () {
if (controller.selectedAmount != 0) {
controller.payWithPayMobWallet(
context,
controller.selectedAmount
.toString(), // Convert int to double
box.read(BoxName.countryCode) ==
'Egypt'
? 'EGP'
: 'JOD',
() async {
await controller
.addPassengerWallet();
controller
.changePromoSheetDialogue();
await controller
.getPassengerWallet();
},
);
} else {
Toast.show(
context,
'⚠️ You need to choose an amount!'
.tr,
AppColor.redColor,
);
}
},
),
],
)
: MyElevatedButton(
title: 'Pay with Credit Card'.tr,
onPressed: () {
if (controller.selectedAmount != 0) {
controller.makePaymentStripe(
controller.selectedAmount!
.toDouble(), // Convert int to double
box.read(BoxName.countryCode) !=
'Egypt'
? 'usd'
: 'jod', () {
controller.addPassengerWallet();
controller.changePromoSheetDialogue();
controller.getPassengerWallet();
});
} else {
Toast.show(
context,
'You will choose one of above !'.tr,
AppColor.redColor);
}
})
: MyElevatedButton(
kolor: AppColor.deepPurpleAccent,
title: "Add wallet phone you use".tr,
onPressed: () {
Get.defaultDialog(
barrierDismissible: false,
title: 'Insert Wallet phone number'.tr,
content: Form(
key: controller.formKey,
child: MyTextForm(
controller: controller
.walletphoneController,
label:
'Insert Wallet phone number'
.tr,
hint: 'Insert Wallet phone number'
.tr,
type: TextInputType.phone)),
confirm: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'OK'.tr,
onPressed: () async {
Get.back();
box.write(
BoxName.phoneWallet,
controller
.walletphoneController.text);
Toast.show(
context,
'Phone Wallet Saved Successfully'
.tr,
AppColor.greenColor);
},
),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
kolor: AppColor.redColor,
onPressed: () {
Get.back();
}));
}),
MyElevatedButton(
title: 'Cancel'.tr,
kolor: AppColor.redColor,
],
),
actions: [
CupertinoDialogAction(
child: Text('Cancel'.tr,
style: const TextStyle(
color: CupertinoColors.destructiveRed)),
onPressed: () {
controller.changePromoSheetDialogue();
Get.back();
},
),
CupertinoDialogAction(
child: Text('OK'.tr,
style: const TextStyle(
color: CupertinoColors.activeGreen)),
onPressed: () async {
Get.back();
box.write(BoxName.phoneWallet,
controller.walletphoneController.text);
Toast.show(
context,
'Phone Wallet Saved Successfully'.tr,
AppColor.greenColor);
},
),
],
),
))
: const SizedBox()),
);
}
barrierDismissible: false,
);
},
),
],
cancelButton: CupertinoActionSheetAction(
child: Text('Cancel'.tr),
onPressed: () {
controller.changePromoSheetDialogue();
},
),
),
);
}

View File

@@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/colors.dart';
@@ -17,7 +18,7 @@ class PaymentHistoryPassengerPage extends StatelessWidget {
body: [
GetBuilder<PassengerWalletHistoryController>(
builder: (controller) => controller.isLoading
? const MyCircularProgressIndicator()
? const MyCircularProgressIndicator() // iOS-style loading indicator
: controller.archive.isEmpty
? Center(
child: Text(
@@ -25,37 +26,33 @@ class PaymentHistoryPassengerPage extends StatelessWidget {
style: AppStyle.title,
),
)
: ListView.builder(
itemCount: controller.archive.length,
itemBuilder: (BuildContext context, int index) {
var list = controller.archive[index];
return Padding(
padding: const EdgeInsets.all(4),
child: Container(
decoration: BoxDecoration(
color: double.parse(list['balance']) < 0
? AppColor.redColor.withOpacity(.4)
: AppColor.greenColor.withOpacity(.4)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
list['balance'],
style: AppStyle.title,
),
Text(
list['created_at'],
style: AppStyle.title,
),
],
: CupertinoListSection.insetGrouped(
children: List.generate(
controller.archive.length,
(index) {
var list = controller.archive[index];
return CupertinoListTile(
backgroundColor: double.parse(list['balance']) < 0
? AppColor.redColor.withOpacity(.2)
: AppColor.greenColor.withOpacity(.2),
title: Text(
list['balance'],
style: AppStyle.title.copyWith(
color: CupertinoColors.black,
),
),
),
);
},
additionalInfo: Text(
list['created_at'],
style: AppStyle.title.copyWith(
fontSize: 12,
color: CupertinoColors.systemGrey,
),
),
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
);
},
),
),
)
],

View File

@@ -1,5 +1,7 @@
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:SEFER/controller/home/profile/promos_controller.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
@@ -106,13 +108,26 @@ class PromosPassengerPage extends StatelessWidget {
} else {
// Promo items
final rides = orderHistoryController.promoList[index - 1];
return Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(12.0),
child: Container(
decoration: AppStyle.boxDecoration,
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color:
CupertinoColors.systemGrey.withOpacity(0.5),
blurRadius: 8,
offset: Offset(0, 4),
),
],
),
child: Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
@@ -122,50 +137,88 @@ class PromosPassengerPage extends StatelessWidget {
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,
GestureDetector(
onTap: () {},
child: AnimatedTextKit(
animatedTexts: [
ScaleAnimatedText(
rides['promo_code'],
textStyle:
AppStyle.title.copyWith(
fontSize:
32, // Increased font size for emphasis
color: CupertinoColors
.activeBlue,
fontWeight: FontWeight.bold,
),
),
WavyAnimatedText(
rides['promo_code'],
textStyle:
AppStyle.title.copyWith(
fontSize:
32, // Increased font size for emphasis
color: CupertinoColors
.activeBlue,
fontWeight: FontWeight.bold,
),
),
],
isRepeatingAnimation: true,
),
),
const SizedBox(height: 8),
// Description Text
Text(
rides['description'],
style: AppStyle.title,
style: AppStyle.title.copyWith(
fontSize: 22,
color: CupertinoColors.systemGrey,
),
),
],
),
Column(
children: [
// Only displaying end date
Text(
rides['validity_start_date'],
style: AppStyle.title,
),
Text(
rides['validity_end_date'],
style: AppStyle.title,
'${'Valid Until:'.tr} ${rides['validity_end_date']}',
style: AppStyle.subtitle.copyWith(
fontWeight: FontWeight.bold,
fontSize: 20,
color: CupertinoColors.systemGrey,
),
),
],
),
],
),
Text(
'Copy this Promo to use it in your Ride!'.tr,
textAlign: TextAlign.center,
style: AppStyle.headTitle2
.copyWith(color: AppColor.accentColor),
)
// const SizedBox(height: 16),
// Copy Promo Text
Center(
child: GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: rides['promo_code']));
Get.snackbar(
'Promo Copied!'.tr,
'You have copied the promo code.'.tr,
snackPosition: SnackPosition.BOTTOM,
backgroundColor:
CupertinoColors.systemGrey,
colorText: CupertinoColors.white,
);
},
child: Text(
'Copy Code'.tr,
textAlign: TextAlign.center,
style: AppStyle.headTitle2.copyWith(
color: CupertinoColors.systemBlue,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),

View File

@@ -1,10 +1,10 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import '../../controller/notification/passenger_notification_controller.dart';
import '../widgets/elevated_btn.dart';
import '../widgets/my_scafold.dart';
import '../widgets/mycircular.dart';
@@ -19,64 +19,82 @@ class NotificationPage extends StatelessWidget {
title: 'Notifications',
body: [
GetBuilder<PassengerNotificationController>(
builder: (notificationCaptainController) =>
notificationCaptainController.isloading
? const MyCircularProgressIndicator()
: SafeArea(
child: ListView.builder(
itemCount: notificationCaptainController
.notificationData['message'].length,
itemBuilder: (BuildContext context, int index) {
if (notificationCaptainController
.notificationData['message'] ==
"No notification data found") {
Get.defaultDialog();
}
var res = notificationCaptainController
.notificationData['message'][index];
return Card(
elevation: 4,
color: res['isShown'] == 'true'
? AppColor.secondaryColor.withOpacity(.5)
: AppColor.secondaryColor.withOpacity(.9),
child: ListTile(
onTap: () {
Get.defaultDialog(
title: res['title'],
titleStyle: AppStyle.title,
content: SizedBox(
width: Get.width * .8,
// height: Get.height * .4,
child: Text(
res['body'],
style: AppStyle.title,
),
),
confirm: MyElevatedButton(
title: 'Ok',
onPressed: () {
notificationCaptainController
.updateNotification(
res['id'].toString());
}));
},
leading: res['isShown'] == 'true'
? const Icon(
Icons.notifications_off_outlined)
: const Icon(Icons.notifications_active),
title: Text(
res['title'],
style: AppStyle.title,
),
subtitle: Text(
res['body'],
style: AppStyle.subtitle,
),
),
builder: (notificationCaptainController) => notificationCaptainController
.isloading
? const MyCircularProgressIndicator() // iOS-style loading indicator
: SafeArea(
child: ListView.builder(
itemCount: notificationCaptainController
.notificationData['message'].length,
itemBuilder: (BuildContext context, int index) {
if (notificationCaptainController
.notificationData['message'] ==
"No notification data found") {
Get.defaultDialog(
title: 'No Notifications'.tr,
content: Text(
'No notification data found.'.tr,
),
);
}
var res = notificationCaptainController
.notificationData['message'][index];
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
child: CupertinoListTile(
backgroundColor: res['isShown'] == 'true'
? AppColor.secondaryColor.withOpacity(.2)
: AppColor.secondaryColor.withOpacity(.8),
leading: res['isShown'] == 'true'
? const Icon(CupertinoIcons.bell_slash_fill)
: const Icon(CupertinoIcons.bell_fill),
title: Text(
res['title'],
style: AppStyle.title.copyWith(
color: CupertinoColors.black,
),
),
subtitle: Text(
res['body'],
style: AppStyle.subtitle.copyWith(
color: CupertinoColors.systemGrey,
),
),
onTap: () {
showCupertinoDialog(
context: context,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text(
res['title'],
style: AppStyle.title,
),
content: Text(
res['body'],
style: AppStyle.subtitle,
),
actions: [
CupertinoDialogAction(
child: const Text('Ok'),
onPressed: () {
notificationCaptainController
.updateNotification(
res['id'].toString());
Get.back();
},
),
],
);
},
);
},
),
))
);
},
),
),
)
],
);
}

View File

@@ -1,5 +1,6 @@
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -11,34 +12,98 @@ import 'elevated_btn.dart';
class MyDialog extends GetxController {
void getDialog(String title, String? midTitle, VoidCallback onPressed) {
final textToSpeechController = Get.put(TextToSpeechController());
Get.defaultDialog(
title: title,
titleStyle: AppStyle.title,
barrierDismissible: false,
middleTextStyle: AppStyle.title,
content: Column(
children: [
IconButton(
Get.dialog(
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: CupertinoAlertDialog(
title: Text(
title,
style: AppStyle.title.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
content: Column(
children: [
CupertinoButton(
onPressed: () async {
await textToSpeechController.speakText(title ?? midTitle!);
},
icon: const Icon(Icons.headphones)),
Text(
midTitle!,
style: AppStyle.title,
)
child: const Icon(CupertinoIcons.headphones,
color: AppColor.primaryColor),
),
Text(
midTitle!,
style: AppStyle.title.copyWith(fontSize: 16),
),
],
),
actions: [
CupertinoDialogAction(
child: const Text('Cancel',
style: TextStyle(color: AppColor.redColor)),
onPressed: () {
Get.back();
},
),
CupertinoDialogAction(
onPressed: onPressed,
child: Text('OK'.tr,
style: const TextStyle(color: AppColor.greenColor)),
),
],
),
confirm: MyElevatedButton(
title: 'Ok'.tr,
onPressed: onPressed,
kolor: AppColor.greenColor,
),
cancel: MyElevatedButton(
title: 'Cancel',
kolor: AppColor.redColor,
onPressed: () {
Get.back();
}));
),
barrierDismissible: false,
);
}
}
class MyDialogContent extends GetxController {
void getDialog(String title, Widget? content, VoidCallback onPressed) {
final textToSpeechController = Get.put(TextToSpeechController());
Get.dialog(
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: CupertinoAlertDialog(
title: Text(
title,
style: AppStyle.title.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
content: Column(
children: [
CupertinoButton(
onPressed: () async {
await textToSpeechController.speakText(title);
},
child: const Icon(CupertinoIcons.headphones,
color: AppColor.primaryColor),
),
content!
],
),
actions: [
CupertinoDialogAction(
child: const Text('Cancel',
style: TextStyle(color: AppColor.redColor)),
onPressed: () {
Get.back();
},
),
CupertinoDialogAction(
onPressed: onPressed,
child: Text('OK'.tr,
style: const TextStyle(color: AppColor.greenColor)),
),
],
),
),
barrierDismissible: false,
);
}
}