import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:calorimeter/utils/scan_food_floating_button.dart'; import 'package:calorimeter/utils/app_drawer.dart'; import 'package:calorimeter/food_entry/food_entry_bloc.dart'; import 'package:calorimeter/perdate/entry_list.dart'; import 'package:calorimeter/storage/storage.dart'; import 'package:calorimeter/utils/calendar_floating_button.dart'; import 'package:calorimeter/utils/rectangular_notch_shape.dart'; import 'package:calorimeter/utils/sum_widget.dart'; import 'package:calorimeter/utils/theme_switcher_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; class PerDateWidget extends StatefulWidget { final DateTime date; final Function(DateTime?) onDateSelected; const PerDateWidget( {super.key, required this.date, required this.onDateSelected}); @override State createState() => _PerDateWidgetState(); } class _PerDateWidgetState extends State with AutomaticKeepAliveClientMixin { late FoodStorage storage; late Future> entriesFuture; List entries = []; @override void initState() { storage = FoodStorage.getInstance(); entriesFuture = storage.getEntriesForDate(widget.date); entriesFuture.then((val) { entries = val; }); super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { super.build(context); return FutureBuilder( future: entriesFuture, builder: (context, snapshot) { return snapshot.connectionState != ConnectionState.done ? const Center(child: CircularProgressIndicator()) : MultiProvider( providers: [ BlocProvider( create: (context) => FoodEntryBloc( initialState: PageState(foodEntries: entries), storage: storage, forDate: widget.date, ), ) ], child: BlocConsumer( listener: (context, pageState) { if (pageState.errorString != null) { showNewSnackbarWith(context, pageState.errorString!); } }, builder: (context, pageState) { return Scaffold( appBar: AppBar( title: Text( DateFormat.yMMMMd('de').format(widget.date)), actions: const [ThemeSwitcherButton()], ), body: FoodEntryList(entries: pageState.foodEntries), bottomNavigationBar: BottomAppBar( shape: const RectangularNotchShape(), color: Theme.of(context).colorScheme.secondary, child: SumWidget( foodEntries: pageState.foodEntries)), drawer: const AppDrawer(), floatingActionButton: OverflowBar(children: [ ScanFoodFloatingButton( onPressed: () { var result = BarcodeScanner.scan(); context.read().add( BarcodeScanned(scanResultFuture: result)); }, ), const SizedBox(width: 8), CalendarFloatingButton( startFromDate: widget.date, onDateSelected: (dateSelected) { widget.onDateSelected(dateSelected); }, ), ]), floatingActionButtonLocation: FloatingActionButtonLocation.endDocked); }, ), ); }); } void showNewSnackbarWith(BuildContext context, String text) { var snackbar = ErrorSnackbar(colorScheme: Theme.of(context).colorScheme, text: text); ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(snackbar); } @override bool get wantKeepAlive => true; } class ErrorSnackbar extends SnackBar { final String text; final ColorScheme colorScheme; ErrorSnackbar({ required this.text, required this.colorScheme, super.key, }) : super( content: Text(text, style: TextStyle(color: colorScheme.onError)), backgroundColor: colorScheme.error); }