25-7-26-1

This commit is contained in:
Hamza-Ayed
2025-07-26 10:30:10 +03:00
parent 83fa8c776c
commit 3742d5b417
645 changed files with 134317 additions and 0 deletions

View File

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

View File

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

View File

@@ -0,0 +1,15 @@
import 'package:get/get.dart';
import '../../constant/box_name.dart';
import '../../main.dart';
class HomePageController extends GetxController {
late bool isVibrate = box.read(BoxName.isvibrate) ?? true;
void changeVibrateOption(bool value) {
isVibrate = box.read(BoxName.isvibrate) ?? true;
isVibrate = value;
box.write(BoxName.isvibrate, value);
update();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
import 'package:get/get.dart';
class MyMenuController extends GetxController {
bool isDrawerOpen = true;
void getDrawerMenu() {
if (isDrawerOpen == true) {
isDrawerOpen = false;
} else {
isDrawerOpen = true;
}
update();
}
}

View File

@@ -0,0 +1,129 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:Intaleq/constant/box_name.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:Intaleq/main.dart';
class CaptainWalletController extends GetxController {
bool isLoading = false;
Map walletDate = {};
Map walletDateVisa = {};
Map walletDriverPointsDate = {};
final formKey = GlobalKey<FormState>();
String totalAmount = '0';
String totalAmountVisa = '0';
String totalPoints = '0';
final amountFromBudgetController = TextEditingController();
payFromBudget() async {
if (formKey.currentState!.validate()) {
var pointFromBudget = box.read(BoxName.countryCode) == 'Jordan'
? int.parse((amountFromBudgetController.text)) * 100
: int.parse((amountFromBudgetController.text));
await addDriverPayment('fromBudgetToPoints',
int.parse((amountFromBudgetController.text)) * -1);
Future.delayed(const Duration(seconds: 2));
await addDriverWallet('fromBudget', pointFromBudget.toString());
update();
Get.back();
// getCaptainWalletFromRide();
// getCaptainWalletFromBuyPoints();
// checkAccountCaptainBank();
}
}
// Future getCaptainWalletFromRide() async {
// isLoading = true;
// update();
// var res = await CRUD().get(
// link: AppLink.getAllPaymentFromRide,
// payload: {'driverID': box.read(BoxName.driverID)},
// );
// walletDate = jsonDecode(res);
// totalAmount = walletDate['message'][0]['total_amount'].toString() == null
// ? '0'
// : walletDate['message'][0]['total_amount'];
// var res1 = await CRUD().get(
// link: AppLink.getAllPaymentVisa,
// payload: {'driverID': box.read(BoxName.driverID)});
// walletDateVisa = jsonDecode(res1);
// totalAmountVisa = walletDateVisa['message'][0]['diff'].toString() == null
// ? '0'
// : walletDateVisa['message'][0]['diff'];
// isLoading = false;
// update();
// }
// Future getCaptainWalletFromBuyPoints() async {
// isLoading = true;
// update();
// var res = await CRUD().get(
// link: AppLink.getDriverPaymentPoints,
// payload: {'driverID': box.read(BoxName.driverID)},
// );
// walletDriverPointsDate = jsonDecode(res);
// if (walletDriverPointsDate['message'][0]['driverID'].toString() ==
// box.read(BoxName.driverID)) {
// double totalPointsDouble = double.parse(
// walletDriverPointsDate['message'][0]['total_amount'].toString());
// totalPoints = totalPointsDouble.toStringAsFixed(0);
// } else {
// totalPoints = '0';
// }
// isLoading = false;
// update();
// }
late String paymentID;
Future addDriverPayment(String paymentMethod, amount) async {
var res =
await CRUD().postWallet(link: AppLink.addDriverPaymentPoints, payload: {
'driverID': box.read(BoxName.driverID).toString(),
'amount': amount.toString(),
'payment_method': paymentMethod.toString(),
});
var d = jsonDecode(res);
paymentID = d['message'].toString();
}
Future addDriverWallet(String paymentMethod, point) async {
await CRUD().postWallet(link: AppLink.addDriversWalletPoints, payload: {
'driverID': box.read(BoxName.driverID).toString(),
'paymentID': paymentID.toString(),
'amount': point,
'paymentMethod': paymentMethod.toString(),
});
}
//check if account bank is created or not
Future checkAccountCaptainBank() async {
isLoading = false;
update();
if (box.read(BoxName.accountIdStripeConnect).toString().isEmpty) {
var res = await CRUD().getWallet(link: AppLink.getAccount, payload: {
'id': box.read(BoxName.driverID).toString(),
});
var d = jsonDecode(res);
if (d['status'] != 'failure') {
box.write(BoxName.accountIdStripeConnect,
d['message'][0]['accountBank'].toString());
}
}
isLoading = true;
update();
}
@override
void onInit() {
// getCaptainWalletFromRide();
// getCaptainWalletFromBuyPoints();
// checkAccountCaptainBank();
super.onInit();
}
}

View File

@@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../constant/box_name.dart';
import '../../functions/digit_obsecur_formate.dart';
import '../../functions/secure_storage.dart';
class CreditCardController extends GetxController {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final TextEditingController cardNumberController = TextEditingController();
final TextEditingController cardHolderNameController =
TextEditingController();
final TextEditingController expiryDateController = TextEditingController();
final TextEditingController cvvCodeController = TextEditingController();
openPayment() async {
String? cardNumber = await SecureStorage().readData(BoxName.cardNumber);
String? cardHolderName =
await SecureStorage().readData(BoxName.cardHolderName);
String? expiryDate = await SecureStorage().readData(BoxName.expiryDate);
String? cvvCode = await SecureStorage().readData(BoxName.cvvCode);
// if (cvvCode != null && cvvCode.isNotEmpty) {
// final maskedCardNumber = DigitObscuringFormatter()
// .formatEditUpdate(
// TextEditingValue.empty,
// TextEditingValue(text: cardNumber ?? ''),
// )
// .text;
// cardNumberController.text = maskedCardNumber;
// cardHolderNameController.text = cardHolderName ?? '';
// expiryDateController.text = expiryDate ?? '';
// cvvCodeController.text = cvvCode;
// }
}
@override
void onInit() async {
super.onInit();
openPayment();
// String? cardNumber = await SecureStorage().readData(BoxName.cardNumber);
// String? cardHolderName =
// await SecureStorage().readData(BoxName.cardHolderName);
// String? expiryDate = await SecureStorage().readData(BoxName.expiryDate);
// String? cvvCode = await SecureStorage().readData(BoxName.cvvCode);
// if (cvvCode != null && cvvCode.isNotEmpty) {
// final maskedCardNumber = DigitObscuringFormatter()
// .formatEditUpdate(
// TextEditingValue.empty,
// TextEditingValue(text: cardNumber ?? ''),
// )
// .text;
// cardNumberController.text = maskedCardNumber;
// cardHolderNameController.text = cardHolderName ?? '';
// expiryDateController.text = expiryDate ?? '';
// cvvCodeController.text = cvvCode;
// }
}
}
class CreditCardModel {
String cardNumber;
String cardHolderName;
String expiryDate;
String cvvCode;
CreditCardModel({
required this.cardNumber,
required this.cardHolderName,
required this.expiryDate,
required this.cvvCode,
});
}

View File

@@ -0,0 +1,148 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/home/map_passenger_controller.dart';
import '../../constant/api_key.dart';
import '../../constant/links.dart';
import '../functions/crud.dart';
import '../functions/location_controller.dart';
class PointsForRiderController extends GetxController {
List<String> locations = [];
String hintTextDestinationPoint = 'Search for your destination'.tr;
TextEditingController placeStartController = TextEditingController();
void addLocation(String location) {
locations.add(location);
update();
}
void getTextFromList(String location) {
locations.add(location);
update();
Get.back();
}
void removeLocation(int index) {
locations.removeAt(index);
update();
}
void onReorder(int oldIndex, int newIndex) {
if (newIndex > oldIndex) {
newIndex -= 1;
update();
}
final item = locations.removeAt(oldIndex);
locations.insert(newIndex, item);
update();
}
}
class LocationModel {
String name;
double lat, lon;
LocationModel({required this.name, required this.lat, required this.lon});
}
class WayPointController extends GetxController {
// A list of text editing controllers for each text field
// final textFields = [TextEditingController()].obs;
List<String> wayPoints = [];
List<List<dynamic>> placeListResponse = [];
double wayPointHeight = 400;
String hintTextDestinationPoint = 'Search for your destination'.tr;
TextEditingController textSearchCotroller = TextEditingController();
// A list of places corresponding to each text field
final places = <String>[];
final hintTextPointList = <String>[];
late LatLng myLocation;
void addWayPoints() {
String wayPoint = 'Add a Stop'.tr;
if (wayPoints.length < 5) {
wayPoints.add(wayPoint);
update();
} else {
Get.defaultDialog(
title: 'This is most WayPoints',
titleStyle: AppStyle.title,
middleText: '');
}
update();
}
void removeTextField(int index) {
wayPoints.removeAt(index);
update();
}
// A method to reorder the text fields and the places
void reorderTextFields(int oldIndex, int newIndex) {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final wayPoint = wayPoints.removeAt(oldIndex);
wayPoints.insert(newIndex, wayPoint);
update();
}
void updatePlace(int index, String input) async {
var url =
'${AppLink.googleMapsLink}place/nearbysearch/json?keyword=$input&location=${myLocation.latitude},${myLocation.longitude}&radius=50000&language=en&key=${AK.mapAPIKEY.toString()}';
var response = await CRUD().getGoogleApi(link: url, payload: {});
// final place = input;
// if (index == 0) {
List<dynamic> newList = [];
placeListResponse.add(newList);
newList = response['results'];
placeListResponse[index].add(newList);
update();
// }
update();
}
@override
void onInit() {
Get.put(LocationController());
addWayPoints();
myLocation = Get.find<MapPassengerController>().passengerLocation;
super.onInit();
}
}
class PlaceList extends StatelessWidget {
// Get the controller instance
final controller = Get.put(WayPointController());
@override
Widget build(BuildContext context) {
// Use the Obx widget to rebuild the widget when the controller changes
return Obx(() {
// Use the ListView widget to display the list of places
return ListView(
// The children of the list are the places
children: [
// Loop through the places in the controller
for (final place in controller.places)
// Create a text widget for each place
Text(
// Use the place as the text
place,
// Add some style and padding
style: const TextStyle(fontSize: 18.0),
),
],
);
});
}
}

View File

@@ -0,0 +1,238 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:Intaleq/constant/box_name.dart';
import 'package:Intaleq/constant/colors.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:Intaleq/main.dart';
import 'package:Intaleq/views/widgets/elevated_btn.dart';
import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';
import '../../../constant/api_key.dart';
import '../../../print.dart';
import '../../../views/widgets/mydialoug.dart';
class ComplaintController extends GetxController {
bool isLoading = false;
final formKey = GlobalKey<FormState>();
final complaintController = TextEditingController();
final suggestionController = TextEditingController();
List feedBack = [];
@override
void onInit() {
super.onInit();
getLatestRidesForPassengers();
}
getLatestRidesForPassengers() async {
isLoading = true;
update();
var res = await CRUD().get(link: AppLink.getFeedBack, payload: {
'passengerId': box.read(BoxName.passengerID).toString(),
});
if (res != 'failure') {
var d = jsonDecode(res)['message'];
feedBack = d;
}
isLoading = false;
update();
}
void addComplaint() async {
isLoading = true;
update();
var res = await CRUD().post(link: AppLink.addFeedBack, payload: {
'passengerId': box.read(BoxName.passengerID).toString(),
'feedBack': complaintController.text
});
// var d = jsonDecode(res);
if (res != 'failure') {
Get.defaultDialog(
title: 'Success'.tr,
titleStyle: AppStyle.title,
middleText: 'Complaint data saved successfully'.tr,
middleTextStyle: AppStyle.title,
confirm: MyElevatedButton(
kolor: AppColor.greenColor,
title: 'Ok'.tr,
onPressed: () {
Get.back();
// Get.back();
}));
}
isLoading = false;
update();
}
var isUploading = false.obs;
var uploadSuccess = false.obs;
late String audioLink = '';
Future<void> uploadAudioFile(File audioFile) async {
try {
isUploading.value = true;
// Prepare the file upload
var uri = Uri.parse('${AppLink.IntaleqCairoServer}/upload_audio.php');
var request = http.MultipartRequest('POST', uri);
// Add the file to the request with MIME type
var mimeType = lookupMimeType(audioFile.path);
request.headers.addAll({
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
});
request.files.add(
await http.MultipartFile.fromPath(
'audio',
audioFile.path,
contentType: mimeType != null ? MediaType.parse(mimeType) : null,
),
);
// Send the request
var response = await request.send();
// Convert response to string for parsing
var responseBody = await http.Response.fromStream(response);
// After the upload request
if (response.statusCode == 200) {
var jsonResponse = jsonDecode(responseBody.body);
if (jsonResponse['status'] == 'Audio file uploaded successfully.') {
uploadSuccess.value = true;
audioLink = jsonResponse['link']; // Get the audio link
Get.back();
Get.snackbar('Success'.tr, 'Audio uploaded successfully.'.tr,
backgroundColor: const Color.fromARGB(255, 89, 185, 115));
} else {
uploadSuccess.value = false;
}
} else {
uploadSuccess.value = false;
}
} catch (e) {
uploadSuccess.value = false;
} finally {
isUploading.value = false;
}
}
var customerServiceSolutions;
var passengerReport;
var driverReport;
var isloading = false;
Future<void> geminiAudio(payload, String audioLink, String complain) async {
String prompt = '''
Analyze the following complaint between a passenger and driver in a ride-hailing service. The complaint includes an audio link for reference. Provide two possible solutions for customer service to resolve the issue, and generate a detailed report for both the passenger and the driver.
Complaint details:
- Passenger: $complain
- Driver: [Driver's complaint]
- Ride Information: {ride details such as start_location, end_location, date, price, status, and rating details}
- Audio Link: [$audioLink]
Output the result in JSON format with the following structure:
{
"customerServiceSolutions": [
"solution1",
"solution2"
],
"passengerReport": {
"solution": "Passenger's solution" if passenger right,
"complaint": "Passenger's complaint",
"rideDetails": {detailed ride info}
},
"driverReport": {
"complaint": "Driver's complaint",
"rideDetails": {detailed ride info}
}
} the response in arabic language with egypt
''';
var requestBody = jsonEncode({
"contents": [
{
"parts": [
{"text": "$payload $prompt"}
]
}
],
"generationConfig": {
"temperature": 1,
"topK": 64,
"topP": 0.95,
"maxOutputTokens": 8192,
"stopSequences": []
},
"safetySettings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
}
]
});
final response = await http.post(
Uri.parse(
'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro:generateContent?key=${AK.geminiApi}'),
headers: {'Content-Type': 'application/json'},
body: requestBody,
);
if (response.statusCode == 200) {
var responseData = jsonDecode(response.body);
var result = responseData['candidates'][0]['content']['parts'][0]['text'];
Log.print('result: ${result}');
// Clean up the result by removing surrounding backticks if they exist
result = result.replaceAll(RegExp(r'^```json\s*|\s*```$'), '');
// Attempt to decode the cleaned result as JSON
try {
var jsonResult = jsonDecode(result);
// Access customer service solutions and reports for both passenger and driver
customerServiceSolutions = jsonResult['customerServiceSolutions'];
passengerReport = jsonResult['passengerReport'];
driverReport = jsonResult['driverReport'];
update();
// Use the data accordingly
// For example, log the reports or display them in a UI dialog
update();
} catch (e) {
MyDialog().getDialog(
'Error'.tr,
'Unable to parse the response as JSON. Please check the format and try again.'
.tr, () {
Get.back();
});
}
} else {
Get.snackbar(
'Error', "Request failed with status: ${response.statusCode}",
backgroundColor: AppColor.redColor);
}
}
}

