131 lines
8.3 KiB
TypeScript
131 lines
8.3 KiB
TypeScript
import AppLogoIcon from '@/components/app-logo-icon';
|
||
import { Button } from '@/components/ui/button';
|
||
import { useLocalizedRoutes } from '@/hooks/useLocalizedRoutes';
|
||
import { Link } from '@inertiajs/react';
|
||
import { Sparkles, Camera, ShieldCheck } from 'lucide-react';
|
||
import { type PropsWithChildren } from 'react';
|
||
import { useTranslation } from 'react-i18next';
|
||
|
||
interface AuthLayoutProps {
|
||
name?: string;
|
||
title?: string;
|
||
description?: string;
|
||
logoSrc?: string;
|
||
logoAlt?: string;
|
||
}
|
||
|
||
export default function AuthSimpleLayout({ children, title, description, name, logoSrc, logoAlt }: PropsWithChildren<AuthLayoutProps>) {
|
||
const { t } = useTranslation('auth');
|
||
const { localizedPath } = useLocalizedRoutes();
|
||
const brandLabel = name ?? 'Fotospiel';
|
||
|
||
const highlights = [
|
||
{
|
||
icon: Sparkles,
|
||
title: t('login.highlights.moments', 'Momente in Echtzeit teilen'),
|
||
description: t('login.highlights.moments_description', 'Uploads landen sofort in der Event-Galerie – ohne App-Download.'),
|
||
},
|
||
{
|
||
icon: Camera,
|
||
title: t('login.highlights.branding', 'Branding & Slideshows, die begeistern'),
|
||
description: t('login.highlights.branding_description', 'Konfiguriere Slideshow, Wasserzeichen und Aufgaben für dein Event.'),
|
||
},
|
||
{
|
||
icon: ShieldCheck,
|
||
title: t('login.highlights.privacy', 'Sicherer Zugang über Tokens'),
|
||
description: t('login.highlights.privacy_description', 'Eventzugänge bleiben geschützt – DSGVO-konform mit Join Tokens.'),
|
||
},
|
||
];
|
||
|
||
return (
|
||
<div className="relative min-h-svh overflow-hidden bg-slate-950">
|
||
<div
|
||
aria-hidden
|
||
className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,_rgba(255,137,170,0.35),_transparent_60%),radial-gradient(ellipse_at_bottom,_rgba(99,102,241,0.35),_transparent_55%)] blur-3xl"
|
||
/>
|
||
<div className="absolute inset-0 bg-gradient-to-br from-gray-950 via-gray-950/70 to-[#1a0f1f]" aria-hidden />
|
||
|
||
<div className="relative z-10 flex min-h-svh items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
|
||
<div className="w-full max-w-5xl">
|
||
<div className="grid overflow-hidden rounded-3xl border border-white/15 bg-white/95 shadow-2xl shadow-fuchsia-500/10 backdrop-blur-2xl dark:border-gray-800/70 dark:bg-gray-950/85 md:grid-cols-[1.08fr_1fr]">
|
||
<div className="relative hidden flex-col justify-between gap-10 overflow-hidden bg-gradient-to-br from-[#1d1937] via-[#2a1134] to-[#ff5f87] p-10 text-white md:flex">
|
||
<div aria-hidden className="pointer-events-none absolute inset-0 opacity-45">
|
||
<div className="absolute -inset-20 bg-[radial-gradient(circle_at_top,_rgba(255,255,255,0.4),_transparent_55%),radial-gradient(circle_at_bottom_left,_rgba(236,72,153,0.35),_transparent_60%)]" />
|
||
</div>
|
||
|
||
<div className="relative z-10 flex flex-col gap-6">
|
||
<div className="flex items-center gap-3 text-xs font-semibold uppercase tracking-[0.45em] text-white/70">
|
||
<Sparkles className="h-4 w-4" aria-hidden />
|
||
<span className="font-sans-marketing">{t('login.hero_tagline', 'Event-Tech mit Herz')}</span>
|
||
</div>
|
||
|
||
<div className="space-y-4">
|
||
<h2 className="font-display text-3xl leading-tight sm:text-4xl">
|
||
{t('login.hero_heading', 'Willkommen zurück bei Fotospiel')}
|
||
</h2>
|
||
<p className="text-sm text-white/80 sm:text-base">
|
||
{t('login.hero_subheading', 'Verwalte Events, Galerien und Gästelisten in einem liebevoll gestalteten Dashboard.')}
|
||
</p>
|
||
</div>
|
||
|
||
<ul className="space-y-4">
|
||
{highlights.map(({ icon: Icon, title: highlightTitle, description: highlightDescription }) => (
|
||
<li key={highlightTitle} className="flex items-start gap-3">
|
||
<span className="mt-1 flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-white/15 backdrop-blur">
|
||
<Icon className="h-4 w-4" aria-hidden />
|
||
</span>
|
||
<span className="space-y-1">
|
||
<p className="text-sm font-semibold tracking-tight sm:text-base">{highlightTitle}</p>
|
||
<p className="text-xs text-white/70 sm:text-sm">{highlightDescription}</p>
|
||
</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
|
||
<div className="relative z-10 flex items-center justify-between gap-4 rounded-2xl border border-white/15 bg-white/10 p-4 text-xs text-white/80 sm:text-sm">
|
||
<div className="space-y-1">
|
||
<p className="font-semibold">{t('login.hero_footer.headline', 'Noch kein Account?')}</p>
|
||
<p>{t('login.hero_footer.subline', 'Entdecke unsere Packages und erlebe Fotospiel live.')}</p>
|
||
</div>
|
||
<Button asChild variant="secondary" className="h-10 rounded-full bg-white px-5 text-sm font-semibold text-gray-900 shadow-md shadow-white/30 transition hover:bg-white/90">
|
||
<Link href={localizedPath('/packages')}>{t('login.hero_footer.cta', 'Packages entdecken')}</Link>
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="relative bg-white/95 px-6 py-10 sm:px-10 dark:bg-gray-950/90">
|
||
<div className="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-pink-400 via-fuchsia-400 to-sky-400" aria-hidden />
|
||
<div className="relative z-10 flex flex-col gap-8">
|
||
<div className="flex flex-col items-center gap-4 text-center">
|
||
<Link href={localizedPath('/')} className="group flex flex-col items-center gap-3 font-medium">
|
||
{logoSrc ? (
|
||
<img
|
||
src={logoSrc}
|
||
alt={logoAlt ?? brandLabel}
|
||
className="h-16 w-auto transition duration-300 group-hover:scale-105"
|
||
/>
|
||
) : (
|
||
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-[#ff8ab4] to-[#a855f7] shadow-lg shadow-pink-400/40 transition duration-300 group-hover:scale-105">
|
||
<AppLogoIcon className="size-8 fill-white" aria-hidden />
|
||
</span>
|
||
)}
|
||
<span className="text-2xl font-semibold font-display text-gray-900 dark:text-white">{brandLabel}</span>
|
||
</Link>
|
||
|
||
<div className="space-y-2">
|
||
<h1 className="text-2xl font-semibold tracking-tight text-gray-900 dark:text-white sm:text-3xl">{title}</h1>
|
||
<p className="text-sm text-muted-foreground sm:text-base">{description}</p>
|
||
</div>
|
||
</div>
|
||
|
||
{children}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|