From da74308bad884cd59318c36788609355c09c688b Mon Sep 17 00:00:00 2001 From: alexis Date: Sat, 11 Jul 2026 22:13:51 +0200 Subject: [PATCH] budget screen: dynamic month display, editable budget amounts (tap to set) --- lib/screens/budget_screen.dart | 62 ++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/lib/screens/budget_screen.dart b/lib/screens/budget_screen.dart index 0dcff66..c69e770 100644 --- a/lib/screens/budget_screen.dart +++ b/lib/screens/budget_screen.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../providers/db_provider.dart'; import '../theme/app_theme.dart'; +import 'package:drift/drift.dart' show Value; +import '../data/db.dart'; class BudgetScreen extends ConsumerWidget { const BudgetScreen({super.key}); @@ -10,6 +12,9 @@ class BudgetScreen extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final groups = ref.watch(categoryGroupsProvider).valueOrNull ?? []; final catsByGroup = ref.watch(categoriesByGroupProvider); + final now = DateTime.now(); + final months = ['', 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']; + final monthLabel = '${months[now.month]} ${now.year}'; return ListView( padding: const EdgeInsets.fromLTRB(16, 8, 16, 90), @@ -22,7 +27,7 @@ class BudgetScreen extends ConsumerWidget { children: [ Text('Budget du mois', style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: 4), - Text('Juillet 2026', style: Theme.of(context).textTheme.bodySmall), + Text(monthLabel, style: Theme.of(context).textTheme.bodySmall), ], ), ), @@ -106,6 +111,51 @@ class _CategoryRow extends ConsumerWidget { final remaining = ref.watch(categoryRemainingProvider(categoryId)); final pct = budgeted > 0 ? ((budgeted + spent) / budgeted).clamp(0.0, 1.0) : 0.0; + void _editBudget() async { + final month = ref.read(currentMonthProvider); + final db = ref.read(dbProvider); + final ctrl = TextEditingController(text: budgeted > 0 ? budgeted.toStringAsFixed(2) : ''); + + final newAmount = await showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text('Budget : ${category.name}'), + content: TextField( + controller: ctrl, + decoration: const InputDecoration(labelText: 'Montant', hintText: '0,00'), + keyboardType: const TextInputType.numberWithOptions(decimal: true), + autofocus: true, + ), + actions: [ + TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Annuler')), + FilledButton( + onPressed: () { + final v = double.tryParse(ctrl.text.trim().replaceAll(',', '.')); + if (v != null) Navigator.pop(ctx, v); + }, + child: const Text('Enregistrer'), + ), + ], + ), + ); + ctrl.dispose(); + + if (newAmount == null) return; + final existing = await (db.select(db.budgets) + ..where((b) => b.categoryId.equals(categoryId)) + ..where((b) => b.month.equals(month))) + .get(); + if (existing.isNotEmpty) { + await db.update(db.budgets).replace(existing.first.copyWith(budgeted: newAmount)); + } else { + await db.into(db.budgets).insert(BudgetsCompanion.insert( + categoryId: categoryId, + month: month, + budgeted: Value(newAmount), + )); + } + } + return Padding( padding: const EdgeInsets.only(left: 8, bottom: 4), child: Card( @@ -144,8 +194,14 @@ class _CategoryRow extends ConsumerWidget { const SizedBox(height: 2), Row( children: [ - Text('Budget: ${formatCurrency(budgeted)}', - style: Theme.of(context).textTheme.bodySmall), + GestureDetector( + onTap: _editBudget, + child: Text('Budget: ${formatCurrency(budgeted)}', + style: Theme.of(context).textTheme.bodySmall?.copyWith( + decoration: TextDecoration.underline, + color: Theme.of(context).colorScheme.primary, + )), + ), const SizedBox(width: 12), Text('Dépensé: ${formatCurrency(spent.abs())}', style: Theme.of(context).textTheme.bodySmall),