View File

@@ -0,0 +1,314 @@
import 'dart:convert';
import 'package:Intaleq/constant/box_name.dart';
import 'package:Intaleq/constant/colors.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:Intaleq/controller/functions/encrypt_decrypt.dart';
import 'package:Intaleq/controller/payment/payment_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:get/get.dart';
import 'package:share/share.dart';
import '../../../main.dart';
import '../../../print.dart';
import '../../../views/widgets/error_snakbar.dart';
import '../../../views/widgets/mydialoug.dart';
import '../../functions/launch.dart';
import '../../notification/notification_captain_controller.dart';
class InviteController extends GetxController {
final TextEditingController invitePhoneController = TextEditingController();
List driverInvitationData = [];
List driverInvitationDataToPassengers = [];
String? couponCode;
String? driverCouponCode;
int selectedTab = 0;
PassengerStats passengerStats = PassengerStats();
void updateSelectedTab(int index) {
selectedTab = index;
update();
}
Future<void> shareCouponCode() async {
// TODO: Implement sharing functionality
// You can use share_plus package to share the coupon code
}
Future<void> shareDriverCode() async {
if (driverCouponCode != null) {
final String shareText = '''
Join Intaleq as a driver using my referral code!
Use code: $driverCouponCode
Download the Intaleq Driver app now and earn rewards!
''';
await Share.share(shareText);
}
}
Future<void> sharePassengerCode() async {
if (couponCode != null) {
final String shareText = '''
Get a discount on your first Intaleq ride!
Use my referral code: $couponCode
Download the Intaleq app now and enjoy your ride!
''';
await Share.share(shareText);
}
}
@override
void onInit() {
super.onInit();
// fetchDriverStats();
}
void fetchDriverStats() async {
try {
var response = await CRUD().get(link: AppLink.getInviteDriver, payload: {
"driverId": box.read(BoxName.driverID),
});
if (response != 'failure') {
var data = jsonDecode(response);
driverInvitationData = data['message'];
update();
}
} catch (e) {}
}
void fetchDriverStatsPassengers() async {
try {
var response = await CRUD()
.get(link: AppLink.getDriverInvitationToPassengers, payload: {
"driverId": box.read(BoxName.passengerID),
});
if (response != 'failure') {
var data = jsonDecode(response);
driverInvitationDataToPassengers = data['message'];
update();
}
} catch (e) {}
}
void selectPhone(String phone) {
if (box.read(BoxName.countryCode) == 'Egypt') {
invitePhoneController.text = phone;
update();
Get.back();
}
}
Future<void> saveContactsToServer() async {
try {
// TODO: Implement the actual server upload logic here
// Simulating a server request
await Future.delayed(Duration(seconds: 2));
Get.snackbar('Success'.tr,
'${selectedContacts.length} contacts saved to server'.tr);
} catch (e) {
Get.snackbar('Error'.tr,
'An error occurred while saving contacts to server: $e'.tr);
}
}
List<Contact> contacts = <Contact>[];
List<Contact> selectedContacts = <Contact>[];
RxList<Map<String, dynamic>> contactMaps = <Map<String, dynamic>>[].obs;
Future<void> pickContacts() async {
try {
// Request contacts permission
if (await FlutterContacts.requestPermission(readonly: true)) {
// Fetch all contacts with full properties
final List<Contact> allContacts = await FlutterContacts.getContacts(
withProperties: true,
withThumbnail: false,
withPhoto: true,
);
// Check if contacts are available
if (allContacts.isNotEmpty) {
// Store the contacts
contacts = allContacts;
Log.print('contacts: $contacts');
// Convert contacts to a list of maps
contactMaps.value = await Future.wait(contacts.map((contact) async {
Log.print('Contact name: ${contact.displayName}');
// Fetch phone numbers separately
final phones = await contact.phones;
Log.print('Contact phones: $phones');
// Fetch email addresses separately
final emails = await contact.emails;
Log.print('Contact emails: $emails');
// Handle empty or null values
return {
'name': contact.displayName ?? '',
'phones': phones
.where((phone) => phone.normalizedNumber != null)
.map((phone) => phone.normalizedNumber ?? 'No number')
.toList(),
'emails': emails
.where((email) => email.address != null)
.map((email) => email.address ?? 'No email')
.toList(),
};
}).toList());
update();
} else {
Get.snackbar('No contacts available'.tr,
'Please add contacts to your phone.'.tr);
}
} else {
Get.snackbar('Permission denied'.tr,
'Contact permission is required to pick contacts'.tr);
}
} catch (e) {
Get.snackbar(
'Error'.tr, 'An error occurred while picking contacts: $e'.tr);
}
}
void onSelectPassengerInvitation(int index) async {
MyDialog().getDialog(
int.parse(driverInvitationDataToPassengers[index]['countOfInvitDriver']
.toString()) <
2
? '${'When'.tr} ${(driverInvitationDataToPassengers[index]['passengerName'].toString())} ${"complete, you can claim your gift".tr} '
: 'You deserve the gift'.tr,
'${(driverInvitationDataToPassengers[index]['passengerName'].toString())} ${driverInvitationDataToPassengers[index]['countOfInvitDriver'].toString()} / 2 ${'Trip'.tr}',
() async {
if (int.parse(driverInvitationDataToPassengers[index]
['countOfInvitDriver']
.toString()) <
2) {
Get.back();
} else {
// Claim the gift if 100 trips are completed
if (driverInvitationDataToPassengers[index]['isGiftToken']
.toString() ==
'0') {
Get.back();
// Add wallet to the inviter
await Get.find<PaymentController>().addPassengersWallet('20');
// add for invitor too
// await Get.find<CaptainWalletController>().addDriverWalletToInvitor(
// 'paymentMethod',
// driverInvitationData[index]['driverInviterId'],
// '50');
// Update invitation as claimed
await CRUD().post(
link: AppLink.updatePassengerGift,
payload: {'id': driverInvitationDataToPassengers[index]['id']},
);
// Notify the inviter
NotificationCaptainController().addNotificationCaptain(
driverInvitationDataToPassengers[index]['passengerInviterId']
.toString(),
"You have got a gift for invitation".tr,
'${"You have 20".tr} ${'LE'}',
false,
);
} else {
Get.back();
MyDialog().getDialog(
"You have got a gift".tr,
"Share the app with another new passenger".tr,
() {
Get.back();
},
);
}
}
},
);
}
savePhoneToServer() async {
for (var i = 0; i < contactMaps.length; i++) {
var phones = contactMaps[i]['phones'];
if (phones != null && phones.isNotEmpty && phones[0].isNotEmpty) {
var res = await CRUD().post(link: AppLink.savePhones, payload: {
"name": contactMaps[i]['name'] ?? 'none',
"phones": phones[0] ?? 'none',
"phones2": phones.join(', ') ??
'none', // Convert List<String> to a comma-separated string
});
if (res != 'failure') {}
} else {}
}
}
String formatPhoneNumber(String input) {
// Remove any non-digit characters
String digitsOnly = input.replaceAll(RegExp(r'\D'), '');
// Ensure the number starts with the country code
if (digitsOnly.startsWith('20')) {
digitsOnly = digitsOnly.substring(1);
}
return digitsOnly;
}
void sendInviteToPassenger() async {
if (invitePhoneController.text.isEmpty ||
invitePhoneController.text.length < 11) {
mySnackeBarError('Please enter a correct phone'.tr);
return;
}
// try {
String phoneNumber = formatPhoneNumber(invitePhoneController.text);
var response =
await CRUD().post(link: AppLink.addInvitationPassenger, payload: {
"driverId": box.read(BoxName.passengerID),
"inviterPassengerPhone": ('+2$phoneNumber')
});
if (response != 'failure') {
var d = response;
Get.snackbar('Success', 'Invite sent successfully'.tr);
String message = '${'*Intaleq APP CODE*'.tr}\n\n'
'${"Use this code in registration".tr}\n'
'${"To get a gift for both".tr}\n\n'
'${"The period of this code is 1 hour".tr}\n\n'
'${'before'.tr} *${d['message']['expirationTime'].toString()}*\n\n'
'_*${d['message']['inviteCode'].toString()}*_\n\n'
'${"Install our app:".tr}\n'
'*Android:* https://play.google.com/store/apps/details?id=com.mobileapp.store.ride\n\n\n'
'*iOS:* https://apps.apple.com/us/app/sefer/id6458734951';
launchCommunication('whatsapp', '+2$phoneNumber', message);
invitePhoneController.clear();
} else {
Get.snackbar('Error'.tr, "Invite code already used".tr,
backgroundColor: AppColor.redColor,
duration: const Duration(seconds: 4));
}
// } catch (e) {
// Get.snackbar('Error', 'An error occurred'.tr);
// }
}
}
class PassengerStats {
final int totalInvites;
final int activeUsers;
final double totalEarnings;
PassengerStats({
this.totalInvites = 0,
this.activeUsers = 0,
this.totalEarnings = 0.0,
});
}

