delete users

This commit is contained in:
2025-07-20 14:06:29 +02:00
parent 41e23af55c
commit 6e0880eb3d
21 changed files with 530 additions and 264 deletions

View File

@@ -12,12 +12,15 @@ import {
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import type { AuthUser } from '#shared/types/auth';
import { deleteUser } from '~/lib/api/admin/deleteUser';
const adminStore = useAdminStore();
// We'll only update this value if there is a user to prevent layout shifts on close
const user = ref<AuthUser>();
const confirmEmailInput = ref<InstanceType<typeof Input>>();
const deleting = ref(false);
const confirmEmail = ref<string>('');
const confirmEmailInput = ref<InstanceType<typeof Input>>();
const emailMatches = computed(
() => user.value != null && user.value.email === confirmEmail.value
@@ -30,11 +33,26 @@ adminStore.$subscribe(async (_mutation, state) => {
}
});
function cancel() {
function close() {
confirmEmail.value = '';
adminStore.clearDeleteUserDialog();
}
function submit() {}
async function submit() {
if (deleting.value || adminStore.deleteUserDialog == null) {
return;
}
deleting.value = true;
const { success } = await deleteUser(adminStore.deleteUserDialog.user.id);
if (success) {
close();
}
deleting.value = false;
}
</script>
<template>
@@ -42,7 +60,7 @@ function submit() {}
<AlertDialogTrigger as-child>
<slot />
</AlertDialogTrigger>
<AlertDialogContent @escape-key-down="cancel">
<AlertDialogContent @escape-key-down="close">
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription class="space-y-1">
@@ -80,8 +98,10 @@ function submit() {}
</div>
</AlterDialogContent>
<AlertDialogFooter>
<AlertDialogCancel @click="cancel">Cancel</AlertDialogCancel>
<AlertDialogAction :disabled="!emailMatches" @click="submit"
<AlertDialogCancel @click="close">Cancel</AlertDialogCancel>
<AlertDialogAction
:disabled="!emailMatches || deleting"
@click="submit"
>Delete</AlertDialogAction
>
</AlertDialogFooter>

View File

@@ -0,0 +1,42 @@
import type { ApiResponse } from '~/shared/types/api';
import type { AuthUser } from '~/shared/types/auth';
import { getApiHeaders } from '..';
import { toast } from 'vue-sonner';
/** Admin function to create a new user */
export async function deleteUser(
userId: string
): Promise<{ success: true; user: AuthUser } | { success: false }> {
const { data, error } = await useFetch<ApiResponse<AuthUser>>(
getApiUrl('admin/users'),
{
method: 'DELETE',
headers: getApiHeaders(),
body: JSON.stringify({
userId: userId,
}),
responseType: 'json',
}
);
if (data.value == null) {
toast.error('Delete user', {
description: error.value?.data ?? 'Failed to delete user',
});
return {
success: false,
};
}
await refreshNuxtData('users');
toast.success('Delete user', {
description: 'Successfully delete user',
});
return {
success: true,
user: data.value.data,
};
}