@@ -1,8 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { addUser, deleteUser, listRoles, listUsers } from '$lib/api/admin-users';
|
||||
import { toErrorMessage } from '$lib/api/errors';
|
||||
import { errorReporter } from '$lib/api/errors';
|
||||
import type { ApplicationUserDTO } from '$lib/api/schema-helpers';
|
||||
import { requireAdmin } from '$lib/auth/guard.svelte';
|
||||
import { fullName } from '$lib/format';
|
||||
import { session } from '$lib/stores/session.svelte';
|
||||
import { alertError, alertNotice, card, cardHeading, danger, field, ghost, label, primary } from '$lib/ui/classes';
|
||||
|
||||
@@ -23,27 +24,11 @@
|
||||
|
||||
const canCreate = $derived(username.trim() !== '' && password !== '' && !creating);
|
||||
|
||||
let started = false;
|
||||
$effect(() => {
|
||||
// The page is admin-only on the server too; this just avoids showing a shell that
|
||||
// can only produce 403s.
|
||||
if (!session.isLoggedIn) {
|
||||
goto('/login', { replaceState: true });
|
||||
return;
|
||||
}
|
||||
if (!session.isAdmin) {
|
||||
goto('/', { replaceState: true });
|
||||
return;
|
||||
}
|
||||
if (!started) {
|
||||
started = true;
|
||||
void refresh();
|
||||
}
|
||||
});
|
||||
// The page is admin-only on the server too; this just avoids showing a shell that
|
||||
// can only produce 403s.
|
||||
const guard = requireAdmin(() => void refresh());
|
||||
|
||||
function report(cause: unknown, fallback: string) {
|
||||
error = toErrorMessage(cause, fallback);
|
||||
}
|
||||
const report = errorReporter((message) => (error = message));
|
||||
|
||||
async function refresh() {
|
||||
loading = true;
|
||||
@@ -112,8 +97,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
function fullName(user: ApplicationUserDTO): string {
|
||||
return [user.firstName, user.lastName].filter(Boolean).join(' ').trim();
|
||||
function displayName(user: ApplicationUserDTO): string {
|
||||
return fullName(user.firstName, user.lastName);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -122,6 +107,7 @@
|
||||
</svelte:head>
|
||||
|
||||
<main id="main" class="mx-auto max-w-5xl px-4 py-10">
|
||||
{#if guard.ready}
|
||||
<header class="mb-8">
|
||||
<h1 class="text-3xl font-semibold tracking-tight">Users</h1>
|
||||
<p class="mt-1 text-sm text-muted">
|
||||
@@ -168,7 +154,7 @@
|
||||
<span class="ml-1 text-xs font-normal text-subtle">(you)</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="py-2 pr-4 text-muted">{fullName(user) || '—'}</td>
|
||||
<td class="py-2 pr-4 text-muted">{displayName(user) || '—'}</td>
|
||||
<td class="py-2 pr-4">
|
||||
{#if user.roles?.length}
|
||||
{#each user.roles as role (role)}
|
||||
@@ -290,4 +276,5 @@
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user