import SwiftUI /// Der Hinweis über einer Liste, deren Daten aus dem Zwischenspeicher kommen. /// /// Wichtiger als er aussieht: Ohne ihn zeigt die App im Flugmodus alte Zahlen, /// die aussehen wie frische. Mit Datum, weil „offline" allein nicht sagt, ob /// der Stand von vor fünf Minuten oder von vor drei Wochen ist. struct StandHinweis: View { let geholtAm: Date var body: some View { Label { Text(String(format: String(localized: "stand.hinweis"), geholtAm.formatted(.relative(presentation: .named)))) } icon: { Image(systemName: "wifi.slash") } .font(.footnote) .foregroundStyle(.secondary) .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal) .padding(.vertical, 6) .background(.quaternary.opacity(0.4)) } } /// Wenn gar nichts da ist: Fehler zeigen und, wo es Sinn ergibt, einen /// Knopf zum Nochmalversuchen. struct FehlerAnsicht: View { let fehler: APIFehler var nochmal: (() -> Void)? var body: some View { ContentUnavailableView { Label(String(localized: "fehler.titel"), systemImage: symbol) } description: { Text(fehler.errorDescription ?? String(localized: "fehler.unbekannt")) } actions: { if let nochmal, fehler.lohntWiederholung { Button(String(localized: "allgemein.nochmal"), action: nochmal) .buttonStyle(.borderedProminent) } } } private var symbol: String { switch fehler { case .keineVerbindung: return "wifi.slash" case .nichtAngemeldet: return "person.crop.circle.badge.exclamationmark" case .nichtGefunden: return "questionmark.folder" default: return "exclamationmark.triangle" } } } /// Eine Liste, die noch nichts enthält – aber nicht wegen eines Fehlers. struct LeerAnsicht: View { let titel: String let erklaerung: String var symbol: String = "tray" var body: some View { ContentUnavailableView { Label(titel, systemImage: symbol) } description: { Text(erklaerung) } } } /// Setzt die drei Zustände für eine Liste zusammen, damit das nicht jede /// Ansicht neu baut. struct Inhalt: View { let zustand: Ladezustand var nochmal: (() -> Void)? @ViewBuilder let darstellung: (A) -> Darstellung var body: some View { switch zustand { case .laedt: ProgressView() .frame(maxWidth: .infinity, maxHeight: .infinity) case .da(let wert): darstellung(wert) case .ausSpeicher(let wert, let wann, _): VStack(spacing: 0) { StandHinweis(geholtAm: wann) darstellung(wert) } case .fehler(let fehler): FehlerAnsicht(fehler: fehler, nochmal: nochmal) } } }