View File

@@ -0,0 +1,35 @@
import 'dart:convert';
import 'package:get/get.dart';
import 'package:Intaleq/constant/box_name.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:Intaleq/main.dart';
class OrderHistoryController extends GetxController {
List<dynamic> orderHistoryListPassenger = [];
bool isloading = true;
@override
void onInit() {
getOrderHistoryByPassenger();
super.onInit();
}
Future getOrderHistoryByPassenger() async {
var res = await CRUD().get(link: AppLink.getRides, payload: {
'passenger_id': box.read(BoxName.passengerID).toString(),
});
if (res.toString() == 'failure') {
// Get.snackbar('failure', 'message');
isloading = false;
update();
} else {
var jsonDecoded = jsonDecode(res);
orderHistoryListPassenger = jsonDecoded['data'];
isloading = false;
update();
}
}
}

View File

@@ -0,0 +1,45 @@
import 'dart:convert';
import 'package:Intaleq/constant/box_name.dart';
import 'package:get/get.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import '../../../main.dart';
class PromosController extends GetxController {
List<dynamic> promoList = [];
bool isLoading = true;
late String promos;
@override
void onInit() {
getPromoByToday();
super.onInit();
}
Future getPromoByToday() async {
var res = await CRUD().get(link: AppLink.getPromoBytody, payload: {
'passengerID': box.read(BoxName.passengerID).toString(),
});
if (res.toString() == 'failure') {
// Get.defaultDialog(
// title: 'No Promo for today .'.tr,
// middleText: '',
// titleStyle: AppStyle.title,
// confirm: MyElevatedButton(
// title: 'Back'.tr,
// onPressed: () {
// Get.back();
// Get.back();
// }));
isLoading = false;
update();
} else {
var jsonDecoded = jsonDecode(res);
promoList = jsonDecoded['message'];
isLoading = false;
update();
}
}
}

