Initial commit
This commit is contained in:
100
resources/js/components/layout/ContestsLeftPanel.tsx
Normal file
100
resources/js/components/layout/ContestsLeftPanel.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user