Initial commit
This commit is contained in:
@@ -148,8 +148,8 @@ android {
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdk = 23
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = 71
|
||||
versionName = '1.5.71'
|
||||
versionCode = 82
|
||||
versionName = '1.5.82'
|
||||
multiDexEnabled =true
|
||||
|
||||
// manifestPlaceholders can be specified here if needed
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<resources>
|
||||
<string name="app_name">My App</string>
|
||||
<!-- <string name="default_notification_channel_id">ride_channel</string> -->
|
||||
<string name="default_notification_channel_id">default_channel</string>
|
||||
<!-- <string name="default_notification_channel_id">default_channel</string> -->
|
||||
<string name="default_notification_channel_id">high_importance_channel</string>
|
||||
<string name="api_key">AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0</string>
|
||||
</resources>
|
||||
@@ -37,11 +37,13 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>52</string>
|
||||
<string>59</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>4.3.52</string>
|
||||
<string>4.3.59</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>FirebaseAppDelegateProxyEnabled</key>
|
||||
<string>NO</string>
|
||||
<key>GMSApiKey</key>
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
83
lib/constant/univeries_polygon.dart
Normal file
83
lib/constant/univeries_polygon.dart
Normal 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...
|
||||
];
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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: () {
|
||||
|
||||
@@ -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'
|
||||
|
||||
91
lib/controller/home/blinking_promo_controller.dart.dart
Normal file
91
lib/controller/home/blinking_promo_controller.dart.dart
Normal 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();
|
||||
}
|
||||
}
|
||||
78
lib/controller/home/contact_us_controller.dart
Normal file
78
lib/controller/home/contact_us_controller.dart
Normal 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
@@ -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.":
|
||||
"سيارة ميسورة التكلفة، مثالية للرحلات الاقتصادية.",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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());
|
||||
});
|
||||
|
||||
275
lib/models/model/painter_copoun.dart
Normal file
275
lib/models/model/painter_copoun.dart
Normal 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],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
@@ -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,
|
||||
|
||||
102
lib/views/home/HomePage/contact_us.dart
Normal file
102
lib/views/home/HomePage/contact_us.dart
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ class MapPagePassenger extends StatelessWidget {
|
||||
CarDetailsTypeToChoose(),
|
||||
const HeaderDestination(),
|
||||
const BurcMoney(),
|
||||
const PromoCode(),
|
||||
const ApplyOrderWidget(), const MapMenuWidget(),
|
||||
// hexagonClipper(),
|
||||
const CancelRidePageShow(),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -318,7 +318,7 @@ class GoogleMapPassengerWidget extends StatelessWidget {
|
||||
// icon: controller.endIcon,
|
||||
// ),
|
||||
// },
|
||||
|
||||
polygons: controller.polygons,
|
||||
polylines: {
|
||||
Polyline(
|
||||
zIndex: 2,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
))
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Cocoa
|
||||
import FlutterMacOS
|
||||
|
||||
@NSApplicationMain
|
||||
@main
|
||||
class AppDelegate: FlutterAppDelegate {
|
||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
return true
|
||||
|
||||
@@ -491,6 +491,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
flutter_confetti:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_confetti
|
||||
sha256: "7a0f586a0295b1dad6be364a82c59b8579e1cc8af99b0cba0461b6fabd60ff78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
flutter_font_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -61,6 +61,7 @@ dependencies:
|
||||
package_info_plus: ^8.0.0
|
||||
uni_links: ^0.5.1
|
||||
googleapis_auth: ^1.6.0
|
||||
flutter_confetti: ^0.3.0
|
||||
# intl_phone_field: ^3.1.0
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user