import 'dart:convert'; import 'package:local_auth/local_auth.dart'; import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/links.dart'; import 'package:sefer_driver/controller/firebase/local_notification.dart'; import 'package:sefer_driver/controller/functions/crud.dart'; import 'package:sefer_driver/controller/functions/encrypt_decrypt.dart'; import 'package:sefer_driver/controller/home/payment/captain_wallet_controller.dart'; import 'package:sefer_driver/views/widgets/mydialoug.dart'; import 'package:flutter/material.dart'; import 'package:flutter_contacts/contact.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:get/get.dart'; import 'package:share_plus/share_plus.dart'; import '../../../main.dart'; import '../../../views/widgets/error_snakbar.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 shareCouponCode() async { // TODO: Implement sharing functionality // You can use share_plus package to share the coupon code } Future shareDriverCode() async { if (driverCouponCode != null) { final String shareText = ''' Join Tripz as a driver using my referral code! Use code: $driverCouponCode Download the Tripz Driver app now and earn rewards! '''; await Share.share(shareText); } } Future sharePassengerCode() async { if (couponCode != null) { final String shareText = ''' Get a discount on your first Tripz ride! Use my referral code: $couponCode Download the Tripz 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.driverID), }); if (response != 'failure') { var data = jsonDecode(response); driverInvitationDataToPassengers = data['message']; update(); } } catch (e) {} } void selectPhone(String phone) { if (box.read(BoxName.countryCode) == 'Egypt') { invitePhoneController.text = phone; update(); Get.back(); } } Future saveContactsToServer() async { try { // TODO: Implement the actual server upload logic here // Simulating a server request await Future.delayed(Duration(seconds: 2)); mySnackbarSuccess( '${selectedContacts.length} contacts saved to server'.tr); } catch (e) { mySnackeBarError( 'An error occurred while saving contacts to server: $e'.tr); } } List contacts = []; List selectedContacts = []; RxList> contactMaps = >[].obs; Future pickContacts() async { try { if (await FlutterContacts.requestPermission(readonly: true)) { final List fetchedContacts = await FlutterContacts.getContacts(withProperties: true); contacts = fetchedContacts; // Convert contacts to a list of maps contactMaps.value = fetchedContacts.map((contact) { return { 'name': contact.displayName, 'phones': contact.phones.map((phone) => phone.normalizedNumber).toList(), 'emails': contact.emails.map((email) => email.address).toList(), }; }).toList(); update(); if (contacts.isEmpty) { mySnackeBarError('Please add contacts to your phone.'.tr); } } else { mySnackeBarError('Contact permission is required to pick contacts'.tr); } } catch (e) { mySnackeBarError('An error occurred while picking contacts: $e'.tr); } } void onSelectDriverInvitation(int index) async { MyDialog().getDialog( int.parse((driverInvitationData[index]['countOfInvitDriver'])) < 100 ? '${'When'.tr} ${(driverInvitationData[index]['invitorName'])} ${"complete, you can claim your gift".tr} ' : 'You deserve the gift'.tr, '${(driverInvitationData[index]['invitorName'])} ${(driverInvitationData[index]['countOfInvitDriver'])} / 100 ${'Trip'.tr}', () async { bool isAvailable = await LocalAuthentication().isDeviceSupported(); if (int.parse((driverInvitationData[index]['countOfInvitDriver'])) < 100) { Get.back(); } else //claim your gift if (isAvailable) { // Authenticate the user bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: 'Use Touch ID or Face ID to confirm payment', options: AuthenticationOptions( biometricOnly: true, sensitiveTransaction: true, )); if (didAuthenticate) { if ((driverInvitationData[index]['isGiftToken']).toString() == '0') { Get.back(); await CRUD().post( link: AppLink.updateInviteDriver, payload: {'id': (driverInvitationData[index]['id'])}); await Get.find().addDriverPayment( 'paymentMethod', ('500'), '', ); // add for invitor too await Get.find() .addDriverWalletToInvitor( 'paymentMethod', (driverInvitationData[index]['driverInviterId']), ('500'), ); // await Get.find() // .addSeferWallet('giftInvitation', ('-1000')); NotificationCaptainController().addNotificationCaptain( driverInvitationData[index]['driverInviterId'].toString(), "You have got a gift for invitation".tr, '${"You have 500".tr} ${'LE'.tr}', false); NotificationController().showNotification( "You have got a gift for invitation".tr, '${"You have 500".tr} ${'LE'.tr}', 'tone1', ''); } else { Get.back(); MyDialog().getDialog("You have got a gift".tr, "Share the app with another new driver".tr, () { Get.back(); }); } } else { // Authentication failed, handle accordingly MyDialog().getDialog('Authentication failed'.tr, ''.tr, () { Get.back(); }); } } else { MyDialog().getDialog('Biometric Authentication'.tr, 'You should use Touch ID or Face ID to confirm payment'.tr, () { Get.back(); }); } }, ); } void onSelectPassengerInvitation(int index) async { bool isAvailable = await LocalAuthentication().isDeviceSupported(); MyDialog().getDialog( int.parse(driverInvitationDataToPassengers[index]['countOfInvitDriver'] .toString()) < 3 ? '${'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']} / 3 ${'Trip'.tr}', () async { if (int.parse(driverInvitationDataToPassengers[index] ['countOfInvitDriver'] .toString()) < 3) { Get.back(); } else if (isAvailable) { // Authenticate the user bool didAuthenticate = await LocalAuthentication().authenticate( localizedReason: 'Use Touch ID or Face ID to confirm payment', options: AuthenticationOptions( biometricOnly: true, sensitiveTransaction: true, )); if (didAuthenticate) { // Claim the gift if 100 trips are completed if (driverInvitationDataToPassengers[index]['isGiftToken'] .toString() == '0') { Get.back(); // Add wallet to the inviter await Get.find() .addDriverWallet('paymentMethod', '50', '50'); // add for invitor too await Get.find() .addDriverWalletToInvitor('paymentMethod', driverInvitationData[index]['driverInviterId'], '50'); // Update invitation as claimed await CRUD().post( link: AppLink.updatePassengerGift, payload: {'id': driverInvitationDataToPassengers[index]['id']}, ); // Notify the inviter NotificationCaptainController().addNotificationCaptain( driverInvitationDataToPassengers[index]['passengerInviterId'] .toString(), "You have got a gift for invitation".tr, '${"You have 50".tr} ${'LE'}', false, ); } else { Get.back(); MyDialog().getDialog( "You have got a gift".tr, "Share the app with another new passenger".tr, () { Get.back(); }, ); } } else { // Authentication failed, handle accordingly MyDialog().getDialog('Authentication failed'.tr, ''.tr, () { Get.back(); }); } } else { MyDialog().getDialog('Biometric Authentication'.tr, 'You should use Touch ID or Face ID to confirm payment'.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 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 sendInvite() async { if (invitePhoneController.text.isEmpty) { mySnackeBarError('Please enter an phone address'.tr); return; } // try { String phoneNumber = formatPhoneNumber(invitePhoneController.text); var response = await CRUD().post(link: AppLink.addInviteDriver, payload: { "driverId": box.read(BoxName.driverID), "inviterDriverPhone": '+2$phoneNumber' }); if (response != 'failure') { var d = (response); mySnackbarSuccess('Invite sent successfully'.tr); String message = '${'*Tripz DRIVER 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.sefer_driver\n\n\n' '*iOS:* https://apps.apple.com/ae/app/sefer-driver/id6502189302'; launchCommunication('whatsapp', '+2$phoneNumber', message); invitePhoneController.clear(); } else { mySnackeBarError("Invite code already used".tr); } } void sendInviteToPassenger() async { if (invitePhoneController.text.isEmpty) { mySnackeBarError('Please enter an phone address'.tr); return; } // try { String phoneNumber = formatPhoneNumber(invitePhoneController.text); var response = await CRUD().post(link: AppLink.addInvitationPassenger, payload: { "driverId": box.read(BoxName.driverID), "inviterPassengerPhone": '+2$phoneNumber' }); if (response != 'failure') { var d = jsonDecode(response); mySnackbarSuccess('Invite sent successfully'.tr); String message = '${'*Tripz 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 { mySnackeBarError( "Invite code already used".tr, ); } } } class PassengerStats { final int totalInvites; final int activeUsers; final double totalEarnings; PassengerStats({ this.totalInvites = 0, this.activeUsers = 0, this.totalEarnings = 0.0, }); }