import { useParams, Navigate } from 'react-router-dom'; import CodeEditor from '../views/mission/codeeditor/CodeEditor'; import Statement, { StatementData } from '../views/mission/statement/Statement'; import { PrimaryButton } from '../components/button/PrimaryButton'; import { useEffect, useRef, useState } from 'react'; import { useAppDispatch, useAppSelector } from '../redux/hooks'; import { fetchMySubmitsByMission, submitMission } from '../redux/slices/submit'; import { fetchMissionById } from '../redux/slices/missions'; import Header from '../views/mission/statement/Header'; import MissionSubmissions from '../views/mission/statement/MissionSubmissions'; const Mission = () => { const dispatch = useAppDispatch(); // Получаем параметры из URL const { missionId } = useParams<{ missionId: string }>(); const mission = useAppSelector((state) => state.missions.currentMission); const missionIdNumber = Number(missionId); if (!missionId || isNaN(missionIdNumber)) { return ; } const [code, setCode] = useState(""); const [language, setLanguage] = useState(""); const pollingRef = useRef(null); const submissions = useAppSelector((state) => state.submin.submitsById[missionIdNumber] || []); useEffect(() => { dispatch(fetchMissionById(missionIdNumber)); dispatch(fetchMySubmitsByMission(missionIdNumber)); }, [missionIdNumber]); useEffect(() => { return () => { if (pollingRef.current) { clearInterval(pollingRef.current); pollingRef.current = null; } }; }, []); useEffect(() => { if (submissions.length === 0) return; const hasWaiting = submissions.some( s => s.solution.status === "Waiting" || s.solution.testerState === "Waiting" ); if (hasWaiting) { startPolling(); } }, [submissions]); if (!mission || !mission.statements || mission.statements.length === 0) { return
Загрузка...
; } interface StatementData { id: number; legend?: string; timeLimit?: number; output?: string; input?: string; sampleTests?: any[]; name?: string; memoryLimit?: number; tags?: string[]; notes?: string; html?: string; mediaFiles?: any[]; } let statementData: StatementData = { id: mission.id }; try { // 1. Берём первый statement с форматом Latex и языком russian const latexStatement = mission.statements.find( (stmt: any) => stmt && stmt.language === "russian" && stmt.format === "Latex" ); // 2. Берём первый statement с форматом Html и языком russian const htmlStatement = mission.statements.find( (stmt: any) => stmt && stmt.language === "russian" && stmt.format === "Html" ); if (!latexStatement) throw new Error("Не найден блок Latex на русском"); if (!htmlStatement) throw new Error("Не найден блок Html на русском"); // 3. Парсим данные из problem-properties.json const statementTexts = JSON.parse(latexStatement.statementTexts["problem-properties.json"]); statementData = { id: missionIdNumber, legend: statementTexts.legend, timeLimit: statementTexts.timeLimit, output: statementTexts.output, input: statementTexts.input, sampleTests: statementTexts.sampleTests, name: statementTexts.name, memoryLimit: statementTexts.memoryLimit, tags: mission.tags, notes: statementTexts.notes, html: htmlStatement.statementTexts["problem.html"], mediaFiles: latexStatement.mediaFiles }; } catch (err) { console.error("Ошибка парсинга statementTexts:", err); } const startPolling = () => { if (pollingRef.current) return; pollingRef.current = setInterval(async () => { dispatch(fetchMySubmitsByMission(missionIdNumber)); const hasWaiting = submissions.some( (s: any) => s.solution.status == "Waiting" || s.solution.testerState === "Waiting" ); if (!hasWaiting) { // Всё проверено — стоп if (pollingRef.current) { clearInterval(pollingRef.current); pollingRef.current = null; } } }, 5000); // 10 секунд }; return (
{ setCode(value); }} onChangeLanguage={((value: string) => { setLanguage(value); })} />
{ await dispatch(submitMission({ missionId: missionIdNumber, language: language, languageVersion: "latest", sourceCode: code, contestId: null, })).unwrap(); dispatch(fetchMySubmitsByMission(missionIdNumber)); }} />
); }; export default Mission;