vbytes-lan-attendence/web/src/routes/+layout.svelte
2025-09-20 12:37:44 +02:00

125 lines
3.6 KiB
Svelte

<script lang="ts">
import '../app.css';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import favicon from '$lib/assets/favicon.svg';
const props = $props();
const children = $derived(props.children);
const data = $derived(props.data);
let ui = $state({
loggedIn: false,
loggingOut: false,
message: ''
});
$effect(() => {
ui.loggedIn = Boolean(data?.isLoggedIn);
});
async function handleLogout() {
if (ui.loggingOut) return;
ui.loggingOut = true;
ui.message = '';
try {
const response = await fetch('/api/logout', { method: 'POST' });
if (!response.ok) {
const body = await response.json().catch(() => ({}));
ui.message = body.message ?? 'Kunde inte logga ut. Försök igen.';
} else {
ui.loggedIn = false;
await goto('/login', { invalidateAll: true });
}
} catch (err) {
console.error('Logout failed', err);
ui.message = 'Ett oväntat fel uppstod vid utloggning.';
} finally {
ui.loggingOut = false;
}
}
</script>
<svelte:head>
<link rel="icon" href={favicon} />
</svelte:head>
<div class="min-h-screen bg-slate-100 text-slate-900">
<header class="border-b border-slate-200 bg-white">
<div class="mx-auto flex max-w-5xl flex-col gap-4 px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<p class="text-sm font-medium uppercase tracking-wide text-slate-500">VBytes</p>
<h1 class="text-xl font-semibold text-slate-900">Gästhantering</h1>
</div>
{#if ui.loggedIn}
<div class="flex flex-col items-start gap-3 sm:flex-row sm:items-center sm:gap-4">
<nav class="flex items-center gap-2">
<a
href="/"
class={`rounded-md px-3 py-2 text-sm font-medium transition-colors ${
$page.url.pathname === '/'
? 'bg-indigo-600 text-white shadow'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
Checka in
</a>
<a
href="/checkout"
class={`rounded-md px-3 py-2 text-sm font-medium transition-colors ${
$page.url.pathname === '/checkout'
? 'bg-indigo-600 text-white shadow'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
Checka ut
</a>
<a
href="/create"
class={`rounded-md px-3 py-2 text-sm font-medium transition-colors ${
$page.url.pathname === '/create'
? 'bg-indigo-600 text-white shadow'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
Lägg till
</a>
<a
href="/inside-status"
class={`rounded-md px-3 py-2 text-sm font-medium transition-colors ${
$page.url.pathname === '/inside-status'
? 'bg-indigo-600 text-white shadow'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
Inne/ute
</a>
<a
href="/checked-in"
class={`rounded-md px-3 py-2 text-sm font-medium transition-colors ${
$page.url.pathname === '/checked-in'
? 'bg-indigo-600 text-white shadow'
: 'text-slate-600 hover:bg-slate-100'
}`}
>
Översikt
</a>
</nav>
<button
onclick={handleLogout}
disabled={ui.loggingOut}
class="rounded-md border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 transition-colors hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-60"
>
{ui.loggingOut ? 'Loggar ut…' : 'Logga ut'}
</button>
</div>
{/if}
</div>
{#if ui.message}
<p class="bg-red-50 px-4 py-2 text-center text-sm text-red-600">{ui.message}</p>
{/if}
</header>
<main class="mx-auto max-w-5xl px-4 py-6">
{@render children?.()}
</main>
</div>