feat: redesign behavior page, add fatigue monitoring and fix map controller
This commit is contained in:
189
lib/controller/gamification/referral_controller.dart
Normal file
189
lib/controller/gamification/referral_controller.dart
Normal file
@@ -0,0 +1,189 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sefer_driver/constant/box_name.dart';
|
||||
import 'package:sefer_driver/constant/links.dart';
|
||||
import 'package:sefer_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 = 'Intaleq';
|
||||
return 'Join $appName as a driver! Use my code: $referralCode\nDownload: https://intaleq.app/driver?ref=$referralCode';
|
||||
}
|
||||
|
||||
String get shareMessagePassenger {
|
||||
final appName = 'Intaleq';
|
||||
return 'Get a ride with $appName! Use my code: $referralCode for a discount.\nDownload: https://intaleq.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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user