import { useEffect, useState } from "react"; import axios from "axios"; import { Card, CardHeader, CardBody, Divider } from "@heroui/react"; import { useLanguageStore } from "@/stores/languageStore"; import { useContestStore, type ContestSummary, type RoundSummary } from "@/stores/contestStore"; import { useTranslation } from "react-i18next"; type RoundDetailProps = { roundId: number; }; type RoundDetailData = RoundSummary & { contest_id: number; contest?: ContestSummary | null; description?: string | Record | null; logs_deadline?: string | null; start_time: string | null; end_time: string | null; rule_set_id?: number | null; rule_set?: { id: number; name: string } | null; preliminary_evaluation_run_id?: number | null; official_evaluation_run_id?: number | null; test_evaluation_run_id?: number | null; }; function parseRoundDate(value: string | null): Date | null { if (!value) return null; const direct = new Date(value); if (!Number.isNaN(direct.getTime())) return direct; const normalized = value.includes("T") ? value : value.replace(" ", "T"); const fallback = new Date(normalized); if (!Number.isNaN(fallback.getTime())) return fallback; return null; } function formatDateTime(value: string | null, locale: string): string { if (!value) return "—"; const date = parseRoundDate(value); if (!date) return value; return date.toLocaleString(locale); } function isPastDeadline(value: string | null): boolean { const date = parseRoundDate(value); if (!date) return false; return (new Date() > date); } const resolveTranslation = (field: any, locale: string): string => { if (!field) return ""; if (typeof field === "string") return field; if (typeof field === "object") { if (field[locale]) return field[locale]; if (field["en"]) return field["en"]; const first = Object.values(field)[0]; return typeof first === "string" ? first : ""; } return String(field); }; export default function RoundDetail({ roundId }: RoundDetailProps) { const { t } = useTranslation("common"); const locale = useLanguageStore((s) => s.locale); const setSelectedContest = useContestStore((s) => s.setSelectedContest); const setSelectedRound = useContestStore((s) => s.setSelectedRound); const [detail, setDetail] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { if (!roundId) return; let active = true; (async () => { try { setLoading(true); setError(null); const res = await axios.get(`/api/rounds/${roundId}`, { headers: { Accept: "application/json" }, params: { lang: locale }, withCredentials: true, }); if (!active) return; setDetail(res.data); // set store for breadcrumbs/overview if (res.data.contest) { setSelectedContest({ id: res.data.contest.id, name: resolveTranslation((res.data as any).contest.name, locale), description: resolveTranslation((res.data as any).contest.description ?? null, locale), is_active: res.data.contest.is_active, is_mcr: res.data.contest.is_mcr, is_sixhr: res.data.contest.is_sixhr, start_time: res.data.contest.start_time ?? null, duration: res.data.contest.duration ?? 0, }); } setSelectedRound({ id: res.data.id, contest_id: res.data.contest_id, name: resolveTranslation(res.data.name, locale), description: resolveTranslation(res.data.description ?? null, locale), is_active: res.data.is_active, is_test: res.data.is_test, is_sixhr: res.data.is_sixhr, start_time: res.data.start_time, end_time: res.data.end_time, logs_deadline: res.data.logs_deadline ?? null, preliminary_evaluation_run_id: res.data.preliminary_evaluation_run_id ?? null, official_evaluation_run_id: res.data.official_evaluation_run_id ?? null, test_evaluation_run_id: res.data.test_evaluation_run_id ?? null, }); } catch { if (!active) return; setError("Nepodařilo se načíst detail kola."); } finally { if (active) setLoading(false); } })(); return () => { active = false; }; }, [roundId, locale, setSelectedContest, setSelectedRound]); return (
{detail ? resolveTranslation(detail.name, locale) : t("round_name") ?? "Kolo"} {detail?.description && ( {resolveTranslation(detail.description, locale)} )}
{error &&

{error}

} {loading &&

Načítám detail…

} {detail && !loading && (
{t("round_schedule") ?? "Termín"}: {formatDateTime(detail.start_time, locale)} — {formatDateTime(detail.end_time, locale)}
{detail.logs_deadline && (
{t("round_logs_deadline") ?? "Logy do"}: {formatDateTime(detail.logs_deadline, locale)} {detail.logs_deadline && isPastDeadline(detail.logs_deadline) && ( {t("round_logs_deadline_passed") ?? "Termín pro nahrání logů již vypršel."} )}
)}
{t("round_active") ?? "Aktivní"}: {detail.is_active ? (t("yes") ?? "Ano") : (t("no") ?? "Ne")}
{detail.is_test && (
{t("round_test") ?? "Test"}: {t("yes") ?? "Ano"}
)}
6h: {detail.is_sixhr ? (t("yes") ?? "Ano") : (t("no") ?? "Ne")}
{(detail.rule_set || detail.rule_set_id) && (
Ruleset: {detail.rule_set?.name ?? `#${detail.rule_set_id}`}
)}
)}
); }