Files
LiquidCode_Frontend/src/views/home/contest/Submissions.tsx
Виталий Лавшонок 69655dda82 contests
2025-11-07 19:04:45 +03:00

130 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SubmissionItem from "./SubmissionItem";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
import { FC, useEffect } from "react";
import {
Contest,
fetchMySubmissions,
setContestStatus,
} from "../../../redux/slices/contests";
import { arrowLeft } from "../../../assets/icons/header";
import { useNavigate } from "react-router-dom";
export interface Mission {
id: number;
authorId: number;
name: string;
difficulty: "Easy" | "Medium" | "Hard";
tags: string[];
timeLimit: number;
memoryLimit: number;
createdAt: string;
updatedAt: string;
}
interface SubmissionsProps {
contest: Contest;
}
const Submissions: FC<SubmissionsProps> = ({ contest }) => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const { submissions, status } = useAppSelector(
(state) => state.contests.fetchMySubmissions
);
useEffect(() => {
if (contest && contest.id) dispatch(fetchMySubmissions(contest.id));
}, [contest]);
useEffect(() => {
if (status == "successful") {
dispatch(setContestStatus({ key: "fetchMySubmissions", status: "idle" }));
}
}, [status]);
const checkStatus = (status: string) => {
if (status == "IncorrectAnswer") return "wronganswer";
if (status == "TimeLimitError") return "timelimit";
return undefined;
};
const solvedCount = (contest.missions ?? []).filter((mission) =>
submissions.some(
(s) =>
s.solution.missionId === mission.id &&
s.solution.status === "Accepted: All tests passed"
)
).length;
const totalCount = contest.missions?.length ?? 0;
return (
<div className="h-full w-[calc(100%+250px)] box-border overflow-y-scroll overflow-x-hidden thin-scrollbar p-[20px] flex flex-col gap-[20px]">
<div className="">
<div className="h-[50px] text-[40px] text-liquid-white font-bold">
{contest.name}
</div>
<div className="flex justify-between h-[24px] items-center gap-[10px]">
<div className="flex items-center">
<img
src={arrowLeft}
className="cursor-pointer"
onClick={() => {
navigate(`/contest/${contest.id}`);
}}
/>
<span className="text-liquid-light font-bold text-[18px]">
Контест #{contest.id}
</span>
</div>
<div className="text-liquid-white text-[16px] font-bold">{`${solvedCount}/${totalCount} Решено`}</div>
</div>
</div>
<div>
<div className="grid grid-cols-7 text-center items-center h-[43px] mb-[10px] text-[16px] font-bold text-liquid-white">
<div>Посылка</div>
<div>Когда</div>
<div>Задача</div>
<div>Язык</div>
<div>Вердикт</div>
<div>Время</div>
<div>Память</div>
</div>
{!submissions || submissions.length == 0 ? (
<div className="text-liquid-brightmain text-[16px] font-medium text-center mt-[50px]">Вы еще ничего не отсылали</div>
) : (
<>
{submissions.map((v, i) => (
<SubmissionItem
key={i}
id={v.id ?? 0}
datetime={v.solution.time}
missionId={v.solution.missionId}
language={v.solution.language}
verdict={
v.solution.testerMessage?.includes("Compilation failed")
? "Compilation failed"
: v.solution.testerMessage
}
duration={1000}
memory={256 * 1024 * 1024}
type={i % 2 ? "second" : "first"}
status={
v.solution.testerMessage == "All tests passed"
? "success"
: checkStatus(v.solution.testerErrorCode)
}
/>
))}
</>
)}
</div>
</div>
);
};
export default Submissions;