import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_bloc.dart'; import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_state.dart'; import 'package:hl_lieferservice/feature/scan/presentation/scan_screen.dart'; import 'package:hl_lieferservice/model/tour.dart'; import 'package:hl_lieferservice/widget/home/bloc/navigation_bloc.dart'; import 'package:hl_lieferservice/widget/home/bloc/navigation_event.dart'; enum TourHomeSteps { planning, delivery, off } class ScanPage extends StatefulWidget { const ScanPage({super.key}); @override State createState() => _ScanPageState(); } class _ScanPageState extends State { int _currentStepIndex = 0; @override void initState() { super.initState(); _tryFinish(context .read() .state); } void _onStartScan() { Navigator.of( context, ).push(MaterialPageRoute(builder: (context) => ArticleScanningScreen())); } Widget _tourSteps(Tour tour) { var allArticlesScanned = tour.deliveries.every( (delivery) => delivery.allArticlesScanned(), ); return Stepper( currentStep: _currentStepIndex, controlsBuilder: (context, details) { if (details.stepIndex == TourHomeSteps.planning.index) { return Container( alignment: Alignment.center, child: Padding( padding: const EdgeInsets.only(top: 15), child: FilledButton.icon( label: const Text("Scannen"), onPressed: _onStartScan, icon: const Icon(Icons.qr_code), ), ), ); } else { return Container( alignment: Alignment.center, child: Padding( padding: const EdgeInsets.only(top: 15), child: FilledButton.icon( label: const Text("Auslieferung starten"), onPressed: allArticlesScanned ? () => context.read().add( NavigateToIndex(index: 1)) : null, icon: const Icon(Icons.local_shipping), ), ), ); } }, onStepContinue: _currentStepIndex >= 1 ? null : () => setState(() { if (_currentStepIndex < 2) { _currentStepIndex += 1; } }), onStepCancel: _currentStepIndex == 0 ? null : () => setState(() { if (_currentStepIndex > 0) { _currentStepIndex -= 1; } }), onStepTapped: (value) => setState(() { if (_currentStepIndex == 1 && allArticlesScanned) { return; } _currentStepIndex = value; }), steps: [ Step( title: Row( children: [ Text( "Fahrzeuge beladen", style: TextStyle( color: allArticlesScanned ? Colors.grey : null, ), ), Padding( padding: const EdgeInsets.only(left: 5), child: !allArticlesScanned ? const Icon( Icons.access_time_filled, color: Colors.orangeAccent, ) : const Icon( Icons.check_circle, color: Colors.lightGreen, ), ), ], ), content: const Column( children: [ Padding( padding: EdgeInsets.only(bottom: 10), child: Icon(Icons.barcode_reader, color: Colors.black), ), Text( "Scannen Sie die Ware, die Sie für die Auslieferungen benötigen.", ), ], ), ), Step( title: const Text("Ausliefern"), content: Container( alignment: Alignment.centerLeft, child: !allArticlesScanned ? const Text( "Scannen Sie erst die benötigte Ware, um die Auslieferungen zu beginnen.", ) : null, ), ), ], ); } Widget _info(Tour tour) { int amountArticles = tour.deliveries.fold( 0, (acc, delivery) => acc + delivery.articles .where((article) => article.scannable) .fold( 0, (amountArticles, article) => amountArticles + article.amount, ), ); int amountCars = tour.driver.cars.length; int amountDeliveries = tour.deliveries.length; return Padding( padding: const EdgeInsets.all(10), child: SizedBox( width: double.infinity, child: Card( color: Theme .of(context) .colorScheme .onSecondary, child: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Padding( padding: const EdgeInsets.only(top: 0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Icon(Icons.archive), Padding( padding: const EdgeInsets.only(left: 5), child: Text("Anzahl Artikel"), ), ], ), Text(amountArticles.toString()), ], ), ), Padding( padding: const EdgeInsets.only(top: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Icon(Icons.local_shipping_outlined), Padding( padding: const EdgeInsets.only(left: 5), child: Text("Anzahl Fahrzeuge"), ), ], ), Text(amountCars.toString()), ], ), ), Padding( padding: const EdgeInsets.only(top: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Icon(Icons.person), Padding( padding: const EdgeInsets.only(left: 5), child: Text("Anzahl Lieferungen"), ), ], ), Text(amountDeliveries.toString()), ], ), ), ], ), ), ), ), ); } void _tryFinish(TourState state) { if (state is TourLoaded) { if (state.tour.deliveries.every( (delivery) => delivery.allArticlesScanned(), )) { setState(() { _currentStepIndex = 1; }); } } } @override Widget build(BuildContext context) { return BlocConsumer( listener: (context, state) { _tryFinish(state); }, builder: (context, state) { if (state is TourLoaded) { return Column(children: [_info(state.tour), _tourSteps(state.tour)]); } return Center(child: CircularProgressIndicator()); }, ); } }