import { useState, useEffect } from "react"; import { useParams, Navigate } from "react-router-dom"; import CompetitionHeader from "./components/CompetitionHeader"; import TaskContent from "./components/TaskContent"; import TaskSolution from "./modules/TaskSolution"; import { getCompetitionTasks, submitTaskSolution } from "@/shared/api/session"; import { getCompetition, getCompetitionResults } from "@/shared/api/competitions"; import { Loader2 } from "lucide-react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { TaskType } from "@/shared/types/task"; const CompetitionSession = () => { const { id, taskId } = useParams<{ id: string; taskId?: string }>(); const [answer, setAnswer] = useState(""); const [selectedFile, setSelectedFile] = useState(null); const [isReloading, setIsReloading] = useState(false); const competitionId = id || ""; const queryClient = useQueryClient(); const competitionQuery = useQuery({ queryKey: ["competition", competitionId], queryFn: () => getCompetition(competitionId), enabled: !!competitionId, }); const tasksQuery = useQuery({ queryKey: ["competitionTasks", competitionId], queryFn: () => getCompetitionTasks(competitionId), enabled: !!competitionId, }); const resultsQuery = useQuery({ queryKey: ["competitionResults", competitionId], queryFn: () => getCompetitionResults(competitionId), enabled: !!competitionId, }); const submitMutation = useMutation({ mutationFn: () => { if (!currentTask || !competitionId) throw new Error("Missing task or competition ID"); if (currentTask.type === TaskType.FILE) { if (!selectedFile) throw new Error("No file selected"); return submitTaskSolution(competitionId, taskId || "", selectedFile); } else { if (!answer.trim()) throw new Error("Answer is empty"); return submitTaskSolution(competitionId, taskId || "", answer); } }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['solutionHistory', competitionId, taskId] }); queryClient.invalidateQueries({ queryKey: ['competitionResults', competitionId] }); setIsReloading(true); setTimeout(() => { window.location.reload(); }, 2500); }, onError: (error) => { console.error("Error submitting solution:", error); } }); const competition = competitionQuery.data; const tasks = [...(tasksQuery.data || [])].sort((a, b) => { return a.in_competition_position - b.in_competition_position; }); const results = resultsQuery.data || []; const isLoading = tasksQuery.isLoading || competitionQuery.isLoading; const error = tasksQuery.error || competitionQuery.error ? "Не удалось загрузить данные. Пожалуйста, попробуйте позже." : null; const currentTask = tasks.find((t) => t.id === taskId) || null; if (!taskId && tasks.length > 0 && !isLoading) { return ( ); } const handleSubmit = () => { if (!currentTask || !competitionId) return; if (currentTask.type === TaskType.FILE && !selectedFile) { console.error("No file selected"); return; } if (currentTask.type !== TaskType.FILE && !answer.trim()) { console.error("Answer is empty"); return; } submitMutation.mutate(); }; const competitionTitle = competition?.title || "Загрузка соревнования..."; useEffect(() => { setAnswer(""); setSelectedFile(null); }, [taskId]); const isSubmitting = submitMutation.isPending || isReloading; return (
{isLoading ? (

Загрузка заданий...

) : error ? (

{error}

) : currentTask ? (
{isReloading && (

Решение отправлено! Пожалуйста, подождите...

)}
) : (

Задание не найдено

)}
); }; export default CompetitionSession;