import { cn } from '../../../../lib/cn'; import { useNavigate } from 'react-router-dom'; import { useAppSelector } from '../../../../redux/hooks'; import { useQuery } from '../../../../hooks/useQuery'; import { toastWarning } from '../../../../lib/toastNotification'; export interface UpcoingContestItemProps { name: string; contestId: number; scheduleType: 'AlwaysOpen' | 'FixedWindow' | 'RollingWindow'; visibility: string; startsAt: string; endsAt: string; attemptDurationMinutes: number; role: string; type: 'first' | 'second'; } function formatDate(dateString: string): string { const date = new Date(dateString); const day = date.getDate().toString().padStart(2, '0'); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const year = date.getFullYear(); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); return `${day}/${month}/${year}\n${hours}:${minutes}`; } function formatDurationTime(minutes: number): string { const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (days > 0) { const remainder = days % 10; let suffix = 'дней'; if (remainder === 1 && days !== 11) suffix = 'день'; else if (remainder >= 2 && remainder <= 4 && (days < 10 || days > 20)) suffix = 'дня'; return `${days} ${suffix}`; } else if (hours > 0) { const mins = minutes % 60; return mins > 0 ? `${hours} ч ${mins} мин` : `${hours} ч`; } else { return `${minutes} мин`; } } function formatWaitTime(ms: number): string { const minutes = Math.floor(ms / 60000); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (days > 0) { const remainder = days % 10; let suffix = 'дней'; if (remainder === 1 && days !== 11) suffix = 'день'; else if (remainder >= 2 && remainder <= 4 && (days < 10 || days > 20)) suffix = 'дня'; return `${days} ${suffix}`; } else if (hours > 0) { const mins = minutes % 60; return mins > 0 ? `${hours} ч ${mins} мин` : `${hours} ч`; } else { return `${minutes} мин`; } } const UpcoingContestItem: React.FC = ({ name, contestId, scheduleType, startsAt, endsAt, attemptDurationMinutes, type, }) => { const navigate = useNavigate(); const myname = useAppSelector((state) => state.auth.username); const query = useQuery(); const username = query.get('username') ?? myname ?? ''; const started = new Date(startsAt) <= new Date(); const finished = new Date(endsAt) <= new Date(); const waitTime = !started ? new Date(startsAt).getTime() - new Date().getTime() : new Date(endsAt).getTime() - new Date().getTime(); return (
{ if (!started) { toastWarning('Контест еще не начался'); return; } const params = new URLSearchParams({ back: '/home/account/contests', }); navigate(`/contest/${contestId}?${params}`); }} >
{name}
{username}
{scheduleType == 'AlwaysOpen' ? (
Всегда открыт
) : (
{formatDate(startsAt)}
-
{formatDate(endsAt)}
)}
{formatDurationTime(attemptDurationMinutes)}
{!started ? (
{'До начала\n' + formatWaitTime(waitTime)}
) : ( !finished && (
{'До конца\n' + formatWaitTime(waitTime)}
) )}
{new Date() < new Date(startsAt) ? ( <>{'Не начался'} ) : ( <>{scheduleType == 'AlwaysOpen' ? 'Открыт' : 'Идет'} )}
); }; export default UpcoingContestItem;