const { useMemo: useSportsMemo, useState: useSportsState } = React; const SPORTS_DATA = window.KOMITET_SPORTS; const SPORTS_BARS = window.WC.bars; function sportsDate(value) { return new Date(value + "T12:00:00"); } function eventStart(event) { return new Date(event.date + "T" + event.time + ":00+03:00"); } function monthTitle(date) { return new Intl.DateTimeFormat("ru-RU", { day: "numeric", month: "long" }).format(sportsDate(date)); } function dayTitle(date) { return new Intl.DateTimeFormat("ru-RU", { weekday: "long", day: "numeric", month: "long" }).format(sportsDate(date)); } function SportsIcon({ sport }) { if (sport === "football") { return ; } if (sport === "hockey") { return ; } if (sport === "tennis") { return ; } return ; } function eventPubIds(event) { const byRule = SPORTS_DATA.pubRules .filter((rule) => rule.sport === event.sport && (!rule.tournament || rule.tournament === event.tournament)) .flatMap((rule) => rule.pubIds); return [...new Set([...event.pubIds, ...byRule])]; } function pubName(id) { const bar = SPORTS_BARS.find((item) => item.id === id); if (!bar) return ""; if (id === "brussels_msk") return "Брюссель МСК"; if (id === "brussels_spb") return "Брюссель СПБ"; return bar.name; } function pubLabel(pubIds) { if (pubIds.length === SPORTS_BARS.length) return "Все пабы"; return pubIds.map(pubName).filter(Boolean).join(" · "); } function EventRow({ event, sport, onOpenBars }) { const pubIds = eventPubIds(event); return (
{sport.label} · {event.tournament}
{event.time}
{event.title}
{pubLabel(pubIds)}
); } function DaySchedule({ date, events, sports, onOpenBars, label }) { return (
{label} {date ? dayTitle(date) : ""}
{events.length > 0 ? (
{events.map((event) => )}
) : (
Трансляций пока нет
)}
); } function SportLanding() { const [selectedSport, setSelectedSport] = useSportsState("all"); const [showBars, setShowBars] = useSportsState(false); const [selectedBarIds, setSelectedBarIds] = useSportsState(null); function openBars(pubIds) { setSelectedBarIds(pubIds || null); setShowBars(true); } const now = new Date(); const nextDate = SPORTS_DATA.events .filter((event) => eventStart(event) >= now) .sort((a, b) => a.date.localeCompare(b.date) || a.time.localeCompare(b.time, "ru"))[0]?.date; const activeEvents = SPORTS_DATA.events .filter((event) => event.date === nextDate && eventStart(event) >= now) .sort((a, b) => a.time.localeCompare(b.time, "ru")); const monthEvents = SPORTS_DATA.events .filter((event) => eventStart(event) >= now) .filter((event) => selectedSport === "all" || event.sport === selectedSport) .sort((a, b) => a.date.localeCompare(b.date) || a.time.localeCompare(b.time, "ru")); const sports = Object.fromEntries(SPORTS_DATA.sports.map((sport) => [sport.id, sport])); return (
КОМИТЕТ

Спорт в пабах

Избранные трансляции на больших экранах

Расписание месяца

Все трансляции

{SPORTS_DATA.sports.map((sport) => ( ))}
{monthEvents.length ? monthEvents.map((event) => (
{monthTitle(event.date)}
{event.tournament} {event.title}
)) :
В этом разделе трансляции появятся после подтверждения.
}
Где смотреть Санкт-Петербург и Москва
Расписание обновляется после подтверждения трансляций. Время московское.
{showBars && setShowBars(false)} />}
); } ReactDOM.createRoot(document.getElementById("root")).render();