Files
LiquidCode_Frontend/src/views/mission/statement/Header.tsx
Виталий Лавшонок 358c7def78 Add ettempts in contests
2025-12-03 21:15:42 +03:00

124 lines
3.8 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import {
chevroneLeft,
chevroneRight,
arrowLeft,
} from '../../../assets/icons/header';
import { Logo } from '../../../assets/logos';
import { useNavigate } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { useQuery } from '../../../hooks/useQuery';
import { fetchMyAttemptsInContest } from '../../../redux/slices/contests';
interface HeaderProps {
missionId: number;
back?: string;
}
const Header: React.FC<HeaderProps> = ({ missionId, back }) => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const query = useQuery();
const contestId = Number(query.get('contestId') ?? undefined);
const attempt = useAppSelector(
(state) => state.contests.fetchMyAttemptsInContest.attempts[0],
);
const [time, setTime] = useState(0);
useEffect(() => {
if (!contestId) return;
const calc = (time: string) => {
return time != '' && new Date() <= new Date(time);
};
if (attempt) {
if (!calc(attempt.expiresAt)) {
navigate('/home/contests');
}
const diffMs =
new Date(attempt.expiresAt).getTime() - new Date().getTime();
const seconds = Math.floor(diffMs / 1000);
setTime(seconds);
const interval = setInterval(() => {
setTime((t) => {
if (t <= 1) {
clearInterval(interval);
navigate('/home/contests');
return 0;
}
return t - 1;
});
}, 1000);
return () => clearInterval(interval);
}
}, [attempt]);
useEffect(() => {
if (contestId) {
dispatch(fetchMyAttemptsInContest(contestId));
}
}, [contestId]);
const minutes = String(Math.floor(time / 60)).padStart(2, '0');
const seconds = String(time % 60).padStart(2, '0');
return (
<header className="w-full h-[60px] flex items-center px-4 gap-[20px]">
<img
src={Logo}
alt="Logo"
className="h-[28px] w-auto cursor-pointer"
onClick={() => {
navigate('/home');
}}
/>
<img
src={arrowLeft}
alt="back"
className="h-[24px] w-[24px] cursor-pointer"
onClick={() => {
if (back) navigate(back);
else navigate('/home/missions');
}}
/>
<div className="flex gap-[10px]">
<img
src={chevroneLeft}
alt="back"
className="h-[24px] w-[24px] cursor-pointer"
onClick={() => {
if (missionId <= 1) return;
if (back)
navigate(`/mission/${missionId - 1}?back=${back}`);
else navigate(`/mission/${missionId - 1}`);
}}
/>
<span>{missionId}</span>
<img
src={chevroneRight}
alt="back"
className="h-[24px] w-[24px] cursor-pointer"
onClick={() => {
if (back)
navigate(`/mission/${missionId + 1}?back=${back}`);
else navigate(`/mission/${missionId + 1}`);
}}
/>
</div>
{!!contestId && !!attempt && (
<div className="">{`${minutes}:${seconds}`}</div>
)}
</header>
);
};
export default Header;