Auth fertig erstellt. Aktuell läuft review durch KI

This commit is contained in:
2026-08-29 14:07:44 +02:00
commit 625d026f59
70 changed files with 17032 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
import { Link, useNavigate, useRouter } from '@tanstack/react-router'
import { LogOut, UserCog } from 'lucide-react'
import { useState, type ReactNode } from 'react'
import { Button } from '#/components/ui/button.tsx'
import type { Session } from '#/lib/auth.ts'
import { authClient } from '#/lib/auth-client.ts'
type AppShellProps = {
session: Session
nav?: ReactNode
children: ReactNode
}
export function AppShell({ session, nav, children }: AppShellProps) {
const router = useRouter()
const navigate = useNavigate()
const [stopping, setStopping] = useState(false)
const impersonating = Boolean(session.session.impersonatedBy)
async function signOut() {
await authClient.signOut()
await router.invalidate()
await navigate({ to: '/login' })
}
async function stopImpersonation() {
setStopping(true)
await authClient.admin.stopImpersonating()
await router.invalidate()
setStopping(false)
await navigate({ to: '/admin' })
}
return (
<div className="flex min-h-screen flex-col bg-background">
{impersonating ? (
<div className="border-b border-amber-500/40 bg-amber-500/10 text-amber-900 dark:text-amber-200">
<div className="mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-2 md:px-6">
<p className="flex items-center gap-2 text-sm">
<UserCog className="size-4" />
Du bist als <strong>{session.user.name}</strong> ({session.user.email}) eingeloggt.
</p>
<Button
type="button"
variant="outline"
size="sm"
onClick={stopImpersonation}
disabled={stopping}
>
{stopping ? 'Beende ...' : 'Impersonation beenden'}
</Button>
</div>
</div>
) : null}
<header className="border-b border-border bg-card">
<div className="mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-3 md:px-6">
<Link
to={session.user.role === 'admin' ? '/admin' : '/dashboard'}
className="flex items-center gap-2 no-underline"
>
<img
alt="Logo Webkulisse"
src="/img/logo.png"
className="h-8 w-8 rounded-md"
/>
<span className="font-heading text-base font-bold">webkulisse</span>
</Link>
{nav ? <nav className="flex items-center gap-1">{nav}</nav> : null}
<div className="flex items-center gap-3">
<div className="hidden text-right sm:block">
<div className="text-sm font-medium leading-tight">
{session.user.name}
</div>
<div className="text-xs text-muted-foreground leading-tight">
{session.user.email}
</div>
</div>
<Button
type="button"
variant="outline"
size="sm"
onClick={signOut}
>
<LogOut />
Abmelden
</Button>
</div>
</div>
</header>
<main className="flex-1">
<div className="mx-auto max-w-6xl px-4 py-8 md:px-6">{children}</div>
</main>
</div>
)
}