Nezobrazovat detail logu anonymnímu uživateli #2 - i v tabulce s deklarovanými výsledky byl lokátor a utíkaly informace závodníkům před uzávěrkou.
This commit is contained in:
@@ -6,7 +6,7 @@ import ResultsTables from "@/components/ResultsTables";
|
||||
import RoundEvaluationPanel from "@/components/RoundEvaluationPanel";
|
||||
import { Button, Card, CardHeader, CardBody, Divider, Tabs, Tab } from "@heroui/react";
|
||||
import { useContestStore } from "@/stores/contestStore";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import axios from "axios";
|
||||
@@ -21,7 +21,7 @@ export default function RoundDetailPage() {
|
||||
const user = useUserStore((s) => s.user);
|
||||
const [logsRefreshKey, setLogsRefreshKey] = useState(0);
|
||||
const selectedTab = searchParams.get("tab") ?? "verified";
|
||||
const [declaredFilter, setDeclaredFilter] = useState<"ALL" | "OK">("ALL");
|
||||
const [declaredFilter, setDeclaredFilter] = useState<"ALL" | "OK">("OK");
|
||||
const [finalFilter, setFinalFilter] = useState<"ALL" | "OK">("ALL");
|
||||
const [finalResultLabel, setFinalResultLabel] = useState<string | null>(null);
|
||||
const [finalResultClass, setFinalResultClass] = useState<string>("");
|
||||
@@ -29,8 +29,10 @@ export default function RoundDetailPage() {
|
||||
const [recalcLoading, setRecalcLoading] = useState(false);
|
||||
const [recalcMessage, setRecalcMessage] = useState<string | null>(null);
|
||||
const [recalcError, setRecalcError] = useState<string | null>(null);
|
||||
const [finalPublished, setFinalPublished] = useState(false);
|
||||
const { run } = useRoundEvaluationRun(rId);
|
||||
const { t } = useTranslation("common");
|
||||
const isAdmin = !!user?.is_admin;
|
||||
const roundDeadline =
|
||||
selectedRound?.id === rId ? selectedRound?.logs_deadline ?? null : null;
|
||||
const anonymousUploadClosed = () => {
|
||||
@@ -78,6 +80,45 @@ export default function RoundDetailPage() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isAdmin) {
|
||||
setFinalPublished(true);
|
||||
return;
|
||||
}
|
||||
if (!rId) {
|
||||
setFinalPublished(false);
|
||||
return;
|
||||
}
|
||||
const officialRunId =
|
||||
selectedRound?.id === rId ? selectedRound?.official_evaluation_run_id ?? null : null;
|
||||
if (!officialRunId) {
|
||||
setFinalPublished(false);
|
||||
return;
|
||||
}
|
||||
let active = true;
|
||||
(async () => {
|
||||
try {
|
||||
const res = await axios.get<{ status?: string | null; result_type?: string | null }>(
|
||||
`/api/evaluation-runs/${officialRunId}`,
|
||||
{
|
||||
headers: { Accept: "application/json" },
|
||||
withCredentials: true,
|
||||
}
|
||||
);
|
||||
if (!active) return;
|
||||
const isFinal =
|
||||
res.data?.status === "SUCCEEDED" && res.data?.result_type === "FINAL";
|
||||
setFinalPublished(isFinal);
|
||||
} catch {
|
||||
if (!active) return;
|
||||
setFinalPublished(false);
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [rId, selectedRound?.official_evaluation_run_id, isAdmin]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
@@ -127,16 +168,6 @@ export default function RoundDetailPage() {
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-3 flex items-center gap-3 text-sm">
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="finalFilter"
|
||||
value="ALL"
|
||||
checked={finalFilter === "ALL"}
|
||||
onChange={() => setFinalFilter("ALL")}
|
||||
/>
|
||||
<span>{filterAllLabel}</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
@@ -147,6 +178,16 @@ export default function RoundDetailPage() {
|
||||
/>
|
||||
<span>{filterOkLabel}</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="finalFilter"
|
||||
value="ALL"
|
||||
checked={finalFilter === "ALL"}
|
||||
onChange={() => setFinalFilter("ALL")}
|
||||
/>
|
||||
<span>{filterAllLabel}</span>
|
||||
</label>
|
||||
</div>
|
||||
<ResultsTables
|
||||
roundId={rId}
|
||||
@@ -154,6 +195,8 @@ export default function RoundDetailPage() {
|
||||
filter={finalFilter}
|
||||
mode="final"
|
||||
showResultTypeLabel={false}
|
||||
isFinalPublished={finalPublished}
|
||||
isAdmin={isAdmin}
|
||||
onResultTypeChange={(label, className, resultType) => {
|
||||
setFinalResultLabel(label);
|
||||
setFinalResultClass(className);
|
||||
@@ -174,16 +217,6 @@ export default function RoundDetailPage() {
|
||||
<p>{t("declared_note_line3") ?? "Deklarované výsledky jsou uspořádány na základě údajů v hlavičce EDI souborů v řádce CQSOP=. Další sloupce rovněž zobrazují data z deníku, které jsou kontrolovány pouze na správnost formátu zápisu."}</p>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center gap-3 text-sm">
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="declaredFilter"
|
||||
value="ALL"
|
||||
checked={declaredFilter === "ALL"}
|
||||
onChange={() => setDeclaredFilter("ALL")}
|
||||
/>
|
||||
<span>{filterAllLabel}</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
@@ -194,6 +227,16 @@ export default function RoundDetailPage() {
|
||||
/>
|
||||
<span>{filterOkLabel}</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="declaredFilter"
|
||||
value="ALL"
|
||||
checked={declaredFilter === "ALL"}
|
||||
onChange={() => setDeclaredFilter("ALL")}
|
||||
/>
|
||||
<span>{filterAllLabel}</span>
|
||||
</label>
|
||||
{user && (
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -208,7 +251,13 @@ export default function RoundDetailPage() {
|
||||
</div>
|
||||
{recalcMessage && <div className="mb-2 text-sm text-green-600">{recalcMessage}</div>}
|
||||
{recalcError && <div className="mb-2 text-sm text-red-600">{recalcError}</div>}
|
||||
<ResultsTables roundId={rId} contestId={cId} filter={declaredFilter} />
|
||||
<ResultsTables
|
||||
roundId={rId}
|
||||
contestId={cId}
|
||||
filter={declaredFilter}
|
||||
isFinalPublished={finalPublished}
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
</CardBody>
|
||||
</Tab>
|
||||
<Tab key="logs" title={t("uploaded_logs_tab") ?? "Nahrané logy"}>
|
||||
|
||||
Reference in New Issue
Block a user