'use client' import { useEffect, useState } from 'react' import Image from 'next/image' import dynamic from 'next/dynamic' import { useRouter } from 'next/navigation' import { useVisitor } from '@/context/VisitorContext' import { t, tPlain } from '@/lib/i18n' import type { SectionDTO, EventAgendaDTO } from '@/lib/api/types' import AppBar from '@/components/ui/AppBar' import { trackEvent } from '@/lib/stats' const EventMiniMap = dynamic(() => import('./agenda/EventMiniMap'), { ssr: false, loading: () => (
Chargement…
), }) interface Props { section: SectionDTO slug: string configId: string languages: string[] } function formatMonthHeader(year: number, month: number, lang: string): string { const name = new Date(year, month, 1).toLocaleDateString(lang.toLowerCase(), { month: 'long' }) return name.charAt(0).toUpperCase() + name.slice(1) + ' ' + year } function eventImage(e: EventAgendaDTO): string | undefined { return e.resource?.url } function eventCoords(e: EventAgendaDTO): { lat: number; lng: number } | null { const c = e.address?.geometry?.coordinates if (!Array.isArray(c) || c.length < 2) return null return { lat: c[1], lng: c[0] } } function fullAddress(e: EventAgendaDTO): string { const a = e.address if (!a) return '' return [ [a.streetNumber, a.streetName].filter(Boolean).join(' '), [a.postCode, a.city].filter(Boolean).join(' '), a.country, ].filter(Boolean).join(', ') } function youtubeEmbedUrl(idOrUrl: string): string { if (idOrUrl.includes('youtube.com') || idOrUrl.includes('youtu.be')) { const m = idOrUrl.match(/(?:v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/) if (m) return `https://www.youtube.com/embed/${m[1]}` return idOrUrl } return `https://www.youtube.com/embed/${idOrUrl}` } export default function AgendaSection({ section, configId, languages }: Props) { const { language, setAvailableLanguages, instanceId } = useVisitor() const router = useRouter() const events = section.agenda?.events ?? [] useEffect(() => { setAvailableLanguages(languages) }, [languages]) const now = new Date() const [selectedMonth, setSelectedMonth] = useState(now.getMonth()) const [selectedYear, setSelectedYear] = useState(now.getFullYear()) const [selected, setSelected] = useState(null) const filtered = events.filter((e) => { if (!e.dateFrom) return false const d = new Date(e.dateFrom) return d.getMonth() === selectedMonth && d.getFullYear() === selectedYear }) function prevMonth() { if (selectedMonth === 0) { setSelectedMonth(11); setSelectedYear(y => y - 1) } else setSelectedMonth(m => m - 1) } function nextMonth() { if (selectedMonth === 11) { setSelectedMonth(0); setSelectedYear(y => y + 1) } else setSelectedMonth(m => m + 1) } return (
router.back()} /> {/* Month selector */}
{formatMonthHeader(selectedYear, selectedMonth, language)}
{/* Events grid */}
{filtered.length === 0 ? (

Aucun événement ce mois-ci

) : (
{filtered.map((event) => { const img = eventImage(event) return ( ) })}
)}
{/* Event detail popup */} {selected && ( setSelected(null)} /> )}
) } function EventDetail({ event, language, onClose, }: { event: EventAgendaDTO language: string onClose: () => void }) { const img = eventImage(event) const coords = eventCoords(event) const address = fullAddress(event) const yt = event.idVideoYoutube const videoLink = event.videoLink const videoResource = event.videoResource?.url return (
{img && (
)}
{event.dateFrom && (
{new Date(event.dateFrom).toLocaleDateString(language.toLowerCase(), { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })} {event.dateTo && event.dateTo !== event.dateFrom && ( <> → {new Date(event.dateTo).toLocaleDateString(language.toLowerCase(), { day: 'numeric', month: 'long' })} )}
)} {t(event.description, language) && (
)} {/* Video */} {(yt || videoLink || videoResource) && (
{yt ? (