diff --git a/frontend/src/api/client.js b/frontend/src/api/client.js index 2b5b730..0d9b5b8 100644 --- a/frontend/src/api/client.js +++ b/frontend/src/api/client.js @@ -269,6 +269,14 @@ export function adminUpdateAiConfig(id, provider, model) { }) } +export function adminDeleteUser(id, adminPassword) { + return request(`/api/admin/users/${id}`, { + method: 'DELETE', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ admin_password: adminPassword }), + }) +} + // ── Folders ─────────────────────────────────────────────────────────────────── export function listFolders(parentId = null) { diff --git a/frontend/src/components/admin/AdminUsersTab.vue b/frontend/src/components/admin/AdminUsersTab.vue index ce37f28..2928f8a 100644 --- a/frontend/src/components/admin/AdminUsersTab.vue +++ b/frontend/src/components/admin/AdminUsersTab.vue @@ -171,6 +171,43 @@ + +
+

+ Permanently delete {{ user.email }}? + This will erase all their documents, cloud connections, and quota data. This cannot be undone. +

+
+ + +
+

{{ deleteError }}

+
+ + · + +
+
+
@@ -191,6 +228,13 @@ > Deactivate + · +
@@ -221,6 +272,9 @@ const users = ref([]) const loading = ref(false) const showCreateForm = ref(false) const confirmDeactivate = ref(null) +const confirmDelete = ref(null) +const deletePassword = ref('') +const deleteError = ref(null) const pendingAction = reactive({}) const actionError = ref(null) const creating = ref(false) @@ -308,6 +362,36 @@ async function submitCreate() { function startDeactivate(id) { confirmDeactivate.value = id + confirmDelete.value = null + deletePassword.value = '' + deleteError.value = null +} + +function startDelete(id) { + confirmDelete.value = id + deletePassword.value = '' + deleteError.value = null + confirmDeactivate.value = null +} + +function cancelDelete() { + confirmDelete.value = null + deletePassword.value = '' + deleteError.value = null +} + +async function confirmDoDelete(id) { + pendingAction[id] = true + deleteError.value = null + try { + await api.adminDeleteUser(id, deletePassword.value) + users.value = users.value.filter(u => u.id !== id) + cancelDelete() + } catch (e) { + deleteError.value = e.message + } finally { + delete pendingAction[id] + } } async function confirmDoDeactivate(id) {