Account deletion
This commit is contained in:
@@ -8,6 +8,8 @@ final class ProfileViewModel {
|
|||||||
var isSaving = false
|
var isSaving = false
|
||||||
var isEditing = false
|
var isEditing = false
|
||||||
var errorMessage: String?
|
var errorMessage: String?
|
||||||
|
var showDeleteConfirm = false
|
||||||
|
var isDeleting = false
|
||||||
|
|
||||||
// Editable fields
|
// Editable fields
|
||||||
var piFirstName = ""
|
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 {
|
func signOut() async {
|
||||||
try? await authClient.signOut()
|
try? await authClient.signOut()
|
||||||
await MainActor.run {
|
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 {
|
Section {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
Task { await viewModel.signOut() }
|
Task { await viewModel.signOut() }
|
||||||
@@ -142,6 +172,14 @@ struct ProfileView: View {
|
|||||||
} message: {
|
} message: {
|
||||||
Text(viewModel.errorMessage ?? "")
|
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 {
|
.task {
|
||||||
await viewModel.load()
|
await viewModel.load()
|
||||||
|
|||||||
@@ -200,6 +200,14 @@ public final class AuthClient: Sendable {
|
|||||||
return user
|
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
|
// MARK: - Sign Out
|
||||||
|
|
||||||
/// Sign out. Clears the session cookie.
|
/// Sign out. Clears the session cookie.
|
||||||
|
|||||||
Reference in New Issue
Block a user