Files
vkv/resources/js/components/layout/ContestsLeftPanel.tsx
Zdeněk Burda 41e3ce6f25 Initial commit
2026-01-09 21:26:40 +01:00

101 lines
2.9 KiB
TypeScript

import React, { useEffect } from "react";
import { useParams } from "react-router-dom";
import { useContestStore } from "@/stores/contestStore";
import { useLanguageStore } from "@/stores/languageStore";
import ContestsOverview from "@/components/ContestsOverview";
import RoundsOverview from "@/components/RoundsOverview";
import axios from "axios";
export default function ContestsLeftPanel() {
const { contestId } = useParams<{ contestId?: string }>();
const { roundId } = useParams();
const cId = contestId ? Number(contestId) : null;
const rId = roundId ? Number(roundId) : null;
const selectedContest = useContestStore((s) => s.selectedContest);
const setSelectedContest = useContestStore((s) => s.setSelectedContest);
const clearSelection = useContestStore((s) => s.clearSelection);
const locale = useLanguageStore((s) => s.locale);
// pokud je contestId v URL, načti a ulož do storu
useEffect(() => {
const numericId = contestId ? Number(contestId) : null;
if (!numericId) {
clearSelection();
return;
}
if (selectedContest && selectedContest.id === numericId) {
// už máme data v store, nefetchuj
return;
}
let active = true;
(async () => {
try {
const res = await axios.get(`/api/contests/${numericId}`, {
headers: { Accept: "application/json" },
params: { lang: locale },
withCredentials: true,
});
if (!active) return;
const data = res.data;
const rounds = Array.isArray(data.rounds)
? data.rounds.map((r: any) => ({
id: r.id,
contest_id: r.contest_id,
name: r.name,
description: r.description ?? null,
is_active: r.is_active,
is_test: r.is_test,
is_sixhr: r.is_sixhr,
start_time: r.start_time ?? null,
end_time: r.end_time ?? null,
logs_deadline: r.logs_deadline ?? null,
}))
: [];
setSelectedContest({
id: data.id,
name: data.name,
description: data.description ?? null,
is_active: data.is_active,
is_mcr: data.is_mcr,
is_sixhr: data.is_sixhr,
start_time: data.start_time ?? null,
duration: data.duration ?? 0,
rounds,
});
} catch {
// při chybě jen nevybere nic
}
})();
return () => {
active = false;
};
}, [contestId, locale, clearSelection, setSelectedContest]);
return (
<div className="space-y-6">
<div>
<ContestsOverview
onlyActive={true}
showTests={false}
/>
</div>
{rId && (
<div>
<RoundsOverview
contestId={cId}
roundsFromStore={selectedContest ? selectedContest.rounds : null}
showTests={false}
/>
</div>
)}
</div>
);
}