إصلاح أخطاء شاشة الكباتن من تحديث الذكاء الاصطناعي
This commit is contained in:
@@ -515,6 +515,11 @@ class _AdminHomePageState extends State<AdminHomePage>
|
||||
final maxBar = [comfort, speed, lady].reduce((a, b) => a > b ? a : b);
|
||||
final barMaxY = maxBar > 0 ? (maxBar * 1.3).ceilToDouble() : 10.0;
|
||||
|
||||
final payments = (data['payments'] ?? 0).toDouble();
|
||||
final passengerCount = (data['countPassengers'] ?? 0).toDouble();
|
||||
final driverCount = (data['countDriver'] ?? 0).toDouble();
|
||||
final monthRides = (data['countRideThisMonth'] ?? 0).toDouble();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
@@ -697,6 +702,203 @@ class _AdminHomePageState extends State<AdminHomePage>
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
AnimationConfiguration.staggeredList(
|
||||
position: 0,
|
||||
duration: const Duration(milliseconds: 450),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 40.0,
|
||||
child: FadeInAnimation(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: cs.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: cs.outline),
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.account_balance_rounded, color: cs.primary, size: 18),
|
||||
const SizedBox(width: 8),
|
||||
Text('نظرة عامة على الإيرادات', style: TextStyle(color: cs.onSurface, fontSize: 13, fontWeight: FontWeight.w600)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SizedBox(
|
||||
height: 120,
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
alignment: BarChartAlignment.center,
|
||||
maxY: (payments * 1.3) > 0 ? (payments * 1.3) : 10,
|
||||
barTouchData: BarTouchData(
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
getTooltipColor: (_) => cs.surfaceContainerHighest,
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
return BarTooltipItem(
|
||||
_formatCurrency(rod.toY),
|
||||
TextStyle(color: cs.onSurface, fontSize: 11, fontWeight: FontWeight.w600),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
titlesData: FlTitlesData(
|
||||
show: true,
|
||||
topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
leftTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 30,
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 6),
|
||||
child: Text('Payments', style: TextStyle(color: cs.onSurfaceVariant, fontSize: 10)),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
gridData: const FlGridData(show: false),
|
||||
borderData: FlBorderData(show: false),
|
||||
barGroups: [
|
||||
BarChartGroupData(
|
||||
x: 0,
|
||||
barRods: [
|
||||
BarChartRodData(
|
||||
toY: payments,
|
||||
color: cs.primary,
|
||||
width: 40,
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Center(
|
||||
child: Text(
|
||||
'إجمالي المدفوعات: ${_formatCurrency(payments)}',
|
||||
style: TextStyle(color: cs.onSurface, fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
AnimationConfiguration.staggeredList(
|
||||
position: 1,
|
||||
duration: const Duration(milliseconds: 450),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 40.0,
|
||||
child: FadeInAnimation(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: cs.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: cs.outline),
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.compare_arrows_rounded, color: cs.primary, size: 18),
|
||||
const SizedBox(width: 8),
|
||||
Text('نسبة السائقين إلى الركاب', style: TextStyle(color: cs.onSurface, fontSize: 13, fontWeight: FontWeight.w600)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildRatioBar('السائقين', driverCount, driverCount + passengerCount, cs.secondary, cs),
|
||||
const SizedBox(height: 12),
|
||||
_buildRatioBar('الركاب', passengerCount, driverCount + passengerCount, cs.tertiary, cs),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
AnimationConfiguration.staggeredList(
|
||||
position: 2,
|
||||
duration: const Duration(milliseconds: 450),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 40.0,
|
||||
child: FadeInAnimation(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: cs.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: cs.outline),
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
_buildMiniStatCard('رحلات الشهر', monthRides, Icons.calendar_today_rounded, cs.primary, cs),
|
||||
_buildMiniStatCard('الركاب', passengerCount, Icons.group_rounded, cs.tertiary, cs),
|
||||
_buildMiniStatCard('السائقين', driverCount, Icons.drive_eta_rounded, cs.secondary, cs),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildRatioBar(String label, double value, double total, Color color, ColorScheme cs) {
|
||||
final ratio = total > 0 ? value / total : 0.0;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label, style: TextStyle(color: cs.onSurfaceVariant, fontSize: 11)),
|
||||
Text(value.toInt().toString(), style: TextStyle(color: cs.onSurface, fontSize: 12, fontWeight: FontWeight.w600)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: LinearProgressIndicator(
|
||||
value: ratio,
|
||||
backgroundColor: cs.surface,
|
||||
color: color,
|
||||
minHeight: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMiniStatCard(String label, dynamic value, IconData icon, Color color, ColorScheme cs) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withValues(alpha: 0.12),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Icon(icon, color: color, size: 22),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(value.toString(), style: TextStyle(color: cs.onSurface, fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 2),
|
||||
Text(label, style: TextStyle(color: cs.onSurfaceVariant, fontSize: 10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user