feat: dark cinematic hero + public memory write section

- HeroSection: animated warmgold/burgundy/indigo orbs on #060304 bg, film grain CSS overlay, larger glowing typography
- WriteSection: new public component – collapsible form (name optional, title, textarea) posts to /api/memories without auth, shows success state and refreshes page
- API: remove isAdmin() guard from POST /api/memories, accept author field
- DB: migration adds author TEXT column to memories (try/catch for existing DBs)
- Types: add author: string | null to Memory type
- MemorySection: display "— [Name]" beneath date when author is set
- globals.css: grain keyframe animation for film-texture overlay

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
denshooter
2026-02-16 01:45:57 +01:00
parent 8b4dc2e7e6
commit 279a07e4eb
8 changed files with 303 additions and 30 deletions
+3 -7
View File
@@ -20,11 +20,7 @@ export async function GET() {
}
export async function POST(req: NextRequest) {
if (!isAdmin()) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const { title, content } = await req.json()
const { title, content, author } = await req.json()
if (!title?.trim() || !content?.trim()) {
return NextResponse.json(
{ error: 'Titel und Inhalt sind erforderlich' },
@@ -34,8 +30,8 @@ export async function POST(req: NextRequest) {
const db = getDb()
const result = db
.prepare('INSERT INTO memories (title, content) VALUES (?, ?)')
.run(title.trim(), content.trim())
.prepare('INSERT INTO memories (title, content, author) VALUES (?, ?, ?)')
.run(title.trim(), content.trim(), author?.trim() || null)
const memory = db
.prepare('SELECT * FROM memories WHERE id = ?')
.get(result.lastInsertRowid)