import { useEffect, useMemo, useState } from "react"; import axios from "axios"; import { Listbox, ListboxItem, type Selection } from "@heroui/react"; import { useTranslation } from "react-i18next"; import { useLanguageStore } from "@/stores/languageStore"; import { useContestStore, type ContestSummary } from "@/stores/contestStore"; import { useContestRefreshStore } from "@/stores/contestRefreshStore"; type ContestItem = ContestSummary & { description?: string | null; }; type PaginatedResponse = { data: T[]; }; type ContestsListBoxProps = { /** Zobraz pouze aktivní závody (is_active === true). Default: false */ onlyActive?: boolean; }; export default function ContestsListBox({ onlyActive = false }: ContestsListBoxProps) { const { t } = useTranslation("common"); const locale = useLanguageStore((s) => s.locale); const refreshKey = useContestRefreshStore((s) => s.refreshKey); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedKeys, setSelectedKeys] = useState(new Set([])); const setSelectedContest = useContestStore((s) => s.setSelectedContest); const selectedContest = useContestStore((s) => s.selectedContest); // předvyplň výběr podle storu useEffect(() => { if (selectedContest) { setSelectedKeys(new Set([String(selectedContest.id)])); } else { setSelectedKeys(new Set([])); } }, [selectedContest]); useEffect(() => { let active = true; (async () => { try { setLoading(true); setError(null); const res = await axios.get | ContestItem[]>( "/api/contests", { withCredentials: true, headers: { Accept: "application/json" }, params: { lang: locale }, } ); if (!active) return; const data = Array.isArray(res.data) ? res.data : (res.data as PaginatedResponse).data; setItems(data); } catch { if (!active) return; setError(t("unable_to_load_contests") ?? "Nepodařilo se načíst seznam závodů."); } finally { if (active) setLoading(false); } })(); return () => { active = false; }; }, [locale, t, refreshKey]); const visibleItems = useMemo( () => (onlyActive ? items.filter((c) => c.is_active) : items), [items, onlyActive] ); const handleSelectionChange = (keys: Selection) => { setSelectedKeys(keys); if (keys === "all") return; const id = Array.from(keys)[0]; if (!id) { setSelectedContest(null); return; } const selected = visibleItems.find((c) => String(c.id) === String(id)); if (selected) { setSelectedContest(selected); } else { setSelectedContest(null); } }; if (loading) return
{t("contests_loading") ?? "Načítám závody…"}
; if (error) return
{error}
; if (visibleItems.length === 0) { return
{t("contests_empty") ?? "Žádné závody nejsou k dispozici."}
; } return ( {visibleItems.map((item) => (
{item.name} {item.description || "—"}
))}
); }