Auth fertig erstellt. Aktuell läuft review durch KI
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user