'use client' import { useEffect, useMemo, useState } from 'react' import { useRouter } from 'next/navigation' import dynamic from 'next/dynamic' import { useVisitor } from '@/context/VisitorContext' import { t, tPlain } from '@/lib/i18n' import type { SectionDTO, ProgrammeBlock, MapAnnotationDTO, GuidedPathDTO } from '@/lib/api/types' const EventMap = dynamic(() => import('./event/EventMap'), { ssr: false, loading: () => (
Chargement de la carte…
), }) interface Props { section: SectionDTO slug: string configId: string languages: string[] } function formatDateRange(start?: string, end?: string): string { if (!start) return '' const d1 = new Date(start) const d2 = end ? new Date(end) : null const fmt = (d: Date) => `${d.getDate().toString().padStart(2, '0')}/${(d.getMonth() + 1).toString().padStart(2, '0')}` if (!d2 || d1.toDateString() === d2.toDateString()) return fmt(d1) if (d1.getFullYear() === d2.getFullYear()) return `${fmt(d1)} → ${fmt(d2)}/${d2.getFullYear()}` return `${fmt(d1)}/${d1.getFullYear()} → ${fmt(d2)}/${d2.getFullYear()}` } function formatTime(iso?: string): string { if (!iso) return '' const d = new Date(iso) return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}` } export default function EventSection({ section, slug, configId, languages }: Props) { const { language, setAvailableLanguages } = useVisitor() const router = useRouter() useEffect(() => { setAvailableLanguages([]) }, [languages]) const event = section.event const programme = useMemo( () => [...(event?.programme ?? [])].sort((a, b) => { const ta = a.startTime ? new Date(a.startTime).getTime() : 0 const tb = b.startTime ? new Date(b.startTime).getTime() : 0 return ta - tb }), [event] ) const globalAnnotations = useMemo(() => event?.globalMapAnnotations ?? [], [event]) const activeBlock = useMemo(() => { const now = Date.now() return programme.find((b) => { if (!b.startTime || !b.endTime) return false const s = new Date(b.startTime).getTime() const e = new Date(b.endTime).getTime() return now >= s && now <= e }) ?? null }, [programme]) const [selectedBlock, setSelectedBlock] = useState(null) const [mapFullscreen, setMapFullscreen] = useState(false) const [primaryColor, setPrimaryColor] = useState('#3a6ea5') useEffect(() => { const c = getComputedStyle(document.documentElement).getPropertyValue('--color-primary').trim() if (c) setPrimaryColor(c) }, []) const centerLat = section.latitude ?? 50.85 const centerLng = section.longitude ?? 4.35 const hasMap = globalAnnotations.length > 0 || !!event?.baseSectionMapId const hasPaths = (section.event as { guidedPaths?: GuidedPathDTO[] } | undefined)?.guidedPaths?.length const paths: GuidedPathDTO[] = (section.event as { guidedPaths?: GuidedPathDTO[] } | undefined)?.guidedPaths ?? [] const description = t(section.description, language) return (
{/* Hero */}
{section.imageSource && ( // eslint-disable-next-line @next/next/no-img-element )}
{(event?.startDate || event?.endDate) && ( {formatDateRange(event?.startDate, event?.endDate)} )}

{/* Programme */} {programme.length > 0 && (
{programme.map((block, i) => { const isActive = activeBlock?.id === block.id return ( ) })}
)} {/* Carte */} {hasMap && (
{activeBlock && (activeBlock.mapAnnotations?.length ?? 0) > 0 && (
Annotations du bloc en cours en orange
)}
)} {/* Parcours */} {hasPaths && (
{paths.length} parcours disponible{paths.length > 1 ? 's' : ''}
{paths.map((p) => ( ))}
)} {/* À propos */} {description && (
)}
{/* Block detail bottom sheet */} {selectedBlock && ( setSelectedBlock(null)} /> )} {/* Fullscreen map overlay */} {mapFullscreen && (
{tPlain(section.title, language)}
)}
) } function Section({ title, children }: { title: string; children: React.ReactNode }) { return (

{title}

{children}
) } function BlockDetailSheet({ block, language, onClose, }: { block: ProgrammeBlock language: string onClose: () => void }) { return ( <>
{(block.startTime && block.endTime) && (
{formatTime(block.startTime)} – {formatTime(block.endTime)}
)}
{t(block.description, language) && (
)} {(block.mapAnnotations?.length ?? 0) > 0 && (
Lieux concernés
{block.mapAnnotations!.map((a, i) => (
))}
)}
) }