add new featurs like new stat page

This commit is contained in:
Hamza-Ayed
2026-05-08 22:44:55 +03:00
parent efbc921273
commit 8f555691b9
33 changed files with 1194 additions and 585 deletions

View File

@@ -532,7 +532,7 @@ Download the Intaleq app now and enjoy your ride!
String message = '${'*Intaleq 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'
'${"The period of this code is 24 hours".tr}\n\n'
'${'before'.tr} *${d['message']['expirationTime'].toString()}*\n\n'
'_*${d['message']['inviteCode'].toString()}*_\n\n'
'${"Install our app:".tr}\n'
@@ -581,7 +581,7 @@ Download the Intaleq app now and enjoy your ride!
String message = '${'*Intaleq APP CODE*'.tr}\n\n'
'${"Use this code in registration".tr}\n\n'
'${"To get a gift for both".tr}\n\n'
'${"The period of this code is 1 hour".tr}\n\n'
'${"The period of this code is 24 hours".tr}\n\n'
'${'before'.tr} *${d['message']['expirationTime'].toString()}*\n\n'
'_*${d['message']['inviteCode'].toString()}*_\n\n'
'${"Install our app:".tr}\n'

View File

@@ -218,22 +218,34 @@ class ChallengesController extends GetxController {
}
}
// Fetch weekly aggregate for weekly challenges
var weeklyRes = await CRUD().get(
// 2. Fetch weekly earnings from PAYMENT server
var weeklyEarningsRes = await CRUD().getWallet(
link: AppLink.getDriverWeekPaymentMove,
payload: {'driverID': box.read(BoxName.driverID).toString()},
);
double weeklyEarnings = 0;
if (weeklyEarningsRes != null && weeklyEarningsRes != 'failure') {
var data = jsonDecode(weeklyEarningsRes);
if (data['message'] is List && data['message'].isNotEmpty) {
weeklyEarnings = double.tryParse(data['message'][0]['totalAmount']?.toString() ?? '0') ?? 0;
}
}
// 3. Fetch weekly trips and hours from RIDES server (avoiding earnings join)
var weeklyAggregateRes = await CRUD().get(
link: AppLink.getWeeklyAggregate,
payload: {'driver_id': box.read(BoxName.driverID).toString()},
);
int weeklyTrips = 0;
double weeklyEarnings = 0;
double weeklyHours = 0;
if (weeklyRes != null && weeklyRes != 'failure') {
var data = jsonDecode(weeklyRes);
if (weeklyAggregateRes != null && weeklyAggregateRes != 'failure') {
var data = jsonDecode(weeklyAggregateRes);
if (data['message'] is List) {
for (var day in data['message']) {
weeklyTrips += int.tryParse(day['trips']?.toString() ?? '0') ?? 0;
weeklyEarnings += double.tryParse(day['earnings']?.toString() ?? '0') ?? 0;
weeklyHours += double.tryParse(day['hours']?.toString() ?? '0') ?? 0;
}
}

View File

@@ -32,8 +32,7 @@ class StatisticsController extends GetxController {
@override
void onInit() {
super.onInit();
fetchWeeklyData();
fetchMonthlyData();
reloadData();
}
void changeTab(int tab) {
@@ -89,12 +88,13 @@ class StatisticsController extends GetxController {
monthlyEarnings = (data['message'] as List)
.map((e) => MonthlyPriceDriverModel.fromJson(e))
.toList();
monthlyTotalEarnings = monthlyEarnings.fold(0, (s, d) => s + d.pricePerDay);
monthlyTotalEarnings =
monthlyEarnings.fold(0, (s, d) => s + d.pricePerDay);
// أفضل يوم
if (monthlyEarnings.isNotEmpty) {
var best = monthlyEarnings.reduce((a, b) =>
a.pricePerDay > b.pricePerDay ? a : b);
var best = monthlyEarnings
.reduce((a, b) => a.pricePerDay > b.pricePerDay ? a : b);
bestDay = best.day.toString();
bestDayEarnings = best.pricePerDay;
}
@@ -127,7 +127,8 @@ class StatisticsController extends GetxController {
monthlyDuration = (data['message'] as List)
.map((e) => MonthlyDataModel.fromJson(e))
.toList();
monthlyTotalHours = monthlyDuration.fold(0, (s, d) => s + d.totalDuration.toDouble());
monthlyTotalHours =
monthlyDuration.fold(0, (s, d) => s + d.totalDuration.toDouble());
}
}
} catch (e) {
@@ -157,9 +158,26 @@ class StatisticsController extends GetxController {
return days[weekday - 1];
}
Future<void> refresh() async {
await fetchWeeklyData();
await fetchMonthlyData();
bool _isFetching = false;
Future<void> reloadData() async {
if (_isFetching) return;
_isFetching = true;
isLoading = true;
update();
try {
debugPrint('📊 [Statistics] Reloading data...');
await fetchWeeklyData();
await fetchMonthlyData();
debugPrint('📊 [Statistics] Data reload complete.');
} catch (e) {
debugPrint('❌ [Statistics] Error reloading data: $e');
} finally {
_isFetching = false;
isLoading = false;
update();
}
}
}
@@ -180,7 +198,8 @@ class DayStat {
});
factory DayStat.fromJson(Map<String, dynamic> json) {
final date = DateTime.tryParse(json['day']?.toString() ?? '') ?? DateTime.now();
final date =
DateTime.tryParse(json['day']?.toString() ?? '') ?? DateTime.now();
const dayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
return DayStat(
date: date,

View File

@@ -201,7 +201,79 @@ class MyTranslation extends Translations {
"Average of Hours of": "متوسط ساعات",
"Awaiting response...": "عم نستنى الرد...",
"Awfar Car": "سيارة أوفر",
"Back": "رجوع",
"Mon": "الاثنين",
"Tue": "الثلاثاء",
"Wed": "الأربعاء",
"Thu": "الخميس",
"Fri": "الجمعة",
"Sat": "السبت",
"Sun": "الأحد",
"The price must be over than": "السعر لازم يكون أكثر من",
"Driver Level": "مستوى السائق",
"Next Level:": "المستوى التالي:",
"Points": "نقطة",
"Maximum Level Reached!": "وصلت لأعلى مستوى!",
"Basic features": "ميزات أساسية",
"Standard support": "دعم قياسي",
"Priority medium": "أولوية متوسطة",
"Silver badge": "وسام فضي",
"-1% commission": "خصم 1% من العمولة",
"High priority": "أولوية عالية",
"Gold badge": "وسام ذهبي",
"-2% commission": "خصم 2% من العمولة",
"VIP first": "أولوية VIP",
"Diamond badge": "وسام ألماسي",
"-5% commission": "خصم 5% من العمولة",
"Priority support": "دعم فني ذو أولوية",
"Daily Goal": "الهدف اليومي",
"Edit": "تعديل",
"Set Goal": "تحديد هدف",
"Goal Achieved!": "تم تحقيق الهدف!",
"Remaining:": "المتبقي:",
"Set Daily Goal": "تحديد الهدف اليومي",
"How much do you want to earn today?": "كم تريد أن تربح اليوم؟",
"Save": "حفظ",
"Cancel": "إلغاء",
"Today Overview": "نظرة عامة على اليوم",
"Online Duration": "مدة التواجد",
"Refused": "المرفوضة",
"Score": "التقييم",
"Max Speed": "أعلى سرعة",
"Hard Brakes": "الفرامل المفاجئة",
"Driving Behavior": "سلوك القيادة",
"Excellent": "ممتاز",
"Good": "جيد",
"Needs Improvement": "يحتاج تحسين",
"Achievements": "الإنجازات",
"Day Streak": "سلسلة الأيام",
"Rating": "التقييم",
"Referrals": "الإحالات",
"First Trip": "أول رحلة",
"Complete your first trip": "أكمل أول رحلة لك",
"Road Warrior": "محارب الطريق",
"Complete 50 trips": "أكمل 50 رحلة",
"Century Rider": "سائق المئة",
"Complete 100 trips": "أكمل 100 رحلة",
"Road Legend": "أسطورة الطريق",
"Complete 500 trips": "أكمل 500 رحلة",
"Five Star Driver": "سائق 5 نجوم",
"Maintain 5.0 rating": "حافظ على تقييم 5.0",
"Weekly Streak": "سلسلة أسبوعية",
"Work 7 consecutive days": "اعمل 7 أيام متتالية",
"Monthly Streak": "سلسلة شهرية",
"Work 30 consecutive days": "اعمل 30 يوم متتالي",
"Social Butterfly": "الفراشة الاجتماعية",
"Refer 5 drivers": "ادعُ 5 سائقين",
"Weekly Earnings": "الأرباح الأسبوعية",
"Monthly Report": "التقرير الشهري",
"Best Day": "أفضل يوم",
"No data yet": "لا توجد بيانات بعد",
"h": "ساعة",
"Trip": "رحلة",
"Rides": "رحلات",
"Hours": "ساعات",
"Total Trips": "إجمالي الرحلات",
"Total Earnings": "إجمالي الأرباح",
"Back to other sign-in options":
"الرجوع لخيارات تسجيل الدخول التانية",
"Bahrain": "البحرين",
@@ -1511,7 +1583,24 @@ class MyTranslation extends Translations {
"The payment was approved.": "تمت الموافقة على الدفع.",
"The payment was not approved. Please try again.":
"ما انقبل الدفع. تفضل جرّب مرة تانية.",
"The period of this code is 1 hour": "مدة هالكود ساعة وحدة",
"The period of this code is 24 hours": "صلاحية هذا الكود هي 24 ساعة",
"Trips": "الرحلات",
"Challenges": "التحديات",
"My Schedule": "جدولي",
"Leaderboard": "لوحة المتصدرين",
"Daily Challenges": "التحديات اليومية",
"Weekly Challenges": "التحديات الأسبوعية",
"Claim Reward": "استلام المكافأة",
"Claimed": "تم الاستلام",
"Earnings": "الأرباح",
"You": "أنت",
"Weekly Plan": "الخطة الأسبوعية",
"Work Days": "أيام العمل",
"Day Off": "يوم عطلة",
"Helping Center": "مركز المساعدة",
"Invite Driver": "دعوة سائق",
"Available for rides": "متاح للرحلات",
"History of Trip": "سجل الرحلات",
"The price may increase if the route changes.":
"السعر ممكن يزيد إذا تغيّر الطريق.",
"The price must be over than": "السعر لازم يكون أكثر من",
@@ -2477,7 +2566,8 @@ class MyTranslation extends Translations {
"Go Now": "اذهب الآن",
"Selected Location": "الموقع المحدد",
"Add Balance": "إضافة رصيد",
"Select how you want to charge your account": "اختر كيف تريد شحن حسابك",
"Select how you want to charge your account":
"اختر كيف تريد شحن حسابك",
"Recharge Balance Packages": "باقات شحن الرصيد",
"Select Payment Method": "اختر طريقة الدفع",
"Amount to charge:": "المبلغ المطلوب شحنه:",
@@ -2495,7 +2585,8 @@ class MyTranslation extends Translations {
"for": "بـ",
"Points": "نقاط",
"Pay from my budget": "الدفع من الرصيد المتاح",
"Use Touch ID or Face ID to confirm payment": "استخدم بصمة الإصبع أو الوجه لتأكيد الدفع",
"Use Touch ID or Face ID to confirm payment":
"استخدم بصمة الإصبع أو الوجه لتأكيد الدفع",
"Your Budget less than needed": "رصيدك أقل من المطلوب",
"Available Balance": "الرصيد المتاح",
"Total Rides": "إجمالي الرحلات",
@@ -2512,7 +2603,8 @@ class MyTranslation extends Translations {
"Driver Balance": "رصيد السائق",
"Pay from my budget": "الدفع من الرصيد المتاح",
"You have in account": "لديك في الحساب",
"Select how you want to charge your account": "اختر كيف تريد شحن حسابك",
"Select how you want to charge your account":
"اختر كيف تريد شحن حسابك",
"Add Balance": "إضافة رصيد",
"SYP": "ل.س",
"Your completed trips will appear here": "ستظهر رحلاتك المكتملة هنا",

View File

@@ -25,7 +25,10 @@ class SettingController extends GetxController {
isDarkMode = !isDarkMode;
box.write('isDarkMode', isDarkMode);
// Update the theme using the LocaleController to ensure correct fonts are used
// Switch theme instantly across the app
Get.changeThemeMode(isDarkMode ? ThemeMode.dark : ThemeMode.light);
// Update the theme using the LocaleController to ensure correct fonts/colors are refreshed
if (Get.isRegistered<LocaleController>()) {
Get.find<LocaleController>().refreshTheme();
}