@@ -10,6 +10,7 @@ import 'package:kitchenowl/models/expense.dart';
10
10
import 'package:kitchenowl/models/household.dart' ;
11
11
import 'package:kitchenowl/pages/expense_add_update_page.dart' ;
12
12
import 'package:kitchenowl/pages/expense_month_list_page.dart' ;
13
+ import 'package:kitchenowl/styles/colors.dart' ;
13
14
import 'package:kitchenowl/widgets/chart_bar_member_distribution.dart' ;
14
15
import 'package:kitchenowl/widgets/chart_bar_months.dart' ;
15
16
import 'package:kitchenowl/widgets/chart_line_current_month.dart' ;
@@ -93,7 +94,9 @@ class _ExpenseOverviewPageState extends State<ExpenseOverviewPage> {
93
94
94
95
final totalForSelectedMonth =
95
96
state.getTotalForMonth (state.selectedMonthIndex);
96
- final expenseTotalForSelectedMonth =
97
+ final totalIncomeForSelectedMonth =
98
+ state.getIncomeTotalForMonth (state.selectedMonthIndex);
99
+ final totalExpensesForSelectedMonth =
97
100
state.getExpenseTotalForMonth (state.selectedMonthIndex);
98
101
99
102
return CustomScrollView (
@@ -150,34 +153,117 @@ class _ExpenseOverviewPageState extends State<ExpenseOverviewPage> {
150
153
),
151
154
),
152
155
const SizedBox (height: 32 ),
153
- Row (
154
- children: [
155
- Expanded (
156
- child: Text (
156
+ ExpansionTile (
157
+ tilePadding: EdgeInsets .zero,
158
+ childrenPadding: EdgeInsets .zero,
159
+ title: Card (
160
+ elevation: 3 ,
161
+ child: ListTile (
162
+ title: Text (
157
163
AppLocalizations .of (context)!
158
164
.expenseOverviewTotalTitle (
159
165
_monthOffsetToString (state.selectedMonthIndex),
160
166
),
161
167
style: Theme .of (context).textTheme.titleMedium,
162
168
),
169
+ trailing: Row (
170
+ crossAxisAlignment: CrossAxisAlignment .center,
171
+ mainAxisSize: MainAxisSize .min,
172
+ children: [
173
+ Icon (
174
+ state.trendUp (totalForSelectedMonth,
175
+ state.getAverageForLastMonths (6 ))
176
+ ? Icons .trending_up_rounded
177
+ : Icons .trending_down_rounded,
178
+ ),
179
+ SizedBox (width: 8 ),
180
+ Text (
181
+ NumberFormat .simpleCurrency ()
182
+ .format (totalForSelectedMonth.abs ()),
183
+ style: Theme .of (context)
184
+ .textTheme
185
+ .titleLarge
186
+ ? .copyWith (
187
+ color: totalForSelectedMonth < 0
188
+ ? Theme .of (context)
189
+ .colorScheme
190
+ .error
191
+ : AppColors .green,
192
+ ),
193
+ ),
194
+ if (state
195
+ .getAverageForLastMonths (6 )
196
+ .isFinite) ...[
197
+ SizedBox (width: 8 ),
198
+ Text (
199
+ "⌀ ${NumberFormat .simpleCurrency ().format (state .getAverageForLastMonths (6 ))}" ,
200
+ style: Theme .of (context)
201
+ .textTheme
202
+ .bodyMedium
203
+ ? .copyWith (
204
+ color: Theme .of (context)
205
+ .colorScheme
206
+ .onSurface
207
+ .withOpacity (0.6 ),
208
+ ),
209
+ ),
210
+ ],
211
+ ],
212
+ ),
163
213
),
164
- Icon (state.trendUp (totalForSelectedMonth,
165
- state.getAverageForLastMonths (6 ))
166
- ? Icons .trending_up_rounded
167
- : Icons .trending_down_rounded),
168
- Text (
169
- " ${NumberFormat .simpleCurrency ().format (
170
- totalForSelectedMonth ,
171
- )}" ,
172
- style: Theme .of (context).textTheme.titleMedium,
173
- ),
174
- if (state.getAverageForLastMonths (6 ).isFinite)
175
- Text (
176
- " ⌀ ${NumberFormat .simpleCurrency ().format (
177
- state .getAverageForLastMonths (6 ),
178
- )}" ,
179
- style: Theme .of (context).textTheme.titleMedium,
214
+ ),
215
+ children: [
216
+ Card (
217
+ child: Column (
218
+ children: [
219
+ ListTile (
220
+ leading: Icon (Icons .add_circle_outline,
221
+ color: AppColors .green),
222
+ title: Text (
223
+ AppLocalizations .of (context)! .income,
224
+ style:
225
+ Theme .of (context).textTheme.bodyMedium,
226
+ ),
227
+ trailing: Text (
228
+ NumberFormat .simpleCurrency ().format (
229
+ totalIncomeForSelectedMonth.abs ()),
230
+ style: Theme .of (context)
231
+ .textTheme
232
+ .bodyMedium
233
+ ? .copyWith (
234
+ color: AppColors .green,
235
+ fontWeight: FontWeight .w500,
236
+ ),
237
+ ),
238
+ ),
239
+ Divider (thickness: 1 ),
240
+ ListTile (
241
+ leading: Icon (Icons .remove_circle_outline,
242
+ color:
243
+ Theme .of (context).colorScheme.error),
244
+ title: Text (
245
+ AppLocalizations .of (context)!
246
+ .expenseOverviewExpenses,
247
+ style:
248
+ Theme .of (context).textTheme.bodyMedium,
249
+ ),
250
+ trailing: Text (
251
+ NumberFormat .simpleCurrency ()
252
+ .format (totalExpensesForSelectedMonth),
253
+ style: Theme .of (context)
254
+ .textTheme
255
+ .bodyMedium
256
+ ? .copyWith (
257
+ color: Theme .of (context)
258
+ .colorScheme
259
+ .error,
260
+ fontWeight: FontWeight .w500,
261
+ ),
262
+ ),
263
+ ),
264
+ ],
180
265
),
266
+ ),
181
267
],
182
268
),
183
269
if (state.monthOverview[state.selectedMonthIndex] != null )
@@ -212,6 +298,8 @@ class _ExpenseOverviewPageState extends State<ExpenseOverviewPage> {
212
298
.sorted ((a, b) => b.value.compareTo (a.value))
213
299
.elementAt (i);
214
300
final amount = entry.value;
301
+ final amountPercentage =
302
+ state.getTransactionAmountPercentage (amount);
215
303
final category = entry.key < 0
216
304
? null
217
305
: state.categories
@@ -220,10 +308,9 @@ class _ExpenseOverviewPageState extends State<ExpenseOverviewPage> {
220
308
return Card (
221
309
child: ListTile (
222
310
leading: Padding (
223
- padding:
224
- (amount / expenseTotalForSelectedMonth >= 0 )
225
- ? EdgeInsets .zero
226
- : const EdgeInsets .all (4.0 ),
311
+ padding: (amountPercentage > 0 )
312
+ ? EdgeInsets .zero
313
+ : const EdgeInsets .all (4.0 ),
227
314
child: ExpenseCategoryIcon (
228
315
name: category? .name ?? '🪙' ,
229
316
color: category? .color,
@@ -234,11 +321,10 @@ class _ExpenseOverviewPageState extends State<ExpenseOverviewPage> {
234
321
trailing: Text (
235
322
NumberFormat .simpleCurrency ().format (amount),
236
323
),
237
- subtitle:
238
- (amount / expenseTotalForSelectedMonth >= 0 )
239
- ? Text (NumberFormat .percentPattern ().format (
240
- amount / expenseTotalForSelectedMonth))
241
- : null ,
324
+ subtitle: (amountPercentage > 0 )
325
+ ? Text (NumberFormat .percentPattern ()
326
+ .format (amountPercentage))
327
+ : null ,
242
328
onTap: () => Navigator .of (context).push (
243
329
MaterialPageRoute (
244
330
builder: (context) => ExpenseMonthListPage (
0 commit comments