Tagebuch (Diary):
- DiaryEntry + DiaryMedia + DiaryCreateBody DTOs
- TagebuchView: Liste der Einträge für aktiven Hund mit Titel, Text,
Ortsname, Meilenstein-Stern, Foto-Strip
- AddDiaryEntrySheet: Titel/Text/Datum/Meilenstein/Ort/Tags +
PhotosPicker, nach POST /api/dogs/{id}/diary werden Fotos einzeln
via POST /api/dogs/{id}/diary/{entry_id}/media hochgeladen (mit
ImageResize.resizedJPEG)
Heim-Tab als neuer 1. Tab:
- DashboardSnapshot DTO für /api/dogs/{id}/welcome-dashboard
- ActiveDogStore (@Observable + UserDefaults("activeDogId")): hält
den aktiven Hund app-weit
- HeimView: tägliches Hintergrundfoto aus random_photo.url (rotiert
pro Tag, vom Backend gewählt), Gradient zur Lesbarkeit, Tagezeit-
Begrüßung mit User-Namen, Hund-Picker (Menu), Info-Karten für
letzten Eintrag/nächsten Termin/Gewicht/Eintragszahl,
Quick-Action-Buttons (Tagebuch, Wetter, Erste Hilfe)
Reorganisation:
- 5 Tabs: Heim, Touren, Aufnehmen, Statistik, Mehr
- Hunde-Liste wandert in Mehr → "Hund & Alltag"
- Tagebuch in Mehr → "Hund & Alltag" + erreichbar von Heim
37 lines
1 KiB
Swift
37 lines
1 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
/// Tracks the user's currently selected dog across the app. Picked once,
|
|
/// reused everywhere (Heim, Tagebuch, Statistik, …). Persisted in UserDefaults.
|
|
@Observable
|
|
@MainActor
|
|
final class ActiveDogStore {
|
|
var activeDogId: Int
|
|
var dogs: [Dog] = []
|
|
|
|
var activeDog: Dog? {
|
|
dogs.first(where: { $0.id == activeDogId }) ?? dogs.first
|
|
}
|
|
|
|
init() {
|
|
self.activeDogId = UserDefaults.standard.integer(forKey: "activeDogId")
|
|
}
|
|
|
|
func loadDogs() async {
|
|
do {
|
|
let fetched: [Dog] = try await APIClient.shared.get("/api/dogs")
|
|
self.dogs = fetched
|
|
if !fetched.contains(where: { $0.id == activeDogId }),
|
|
let first = fetched.first {
|
|
setActive(first.id)
|
|
}
|
|
} catch {
|
|
print("ActiveDogStore loadDogs failed: \(error)")
|
|
}
|
|
}
|
|
|
|
func setActive(_ dogId: Int) {
|
|
activeDogId = dogId
|
|
UserDefaults.standard.set(dogId, forKey: "activeDogId")
|
|
}
|
|
}
|