2024-08-12 11:00:25 +02:00
|
|
|
<script lang="ts">
|
2024-10-31 17:22:58 +01:00
|
|
|
import { goto } from '$app/navigation';
|
2024-10-16 08:49:19 +02:00
|
|
|
import AdvancedTable from '$lib/components/advanced-table.svelte';
|
2024-08-12 11:00:25 +02:00
|
|
|
import { openConfirmDialog } from '$lib/components/confirm-dialog/';
|
|
|
|
|
import { Badge } from '$lib/components/ui/badge/index';
|
2024-10-31 17:22:58 +01:00
|
|
|
import { buttonVariants } from '$lib/components/ui/button';
|
2024-08-12 11:00:25 +02:00
|
|
|
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
|
|
|
|
import * as Table from '$lib/components/ui/table';
|
|
|
|
|
import UserService from '$lib/services/user-service';
|
2025-01-11 20:14:12 +01:00
|
|
|
import type { Paginated, SearchPaginationSortRequest } from '$lib/types/pagination.type';
|
2024-08-12 11:00:25 +02:00
|
|
|
import type { User } from '$lib/types/user.type';
|
|
|
|
|
import { axiosErrorToast } from '$lib/utils/error-util';
|
|
|
|
|
import { LucideLink, LucidePencil, LucideTrash } from 'lucide-svelte';
|
|
|
|
|
import Ellipsis from 'lucide-svelte/icons/ellipsis';
|
|
|
|
|
import { toast } from 'svelte-sonner';
|
|
|
|
|
import OneTimeLinkModal from './one-time-link-modal.svelte';
|
|
|
|
|
|
2025-01-11 20:14:12 +01:00
|
|
|
let { users = $bindable() }: { users: Paginated<User> } = $props();
|
|
|
|
|
let requestOptions: SearchPaginationSortRequest | undefined = $state();
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2025-01-11 20:14:12 +01:00
|
|
|
let userIdToCreateOneTimeLink: string | null = $state(null);
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2024-10-16 08:49:19 +02:00
|
|
|
const userService = new UserService();
|
2024-08-12 11:00:25 +02:00
|
|
|
|
|
|
|
|
async function deleteUser(user: User) {
|
|
|
|
|
openConfirmDialog({
|
|
|
|
|
title: `Delete ${user.firstName} ${user.lastName}`,
|
|
|
|
|
message: 'Are you sure you want to delete this user?',
|
|
|
|
|
confirm: {
|
|
|
|
|
label: 'Delete',
|
|
|
|
|
destructive: true,
|
|
|
|
|
action: async () => {
|
|
|
|
|
try {
|
|
|
|
|
await userService.remove(user.id);
|
2025-01-11 20:14:12 +01:00
|
|
|
users = await userService.list(requestOptions!);
|
2024-08-12 11:00:25 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
axiosErrorToast(e);
|
|
|
|
|
}
|
|
|
|
|
toast.success('User deleted successfully');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
2024-10-16 08:49:19 +02:00
|
|
|
<AdvancedTable
|
|
|
|
|
items={users}
|
2025-01-11 20:14:12 +01:00
|
|
|
{requestOptions}
|
|
|
|
|
onRefresh={async (options) => (users = await userService.list(options))}
|
2024-10-16 08:49:19 +02:00
|
|
|
columns={[
|
2025-01-11 20:14:12 +01:00
|
|
|
{
|
|
|
|
|
label: 'First name',
|
|
|
|
|
sortColumn: 'firstName'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Last name',
|
|
|
|
|
sortColumn: 'lastName'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Email',
|
|
|
|
|
sortColumn: 'email'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Username',
|
|
|
|
|
sortColumn: 'username'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Role',
|
|
|
|
|
sortColumn: 'isAdmin'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Actions',
|
|
|
|
|
hidden: true
|
|
|
|
|
}
|
2024-10-16 08:49:19 +02:00
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
{#snippet rows({ item })}
|
|
|
|
|
<Table.Cell>{item.firstName}</Table.Cell>
|
|
|
|
|
<Table.Cell>{item.lastName}</Table.Cell>
|
|
|
|
|
<Table.Cell>{item.email}</Table.Cell>
|
|
|
|
|
<Table.Cell>{item.username}</Table.Cell>
|
|
|
|
|
<Table.Cell class="hidden lg:table-cell">
|
|
|
|
|
<Badge variant="outline">{item.isAdmin ? 'Admin' : 'User'}</Badge>
|
|
|
|
|
</Table.Cell>
|
|
|
|
|
<Table.Cell>
|
|
|
|
|
<DropdownMenu.Root>
|
2024-10-31 17:22:58 +01:00
|
|
|
<DropdownMenu.Trigger class={buttonVariants({ variant: 'ghost', size: 'icon' })}>
|
|
|
|
|
<Ellipsis class="h-4 w-4" />
|
|
|
|
|
<span class="sr-only">Toggle menu</span>
|
2024-10-16 08:49:19 +02:00
|
|
|
</DropdownMenu.Trigger>
|
|
|
|
|
<DropdownMenu.Content align="end">
|
2024-10-31 17:22:58 +01:00
|
|
|
<DropdownMenu.Item onclick={() => (userIdToCreateOneTimeLink = item.id)}
|
2024-10-16 08:49:19 +02:00
|
|
|
><LucideLink class="mr-2 h-4 w-4" />One-time link</DropdownMenu.Item
|
|
|
|
|
>
|
2024-10-31 17:22:58 +01:00
|
|
|
<DropdownMenu.Item onclick={() => goto(`/settings/admin/users/${item.id}`)}
|
2024-10-16 08:49:19 +02:00
|
|
|
><LucidePencil class="mr-2 h-4 w-4" /> Edit</DropdownMenu.Item
|
|
|
|
|
>
|
|
|
|
|
<DropdownMenu.Item
|
|
|
|
|
class="text-red-500 focus:!text-red-700"
|
2024-10-31 17:22:58 +01:00
|
|
|
onclick={() => deleteUser(item)}
|
2024-10-16 08:49:19 +02:00
|
|
|
><LucideTrash class="mr-2 h-4 w-4" />Delete</DropdownMenu.Item
|
|
|
|
|
>
|
|
|
|
|
</DropdownMenu.Content>
|
|
|
|
|
</DropdownMenu.Root>
|
|
|
|
|
</Table.Cell>
|
|
|
|
|
{/snippet}
|
|
|
|
|
</AdvancedTable>
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2024-10-31 17:22:58 +01:00
|
|
|
<OneTimeLinkModal userId={userIdToCreateOneTimeLink} />
|