Final commit.

This commit is contained in:
Dennis Nemec
2026-06-01 17:12:28 +02:00
parent 3ecbc82885
commit a9bf8ecdd1
385 changed files with 29081 additions and 12089 deletions

View File

@ -0,0 +1,87 @@
import 'package:image_picker/image_picker.dart';
/// Die 5 Steps der Auslieferungs-Detail-Page. Reihenfolge ≙ Index.
enum WorkflowStep {
info,
notes,
articles,
services,
summary,
}
extension WorkflowStepX on WorkflowStep {
String get displayName => switch (this) {
WorkflowStep.info => 'Info',
WorkflowStep.notes => 'Notizen',
WorkflowStep.articles => 'Artikel & Gutschriften',
WorkflowStep.services => 'Services',
WorkflowStep.summary => 'Übersicht',
};
/// Kurze Bezeichnung für den Header-Step (Platz ist eng auf Mobilgeräten).
String get shortName => switch (this) {
WorkflowStep.info => 'Info',
WorkflowStep.notes => 'Notizen',
WorkflowStep.articles => 'Artikel',
WorkflowStep.services => 'Services',
WorkflowStep.summary => 'Übersicht',
};
}
/// Eine im Workflow geparkte Bild-Notiz, die noch nicht hochgeladen werden
/// kann — wartet auf den Foto-Upload-Endpoint.
class PendingImageNote {
const PendingImageNote({required this.file, required this.pickedAt});
/// Das vom `image_picker` zurückgegebene File-Handle.
final XFile file;
final DateTime pickedAt;
}
/// State des Detail-Workflows. Ein State, ein Bloc — der Step-Wechsel,
/// die Drafts und die Payment-Auswahl liegen alle hier. So sieht jede
/// Step-Page denselben kohärenten Zustand und ein Step kann Daten aus
/// einem anderen lesen (z. B. Summary liest Article-Drafts).
class DeliveryWorkflowState {
const DeliveryWorkflowState({
required this.deliveryId,
required this.step,
required this.pendingImageNotes,
required this.paymentMethodOverrideId,
});
factory DeliveryWorkflowState.initial(String deliveryId) =>
DeliveryWorkflowState(
deliveryId: deliveryId,
step: WorkflowStep.info,
pendingImageNotes: const [],
paymentMethodOverrideId: null,
);
final String deliveryId;
final WorkflowStep step;
/// Lokal gehaltene Bild-Notizen — solange kein Upload-Endpoint da ist.
final List<PendingImageNote> pendingImageNotes;
/// Wenn der Fahrer im Summary die Zahlungsmethode überschreibt, landet
/// die neue Id hier. `null` = Methode der Lieferung bleibt.
final String? paymentMethodOverrideId;
DeliveryWorkflowState copyWith({
WorkflowStep? step,
List<PendingImageNote>? pendingImageNotes,
Object? paymentMethodOverrideId = _sentinel,
}) {
return DeliveryWorkflowState(
deliveryId: deliveryId,
step: step ?? this.step,
pendingImageNotes: pendingImageNotes ?? this.pendingImageNotes,
paymentMethodOverrideId: identical(paymentMethodOverrideId, _sentinel)
? this.paymentMethodOverrideId
: paymentMethodOverrideId as String?,
);
}
}
const Object _sentinel = Object();