iOS: getrennte Lebensmittel/Gegenstaende-Listen + anklickbarer Verlauf
Listen-Tab: zwei halbe Kacheln "Lebensmittel" und "Gegenstaende" (ProductListView mit fixedType, clientseitig ueber isObject gefiltert wie im Web); Neuanlage uebernimmt den Typ. Einzelstuecke bleiben unveraendert (reine Gegenstands-Welt). Verlauf und "Letzte Bewegungen" auf der Startseite: Tippen auf eine Bewegung oeffnet ueber den neuen Lader ProductByIdView das jeweilige Produkt. Der artikel-eigene Verlauf bleibt ohne Link. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -191,6 +191,10 @@ struct ExpiringView: View {
|
||||
// MARK: - Produktliste
|
||||
|
||||
struct ProductListView: View {
|
||||
/// nil = alle, "food" = nur Lebensmittel, "object" = nur Gegenstände.
|
||||
/// Getrennte Listen wie im Web (dort über `fixedType`/`p.tracking`).
|
||||
var fixedType: String? = nil
|
||||
|
||||
@EnvironmentObject private var session: Session
|
||||
@State private var query = ""
|
||||
@State private var products: [Product] = []
|
||||
@@ -200,6 +204,20 @@ struct ProductListView: View {
|
||||
@State private var busy = false
|
||||
@State private var showNew = false
|
||||
|
||||
/// Auf den festen Typ gefiltert (clientseitig, wie im Web).
|
||||
private var sichtbar: [Product] {
|
||||
guard let fixedType else { return products }
|
||||
return products.filter { ($0.isObject ? "object" : "food") == fixedType }
|
||||
}
|
||||
|
||||
private var titel: String {
|
||||
switch fixedType {
|
||||
case "food": return "Lebensmittel"
|
||||
case "object": return "Gegenstände"
|
||||
default: return "Produkte"
|
||||
}
|
||||
}
|
||||
|
||||
private var filterLabel: String {
|
||||
if categoryId == 0 { return "Ohne Kategorie" }
|
||||
if let id = categoryId, let treffer = categories.first(where: { $0.id == id }) {
|
||||
@@ -228,21 +246,21 @@ struct ProductListView: View {
|
||||
}
|
||||
|
||||
Section {
|
||||
ForEach(products) { product in
|
||||
ForEach(sichtbar) { product in
|
||||
NavigationLink {
|
||||
ProductDetailView(product: product)
|
||||
} label: {
|
||||
ProductRow(product: product)
|
||||
}
|
||||
}
|
||||
if products.isEmpty && !busy {
|
||||
if sichtbar.isEmpty && !busy {
|
||||
Text("Keine Treffer").foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
.searchable(text: $query, prompt: "Artikel suchen")
|
||||
.onChange(of: query) { _ in Task { await load() } }
|
||||
.navigationTitle("Produkte")
|
||||
.navigationTitle(titel)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.refreshable { await load() }
|
||||
.toolbar {
|
||||
@@ -256,9 +274,10 @@ struct ProductListView: View {
|
||||
}
|
||||
.sheet(isPresented: $showNew) {
|
||||
NavigationStack {
|
||||
// Ohne Barcode: nur Name + Kategorie nötig. Nach dem Anlegen
|
||||
// schließt sich das Formular und die Liste wird aufgefrischt.
|
||||
ProductFormView(prefillBarcode: nil, groupId: nil) { _ in
|
||||
// Ohne Barcode: nur Name + Kategorie nötig. Typ aus der Liste
|
||||
// vorbelegen. Nach dem Anlegen schließt sich das Formular und die
|
||||
// Liste wird aufgefrischt.
|
||||
ProductFormView(prefillBarcode: nil, groupId: nil, initialType: fixedType) { _ in
|
||||
showNew = false
|
||||
Task { await load() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user