310 lines
10 KiB
Dart
310 lines
10 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:SEFER/constant/box_name.dart';
|
|
import 'package:SEFER/constant/colors.dart';
|
|
import 'package:SEFER/constant/links.dart';
|
|
import 'package:SEFER/controller/functions/crud.dart';
|
|
import 'package:SEFER/controller/payment/payment_controller.dart';
|
|
import 'package:SEFER/views/widgets/mysnakbar.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/share.dart';
|
|
|
|
import '../../../main.dart';
|
|
import '../../../print.dart';
|
|
import '../../../views/widgets/my_dialog.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 SEFER as a driver using my referral code!
|
|
Use code: $driverCouponCode
|
|
Download the SEFER 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 SEFER ride!
|
|
Use my referral code: $couponCode
|
|
Download the SEFER 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(
|
|
driverInvitationDataToPassengers[index]['countOfInvitDriver'] < 2
|
|
? '${'When'.tr} ${driverInvitationDataToPassengers[index]['passengerName']} ${"complete, you can claim your gift".tr} '
|
|
: 'You deserve the gift'.tr,
|
|
'${driverInvitationDataToPassengers[index]['passengerName']} ${driverInvitationDataToPassengers[index]['countOfInvitDriver']} / 2 ${'Trip'.tr}',
|
|
() async {
|
|
if (driverInvitationDataToPassengers[index]['countOfInvitDriver'] < 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 = '${'*SEFER 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,
|
|
});
|
|
}
|