Sechs Offline-Features: Erste Hilfe, Ausgaben, Wetter, Gassi-Zeiten, Giftköder, Verlorene

Pitch-Karte erweitert um die neuen Features (sowie Hundesitting, Züchter).

Neue DTOs in DTOs.swift:
- Expense + ExpenseCreateBody
- GassiZeit + GassiZeitCreateBody (mit wochentage [String], radius_m)
- PoisonAlert + PoisonCreateBody
- LostDog + LostDogCreateBody
- WeatherForecast + WeatherDay (mit asphalt_temp, zecken, pollen-Felder)

Neue Views:
- ErsteHilfeView + Detail: sechs Notfall-Topics (Vergiftung, Hitzschlag,
  Wunden, Atemnot, Krampfanfall, Magendrehung) — komplett offline, kein API
- AusgabenView: Liste mit Total, AddExpenseSheet mit Kategorie/Betrag/
  Datum/Hund-Picker
- WetterView: One-Shot Location + /api/weather/forecast, 7-Tage-Vorhersage
  mit Hunde-Tipps (Hitze ab 25°/30°, Frost, Asphalt ≥50°, Zecken, Regen)
- GassiZeitenView: eigene Zeiten + Add-Sheet (Wochentag-Picker, Hund-
  Auswahl), automatische lokale UNCalendarNotifications via Scheduler
- GiftkoederView: Map mit Pins + Liste in 5km Umkreis, Report-Sheet mit
  Typ-Auswahl
- VerloreneHundeView: Liste mit Foto/Distanz, Detail mit Karte

Support:
- OneShotLocation: kleiner CLLocationManager-Wrapper für einmalige
  Positionsabfrage (Wetter, Giftköder)
- GassiZeitenScheduler: UNCalendarNotificationTrigger pro Wochentag,
  Identifier-Schema "gz-{id}-{weekday}"

Navigation: Section "Hund & Alltag" im Mehr-Tab mit NavigationLinks zu
allen sechs neuen Ansichten.
This commit is contained in:
rene 2026-05-30 12:03:24 +02:00
parent f1b3ff4035
commit 68b084be97
11 changed files with 1547 additions and 0 deletions

View file

@ -27,6 +27,39 @@ struct SettingsView: View {
.padding(.vertical, 4)
}
Section("Hund & Alltag") {
NavigationLink {
ErsteHilfeView()
} label: {
Label("Erste Hilfe", systemImage: "cross.case.fill")
}
NavigationLink {
WetterView()
} label: {
Label("Wetter", systemImage: "cloud.sun.fill")
}
NavigationLink {
GassiZeitenView()
} label: {
Label("Gassi-Zeiten", systemImage: "alarm.fill")
}
NavigationLink {
GiftkoederView()
} label: {
Label("Giftköder", systemImage: "exclamationmark.octagon.fill")
}
NavigationLink {
VerloreneHundeView()
} label: {
Label("Verlorene Hunde", systemImage: "magnifyingglass.circle.fill")
}
NavigationLink {
AusgabenView()
} label: {
Label("Ausgaben", systemImage: "eurosign.circle.fill")
}
}
Section("Account") {
LabeledContent("Rolle", value: rolleLabel)
if auth.profile?.isFounderFlag == true {