e6b50fb4f1
Fix all build/type/lint errors (zod 3.25 compat wrapper, Svelte 5 fixes), write 115 unit tests across 10 test files, expand seed script with demo data, update Docker config with migration on startup.
44 lines
1.2 KiB
Svelte
44 lines
1.2 KiB
Svelte
<script lang="ts">
|
|
import type { Snippet } from 'svelte';
|
|
import type { LayoutData } from './$types.js';
|
|
import { page } from '$app/stores';
|
|
|
|
let { data, children }: { data: LayoutData; children: Snippet } = $props();
|
|
|
|
const navItems = [
|
|
{ href: '/admin/users', label: 'Users' },
|
|
{ href: '/admin/groups', label: 'Groups' },
|
|
{ href: '/admin/settings', label: 'Settings' }
|
|
] as const;
|
|
|
|
function isActive(href: string): boolean {
|
|
return $page.url.pathname === href;
|
|
}
|
|
</script>
|
|
|
|
<div class="p-6">
|
|
<div class="mx-auto max-w-6xl">
|
|
<!-- Admin header -->
|
|
<div class="mb-6 flex flex-wrap items-center gap-4 rounded-xl border border-border bg-card p-4 shadow-sm">
|
|
<span class="text-sm font-semibold text-foreground">Admin Panel</span>
|
|
<div class="flex gap-1">
|
|
{#each navItems as item (item.href)}
|
|
<a
|
|
href={item.href}
|
|
class="rounded-lg px-3 py-1.5 text-sm font-medium transition-colors {isActive(item.href)
|
|
? 'bg-primary text-primary-foreground'
|
|
: 'text-muted-foreground hover:bg-accent hover:text-foreground'}"
|
|
>
|
|
{item.label}
|
|
</a>
|
|
{/each}
|
|
</div>
|
|
<div class="ml-auto text-xs text-muted-foreground">
|
|
{data.user.displayName} (admin)
|
|
</div>
|
|
</div>
|
|
|
|
{@render children()}
|
|
</div>
|
|
</div>
|