diff --git a/BanYaroGo-Info.plist b/BanYaroGo-Info.plist index a15a288..d6e4fb7 100644 --- a/BanYaroGo-Info.plist +++ b/BanYaroGo-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + de CFBundleDisplayName Ban Yaro Go CFBundleExecutable @@ -51,7 +51,7 @@ NSCameraUsageDescription Für Fotos während deiner Gassi-Tour brauchen wir Zugriff auf die Kamera. NSHealthShareUsageDescription - Wir lesen keine Daten aus Apple Health. + Ban Yaro Go liest keine Daten aus Apple Health. Diese Berechtigung wird vom System nur als Vorab-Bestätigung abgefragt, bevor die App Gassi-Touren in Health schreiben kann. NSHealthUpdateUsageDescription Auf Wunsch speichern wir deine Gassi-Touren als Spaziergang-Workout mit Route in Apple Health. UIBackgroundModes diff --git a/BanYaroGo/PrivacyInfo.xcprivacy b/BanYaroGo/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..1eab8fd --- /dev/null +++ b/BanYaroGo/PrivacyInfo.xcprivacy @@ -0,0 +1,144 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeEmailAddress + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeName + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeUserID + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePreciseLocation + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeCoarseLocation + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePhotosorVideos + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeFitness + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherUserContent + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + E174.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + + diff --git a/BanYaroGo/Views/SettingsView.swift b/BanYaroGo/Views/SettingsView.swift index 25906e3..5438e79 100644 --- a/BanYaroGo/Views/SettingsView.swift +++ b/BanYaroGo/Views/SettingsView.swift @@ -5,6 +5,10 @@ struct SettingsView: View { @AppStorage("autoPauseEnabled") private var autoPauseEnabled = true @AppStorage("healthKitSyncEnabled") private var healthKitSyncEnabled = false @State private var showHealthPermissionAlert = false + @State private var showDeleteConfirm1 = false + @State private var showDeleteConfirm2 = false + @State private var isDeleting = false + @State private var deleteError: String? var body: some View { NavigationStack { @@ -145,6 +149,26 @@ struct SettingsView: View { } } + Section { + Button(role: .destructive) { + showDeleteConfirm1 = true + } label: { + if isDeleting { + HStack { ProgressView(); Text("Wird gelöscht…") } + } else { + Label("Konto unwiderruflich löschen", systemImage: "trash") + } + } + .disabled(isDeleting) + if let deleteError { + Text(deleteError).font(.footnote).foregroundStyle(.red) + } + } header: { + Text("Konto löschen") + } footer: { + Text("Löscht dein banyaro-Konto, alle Hunde, Touren, Tagebuch-Einträge, Ausgaben und Fotos endgültig. Das gilt App-übergreifend (auch für banyaro.app im Browser). Die Aktion kann nicht rückgängig gemacht werden.") + } + Section("Über") { Text("Ban Yaro Go ist die native iOS-Ergänzung zur banyaro.app PWA. Phase 1: deine Touren ansehen.") .font(.footnote) @@ -158,6 +182,32 @@ struct SettingsView: View { } message: { Text("Du kannst die Berechtigung in den iOS-Einstellungen unter Datenschutz & Sicherheit → Health → Ban Yaro Go nachträglich ändern.") } + .alert("Konto wirklich löschen?", isPresented: $showDeleteConfirm1) { + Button("Abbrechen", role: .cancel) {} + Button("Weiter", role: .destructive) { showDeleteConfirm2 = true } + } message: { + Text("Alle Hunde, Touren, Tagebuch, Ausgaben und Fotos werden endgültig gelöscht — App und banyaro.app gleichermaßen. Diese Aktion kann nicht rückgängig gemacht werden.") + } + .alert("Letzte Bestätigung", isPresented: $showDeleteConfirm2) { + Button("Abbrechen", role: .cancel) {} + Button("Endgültig löschen", role: .destructive) { + Task { await deleteAccount() } + } + } message: { + Text("Bist du dir sicher? Dein Konto und alle Daten werden jetzt sofort und unwiderruflich entfernt.") + } + } + } + + private func deleteAccount() async { + isDeleting = true + deleteError = nil + defer { isDeleting = false } + do { + try await APIClient.shared.delete("/api/profile/account") + auth.logout() + } catch { + deleteError = error.localizedDescription } }