From ba84e4ea01b30aab55639ad70669c7208555d550 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Sat, 12 Sep 2026 14:05:47 +0200 Subject: [PATCH] Ort zuordnen: Karte zeigt, was man da in der Hand haelt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bisher stand dort nur "Einzelstück R9D55SDC". Die UID sagt aber nichts darueber, welches Stueck das ist - gerade bei Kleidung, wo das NFC-Tag eingenaeht und unsichtbar ist. Unter dem Sucher lag dafuer die halbe Seite ungenutzt. Die Karte zeigt jetzt Vorschaubild, Artikelname, Marke und die Notiz, darunter als beschriftete Zeilen die Einzelstuecknummer und den aktuellen Lagerort. Der Ort ist beim Zuordnen die nuetzlichste Angabe ueberhaupt: man sieht sofort, ob das Stueck schon irgendwo liegt. Der Block war mit 50 Zeilen zu gross fuer den ohnehin langen body und steht jetzt als EinzelstueckKarte fuer sich. ProductThumb bekommt dafuer einen Groessenparameter (Vorgabe 34 wie bisher, also keine Aenderung an den Listen) und bei grossen Bildern einen passenderen Eckenradius und ein groesseres Ersatzsymbol. Co-Authored-By: Claude Opus 5 --- ios/Sources/AssignScanView.swift | 72 +++++++++++++++++++++++++----- ios/Sources/ProductPhotoView.swift | 12 +++-- 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/ios/Sources/AssignScanView.swift b/ios/Sources/AssignScanView.swift index 4a598d8..f506658 100644 --- a/ios/Sources/AssignScanView.swift +++ b/ios/Sources/AssignScanView.swift @@ -24,16 +24,7 @@ struct AssignScanView: View { .padding(.horizontal) if let pending { - VStack(spacing: 4) { - Text("Einzelstück \(pending.uid)").font(.headline) - Text("Jetzt den Lagerort-QR scannen") - .font(.caption).foregroundStyle(.secondary) - Button("Abbrechen") { self.pending = nil } - .font(.caption).padding(.top, 2) - } - .padding().frame(maxWidth: .infinity) - .background(Color.marke.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 12)).padding(.horizontal) + EinzelstueckKarte(item: pending) { self.pending = nil } } else { VStack(spacing: 8) { Text("Schritt 1: Einzelstück-QR scannen – oder ohne Code:") @@ -125,6 +116,67 @@ struct AssignScanView: View { } } +/// Was gerade in der Hand liegt und auf einen Lagerort wartet. +/// +/// Die UID allein sagt nichts darueber, was man da haelt - gerade bei Kleidung, +/// wo das NFC-Tag eingenaeht und unsichtbar ist. Unter dem Sucher ist reichlich +/// Platz, also zeigt die Karte Bild, Name, Marke und den aktuellen Ort. +private struct EinzelstueckKarte: View { + let item: Item + var onAbbrechen: () -> Void + + var body: some View { + VStack(alignment: .leading, spacing: 10) { + HStack(alignment: .top, spacing: 12) { + ProductThumb(productId: item.productId, groesse: 64) + VStack(alignment: .leading, spacing: 3) { + Text(item.productName ?? "Unbekannter Artikel") + .font(.headline) + if let marke = item.productBrand, !marke.isEmpty { + Text(marke).font(.subheadline).foregroundStyle(.secondary) + } + if let notiz = item.note, !notiz.isEmpty { + Text(notiz).font(.caption).foregroundStyle(.secondary).lineLimit(2) + } + } + Spacer(minLength: 0) + } + + Divider() + + zeile("Einzelstücknummer") { + Text(item.uid).font(.callout.monospaced()) + } + zeile("Derzeit") { + Text(item.locationName ?? "ohne Lagerort").multilineTextAlignment(.trailing) + } + + Divider() + + HStack { + Text("Jetzt den Lagerort-QR scannen") + .font(.caption).foregroundStyle(.secondary) + Spacer() + Button("Abbrechen", action: onAbbrechen).font(.caption) + } + } + .padding().frame(maxWidth: .infinity) + .background(Color.marke.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 12)).padding(.horizontal) + } + + private func zeile( + _ titel: String, @ViewBuilder inhalt: () -> Inhalt + ) -> some View { + HStack { + Text(titel).foregroundStyle(.secondary) + Spacer() + inhalt() + } + .font(.callout) + } +} + /// Einzelstück aus einer durchsuchbaren Liste wählen – für Stücke ohne eigenen QR. struct ItemPickerSheet: View { var onPick: (Item) -> Void diff --git a/ios/Sources/ProductPhotoView.swift b/ios/Sources/ProductPhotoView.swift index 1081d38..d67c13d 100644 --- a/ios/Sources/ProductPhotoView.swift +++ b/ios/Sources/ProductPhotoView.swift @@ -93,11 +93,14 @@ final class ProductImageCache { /// Kästchen-Symbol wie bisher. Ergebnisse kommen aus dem gemeinsamen Cache. struct ProductThumb: View { let productId: Int + /// Kantenlaenge. Listen lassen sie weg; wo mehr Platz ist (Ort zuordnen), + /// hilft ein groesseres Bild beim Wiedererkennen. + var groesse: CGFloat = 34 @State private var image: UIImage? var body: some View { content - .frame(width: 34, height: 34) + .frame(width: groesse, height: groesse) .task(id: productId) { await load() } } @@ -105,11 +108,12 @@ struct ProductThumb: View { if let image { Image(uiImage: image) .resizable().scaledToFill() - .frame(width: 34, height: 34) - .clipShape(RoundedRectangle(cornerRadius: 6)) + .frame(width: groesse, height: groesse) + .clipShape(RoundedRectangle(cornerRadius: groesse > 48 ? 10 : 6)) } else { Image(systemName: "shippingbox") - .font(.body).foregroundStyle(.secondary) + .font(groesse > 48 ? .largeTitle : .body) + .foregroundStyle(.secondary) } }