feat: ST-006-ST-008 auth pages, middleware, nav shell en dashboard

- Login/register pages met AuthForm (useActionState + useFormStatus)
- Server Actions voor login, register, logout met Zod validatie
- Middleware checkt session cookie zonder iron-session op Edge runtime
- AppLayout met auth-check en NavBar met demo badge en actieve links
- Dashboard toont productenlijst via ProductList Client Component
- Fix: a-in-a hydration error opgelost door div plus useRouter te gebruiken

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-04-24 11:18:42 +02:00
parent 24924c9b79
commit 8017968e60
9 changed files with 375 additions and 2 deletions

40
app/(auth)/login/page.tsx Normal file
View file

@ -0,0 +1,40 @@
import Link from 'next/link'
import { loginAction } from '@/actions/auth'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { AuthForm } from '@/components/auth/auth-form'
export default function LoginPage() {
return (
<div className="min-h-screen bg-background flex items-center justify-center p-4">
<div className="w-full max-w-sm space-y-6">
{/* Logo / titel */}
<div className="text-center space-y-1">
<h1 className="text-2xl font-medium text-foreground">Scrum4Me</h1>
<p className="text-sm text-muted-foreground">Inloggen bij je account</p>
</div>
{/* Formulier */}
<div className="bg-surface-container-low rounded-xl p-6 space-y-4 border border-border">
<AuthForm action={loginAction} submitLabel="Inloggen" />
<div className="text-center text-sm text-muted-foreground">
Nog geen account?{' '}
<Link href="/register" className="text-primary hover:underline font-medium">
Registreer hier
</Link>
</div>
</div>
{/* Demo credentials */}
<div className="bg-info-container text-info-container-foreground rounded-xl p-4 text-sm space-y-1 border border-border">
<p className="font-medium">Demo-account (alleen lezen)</p>
<p>Gebruikersnaam: <span className="font-mono font-medium">demo</span></p>
<p>Wachtwoord: <span className="font-mono font-medium">demo1234</span></p>
</div>
</div>
</div>
)
}

View file

@ -0,0 +1,31 @@
import Link from 'next/link'
import { registerAction } from '@/actions/auth'
import { AuthForm } from '@/components/auth/auth-form'
export default function RegisterPage() {
return (
<div className="min-h-screen bg-background flex items-center justify-center p-4">
<div className="w-full max-w-sm space-y-6">
{/* Logo / titel */}
<div className="text-center space-y-1">
<h1 className="text-2xl font-medium text-foreground">Scrum4Me</h1>
<p className="text-sm text-muted-foreground">Nieuw account aanmaken</p>
</div>
{/* Formulier */}
<div className="bg-surface-container-low rounded-xl p-6 space-y-4 border border-border">
<AuthForm action={registerAction} submitLabel="Account aanmaken" />
<div className="text-center text-sm text-muted-foreground">
Al een account?{' '}
<Link href="/login" className="text-primary hover:underline font-medium">
Inloggen
</Link>
</div>
</div>
</div>
</div>
)
}