import SwiftUI struct SettingsView: View { @EnvironmentObject var appState: AppState @Environment(\.dismiss) var dismiss @State private var showLegal = false @State private var showDeleteConfirm = false @State private var showDeleteFinal = false @State private var deletePassword = "" @State private var isDeleting = false @State private var deleteError: String? @State private var notificationsEnabled = false var body: some View { NavigationStack { ZStack { Color.nightBase.ignoresSafeArea() List { // Account Section { if let user = appState.currentUser { HStack(spacing: 12) { AvatarView(user: user, size: 44) VStack(alignment: .leading, spacing: 2) { Text(user.displayName) .font(.nightLabel(15, weight: .semibold)) .foregroundColor(.nightPrimary) Text("@\(user.username)") .font(.nightLabel(13)) .foregroundColor(.nightSecondary) } } .padding(.vertical, 4) } } .listRowBackground(Color.nightSurface) // Benachrichtigungen Section("benachrichtigungen") { HStack { VStack(alignment: .leading, spacing: 2) { Text("nightly ping") .font(.nightLabel(15)) .foregroundColor(.nightPrimary) Text("Wenn das Fenster öffnet") .font(.nightLabel(12)) .foregroundColor(.nightSecondary) } Spacer() Toggle("", isOn: $notificationsEnabled) .tint(.nightPurple) } // APNs-Hinweis HStack(spacing: 8) { Image(systemName: "info.circle") .foregroundColor(.nightSecondary) .font(.system(size: 13)) Text("Push-Benachrichtigungen benötigen einen bezahlten Apple Developer Account ($99/Jahr).") .font(.nightLabel(12)) .foregroundColor(.nightSecondary) .lineSpacing(3) } .padding(.vertical, 2) } .listRowBackground(Color.nightSurface) // Rechtliches Section("rechtliches") { Button { showLegal = true } label: { HStack { Text("Impressum & Datenschutz") .font(.nightLabel(15)) .foregroundColor(.nightPrimary) Spacer() Image(systemName: "chevron.right") .font(.system(size: 12)) .foregroundColor(.nightSecondary) } } HStack { Text("Version") .font(.nightLabel(15)) .foregroundColor(.nightPrimary) Spacer() Text(appVersion) .font(.nightMono(13)) .foregroundColor(.nightSecondary) } } .listRowBackground(Color.nightSurface) // Account-Aktionen Section("account") { Button { appState.signOut() dismiss() } label: { Text("abmelden") .font(.nightLabel(15)) .foregroundColor(.nightPrimary) } Button(role: .destructive) { showDeleteConfirm = true } label: { Text("account löschen") .font(.nightLabel(15)) .foregroundColor(.nightRed) } } .listRowBackground(Color.nightSurface) } .scrollContentBackground(.hidden) .listStyle(.insetGrouped) } .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .principal) { Text("einstellungen") .font(.nightTitle(17)) .foregroundColor(.nightPrimary) } ToolbarItem(placement: .navigationBarLeading) { Button("Fertig") { dismiss() } .foregroundColor(.nightSecondary) } } .sheet(isPresented: $showLegal) { LegalView() } } .preferredColorScheme(.dark) // Schritt 1: Erklärung .confirmationDialog( "Account wirklich löschen?", isPresented: $showDeleteConfirm, titleVisibility: .visible ) { Button("Ja, Account löschen", role: .destructive) { showDeleteFinal = true } } message: { Text("Alle deine Posts, Reaktionen und Daten werden sofort und dauerhaft gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden.") } // Schritt 2: Passwort bestätigen .sheet(isPresented: $showDeleteFinal) { DeleteAccountSheet( password: $deletePassword, isDeleting: isDeleting, error: deleteError, onDelete: { Task { await deleteAccount() } } ) } .onAppear { checkNotificationStatus() } } var appVersion: String { Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0" } func checkNotificationStatus() { Task { let settings = await UNUserNotificationCenter.current().notificationSettings() notificationsEnabled = settings.authorizationStatus == .authorized } } func deleteAccount() async { isDeleting = true deleteError = nil defer { isDeleting = false } do { try await appState.deleteAccount() showDeleteFinal = false dismiss() } catch { deleteError = error.localizedDescription } } } struct DeleteAccountSheet: View { @Binding var password: String let isDeleting: Bool let error: String? let onDelete: () -> Void @Environment(\.dismiss) var dismiss var body: some View { NavigationStack { ZStack { Color.nightBase.ignoresSafeArea() VStack(spacing: 24) { Image(systemName: "trash.circle.fill") .font(.system(size: 52)) .foregroundColor(.nightRed) VStack(spacing: 8) { Text("Account löschen") .font(.nightTitle(22)) .foregroundColor(.nightPrimary) Text("Diese Aktion löscht alle deine Daten dauerhaft. Kein Weg zurück.") .font(.nightBody(15)) .foregroundColor(.nightSecondary) .multilineTextAlignment(.center) } NightlyField(text: $password, placeholder: "passwort bestätigen", icon: "lock", isSecure: true) .padding(.horizontal, 24) if let err = error { Text(err).font(.nightLabel(13)).foregroundColor(.nightRed) } Button { onDelete() } label: { Group { if isDeleting { ProgressView().tint(.white) } else { Text("endgültig löschen").font(.nightLabel(16, weight: .semibold)).foregroundColor(.white) } } .frame(maxWidth: .infinity).frame(height: 50) .background(Color.nightRed) .clipShape(RoundedRectangle(cornerRadius: 14)) } .disabled(password.isEmpty || isDeleting) .padding(.horizontal, 24) } .padding(.top, 32) } .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Abbrechen") { dismiss() }.foregroundColor(.nightSecondary) } } } .preferredColorScheme(.dark) .presentationDetents([.medium]) } }