Files
intaleq_driver/lib/views/home/statistics/widgets/monthly_chart_widget.dart

100 lines
5.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:fl_chart/fl_chart.dart';
import '../../../../constant/finance_design_system.dart';
import '../../../../controller/home/statistics/statistics_controller.dart';
class MonthlyChartWidget extends StatelessWidget {
const MonthlyChartWidget({super.key});
@override
Widget build(BuildContext context) {
return GetBuilder<StatisticsController>(
builder: (sc) {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(FinanceDesignSystem.cardRadius),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 10, offset: const Offset(0, 4))],
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text('Monthly Report'.tr, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: FinanceDesignSystem.primaryDark)),
const SizedBox(height: 16),
// Summary Row
Row(children: [
_summaryTile('Total Earnings'.tr, '${sc.monthlyTotalEarnings.toStringAsFixed(0)} ${'SYP'.tr}', FinanceDesignSystem.successGreen),
const SizedBox(width: 12),
_summaryTile('Total Trips'.tr, '${sc.monthlyTotalTrips}', FinanceDesignSystem.accentBlue),
const SizedBox(width: 12),
_summaryTile('Best Day'.tr, '${sc.bestDay}', const Color(0xFFFFD700)),
]),
const SizedBox(height: 20),
// Monthly Earnings Line Chart
SizedBox(
height: 200,
child: sc.monthlyEarnings.isEmpty
? Center(child: Text('No data yet'.tr, style: TextStyle(color: Colors.grey.shade400)))
: LineChart(LineChartData(
lineTouchData: LineTouchData(
enabled: true,
touchTooltipData: LineTouchTooltipData(
getTooltipItems: (spots) => spots.map((s) => LineTooltipItem(
'${s.y.toStringAsFixed(0)} ${'SYP'.tr}',
const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12),
)).toList(),
),
),
gridData: FlGridData(show: true, drawVerticalLine: false,
getDrawingHorizontalLine: (v) => FlLine(color: Colors.grey.shade100, strokeWidth: 1),
),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(sideTitles: SideTitles(showTitles: true, interval: 5,
getTitlesWidget: (v, m) => Padding(padding: const EdgeInsets.only(top: 8),
child: Text('${v.toInt()}', style: TextStyle(fontSize: 10, color: Colors.grey.shade500)),
),
)),
leftTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
),
borderData: FlBorderData(show: false),
lineBarsData: [
LineChartBarData(
spots: sc.monthlyEarnings.map((e) => FlSpot(e.day.toDouble(), e.pricePerDay)).toList(),
isCurved: true, curveSmoothness: 0.3,
color: FinanceDesignSystem.accentBlue, barWidth: 3,
dotData: FlDotData(show: true, getDotPainter: (s, p, d, i) =>
FlDotCirclePainter(radius: 3, color: FinanceDesignSystem.accentBlue, strokeWidth: 1, strokeColor: Colors.white),
),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter,
colors: [FinanceDesignSystem.accentBlue.withOpacity(0.2), FinanceDesignSystem.accentBlue.withOpacity(0.0)],
),
),
),
],
)),
),
]),
);
},
);
}
Widget _summaryTile(String label, String value, Color color) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(color: color.withOpacity(0.08), borderRadius: BorderRadius.circular(12)),
child: Column(children: [
Text(value, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w800, color: color)),
const SizedBox(height: 2),
Text(label, style: TextStyle(fontSize: 9, color: Colors.grey.shade600), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis),
]),
),
);
}
}