Aidra Connect 10.0.2+16
Aidra Connect Mobile Application
Loading...
Searching...
No Matches
emission_tracker_widget.dart
Go to the documentation of this file.
1import '/core/ui/widgets/custom_card.dart';
2import 'package:flutter/material.dart';
3import 'package:fl_chart/fl_chart.dart';
4import 'package:flutter_screenutil/flutter_screenutil.dart';
5
6class EmissionsTracker extends StatelessWidget {
7 final int points;
8 final double emissions;
9 final List<FlSpot> chartData;
11 final Function(int) onCategorySelected;
12
14 super.key,
15 required this.points,
16 required this.emissions,
17 required this.chartData,
18 required this.selectedCategoryIndex,
19 required this.onCategorySelected,
20 });
21
22 @override
23 Widget build(BuildContext context) {
24 return CustomCard(
25 padding: EdgeInsets.all(15.sp),
26 child: Column(
27 crossAxisAlignment: CrossAxisAlignment.start,
28 children: [
29 Row(
30 mainAxisAlignment: MainAxisAlignment.spaceBetween,
31 children: [
32 Column(
33 crossAxisAlignment: CrossAxisAlignment.start,
34 children: [
35 Text(
36 '+$points',
37 style: Theme.of(context).textTheme.bodySmall?.copyWith(
38 fontWeight: FontWeight.bold,
39 ),
40 ),
41 Text(
42 'Points',
43 style: Theme.of(context).textTheme.bodySmall?.copyWith(
44 color: Theme.of(context).hintColor,
45 ),
46 ),
47 ],
48 ),
49 Column(
50 crossAxisAlignment: CrossAxisAlignment.end,
51 children: [
52 Text(
53 '${emissions.toStringAsFixed(0)} kg',
54 style: Theme.of(context).textTheme.bodySmall?.copyWith(
55 fontWeight: FontWeight.bold,
56 ),
57 ),
58 Text(
59 'Emissions',
60 style: Theme.of(context).textTheme.bodySmall?.copyWith(
61 color: Theme.of(context).hintColor,
62 ),
63 ),
64 ],
65 ),
66 ],
67 ),
68
69 const SizedBox(height: 30),
70
71 // Chart
72 SizedBox(
73 height: 100,
74 child: LineChart(
75 LineChartData(
76 gridData: const FlGridData(show: true),
77 titlesData: FlTitlesData(
78 bottomTitles: AxisTitles(
79 sideTitles: SideTitles(
80 showTitles: true,
81 getTitlesWidget: (value, meta) {
82 const months = [
83 'JAN',
84 'FEB',
85 'MAR',
86 'APR',
87 'JUN',
88 'JUL',
89 'AUG',
90 'SEP'
91 ];
92 if (value.toInt() >= 0 &&
93 value.toInt() < months.length) {
94 return Padding(
95 padding: EdgeInsets.only(top: 5.sp),
96 child: Text(
97 months[value.toInt()],
98 style: Theme.of(context)
99 .textTheme
100 .bodySmall
101 ?.copyWith(
102 fontSize: 9.sp,
103 color: Theme.of(context).hintColor,
104 ),
105 ),
106 );
107 }
108 return const Text('');
109 },
110 ),
111 ),
112 leftTitles: const AxisTitles(
113 sideTitles: SideTitles(showTitles: false)),
114 topTitles: const AxisTitles(
115 sideTitles: SideTitles(showTitles: false)),
116 rightTitles: const AxisTitles(
117 sideTitles: SideTitles(showTitles: false)),
118 ),
119 borderData: FlBorderData(show: false),
120 lineBarsData: [
121 LineChartBarData(
122 spots: chartData,
123 isCurved: true,
124 color: Theme.of(context).colorScheme.primary,
125 barWidth: 2,
126 dotData: const FlDotData(show: false),
127 belowBarData: BarAreaData(
128 show: false,
129 ),
130 ),
131 ],
132 ),
133 ),
134 ),
135
136 SizedBox(height: 20.sp),
137
138 // Category Icons
139 SizedBox(
140 height: 60.sp,
141 child: Row(
142 mainAxisAlignment: MainAxisAlignment.spaceAround,
143 children: [
144 _CategoryButton(
145 icon: Icons.bolt,
146 label: 'Energy',
148 onTap: () => onCategorySelected(0),
149 ),
150 _CategoryButton(
151 icon: Icons.restaurant,
152 label: 'Food',
154 onTap: () => onCategorySelected(1),
155 ),
156 _CategoryButton(
157 icon: Icons.delete_outline,
158 label: 'Waste',
160 onTap: () => onCategorySelected(2),
161 ),
162 _CategoryButton(
163 icon: Icons.directions_bus,
164 label: 'Transport',
166 onTap: () => onCategorySelected(3),
167 ),
168 _CategoryButton(
169 icon: Icons.water_drop,
170 label: 'Water',
172 onTap: () => onCategorySelected(4),
173 ),
174 ],
175 ),
176 ),
177 ],
178 ),
179 );
180 }
181}
182
183class _CategoryButton extends StatelessWidget {
184 final IconData icon;
185 final String label;
186 final bool isSelected;
187 final VoidCallback onTap;
188
189 const _CategoryButton({
190 Key? key,
191 required this.icon,
192 required this.label,
193 required this.isSelected,
194 required this.onTap,
195 }) : super(key: key);
196
197 @override
198 Widget build(BuildContext context) {
199 return SizedBox(
200 width: 60.sp,
201 child: ElevatedButton(
202 style: ElevatedButton.styleFrom(
203 padding: EdgeInsets.zero,
205 ? Theme.of(context).colorScheme.secondary
206 : Colors.transparent,
207 ),
208 onPressed: onTap,
209 child: Column(
210 crossAxisAlignment: CrossAxisAlignment.center,
211 mainAxisAlignment: MainAxisAlignment.center,
212 children: [
213 Icon(
214 icon,
216 ? Theme.of(context).colorScheme.onPrimary
217 : Theme.of(context)
218 .textTheme
219 .bodySmall
220 ?.color
221 ?.withOpacity(0.3),
222 ),
223 SizedBox(height: 4.sp),
224 Text(label,
225 style: Theme.of(context).textTheme.bodySmall?.copyWith(
226 fontSize: 10.sp,
228 ? Theme.of(context).colorScheme.onPrimary
229 : Theme.of(context)
230 .textTheme
231 .bodySmall
232 ?.color
233 ?.withOpacity(0.9),
234 )),
235 ],
236 ),
237 ),
238 );
239 }
240}
final List< FlSpot > chartData
final IconData icon
final VoidCallback onTap
const CustomCard({ super.key, required this.child, this.padding, this.bgColor, })
final Function(int) onCategorySelected
final Widget child
override Widget build(BuildContext context)
final String label
const EmissionsTracker({ super.key, required this.points, required this.emissions, required this.chartData, required this.selectedCategoryIndex, required this.onCategorySelected, })
final Widget child
final EdgeInsets padding
final Color backgroundColor
final String label
final VoidCallback onTap
final bool isSelected
final Color color
Definition failures.dart:1
late List< String > months