"use client"; import { useState, useMemo } from "react"; import Image from "next/image"; import { Calendar, Sparkles, User } from "lucide-react"; import { SectionHeading } from "@/components/ui/SectionHeading"; import { Reveal } from "@/components/ui/Reveal"; import { SignupModal } from "@/components/ui/SignupModal"; import type { OpenDayEvent, OpenDayClass } from "@/lib/openDay"; import type { SiteContent } from "@/types"; interface OpenDayProps { data: { event: OpenDayEvent; classes: OpenDayClass[]; }; popups?: SiteContent["popups"]; teamMembers?: { name: string; image: string }[]; } function formatDateRu(dateStr: string): string { const d = new Date(dateStr + "T12:00:00"); return d.toLocaleDateString("ru-RU", { weekday: "long", day: "numeric", month: "long", }); } export function OpenDay({ data, popups, teamMembers }: OpenDayProps) { const { event, classes } = data; const [signup, setSignup] = useState<{ classId: number; label: string } | null>(null); const trainerPhotos = useMemo(() => { const map: Record = {}; if (teamMembers) { for (const m of teamMembers) { if (m.image) map[m.name] = m.image; } } return map; }, [teamMembers]); // Group classes by hall const hallGroups = useMemo(() => { const groups: Record = {}; for (const cls of classes) { if (!groups[cls.hall]) groups[cls.hall] = []; groups[cls.hall].push(cls); } // Sort each hall's classes by time for (const hall in groups) { groups[hall].sort((a, b) => a.startTime.localeCompare(b.startTime)); } return groups; }, [classes]); const halls = Object.keys(hallGroups); if (classes.length === 0) return null; return (
{event.title}
{formatDateRu(event.date)}
{/* Pricing info */}

{event.pricePerClass} BYN за занятие

{event.discountPrice > 0 && event.discountThreshold > 0 && (

От {event.discountThreshold} занятий — {event.discountPrice} BYN за каждое!

)}
{event.description && (

{event.description}

)} {/* Schedule Grid */}
{halls.length === 1 ? ( // Single hall — simple list

{halls[0]}

{hallGroups[halls[0]].map((cls) => ( ))}
) : ( // Multiple halls — columns
{halls.map((hall) => (

{hall}

{hallGroups[hall].map((cls) => ( ))}
))}
)}
{signup && ( setSignup(null)} subtitle={signup.label} endpoint="/api/open-day-register" extraBody={{ classId: signup.classId, eventId: event.id }} successMessage={popups?.successMessage} waitingMessage={popups?.waitingListText} errorMessage={popups?.errorMessage} instagramHint={popups?.instagramHint} /> )}
); } function ClassCard({ cls, maxParticipants = 0, onSignup, trainerPhoto, }: { cls: OpenDayClass; maxParticipants?: number; onSignup: (info: { classId: number; label: string }) => void; trainerPhoto?: string; }) { const label = `${cls.style} · ${cls.trainer} · ${cls.startTime}–${cls.endTime}`; if (cls.cancelled) { return (
{cls.startTime}–{cls.endTime}

{cls.trainer} · {cls.style}

Отменено
); } const isFull = maxParticipants > 0 && cls.bookingCount >= maxParticipants; return (
{/* Trainer photo */}
{/* Trainer name — clickable to bio */} {/* Time + style */}
{cls.startTime}–{cls.endTime} {cls.style}
{/* Badges */}
{maxParticipants > 0 && ( {cls.bookingCount}/{maxParticipants} мест )}
{/* Book button */}
); }