View File

@@ -0,0 +1,152 @@
import 'dart:async';
import 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/functions/secure_storage.dart';
import 'package:Intaleq/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:Intaleq/views/auth/login_page.dart';
import 'package:package_info_plus/package_info_plus.dart';
// import 'package:uni_links/uni_links.dart';
import '../../constant/box_name.dart';
import '../../main.dart';
import '../../onbording_page.dart';
import '../../views/auth/otp_page.dart';
import '../auth/login_controller.dart';
class SplashScreenController extends GetxController
with GetTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> animation;
final progress = 0.0.obs;
Timer? _progressTimer;
String packageInfo = '';
Future<void> _getPackageInfo() async {
final info = await PackageInfo.fromPlatform();
packageInfo = info.version;
box.write(BoxName.packagInfo, packageInfo);
update();
}
String iss = '';
@override
Future<void> onInit() async {
super.onInit();
// storage.read(key: 'iss').then((s) {
// // print(s);
// iss = s!;
// });
// if (iss == null) {
SecureStorage().saveData('iss', 'mobile-app:');
// }
_getPackageInfo();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1500), // Reduced duration
)..forward();
animation =
CurvedAnimation(parent: _animationController, curve: Curves.easeOut);
startTimer();
_startProgressTimer();
}
void _startProgressTimer() {
const totalTime = 2000; // 5 seconds in milliseconds
const interval = 50; // Update every 50ms
int elapsed = 0;
_progressTimer =
Timer.periodic(const Duration(milliseconds: interval), (timer) async {
elapsed += interval;
progress.value = (elapsed / totalTime).clamp(0.0, 1.0);
if (elapsed >= totalTime) {
timer.cancel();
// await SecurityHelper.performSecurityChecks();
// if (box.read('isNotTrust') ||
// box.read('isJailBroken') ||
// box.read('isTampered')) {
// Get.to(() => SecurityPage());
// } else {
box.read(BoxName.onBoarding) == null
? Get.off(() => OnBoardingPage())
: box.read(BoxName.email) != null &&
box.read(BoxName.phone) != null &&
box.read(BoxName.isVerified) == '1'
// ? Get.off(() => const MapPagePassenger())
? await Get.put(LoginController()).loginUsingCredentials(
box.read(BoxName.passengerID).toString(),
box.read(BoxName.email).toString(),
)
: Get.off(() => LoginPage());
}
// }
});
}
void startTimer() async {
Timer(const Duration(seconds: 5), () async {
// box.read(BoxName.onBoarding) == null
// ? Get.off(() => OnBoardingPage())
// : box.read(BoxName.email) != null &&
// box.read(BoxName.phone) != null &&
// box.read(BoxName.isVerified) == '1'
// // ? Get.off(() => const MapPagePassenger())
// ? await Get.put(LoginController()).loginUsingCredentials(
// box.read(BoxName.passengerID).toString(),
// box.read(BoxName.email).toString(),
// )
// : Get.off(() => LoginPage());
});
}
@override
void onClose() {
_progressTimer?.cancel();
_animationController.dispose();
super.onClose();
}
}
class SecurityPage extends StatelessWidget {
const SecurityPage({
super.key,
});
@override
Widget build(BuildContext context) {
return MyScafolld(
title: "security_warning".tr,
body: [
Center(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(
"security_message".tr,
style: AppStyle.headTitle2,
),
TextButton(
onPressed: () async {
// await SecurityHelper.clearAllData();
},
child: Text(
"security_warning".tr,
),
),
],
),
),
)
],
isleading: false);
}
}

