full working application and initial commit
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { PUBLIC_CONVEX_URL } from '$env/static/public';
|
||||
import { BookOpenText, LayoutDashboard, LogOut, PenLine, Settings } from '@lucide/svelte';
|
||||
import { setupConvexAuth, useAuth } from '@mmailaender/convex-auth-svelte/sveltekit';
|
||||
import Logo from '$lib/components/Logo.svelte';
|
||||
import ThemeToggle from '$lib/components/ThemeToggle.svelte';
|
||||
import './layout.css';
|
||||
|
||||
let { children, data } = $props();
|
||||
|
||||
setupConvexAuth({
|
||||
getServerState: () => data.authState,
|
||||
convexUrl: PUBLIC_CONVEX_URL,
|
||||
storage: 'localStorage',
|
||||
storageNamespace: 'journaley'
|
||||
});
|
||||
|
||||
const auth = useAuth();
|
||||
const isAuthenticated = $derived(auth.isAuthenticated);
|
||||
const isLoading = $derived(auth.isLoading);
|
||||
const isAuthRoute = $derived(page.url.pathname.startsWith('/signin'));
|
||||
|
||||
const navItems = [
|
||||
{ href: '/dashboard', label: 'Dashboard', icon: LayoutDashboard },
|
||||
{ href: '/entries', label: 'Daily Entries', icon: BookOpenText },
|
||||
{ href: '/settings', label: 'Settings', icon: Settings }
|
||||
];
|
||||
</script>
|
||||
|
||||
{#if isLoading && !isAuthRoute}
|
||||
<div class="flex min-h-screen items-center justify-center p-6">
|
||||
<div class="app-card max-w-sm p-6 text-center">
|
||||
<div class="mx-auto mb-4 text-primary"><Logo size={44} /></div>
|
||||
<p class="text-sm text-muted-foreground">Opening your journal...</p>
|
||||
</div>
|
||||
</div>
|
||||
{:else if isAuthenticated && !isAuthRoute}
|
||||
<div class="min-h-screen lg:grid lg:grid-cols-[17rem_1fr]">
|
||||
<aside class="hidden border-r bg-card/78 px-5 py-6 backdrop-blur lg:block">
|
||||
<a href="/dashboard" class="mb-9 flex items-center gap-3">
|
||||
<span class="text-primary"><Logo /></span>
|
||||
<span>
|
||||
<span class="block text-lg font-bold tracking-tight">Journaley</span>
|
||||
<span class="text-xs text-muted-foreground">Write, tag, find.</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="space-y-2">
|
||||
{#each navItems as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
<a
|
||||
href={item.href}
|
||||
class="flex items-center gap-3 rounded-md px-3 py-2.5 text-sm font-semibold transition hover:bg-secondary {page.url.pathname.startsWith(
|
||||
item.href
|
||||
)
|
||||
? 'bg-secondary text-foreground'
|
||||
: 'text-muted-foreground'}"
|
||||
>
|
||||
<Icon size={18} />
|
||||
{item.label}
|
||||
</a>
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<div class="mt-8 rounded-lg border bg-background/70 p-4">
|
||||
<div class="mb-2 flex items-center gap-2 text-sm font-semibold">
|
||||
<PenLine size={16} />
|
||||
Today counts
|
||||
</div>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
A few honest lines are enough. Keep the thread alive.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="min-w-0">
|
||||
<header
|
||||
class="sticky top-0 z-20 flex items-center justify-between border-b bg-background/82 px-4 py-3 backdrop-blur lg:px-8"
|
||||
>
|
||||
<a href="/dashboard" class="flex items-center gap-2 font-bold lg:hidden">
|
||||
<span class="text-primary"><Logo size={30} /></span>
|
||||
Journaley
|
||||
</a>
|
||||
|
||||
<nav class="hidden items-center gap-1 lg:flex">
|
||||
{#each navItems as item (item.href)}
|
||||
<a
|
||||
href={item.href}
|
||||
class="rounded-md px-3 py-2 text-sm font-semibold text-muted-foreground transition hover:bg-secondary hover:text-foreground"
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<ThemeToggle />
|
||||
<button class="app-button ghost" type="button" onclick={() => auth.signOut()}>
|
||||
<LogOut size={16} />
|
||||
<span class="hidden sm:inline">Sign out</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="mx-auto w-full max-w-7xl px-4 py-6 lg:px-8 lg:py-8">
|
||||
{@render children()}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
{@render children()}
|
||||
{/if}
|
||||
Reference in New Issue
Block a user