import React from 'react';
import { Link, useParams } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import EmotionPicker from '../components/EmotionPicker';
import GalleryPreview from '../components/GalleryPreview';
import { useGuestIdentity } from '../context/GuestIdentityContext';
import { useEventStats } from '../context/EventStatsContext';
import { useEventData } from '../hooks/useEventData';
import { useGuestTaskProgress } from '../hooks/useGuestTaskProgress';
import { Sparkles, UploadCloud, Images, CheckCircle2, Users, TimerReset, X, Camera, ArrowUpRight } from 'lucide-react';
import { useTranslation, type TranslateFn } from '../i18n/useTranslation';
import { useEventBranding } from '../context/EventBrandingContext';
import type { EventBranding } from '../types/event-branding';
export default function HomePage() {
const { token } = useParams<{ token: string }>();
const { name, hydrated } = useGuestIdentity();
const stats = useEventStats();
const { event } = useEventData();
const { completedCount } = useGuestTaskProgress(token);
const { t } = useTranslation();
const { branding } = useEventBranding();
const heroStorageKey = token ? `guestHeroDismissed_${token}` : 'guestHeroDismissed';
const [heroVisible, setHeroVisible] = React.useState(() => {
if (typeof window === 'undefined') {
return true;
}
try {
return window.sessionStorage.getItem(heroStorageKey) !== '1';
} catch {
return true;
}
});
React.useEffect(() => {
if (typeof window === 'undefined') {
return;
}
try {
setHeroVisible(window.sessionStorage.getItem(heroStorageKey) !== '1');
} catch {
setHeroVisible(true);
}
}, [heroStorageKey]);
const dismissHero = React.useCallback(() => {
setHeroVisible(false);
if (typeof window === 'undefined') {
return;
}
try {
window.sessionStorage.setItem(heroStorageKey, '1');
} catch {
// ignore storage exceptions (e.g. private mode)
}
}, [heroStorageKey]);
const displayName = hydrated && name ? name : t('home.fallbackGuestName');
const eventNameDisplay = event?.name ?? t('home.hero.defaultEventName');
const latestUploadText = formatLatestUpload(stats.latestPhotoAt, t);
const accentColor = branding.primaryColor;
const secondaryAccent = branding.secondaryColor;
const statItems = React.useMemo(
() => [
{
icon: ,
label: t('home.stats.online'),
value: `${stats.onlineGuests}`,
},
{
icon: ,
label: t('home.stats.tasksSolved'),
value: `${stats.tasksSolved}`,
},
{
icon: ,
label: t('home.stats.lastUpload'),
value: latestUploadText,
},
{
icon: ,
label: t('home.stats.completedTasks'),
value: `${completedCount}`,
},
],
[completedCount, latestUploadText, stats.onlineGuests, stats.tasksSolved, t],
);
const quickActions = React.useMemo(
() => [
{
to: 'upload',
label: t('home.actions.items.upload.label'),
description: t('home.actions.items.upload.description'),
icon: ,
highlight: true,
},
{
to: 'tasks',
label: t('home.actions.items.tasks.label'),
description: t('home.actions.items.tasks.description'),
icon: ,
},
{
to: 'gallery',
label: t('home.actions.items.gallery.label'),
description: t('home.actions.items.gallery.description'),
icon: ,
},
],
[t],
);
const checklistItems = React.useMemo(
() => [
t('home.checklist.steps.first'),
t('home.checklist.steps.second'),
t('home.checklist.steps.third'),
],
[t],
);
if (!token) {
return null;
}
return (
{heroVisible && (
)}
{t('home.actions.title')}
{t('home.actions.subtitle')}
{quickActions.map((action) => (
))}
{t('home.checklist.title')}
{t('home.checklist.description')}
{checklistItems.map((item) => (
{item}
))}
);
}
function HeroCard({
name,
eventName,
tasksCompleted,
t,
branding,
onDismiss,
ctaLabel,
ctaHref,
}: {
name: string;
eventName: string;
tasksCompleted: number;
t: TranslateFn;
branding: EventBranding;
onDismiss: () => void;
ctaLabel?: string;
ctaHref?: string;
}) {
const heroTitle = t('home.hero.title').replace('{name}', name);
const heroDescription = t('home.hero.description').replace('{eventName}', eventName);
const progressMessage = tasksCompleted > 0
? t('home.hero.progress.some').replace('{count}', `${tasksCompleted}`)
: t('home.hero.progress.none');
const style = React.useMemo(() => ({
background: `linear-gradient(135deg, ${branding.primaryColor}, ${branding.secondaryColor})`,
color: '#ffffff',
fontFamily: branding.fontFamily ?? undefined,
}), [branding.fontFamily, branding.primaryColor, branding.secondaryColor]);
return (
{t('home.hero.subtitle')}
{heroTitle}
{heroDescription}
{progressMessage}
{ctaHref && ctaLabel && (
)}
);
}
function StatsRibbon({
items,
accentColor,
fontFamily,
}: {
items: { icon: React.ReactNode; label: string; value: string }[];
accentColor: string;
fontFamily?: string | null;
}) {
return (
{items.map((item) => (
{item.icon}
{item.label}
{item.value}
))}
);
}
function QuickActionCard({
action,
accentColor,
secondaryAccent,
}: {
action: { to: string; label: string; description: string; icon: React.ReactNode; highlight?: boolean };
accentColor: string;
secondaryAccent: string;
}) {
const highlightStyle = action.highlight
? {
background: `linear-gradient(120deg, ${accentColor}, ${secondaryAccent})`,
color: '#fff',
}
: undefined;
return (
{action.icon}
{action.label}
{action.description}
);
}
function formatLatestUpload(isoDate: string | null, t: TranslateFn) {
if (!isoDate) {
return t('home.latestUpload.none');
}
const date = new Date(isoDate);
if (Number.isNaN(date.getTime())) {
return t('home.latestUpload.invalid');
}
const diffMs = Date.now() - date.getTime();
const diffMinutes = Math.round(diffMs / 60000);
if (diffMinutes < 1) {
return t('home.latestUpload.justNow');
}
if (diffMinutes < 60) {
return t('home.latestUpload.minutes').replace('{count}', `${diffMinutes}`);
}
const diffHours = Math.round(diffMinutes / 60);
if (diffHours < 24) {
return t('home.latestUpload.hours').replace('{count}', `${diffHours}`);
}
const diffDays = Math.round(diffHours / 24);
return t('home.latestUpload.days').replace('{count}', `${diffDays}`);
}