View File

@@ -0,0 +1,113 @@
import 'dart:async';
import 'dart:convert';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/controller/functions/crud.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class TripMonitorController extends GetxController {
bool isLoading = false;
Map tripData = {};
late String rideId;
late String driverId;
GoogleMapController? mapController;
List myListString = [];
late Timer timer;
late LatLng parentLocation;
BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker;
BitmapDescriptor motoIcon = BitmapDescriptor.defaultMarker;
BitmapDescriptor ladyIcon = BitmapDescriptor.defaultMarker;
double rotation = 0;
double speed = 0;
getLocationParent() async {
var res = await CRUD().get(
link: AppLink.getLocationParents, payload: {"driver_id": driverId});
if (res != 'failure') {
tripData = jsonDecode(res);
parentLocation = LatLng(
double.parse(tripData['message'][0]['latitude'].toString()),
double.parse(tripData['message'][0]['longitude'].toString()));
rotation = double.parse(tripData['message'][0]['heading'].toString());
speed = double.parse(tripData['message'][0]['speed'].toString());
update();
}
}
void onMapCreated(GoogleMapController controller) async {
mapController = controller;
controller.getVisibleRegion();
controller.animateCamera(
CameraUpdate.newLatLng(parentLocation),
);
update();
// Set up a timer or interval to trigger the marker update every 3 seconds.
timer = Timer.periodic(const Duration(seconds: 10), (_) async {
await getLocationParent();
mapController?.animateCamera(CameraUpdate.newLatLng(parentLocation));
update();
});
}
// init() async {
// final arguments = Get.arguments;
// driverId = arguments['driverId'];
// rideId = arguments['rideId'];
// await getLocationParent();
// }
Future<void> init({String? rideId, String? driverId}) async {
this.driverId = driverId!;
this.rideId = rideId!;
await getLocationParent();
update();
}
void addCustomCarIcon() {
ImageConfiguration config = ImageConfiguration(
size: const Size(30, 30), devicePixelRatio: Get.pixelRatio);
BitmapDescriptor.fromAssetImage(config, 'assets/images/car.png',
mipmaps: false)
.then((value) {
carIcon = value;
update();
});
void addCustomMotoIcon() {
ImageConfiguration config = ImageConfiguration(
size: const Size(30, 30), devicePixelRatio: Get.pixelRatio);
BitmapDescriptor.fromAssetImage(config, 'assets/images/moto1.png',
mipmaps: false)
.then((value) {
motoIcon = value;
update();
});
}
void addCustomLadyIcon() {
ImageConfiguration config = ImageConfiguration(
size: const Size(30, 30), devicePixelRatio: Get.pixelRatio);
BitmapDescriptor.fromAssetImage(config, 'assets/images/lady1.png',
mipmaps: false)
.then((value) {
ladyIcon = value;
update();
});
}
}
@override
void onInit() {
addCustomCarIcon();
super.onInit();
}
@override
void onClose() {
timer.cancel();
mapController?.dispose();
super.onClose();
}
}

