import React from 'react'; import AppearanceToggleDropdown from '@/components/appearance-dropdown'; import { User, Heart, Users, PartyPopper, Camera } from 'lucide-react'; import { useEventData } from '../hooks/useEventData'; import { useOptionalEventStats } from '../context/EventStatsContext'; import { useOptionalGuestIdentity } from '../context/GuestIdentityContext'; import { SettingsSheet } from './settings-sheet'; import { useTranslation } from '../i18n/useTranslation'; import { DEFAULT_EVENT_BRANDING, useOptionalEventBranding } from '../context/EventBrandingContext'; const EVENT_ICON_COMPONENTS: Record> = { heart: Heart, guests: Users, party: PartyPopper, camera: Camera, }; function isLikelyEmoji(value: string): boolean { if (!value) { return false; } const characters = Array.from(value.trim()); if (characters.length === 0 || characters.length > 2) { return false; } return characters.some((char) => { const codePoint = char.codePointAt(0) ?? 0; return codePoint > 0x2600; }); } function getInitials(name: string): string { const words = name.split(' ').filter(Boolean); if (words.length >= 2) { return `${words[0][0]}${words[1][0]}`.toUpperCase(); } return name.substring(0, 2).toUpperCase(); } function renderEventAvatar(name: string, icon: unknown, accentColor: string, textColor: string) { if (typeof icon === 'string') { const trimmed = icon.trim(); if (trimmed) { const normalized = trimmed.toLowerCase(); const IconComponent = EVENT_ICON_COMPONENTS[normalized]; if (IconComponent) { return (
); } if (isLikelyEmoji(trimmed)) { return (
{trimmed} {name}
); } } } return (
{getInitials(name)}
); } export default function Header({ eventToken, title = '' }: { eventToken?: string; title?: string }) { const statsContext = useOptionalEventStats(); const identity = useOptionalGuestIdentity(); const { t } = useTranslation(); const brandingContext = useOptionalEventBranding(); const branding = brandingContext?.branding ?? DEFAULT_EVENT_BRANDING; const primaryForeground = '#ffffff'; const { event, status } = useEventData(); if (!eventToken) { const guestName = identity?.name && identity?.hydrated ? identity.name : null; return (
{title}
{guestName && ( {`${t('common.hi')} ${guestName}`} )}
); } const guestName = identity && identity.eventKey === eventToken && identity.hydrated && identity.name ? identity.name : null; const headerStyle: React.CSSProperties = { background: `linear-gradient(135deg, ${branding.primaryColor}, ${branding.secondaryColor})`, color: primaryForeground, fontFamily: branding.fontFamily ?? undefined, }; const accentColor = branding.secondaryColor; if (status === 'loading') { return (
{t('header.loading')}
); } if (status !== 'ready' || !event) { return null; } const stats = statsContext && statsContext.eventKey === eventToken ? statsContext : undefined; return (
{renderEventAvatar(event.name, event.type?.icon, accentColor, primaryForeground)}
{event.name}
{guestName && ( {`${t('common.hi')} ${guestName}`} )}
{stats && ( <> {`${stats.onlineGuests} ${t('header.stats.online')}`} | {stats.tasksSolved}{' '} {t('header.stats.tasksSolved')} )}
); } export {}