160 lines
6.6 KiB
Dart
160 lines
6.6 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: FinanceDesignSystem.cardColor,
|
|
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: 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: FinanceDesignSystem.borderColor,
|
|
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: FinanceDesignSystem.textSecondary)),
|
|
),
|
|
)),
|
|
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: FinanceDesignSystem.textSecondary),
|
|
textAlign: TextAlign.center,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis),
|
|
]),
|
|
),
|
|
);
|
|
}
|
|
}
|