View File

@@ -0,0 +1,324 @@
import 'dart:async';
import 'dart:convert';
import 'package:Intaleq/constant/box_name.dart';
import 'package:Intaleq/constant/colors.dart';
import 'package:Intaleq/constant/links.dart';
import 'package:Intaleq/constant/style.dart';
import 'package:Intaleq/controller/home/map_passenger_controller.dart';
import 'package:Intaleq/main.dart';
import 'package:Intaleq/views/widgets/elevated_btn.dart';
import 'package:Intaleq/views/widgets/my_scafold.dart';
import 'package:Intaleq/views/widgets/mycircular.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import '../functions/crud.dart';
import '../functions/encrypt_decrypt.dart';
class VipOrderController extends GetxController {
RxBool isLoading = false.obs;
final arguments = Get.arguments;
RxList<dynamic> tripData = <dynamic>[].obs;
RxBool isButtonVisible = false.obs;
RxInt countdown = 60.obs;
Timer? _countdownTimer;
@override
void onInit() {
super.onInit();
fetchOrder();
startCountdown();
}
@override
void onClose() {
_countdownTimer?.cancel();
super.onClose();
}
Future<void> fetchOrder() async {
try {
isLoading.value = true;
var mapPassengerController = Get.find<MapPassengerController>();
var res = await CRUD().get(
link: AppLink.getMishwari,
payload: {
// 'driverId': mapPassengerController.driverIdVip.toString(),
'driverId': box.read(BoxName.passengerID).toString(),
},
);
if (res != 'failure') {
var decodedResponse = jsonDecode(res);
if (decodedResponse['message'] is List) {
tripData.value = decodedResponse['message'];
} else {
tripData.clear(); // Ensure empty list if no data
// mySnackeBarError('No trip data found');
}
} else {
tripData.clear();
// mySnackeBarError('Failed to fetch trip data');
}
} catch (e) {
tripData.clear();
// mySnackeBarError('An error occurred: $e');
} finally {
isLoading.value = false;
}
}
void startCountdown() {
_countdownTimer?.cancel(); // Cancel any existing timer
countdown.value = 60;
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (countdown.value > 0) {
countdown.value--;
} else {
timer.cancel();
isButtonVisible.value = true;
}
});
}
void sendToDriverAgain() {
// Reset states
isButtonVisible.value = false;
fetchOrder(); // Refresh order
startCountdown(); // Restart countdown
}
}
class VipWaittingPage extends StatelessWidget {
VipWaittingPage({super.key});
final VipOrderController vipOrderController = Get.put(VipOrderController());
@override
Widget build(BuildContext context) {
return MyScafolld(
title: "Waiting VIP".tr,
body: [
Obx(() {
// Loading state
if (vipOrderController.isLoading.value) {
return const Center(child: MyCircularProgressIndicator());
}
// No data state
if (vipOrderController.tripData.isEmpty) {
return Center(
child: Text(
'No trip data available'.tr,
style: AppStyle.title,
),
);
}
// Data available
var data = vipOrderController.tripData[0];
// Function to get the localized status string
String getLocalizedStatus(String status) {
switch (status) {
case 'pending':
return 'pending'.tr;
case 'accepted':
return 'accepted'.tr;
case 'begin':
return 'begin'.tr;
case 'rejected':
return 'rejected'.tr;
case 'cancelled':
return 'cancelled'.tr;
default:
return 'unknown'.tr;
}
}
// Function to get the appropriate status color
Color getStatusColor(String status) {
switch (status) {
case 'pending':
return Colors.yellow;
case 'accepted':
return Colors.green;
case 'begin':
return Colors.green;
case 'rejected':
return Colors.red;
case 'cancelled':
return Colors.red;
default:
return Colors.grey;
}
}
return Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
margin: const EdgeInsets.all(16),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${'Driver Name:'.tr} ${data['name']}",
style: AppStyle.title,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${'Car Plate:'.tr} ${data['car_plate']}",
style: AppStyle.title,
),
Text(
"${'Car Make:'.tr} ${data['make']}",
style: AppStyle.title,
),
Text(
"${'Car Model:'.tr} ${data['model']}",
style: AppStyle.title,
),
Text(
"${"Car Color:".tr} ${data['color']}",
style: AppStyle.title,
),
],
),
SizedBox(
width: 100,
height: 100,
child: Icon(
Fontisto.car,
size: 80,
color: Color(
int.parse(
data['color_hex'].replaceFirst('#', '0xff'),
),
),
),
),
],
),
const SizedBox(height: 12),
const Divider(),
const SizedBox(height: 12),
Container(
color: getStatusColor(data['status']),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"${'Trip Status:'.tr} ${getLocalizedStatus(data['status'])}",
style: const TextStyle(fontSize: 16),
),
),
),
Text(
"${'Scheduled Time:'.tr} ${DateFormat('yyyy-MM-dd hh:mm a').format(DateTime.parse(data['timeSelected']))}",
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
data['status'].toString() != 'begin'
? MyElevatedButton(
title: "Cancel Trip".tr,
kolor: AppColor.redColor,
onPressed: () {
Get.find<MapPassengerController>().cancelVip(
data['token'].toString(),
data['id'].toString(),
);
},
)
: const SizedBox(),
Obx(() {
// If countdown is still running, show countdown
if (!vipOrderController.isButtonVisible.value) {
return Column(
children: [
CircularProgressIndicator(
value: 1 -
(vipOrderController.countdown.value / 60),
strokeWidth: 6.0,
color: AppColor.greenColor,
backgroundColor: AppColor.accentColor,
),
const SizedBox(height: 10),
Text(
"${vipOrderController.countdown.value}s ${'remaining'.tr}",
style: const TextStyle(fontSize: 16),
),
],
);
}
// Once countdown is complete, show "Send to Driver Again" button
return MyElevatedButton(
title: "Send to Driver Again".tr,
kolor: AppColor.greenColor,
onPressed: () {
Get.find<MapPassengerController>()
.sendToDriverAgain(data['token']);
vipOrderController.fetchOrder();
},
);
}),
],
),
const SizedBox(
height: 30,
),
data['status'].toString() == 'begin'
? MyElevatedButton(
title: "Click here to begin your trip\n\nGood luck, "
.tr +
(box.read(BoxName.name).toString().split(' ')[0])
.toString(),
kolor: AppColor.greenColor,
onPressed: () {
final mapPassengerController =
Get.find<MapPassengerController>();
mapPassengerController.make = data['make'];
mapPassengerController.licensePlate =
data['car_plate'];
mapPassengerController.model = data['model'];
mapPassengerController.driverId = data['driverId'];
mapPassengerController.carColor = data['color'];
mapPassengerController.driverRate = data['rating'];
mapPassengerController.colorHex = data['color_hex'];
mapPassengerController.driverPhone = data['phone'];
mapPassengerController.driverToken = data['token'];
mapPassengerController.driverName =
data['name'].toString().split(' ')[0];
Get.back();
mapPassengerController.begiVIPTripFromPassenger();
},
)
: const SizedBox()
],
),
),
);
}),
],
isleading: true,
);
}
}