190 lines
6.3 KiB
Dart
190 lines
6.3 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:siro_driver/constant/box_name.dart';
|
|
import 'package:siro_driver/constant/links.dart';
|
|
import 'package:siro_driver/controller/functions/crud.dart';
|
|
import '../../main.dart';
|
|
|
|
// ════════════════════════════════════════════
|
|
// نموذج الإحالة
|
|
// ════════════════════════════════════════════
|
|
|
|
class ReferralRecord {
|
|
final String id;
|
|
final String name;
|
|
final String phone;
|
|
final String status; // 'registered', 'active', 'inactive'
|
|
final String type; // 'driver', 'passenger'
|
|
final String joinDate;
|
|
final int tripCount;
|
|
|
|
ReferralRecord({
|
|
required this.id,
|
|
required this.name,
|
|
required this.phone,
|
|
required this.status,
|
|
required this.type,
|
|
required this.joinDate,
|
|
required this.tripCount,
|
|
});
|
|
|
|
factory ReferralRecord.fromJson(Map<String, dynamic> json) {
|
|
return ReferralRecord(
|
|
id: json['id']?.toString() ?? '',
|
|
name: json['name']?.toString() ?? json['nameArabic']?.toString() ?? '',
|
|
phone: json['phone']?.toString() ?? '',
|
|
status: json['status']?.toString() ?? 'registered',
|
|
type: json['type']?.toString() ?? 'driver',
|
|
joinDate: json['created_at']?.toString() ?? '',
|
|
tripCount: int.tryParse(json['trip_count']?.toString() ?? '0') ?? 0,
|
|
);
|
|
}
|
|
}
|
|
|
|
// ════════════════════════════════════════════
|
|
// Controller
|
|
// ════════════════════════════════════════════
|
|
|
|
class ReferralController extends GetxController {
|
|
bool isLoading = false;
|
|
List<ReferralRecord> driverReferrals = [];
|
|
List<ReferralRecord> passengerReferrals = [];
|
|
String referralCode = '';
|
|
int totalDriverReferrals = 0;
|
|
int totalPassengerReferrals = 0;
|
|
int activeReferrals = 0;
|
|
double totalRewardsEarned = 0;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_generateReferralCode();
|
|
fetchReferralData();
|
|
}
|
|
|
|
void _generateReferralCode() {
|
|
final driverId = box.read(BoxName.driverID)?.toString() ?? '';
|
|
final name = box.read(BoxName.nameDriver)?.toString() ?? '';
|
|
if (driverId.isNotEmpty) {
|
|
// كود فريد: أول 3 حروف من الاسم + ID
|
|
final prefix = name.length >= 3 ? name.substring(0, 3).toUpperCase() : name.toUpperCase();
|
|
referralCode = '$prefix$driverId';
|
|
}
|
|
}
|
|
|
|
Future<void> fetchReferralData() async {
|
|
isLoading = true;
|
|
update();
|
|
|
|
try {
|
|
// 1. جلب دعوات السائقين
|
|
var driverRes = await CRUD().get(
|
|
link: AppLink.getInviteDriver,
|
|
payload: {'driver_id': box.read(BoxName.driverID).toString()},
|
|
);
|
|
if (driverRes != null && driverRes != 'failure') {
|
|
var data = jsonDecode(driverRes);
|
|
if (data['message'] is List) {
|
|
driverReferrals = (data['message'] as List)
|
|
.map((e) => ReferralRecord.fromJson(e))
|
|
.toList();
|
|
totalDriverReferrals = driverReferrals.length;
|
|
}
|
|
}
|
|
|
|
// 2. جلب دعوات الركاب
|
|
var passengerRes = await CRUD().get(
|
|
link: AppLink.getDriverInvitationToPassengers,
|
|
payload: {'driver_id': box.read(BoxName.driverID).toString()},
|
|
);
|
|
if (passengerRes != null && passengerRes != 'failure') {
|
|
var data = jsonDecode(passengerRes);
|
|
if (data['message'] is List) {
|
|
passengerReferrals = (data['message'] as List)
|
|
.map((e) => ReferralRecord.fromJson(e))
|
|
.toList();
|
|
totalPassengerReferrals = passengerReferrals.length;
|
|
}
|
|
}
|
|
|
|
// 3. جلب الإحصائيات الدقيقة للمكافآت
|
|
var statsRes = await CRUD().get(
|
|
link: AppLink.getReferralStats,
|
|
payload: {'driver_id': box.read(BoxName.driverID).toString()},
|
|
);
|
|
if (statsRes != null && statsRes != 'failure') {
|
|
var data = jsonDecode(statsRes);
|
|
if (data['message'] is List && data['message'].isNotEmpty) {
|
|
var stats = data['message'][0];
|
|
totalRewardsEarned = double.tryParse(stats['totalRewards']?.toString() ?? '0') ?? 0;
|
|
activeReferrals = (int.tryParse(stats['driverInvites']?.toString() ?? '0') ?? 0) +
|
|
(int.tryParse(stats['passengerInvites']?.toString() ?? '0') ?? 0);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
debugPrint('❌ [Referral] Error: $e');
|
|
}
|
|
|
|
isLoading = false;
|
|
update();
|
|
}
|
|
|
|
void copyCode() {
|
|
Clipboard.setData(ClipboardData(text: referralCode));
|
|
}
|
|
|
|
String get shareMessage {
|
|
final appName = 'Siro';
|
|
return 'Join $appName as a driver! Use my code: $referralCode\nDownload: https://siro.app/driver?ref=$referralCode';
|
|
}
|
|
|
|
String get shareMessagePassenger {
|
|
final appName = 'Siro';
|
|
return 'Get a ride with $appName! Use my code: $referralCode for a discount.\nDownload: https://siro.app?ref=$referralCode';
|
|
}
|
|
|
|
int get totalReferrals => totalDriverReferrals + totalPassengerReferrals;
|
|
|
|
// ═══════ إرسال دعوة سائق ═══════
|
|
Future<bool> inviteDriver(String phone) async {
|
|
try {
|
|
var res = await CRUD().post(
|
|
link: AppLink.addInviteDriver,
|
|
payload: {
|
|
'driver_id': box.read(BoxName.driverID).toString(),
|
|
'phone': phone,
|
|
},
|
|
);
|
|
if (res != null && res != 'failure') {
|
|
await fetchReferralData();
|
|
return true;
|
|
}
|
|
} catch (e) {
|
|
debugPrint('❌ [Referral] Invite driver error: $e');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// ═══════ إرسال دعوة راكب ═══════
|
|
Future<bool> invitePassenger(String phone) async {
|
|
try {
|
|
var res = await CRUD().post(
|
|
link: AppLink.addInvitationPassenger,
|
|
payload: {
|
|
'driver_id': box.read(BoxName.driverID).toString(),
|
|
'phone': phone,
|
|
},
|
|
);
|
|
if (res != null && res != 'failure') {
|
|
await fetchReferralData();
|
|
return true;
|
|
}
|
|
} catch (e) {
|
|
debugPrint('❌ [Referral] Invite passenger error: $e');
|
|
}
|
|
return false;
|
|
}
|
|
}
|