"use client"; import { useCallback, useEffect, useState } from "react"; import { Link, useLocation, useNavigate } from "@/lib/router"; import { api } from "@/lib/api"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import ProgressiveImage from "@/components/ProgressiveImage"; import type * as Types from "@/lib/types"; import { formatJalali, formatNumberPersian, formatToman, getEventCardImageUrl } from "@/lib/utils"; import type { EventsContentPage } from "@/lib/content-cms"; type EventsProps = { content: EventsContentPage; initialEvents?: Types.EventListItemSchema[]; initialSearch?: string; }; function labelPrice(event: Types.EventListItemSchema) { const price = Number(event?.price ?? 0); return price <= 0 ? "رایگان" : formatToman(price); } function modeFa(eventType: Types.EventListItemSchema["event_type"]) { return eventType === "online" ? "آنلاین" : "حضوری"; } function spotsLeft(event: Types.EventListItemSchema) { const cap = Number(event.capacity); const used = Number(event.registration_count); return cap - used; } function isAvailable(event: Types.EventListItemSchema) { const now = new Date(); const end = new Date(event.registration_end_date ?? event.start_time); const timeOk = end.getTime() > now.getTime(); return timeOk && spotsLeft(event) > 0; } function notAvailableReasonFa(event: Types.EventListItemSchema) { const now = new Date(); const end = new Date(event.registration_end_date ?? event.start_time); if (end.getTime() <= now.getTime()) return "ثبت‌نام پایان‌یافته"; if (spotsLeft(event) <= 0) return "ظرفیت تکمیل"; return "غیرقابل ثبت‌نام"; } export default function Events({ content, initialEvents = [], initialSearch = "", }: EventsProps) { const navigate = useNavigate(); const location = useLocation(); const [events, setEvents] = useState(initialEvents); const [search, setSearch] = useState(initialSearch); const [loading, setLoading] = useState(!initialEvents.length && !initialSearch); useEffect(() => { setEvents(initialEvents); }, [initialEvents]); useEffect(() => { setSearch(initialSearch); }, [initialSearch]); const loadEvents = useCallback(async () => { try { setLoading(true); const data = await api.getEvents({ search: search || undefined, statuses: ["published", "completed"], limit: 30, }); setEvents(data); } catch (error) { console.error("Error loading events:", error); } finally { setLoading(false); } }, [search]); useEffect(() => { loadEvents(); }, [loadEvents]); useEffect(() => { const params = new URLSearchParams(); if (search.trim()) { params.set("search", search.trim()); } const basePath = location.pathname || "/events"; const nextPath = params.size ? `${basePath}?${params.toString()}` : basePath; navigate(nextPath, { replace: true }); }, [location.pathname, navigate, search]); return (

{content.title}

{content.intro ?

{content.intro}

: null}
setSearch(e.target.value)} className="max-w-md" />
{loading ? (

در حال بارگذاری...

) : events.length === 0 ? (

رویدادی یافت نشد

) : (
{events.map((event) => (
{event.title} {modeFa(event.event_type)}
{formatJalali(event.start_time, false)}
ظرفیت رویداد {formatNumberPersian(Number(event?.capacity ?? 0) - Number(event?.registration_count ?? 0))} / {formatNumberPersian(Number(event?.capacity ?? 0))} نفر
هزینه‌ی ثبت‌نام {labelPrice(event)}
{isAvailable(event) ? ( ) : ( )}
))}
)}
); }