import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:seshat/domain/models/book.dart'; import 'package:seshat/routing/routes.dart'; import 'package:seshat/ui/add_page/view_model/add_view_model.dart'; import 'package:seshat/ui/add_page/widgets/form_popup.dart'; import 'package:seshat/ui/add_page/widgets/owner_popup.dart'; import 'package:seshat/ui/add_page/widgets/confirmation_popup.dart'; import 'package:seshat/ui/core/ui/navigation_bar.dart'; import 'package:seshat/ui/core/ui/await_loading.dart'; import 'package:seshat/utils/result.dart'; class AddPage extends StatefulWidget { const AddPage({super.key, required this.viewModel}); final AddViewModel viewModel; @override State createState() => _AddPageState(); } class _AddPageState extends State { num? price; final MobileScannerController controller = MobileScannerController( formats: [BarcodeFormat.ean13], detectionTimeoutMs: 1000, ); @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); // return Consumer( // builder: (context, screen, child) { return Scaffold( bottomNavigationBar: AppNavigationBar(startIndex: 1), body: ListenableBuilder( listenable: widget.viewModel, builder: (context, child) => switch (widget.viewModel.isLoaded) { false => AwaitLoading(), true => switch (widget.viewModel.currentBal) { null => Center( child: SizedBox( width: 300, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( "Aucune bal n'est active.", style: TextStyle(fontSize: 25), textAlign: TextAlign.center, ), SizedBox(height: 15), Text( "Vous devez créer puis activer une BAL pour pouvoir scanner des livres.", textAlign: TextAlign.center, ), SizedBox(height: 30), ElevatedButton( onPressed: () { context.go(Routes.home); }, child: Text("Gérer les BALs"), ), ], ), ), ), _ => Stack( children: [ ColoredBox(color: Colors.black), MobileScanner( controller: controller, onDetect: (barcodes) async { if (barcodes.barcodes.isEmpty) { return; } if (widget.viewModel.currentOwner == null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( "Attention : vous devez choisir un·e propriétaire", ), behavior: SnackBarBehavior.floating, ), ); return; } void setPrice(num newPrice) async { setState(() { price = newPrice; }); } Result result = await widget.viewModel.scanBook( barcodes, ); switch (result) { case Ok(): await _confirmationDialogBuilder( context, setPrice, controller, widget.viewModel, result.value, ); break; case Error(): ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Erreur : ${result.error}"), behavior: SnackBarBehavior.floating, ), ); break; } }, ), Center( child: SvgPicture.asset( 'assets/scan-overlay.svg', height: (MediaQuery.sizeOf(context).height / 5) * 2, ), ), SafeArea( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 5), Center( child: Card( margin: EdgeInsets.symmetric(horizontal: 50), child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: Icon(Icons.person), title: TextButton( child: Text( (widget.viewModel.currentOwner == null) ? "Aucun" : "${widget.viewModel.currentOwner!.firstName} ${widget.viewModel.currentOwner!.lastName}", ), onPressed: () => _ownerDialogBuilder( context, controller, widget.viewModel, ), ), ), ListTile( leading: Icon(Icons.attach_money), title: TextButton( child: Text( (widget.viewModel.askPrice) ? "Demander à chaque fois" : "Prix libre toujours", ), onPressed: () { setState(() { widget.viewModel.askPrice = !widget.viewModel.askPrice; }); }, ), ), ], ), ), ), ], ), ), ), SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Center( child: TextButton( style: ButtonStyle( backgroundColor: WidgetStatePropertyAll( theme.cardColor, ), ), onPressed: () { if (widget.viewModel.currentOwner == null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( "Attention : vous devez choisir un·e propriétaire", ), behavior: SnackBarBehavior.floating, ), ); } _formDialogBuilder( context, controller, widget.viewModel, ); }, child: Text("Enregistrer manuellement"), ), ), SizedBox(height: 5), ], ), ), ], ), }, }, ), ); // }, // ); } } Future _confirmationDialogBuilder( BuildContext context, Function(num) setPrice, MobileScannerController controller, AddViewModel viewModel, Book book, ) { controller.stop(); void exitPopup(BuildContext localContext) { Navigator.of(localContext).pop(); controller.start(); } return showDialog( context: context, barrierDismissible: false, builder: (context) => ConfirmationPopup( exitPopup: exitPopup, setPrice: setPrice, viewModel: viewModel, book: book, ), ); } Future _formDialogBuilder( BuildContext context, MobileScannerController controller, AddViewModel viewModel, ) { controller.stop(); void exitPopup(BuildContext localContext) { Navigator.of(localContext).pop(); controller.start(); } return showDialog( context: context, barrierDismissible: false, builder: (context) => FormPopup(viewModel: viewModel, exitPopup: exitPopup), ); } Future _ownerDialogBuilder( BuildContext context, MobileScannerController controller, AddViewModel viewModel, ) { controller.stop(); void onPressAccept(BuildContext localContext) { Navigator.of(localContext).pop(); controller.start(); } return showDialog( context: context, barrierDismissible: false, builder: (context) => OwnerPopup(viewModel: viewModel, onPressAccept: onPressAccept), ); }