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

182 lines
5.7 KiB
TypeScript

import React, { useMemo, useRef, useState, useEffect } from "react";
import { Button } from "@heroui/react";
import { useTranslation } from "react-i18next";
import ContestsTable from "../components/ContestsTable";
import ContestCreateForm from "../components/ContestCreateForm";
import RoundsTable from "@/components/RoundsTable";
import RoundCreateForm from "@/components/RoundCreateForm";
import { useContestStore } from "@/stores/contestStore";
import { useContestRefreshStore } from "@/stores/contestRefreshStore";
type FormMode = "none" | "create" | "edit";
type RoundFormMode = "none" | "create" | "edit";
export default function AdminContestsPage() {
const { t } = useTranslation("common");
const [formMode, setFormMode] = useState<FormMode>("none");
const [roundFormMode, setRoundFormMode] = useState<RoundFormMode>("none");
const contestFormRef = useRef<HTMLDivElement | null>(null);
const roundFormRef = useRef<HTMLDivElement | null>(null);
const selectedContest = useContestStore((s) => s.selectedContest);
const setSelectedContest = useContestStore((s) => s.setSelectedContest);
const selectedRound = useContestStore((s) => s.selectedRound);
const setSelectedRound = useContestStore((s) => s.setSelectedRound);
const triggerRefresh = useContestRefreshStore((s) => s.triggerRefresh);
const isFormVisible = formMode !== "none";
const isRoundFormVisible = roundFormMode !== "none";
const formTitle = useMemo(() => {
if (formMode === "create") return t("contest_new");
if (formMode === "edit") return t("contest_edit");
return "";
}, [formMode, t]);
const roundFormTitle = useMemo(() => {
if (roundFormMode === "create") return t("round_new");
if (roundFormMode === "edit") return t("round_edit");
return "";
}, [roundFormMode, t]);
useEffect(() => {
if (formMode !== "none" && contestFormRef.current) {
contestFormRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
}
}, [formMode]);
useEffect(() => {
if (roundFormMode !== "none" && roundFormRef.current) {
roundFormRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
}
}, [roundFormMode]);
return (
<>
<ContestsTable
selectOnRowClick
showTests
onRowSelect={(contest) => {
setSelectedContest(contest);
setSelectedRound(null);
setFormMode("none");
setRoundFormMode("none");
}}
onEditContest={(contest) => {
setSelectedContest(contest);
setSelectedRound(null);
setRoundFormMode("none");
setFormMode("edit");
}}
/>
<div style={{ display: "flex", gap: 12, marginTop: 16 }}>
<Button
onPress={() => {
setSelectedContest(null);
setSelectedRound(null);
setFormMode("create");
setRoundFormMode("none");
}}
>
{t("contest_add_new") ?? "Přidat nový závod"}
</Button>
<Button
onPress={() => {
if (!selectedContest) return;
setFormMode("none");
setRoundFormMode("create");
setSelectedRound(null);
}}
isDisabled={!selectedContest}
>
{t("round_add_new") ?? "Přidat nové kolo"}
</Button>
{(isFormVisible || isRoundFormVisible) && (
<Button
variant="light"
onPress={() => {
setFormMode("none");
setRoundFormMode("none");
setSelectedRound(null);
}}
>
{t("admin_form_close") ?? "Zavřít formulář"}
</Button>
)}
</div>
{isFormVisible && (
<div style={{ marginTop: 16 }} ref={contestFormRef}>
{formTitle && <h2 style={{ fontSize: 18, fontWeight: 600 }}>{formTitle}</h2>}
{formMode === "edit" && selectedContest && (
<ContestCreateForm
mode="edit"
contest={selectedContest}
onUpdated={() => {
setFormMode("none");
triggerRefresh();
}}
/>
)}
{formMode === "create" && (
<ContestCreateForm
mode="create"
onCreated={(contest) => {
setSelectedContest(contest);
setFormMode("none");
triggerRefresh();
}}
/>
)}
</div>
)}
{isRoundFormVisible && selectedContest && (
<div style={{ marginTop: 16 }} ref={roundFormRef}>
{roundFormTitle && <h2 style={{ fontSize: 18, fontWeight: 600 }}>{roundFormTitle}</h2>}
<RoundCreateForm
mode={roundFormMode === "edit" ? "edit" : "create"}
round={roundFormMode === "edit" ? (selectedRound as any) : undefined}
contestId={selectedContest.id}
onCreated={() => {
setRoundFormMode("none");
triggerRefresh();
}}
onUpdated={() => {
setRoundFormMode("none");
triggerRefresh();
}}
/>
</div>
)}
{ selectedContest && (
<RoundsTable
contestId={selectedContest ? selectedContest.id : null}
enableEdit
showContestColumn={false}
showTests
onSelectRound={(round) => {
setSelectedRound(round);
setFormMode("none");
setRoundFormMode("edit");
}}
title={
selectedContest
? (t("contest_rounds_title_named", { name: selectedContest.name }) ??
`Kola závodu "${selectedContest.name}":`)
: ""
}
/>
)}
</>
);
}