feat: scaffold klarbild foundation (astro+postgres+s3, auth, migrations, health)
- Astro 5 SSR (node standalone) + React, OKLCH tokens (no tailwind) - migrations/001_init.sql: full schema per 03-datenmodell-api - lib: db+migrations, crypto (AES-256-GCM), auth (argon2+signed session, ratelimit), storage (S3/MinIO, presigned URLs), openrouter (POST /v1/images, cost) - middleware: init-once + session guard + admin gate; /api/health (db+storage) - login + studio placeholder; seeds (till/lea, default recipes); Dockerfile - verified: astro build passes
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
---
|
||||
import '../styles/tokens.css';
|
||||
interface Props { title?: string }
|
||||
const { title = 'Klarbild' } = Astro.props;
|
||||
const user = Astro.locals.user;
|
||||
---
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta name="theme-color" content="#0e5f6e" />
|
||||
<title>{title}</title>
|
||||
</head>
|
||||
<body>
|
||||
{user && (
|
||||
<header class="topbar">
|
||||
<a href="/" class="brand">Klarbild</a>
|
||||
<nav>
|
||||
<a href="/">Studio</a>
|
||||
<a href="/bibliothek">Bibliothek</a>
|
||||
<a href="/warteschlange">Warteschlange</a>
|
||||
{user.role === 'admin' && <a href="/admin">Admin</a>}
|
||||
</nav>
|
||||
<form method="post" action="/api/auth/logout" class="logout">
|
||||
<span>{user.name}</span>
|
||||
<button type="submit">Abmelden</button>
|
||||
</form>
|
||||
</header>
|
||||
)}
|
||||
<main class="wrap"><slot /></main>
|
||||
<style is:global>
|
||||
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 24px 20px 80px; }
|
||||
.topbar {
|
||||
display: flex; align-items: center; gap: 20px;
|
||||
padding: 12px 20px; border-bottom: 1px solid var(--line);
|
||||
background: var(--surface); position: sticky; top: 0; z-index: 10;
|
||||
}
|
||||
.brand { font-family: var(--font-display); font-weight: 600; font-size: 1.25rem;
|
||||
color: var(--ink); text-decoration: none; letter-spacing: -0.01em; }
|
||||
.topbar nav { display: flex; gap: 16px; margin-left: 8px; }
|
||||
.topbar nav a { color: var(--ink-soft); text-decoration: none; font-size: 0.95rem; }
|
||||
.topbar nav a:hover { color: var(--ink); }
|
||||
.logout { margin-left: auto; display: flex; align-items: center; gap: 10px;
|
||||
color: var(--ink-mute); font-size: 0.9rem; }
|
||||
.logout button { background: none; border: 1px solid var(--line); border-radius: 999px;
|
||||
padding: 5px 12px; color: var(--ink-soft); cursor: pointer; }
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user