import React from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { AlertTriangle, Camera, ClipboardList, MessageSquare, PlugZap, PlusCircle, QrCode, Sparkles, } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, } from '@/components/ui/sheet'; import { useEventContext } from '../context/EventContext'; import { EventSwitcher, EventMenuBar } from './EventNav'; import { ADMIN_EVENT_CREATE_PATH, ADMIN_EVENT_MEMBERS_PATH, ADMIN_EVENT_INVITES_PATH, ADMIN_EVENT_PHOTOS_PATH, ADMIN_EVENT_TASKS_PATH, ADMIN_EVENT_PHOTOBOOTH_PATH, ADMIN_EVENT_VIEW_PATH, } from '../constants'; import { formatEventDate, resolveEngagementMode, resolveEventDisplayName } from '../lib/events'; const MOBILE_SHELF_COACHMARK_KEY = 'tenant-admin:command-shelf-mobile-tip'; type CommandAction = { key: string; label: string; description: string; icon: React.ComponentType>; href: string; }; function formatNumber(value?: number | null): string { if (typeof value !== 'number') { return '–'; } if (value > 999) { return `${(value / 1000).toFixed(1)}k`; } return String(value); } export function CommandShelf() { const { events, activeEvent, isLoading, isError, refetch } = useEventContext(); const { t, i18n } = useTranslation('common'); const navigate = useNavigate(); const [mobileShelfOpen, setMobileShelfOpen] = React.useState(false); const [coachmarkDismissed, setCoachmarkDismissed] = React.useState(() => { if (typeof window === 'undefined') { return false; } return window.localStorage.getItem(MOBILE_SHELF_COACHMARK_KEY) === '1'; }); if (isLoading) { return (
{Array.from({ length: 4 }).map((_, index) => (
))}
); } if (isError) { return (

{t('commandShelf.error.title', 'Events konnten nicht geladen werden')}

{t('commandShelf.error.hint', 'Bitte versuche es erneut oder lade die Seite neu.')}

); } if (!events.length) { // Hide the empty hero entirely; dashboard content already handles the zero-events case. return null; } if (!activeEvent) { return (

{t('commandShelf.selectEvent.title', 'Kein aktives Event ausgewählt')}

{t('commandShelf.selectEvent.hint', 'Wähle unten ein Event aus, um Status und Aktionen zu sehen.')}

); } const slug = activeEvent.slug; const locale = i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE'; const formattedDate = formatEventDate(activeEvent.event_date, locale); const engagementMode = resolveEngagementMode(activeEvent); const handleActionClick = React.useCallback((href: string, closeSheet = false) => { if (closeSheet) { setMobileShelfOpen(false); } navigate(href); }, [navigate]); const handleDismissCoachmark = React.useCallback(() => { setCoachmarkDismissed(true); if (typeof window !== 'undefined') { window.localStorage.setItem(MOBILE_SHELF_COACHMARK_KEY, '1'); } }, []); const showCoachmark = !coachmarkDismissed && !mobileShelfOpen; const actionItems: CommandAction[] = [ { key: 'photos', label: t('commandShelf.actions.photos.label', 'Fotos moderieren'), description: t('commandShelf.actions.photos.desc', 'Prüfe neue Uploads, Highlights & Sperren.'), icon: Camera, href: ADMIN_EVENT_PHOTOS_PATH(slug), }, { key: 'tasks', label: t('commandShelf.actions.tasks.label', 'Aufgaben pflegen'), description: t('commandShelf.actions.tasks.desc', 'Mission Cards & Moderation im Blick.'), icon: ClipboardList, href: ADMIN_EVENT_TASKS_PATH(slug), }, { key: 'invites', label: t('commandShelf.actions.invites.label', 'QR-Codes'), description: t('commandShelf.actions.invites.desc', 'Layouts exportieren oder Links kopieren.'), icon: QrCode, href: ADMIN_EVENT_INVITES_PATH(slug), }, { key: 'photobooth', label: t('commandShelf.actions.photobooth.label', 'Photobooth anbinden'), description: t('commandShelf.actions.photobooth.desc', 'FTP-Zugang und Rate-Limits steuern.'), icon: PlugZap, href: ADMIN_EVENT_PHOTOBOOTH_PATH(slug), }, { key: 'members', label: t('eventMenu.guests', 'Team & Gäste'), description: t('commandShelf.actions.toolkit.desc', 'Broadcasts, Aufgaben & Quicklinks.'), icon: MessageSquare, href: ADMIN_EVENT_MEMBERS_PATH(slug), }, ]; const metrics = [ { key: 'photos', label: t('commandShelf.metrics.photos', 'Uploads'), value: activeEvent.photo_count, hint: t('commandShelf.metrics.total', 'gesamt'), }, { key: 'pending', label: t('commandShelf.metrics.pending', 'Moderation'), value: activeEvent.pending_photo_count, hint: t('commandShelf.metrics.pendingHint', 'offen'), }, { key: 'tasks', label: t('commandShelf.metrics.tasks', 'Aufgaben'), value: activeEvent.tasks_count, hint: t('commandShelf.metrics.tasksHint', 'aktiv'), }, { key: 'invites', label: t('commandShelf.metrics.invites', 'QR-Codes'), value: activeEvent.active_invites_count ?? activeEvent.total_invites_count, hint: t('commandShelf.metrics.invitesHint', 'live'), }, ]; const statusLabel = activeEvent.status === 'published' ? t('commandShelf.status.published', 'Veröffentlicht') : t('commandShelf.status.draft', 'Entwurf'); const liveBadge = activeEvent.is_active ? t('commandShelf.status.live', 'Live für Gäste') : t('commandShelf.status.hidden', 'Versteckt'); const engagementLabel = engagementMode === 'photo_only' ? t('commandShelf.status.photoOnly', 'Nur Foto-Modus') : t('commandShelf.status.tasksMode', 'Mission Cards aktiv'); return ( <>

{t('commandShelf.sectionTitle', 'Aktuelles Event')}

{resolveEventDisplayName(activeEvent)}

{statusLabel} {liveBadge} {engagementMode ? ( {engagementLabel} ) : null}

{formattedDate ? `${formattedDate} · ` : ''} {activeEvent.package?.name ?? t('commandShelf.packageFallback', 'Standard-Paket')}

{metrics.map((metric) => (

{formatNumber(metric.value)}

{metric.label}

{metric.hint}

))}
{actionItems.map((action) => ( ))}

{resolveEventDisplayName(activeEvent)}

{statusLabel} {liveBadge}

{formattedDate ? `${formattedDate} · ` : ''} {activeEvent.package?.name ?? t('commandShelf.packageFallback', 'Standard-Paket')}

{engagementMode ? (

{engagementLabel}

) : null}
{metrics.map((metric) => (

{formatNumber(metric.value)}

{metric.label}

{metric.hint}

))}
{showCoachmark ? (

{t('commandShelf.mobile.tip', 'Tipp: Öffne hier deine wichtigsten Aktionen am Eventtag.')}

) : null}
{t('commandShelf.mobile.sheetTitle', 'Schnellaktionen')} {t('commandShelf.mobile.sheetDescription', 'Moderation, Aufgaben und QR-Codes an einem Ort.')}
{metrics.map((metric) => (
{formatNumber(metric.value)} {metric.label}
))}
{actionItems.map((action) => ( ))}
); }