import React from 'react';
import { Location, useLocation, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Sparkles, ShieldCheck, Images, ArrowRight, Loader2 } from 'lucide-react';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import AppearanceToggleDropdown from '@/components/appearance-dropdown';
import AppLogoIcon from '@/components/app-logo-icon';
import { useAuth } from '../auth/context';
import { ADMIN_HOME_PATH } from '../constants';
interface LocationState {
from?: Location;
}
const featureIcons = [Sparkles, ShieldCheck, Images];
export default function LoginPage(): JSX.Element {
const { status, login } = useAuth();
const { t } = useTranslation('auth');
const location = useLocation();
const navigate = useNavigate();
const searchParams = React.useMemo(() => new URLSearchParams(location.search), [location.search]);
const oauthError = searchParams.get('error');
React.useEffect(() => {
if (status === 'authenticated') {
navigate(ADMIN_HOME_PATH, { replace: true });
}
}, [status, navigate]);
const redirectTarget = React.useMemo(() => {
const state = location.state as LocationState | null;
if (state?.from) {
const from = state.from;
const search = from.search ?? '';
const hash = from.hash ?? '';
return `${from.pathname}${search}${hash}`;
}
return ADMIN_HOME_PATH;
}, [location.state]);
const featureList = React.useMemo(() => {
const raw = t('login.features', { returnObjects: true }) as unknown;
if (!Array.isArray(raw)) {
return [] as Array<{ text: string; Icon: typeof Sparkles }>;
}
return (raw as string[]).map((entry, index) => ({
text: entry,
Icon: featureIcons[index % featureIcons.length],
}));
}, [t]);
const heroTagline = t('login.hero_tagline', 'Stay in control, stay relaxed');
const heroTitle = t('login.hero_title', 'Your cockpit for every Fotospiel event');
const heroSubtitle = t('login.hero_subtitle', 'Moderation, uploads, and communication come together in one calm workspace — on desktop and mobile.');
const panelTitle = t('login.panel_title', t('login.title', 'Event Admin'));
const leadCopy = t('login.lead', 'Use our secure OAuth login and land directly in the event dashboard.');
const panelCopy = t('login.panel_copy', 'Sign in with your Fotospiel admin access. OAuth 2.1 and clear role permissions keep your account protected.');
const supportCopy = t('login.support', "Need access? Contact your event team or email support@fotospiel.de — we're happy to help.");
const isLoading = status === 'loading';
return (
{t('login.badge', 'Fotospiel Event Admin')}
Fotospiel
{heroTagline}
{heroTitle}
{heroSubtitle}
{heroTagline}
{heroTitle}
{heroSubtitle}
{featureList.length ? (
{featureList.map(({ text, Icon }, index) => (
-
{text}
))}
) : null}
{leadCopy}
{t('login.badge', 'Fotospiel Event Admin')}
{oauthError ? (
{t('login.oauth_error_title')}
{t('login.oauth_error', { message: oauthError })}
) : null}
{featureList.length ? (
{featureList.map(({ text, Icon }, index) => (
))}
) : null}
);
}