107 lines
4.3 KiB
Svelte
107 lines
4.3 KiB
Svelte
<script lang="ts">
|
|
import { goto } from '$app/navigation';
|
|
import { auth } from '$lib/auth/store.svelte';
|
|
import { logout } from '$lib/api/auth';
|
|
import { useQueryClient } from '@tanstack/svelte-query';
|
|
import { today } from '$lib/utils/date';
|
|
import { page } from '$app/state';
|
|
import { onMount } from 'svelte';
|
|
|
|
let { children } = $props();
|
|
const queryClient = useQueryClient();
|
|
|
|
onMount(() => {
|
|
if (!auth.isAuthenticated) goto('/login');
|
|
});
|
|
|
|
function handleLogout() {
|
|
logout();
|
|
queryClient.clear();
|
|
goto('/login');
|
|
}
|
|
|
|
const isDiary = $derived(page.url.pathname.startsWith('/diary'));
|
|
const isPresets = $derived(page.url.pathname.startsWith('/presets'));
|
|
</script>
|
|
|
|
{#if auth.isAuthenticated}
|
|
<div class="lg:flex min-h-screen">
|
|
<!-- Sidebar (desktop only) -->
|
|
<aside class="hidden lg:flex flex-col w-52 shrink-0 fixed inset-y-0 border-r border-zinc-800 bg-zinc-950 px-3 py-6 z-20">
|
|
<div class="px-2 mb-8">
|
|
<span class="text-lg font-bold text-green-400">fooder</span>
|
|
</div>
|
|
|
|
<nav class="flex-1 space-y-1">
|
|
<a
|
|
href="/diary/{today()}"
|
|
class="flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium transition-colors
|
|
{isDiary ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:text-zinc-200 hover:bg-zinc-900'}"
|
|
>
|
|
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
|
</svg>
|
|
Diary
|
|
</a>
|
|
<a
|
|
href="/presets"
|
|
class="flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium transition-colors
|
|
{isPresets ? 'bg-zinc-800 text-zinc-100' : 'text-zinc-400 hover:text-zinc-200 hover:bg-zinc-900'}"
|
|
>
|
|
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" />
|
|
</svg>
|
|
Presets
|
|
</a>
|
|
</nav>
|
|
|
|
<button
|
|
onclick={handleLogout}
|
|
class="flex items-center gap-2.5 px-3 py-2 rounded-xl text-sm font-medium text-zinc-400 hover:text-zinc-200 hover:bg-zinc-900 transition-colors"
|
|
>
|
|
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
|
</svg>
|
|
Log out
|
|
</button>
|
|
</aside>
|
|
|
|
<!-- Main content -->
|
|
<div class="flex-1 lg:ml-52 flex flex-col min-h-screen">
|
|
{@render children()}
|
|
</div>
|
|
|
|
<!-- Bottom tab bar (mobile only) -->
|
|
<nav class="lg:hidden fixed bottom-0 left-0 right-0 z-20 bg-zinc-950 border-t border-zinc-800 flex items-center pb-[var(--safe-bottom)]">
|
|
<a
|
|
href="/diary/{today()}"
|
|
class="flex-1 flex flex-col items-center gap-1 py-3 text-xs font-medium transition-colors
|
|
{isDiary ? 'text-green-400' : 'text-zinc-500 hover:text-zinc-300'}"
|
|
>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
|
</svg>
|
|
Diary
|
|
</a>
|
|
<a
|
|
href="/presets"
|
|
class="flex-1 flex flex-col items-center gap-1 py-3 text-xs font-medium transition-colors
|
|
{isPresets ? 'text-green-400' : 'text-zinc-500 hover:text-zinc-300'}"
|
|
>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" />
|
|
</svg>
|
|
Presets
|
|
</a>
|
|
<button
|
|
onclick={handleLogout}
|
|
class="flex-1 flex flex-col items-center gap-1 py-3 text-xs font-medium text-zinc-500 hover:text-zinc-300 transition-colors"
|
|
>
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
|
</svg>
|
|
Log out
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
{/if}
|