diff --git a/LabWise/ProfileView.swift b/LabWise/ProfileView.swift index 0a58748..4c11cf7 100644 --- a/LabWise/ProfileView.swift +++ b/LabWise/ProfileView.swift @@ -8,6 +8,8 @@ final class ProfileViewModel { var isSaving = false var isEditing = false var errorMessage: String? + var showDeleteConfirm = false + var isDeleting = false // Editable fields var piFirstName = "" @@ -49,6 +51,19 @@ final class ProfileViewModel { } } + func deleteAccount() async { + isDeleting = true + defer { isDeleting = false } + do { + try await authClient.deleteAccount() + await MainActor.run { + AppState.shared.signedOut() + } + } catch { + errorMessage = "Failed to delete account. Please try again." + } + } + func signOut() async { try? await authClient.signOut() await MainActor.run { @@ -97,6 +112,21 @@ struct ProfileView: View { } } + Section { + Button(role: .destructive) { + viewModel.showDeleteConfirm = true + } label: { + HStack { + Spacer() + Text("Delete Account") + Spacer() + } + } + .disabled(viewModel.isDeleting) + } footer: { + Text("Permanently deletes your account and all data including chemicals and protocols.") + } + Section { Button(role: .destructive) { Task { await viewModel.signOut() } @@ -142,6 +172,14 @@ struct ProfileView: View { } message: { Text(viewModel.errorMessage ?? "") } + .alert("Delete Account?", isPresented: $viewModel.showDeleteConfirm) { + Button("Cancel", role: .cancel) { } + Button("Delete", role: .destructive) { + Task { await viewModel.deleteAccount() } + } + } message: { + Text("Are you sure? This will permanently delete your account and all your data. This action cannot be undone.") + } } .task { await viewModel.load() diff --git a/LabWiseKit/Sources/LabWiseKit/Auth/AuthClient.swift b/LabWiseKit/Sources/LabWiseKit/Auth/AuthClient.swift index 1cbf236..d39b32f 100644 --- a/LabWiseKit/Sources/LabWiseKit/Auth/AuthClient.swift +++ b/LabWiseKit/Sources/LabWiseKit/Auth/AuthClient.swift @@ -200,6 +200,14 @@ public final class AuthClient: Sendable { return user } + // MARK: - Delete Account + + /// Permanently delete the user's account and all associated data. + public func deleteAccount() async throws { + _ = try await api.postRaw("/api/account/delete", body: EmptyBody()) + api.clearSessionCookies() + } + // MARK: - Sign Out /// Sign out. Clears the session cookie.