Files
fotospiel-app/resources/js/layouts/auth/auth-simple-layout.tsx

131 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}