import { Task, TaskStatus } from "@/shared/types/task"; import { useCompetition, useCurrentTask, useTasks, } from "../providers/session-provider.tsx"; import { CompetitionResult, CompetitionType } from "@/shared/types/competition"; import { Link, useNavigate } from "react-router"; import { cn } from "@/shared/lib/utils"; import React from "react"; import { getTaskStatusByResult } from "../shared/status.ts"; import { ChevronLeft, Clock } from "lucide-react"; import { Button } from "@/components/ui/button.tsx"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog.tsx"; import { finishCompetition } from "@/shared/api/competitions.ts"; export const CompetitionHeader = () => { const competition = useCompetition(); const { task: currentTask } = useCurrentTask(); const { tasks, results } = useTasks(); return (
Назад

{competition.title}

{tasks.map((t) => ( ))}
); }; interface NavigationTaskProps { task: Task; active: boolean; results: CompetitionResult[]; competitionId: string; } const NavigationTask = ({ task, active, results, competitionId, }: NavigationTaskProps) => { const result = React.useMemo( () => results.find((r) => r.position === task.in_competition_position), [results, task], ); const status = getTaskStatusByResult(result); return (
{task.in_competition_position}
); }; const CompleteButton = () => { const { results } = useTasks(); const competition = useCompetition(); const navigate = useNavigate(); const isCompleted = React.useMemo( () => results.every((result) => result.result === result.max_points), [results], ); const completeCompetition = React.useCallback(async () => { await finishCompetition(competition.id); navigate("/"); }, [competition.id, navigate]); if (competition.type === CompetitionType.EDU) { return

Тренировка

; } const CompButton = ( ); if (isCompleted) { return CompButton; } return ( {CompButton} ); }; const CompleteDialog = ({ children, completeCompetition, }: { children: React.ReactNode; completeCompetition: () => void; }) => { return ( {children} Завершить соревнование? Вы решили не все задачи ); }; const TimerNumbers = ({ className, withIcon = true, }: { className?: string; withIcon?: boolean; }) => { const competition = useCompetition(); const navigate = useNavigate(); const [seconds, setSeconds] = React.useState( competition.end_date ? Math.round( (new Date(competition.end_date).getTime() - new Date().getTime()) / 1000, ) : 0, ); const timerRef = React.useRef(null); React.useEffect(() => { timerRef.current = window.setInterval(() => { setSeconds((prev) => prev - 1); }, 1000); return () => { if (timerRef.current) { clearInterval(timerRef.current); } }; }, []); React.useEffect(() => { if ( seconds <= 0 && competition.type === CompetitionType.COMPETITIVE && competition.end_date ) { if (new Date(competition.end_date).getTime() <= new Date().getTime()) { navigate("/"); } } }, [competition.end_date, competition.type, navigate, seconds]); if (competition.type === CompetitionType.EDU) { return null; } const hh = Math.floor(seconds / 3600); const mm = Math.floor((seconds % 3600) / 60); const ss = seconds % 60; return (
{withIcon && } {hh > 0 ? ( <> : ) : ( "" )} :
); }; const TimerNumber = ({ value }: { value: number }) => { return {value < 10 ? `0${value}` : value}; };