Files
Vorrania/ios/Sources/RootView.swift
Scarriffle dc1750d23a Umbenennung in Vorrania vollstaendig durchziehen
Auf ausdruecklichen Wunsch jetzt auch die internen Bezeichner, weil die
Installation noch keine echten Daten enthaelt: POSTGRES_USER/PASSWORD/DB, der
Volume-Name, die Standard-DATABASE_URL, der localStorage-Schluessel und die
iOS-Zeichenketten inklusive Keychain-Konto.

Das setzt eine leere Datenbank voraus: Der neue Volume-Name legt eine neue,
leere Datenbank an. Die alte bleibt als verwaistes Volume liegen und muss von
Hand entfernt werden.

Die Warnung in docker-compose.yml bleibt stehen, damit eine spaetere
Umbenennung nicht versehentlich mit Daten im Volume passiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:13:11 +02:00

119 lines
4.0 KiB
Swift

import SwiftUI
struct RootView: View {
@EnvironmentObject private var session: Session
@EnvironmentObject private var router: Router
@EnvironmentObject private var display: DisplaySettings
var body: some View {
Group {
if session.isLoggedIn {
HomeView()
} else {
LoginView()
}
}
// Anzeigeeinstellungen (Datumsformat) gehoeren dem Server.
.task(id: session.isLoggedIn) {
if session.isLoggedIn { await display.load() }
}
// Shortcut/URL öffnet den passenden Scan-Bildschirm direkt.
.fullScreenCover(item: $router.route) { route in
NavigationStack {
switch route {
case .checkin: CheckInView()
case .checkout: CheckOutView()
}
}
}
}
}
extension Route: Identifiable {
var id: String { rawValue }
}
struct HomeView: View {
@EnvironmentObject private var session: Session
@EnvironmentObject private var router: Router
var body: some View {
NavigationStack {
VStack(spacing: 16) {
Button {
router.route = .checkin
} label: {
ActionTile(title: "Einlagern", subtitle: "Barcode scannen und Bestand erfassen",
systemImage: "arrow.down.to.line")
}
Button {
router.route = .checkout
} label: {
// "arrow.up.from.line" gibt es als SF Symbol nicht - das Icon
// blieb dadurch leer und es war nur die Kachelflaeche zu sehen.
ActionTile(title: "Auslagern", subtitle: "Barcode scannen und Menge entnehmen",
systemImage: "arrow.up.to.line")
}
NavigationLink {
ShoppingListView()
} label: {
ActionTile(title: "Einkaufsliste", subtitle: "Was unter dem Mindestbestand liegt",
systemImage: "cart")
}
NavigationLink {
ExpiringView()
} label: {
ActionTile(title: "Bald ablaufend", subtitle: "Chargen mit knappem MHD",
systemImage: "clock")
}
NavigationLink {
ProductListView()
} label: {
ActionTile(title: "Produkte", subtitle: "Suchen, ansehen und bearbeiten",
systemImage: "list.bullet")
}
Spacer()
}
.padding()
.navigationTitle("Vorrania")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Menu {
Text("Angemeldet als \(session.username)")
Button("Abmelden", role: .destructive) { session.logout() }
} label: {
Image(systemName: "person.circle")
}
}
}
}
}
}
struct ActionTile: View {
let title: String
let subtitle: String
let systemImage: String
var body: some View {
HStack(spacing: 14) {
Image(systemName: systemImage)
.font(.title2)
.frame(width: 44, height: 44)
.background(Color.accentColor.opacity(0.15))
.clipShape(RoundedRectangle(cornerRadius: 10))
VStack(alignment: .leading, spacing: 2) {
Text(title).font(.headline)
Text(subtitle).font(.caption).foregroundStyle(.secondary)
.multilineTextAlignment(.leading)
}
Spacer()
Image(systemName: "chevron.right").foregroundStyle(.tertiary)
}
.padding()
.background(Color(.secondarySystemBackground))
.clipShape(RoundedRectangle(cornerRadius: 12))
.foregroundStyle(.primary)
}
}