Inventur aller Lese-Requests (Tour, Fahrzeuge, Zahlungsmethoden,
Foto-Vorschauen) und aller Stellen, an denen ihr Fehlerzustand gerendert wird.
Geschlossene Luecken:
- Sortieren-Seite: TourLoadFailed fiel in den Lade-Zweig -> Endlos-Spinner
ohne Ausweg. Jetzt Fehlerseite mit 'Erneut versuchen' im Header-Rahmen
- Home: scheiterte beim Start CarLoad oder LoadTour, wurde die Phase nie
geladen -> Endlos-Spinner. Jetzt Fehlerseite mit Retry (+ Drawer)
- Beladen-/Auswaehlen-Seite: Fehlerseite stand ohne Scaffold/Header/Drawer
da; jetzt im selben Rahmen wie die uebrigen Zustaende
- Hintergrund-Reload (refreshError): Snackbar jetzt MIT Retry-Aktion und
zentral im PhaseStepper-Header -> gilt in allen Phasen (vorher nur
Ausliefern, ohne Retry; auf Sortieren/Beladen blieb der Fehler stumm)
- AttachmentImage: Fehleranzeige ist antippbar ('Erneut laden')
Zahlungsmethoden haben den Retry bereits aus dem vorigen Commit.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
107 lines
3.8 KiB
Dart
107 lines
3.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:hl_lieferservice/domain/entity/tour_details.dart';
|
|
import 'package:hl_lieferservice/feature/car_selection/bloc/bloc.dart';
|
|
import 'package:hl_lieferservice/feature/car_selection/bloc/state.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/bloc/tour_bloc.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/bloc/tour_event.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/bloc/tour_state.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/model/delivery_phase.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/overview/presentation/delivery_fail_page.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/overview/presentation/delivery_overview.dart';
|
|
import 'package:hl_lieferservice/widget/home/presentation/home_drawer.dart';
|
|
import 'package:hl_lieferservice/widget/phase_stepper/phase_stepper.dart';
|
|
|
|
/// Inhalt der Phase "Ausliefern". Sortieren und Beladen werden über eigene
|
|
/// Pages und das Phasen-Routing in `Home` gerendert — diese Page übernimmt
|
|
/// nur noch die letzte Phase. Der Phasen-Stepper bleibt sichtbar, damit der
|
|
/// Fahrer bei Bedarf zurückspringen kann; das BottomNav der Auslieferung
|
|
/// liegt im umgebenden `Home`-Scaffold.
|
|
class DeliveryOverviewPage extends StatelessWidget {
|
|
const DeliveryOverviewPage({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final carState = context.watch<CarSelectBloc>().state;
|
|
final carId =
|
|
carState is CarSelectComplete ? carState.selectedCar.id : '';
|
|
|
|
return Scaffold(
|
|
drawer: const HomeAppDrawer(),
|
|
appBar: PreferredSize(
|
|
preferredSize: const Size.fromHeight(140),
|
|
child: PhaseStepper(
|
|
currentPhase: DeliveryPhase.ausliefern,
|
|
carId: carId,
|
|
),
|
|
),
|
|
// Die Refresh-Fehler-Snackbar (inkl. Retry) sitzt zentral im
|
|
// PhaseStepper-Header (`_ReloadButton`) und gilt damit für alle Phasen.
|
|
body: BlocBuilder<TourBloc, TourState>(
|
|
builder: (context, state) {
|
|
switch (state) {
|
|
case TourLoaded(:final details):
|
|
return _OverviewBody(details: details);
|
|
case TourEmpty():
|
|
return const _EmptyTourBody();
|
|
case TourLoadFailed():
|
|
return const DeliveryLoadingFailedPage();
|
|
case TourInitial():
|
|
case TourLoading():
|
|
return const Center(child: CircularProgressIndicator());
|
|
}
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _OverviewBody extends StatelessWidget {
|
|
const _OverviewBody({required this.details});
|
|
|
|
final TourDetails details;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return RefreshIndicator(
|
|
onRefresh: () async {
|
|
context.read<TourBloc>().add(const RefreshTour());
|
|
},
|
|
child: DeliveryOverview(details: details),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _EmptyTourBody extends StatelessWidget {
|
|
const _EmptyTourBody();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// Wenn der ERP-Sync für heute keine Tour gemeldet hat, ist das ein
|
|
// normaler Zustand — kein Fehler. UX-Hinweis und Pull-to-refresh.
|
|
return RefreshIndicator(
|
|
onRefresh: () async {
|
|
context.read<TourBloc>().add(const RefreshTour());
|
|
},
|
|
child: ListView(
|
|
children: const [
|
|
SizedBox(height: 120),
|
|
Icon(Icons.event_busy, size: 64, color: Colors.grey),
|
|
SizedBox(height: 16),
|
|
Center(
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 32),
|
|
child: Text(
|
|
'Für heute ist keine Tour zugewiesen.\n'
|
|
'Zum Aktualisieren nach unten ziehen.',
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(fontSize: 16),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|