115 lines
3.8 KiB
TypeScript
115 lines
3.8 KiB
TypeScript
import { cn } from '../../../../lib/cn';
|
|
import { Account } from '../../../../assets/icons/auth';
|
|
import { PrimaryButton } from '../../../../components/button/PrimaryButton';
|
|
import { ReverseButton } from '../../../../components/button/ReverseButton';
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
export interface ContestItemProps {
|
|
id: number;
|
|
name: string;
|
|
startAt: string;
|
|
duration: number;
|
|
members: number;
|
|
statusRegister: 'reg' | 'nonreg';
|
|
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 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 ContestItem: React.FC<ContestItemProps> = ({
|
|
id,
|
|
name,
|
|
startAt,
|
|
duration,
|
|
members,
|
|
statusRegister,
|
|
type,
|
|
}) => {
|
|
const navigate = useNavigate();
|
|
|
|
const now = new Date();
|
|
|
|
const waitTime = new Date(startAt).getTime() - now.getTime();
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'w-full box-border relative rounded-[10px] px-[20px] py-[10px] text-liquid-white text-[16px] leading-[20px] cursor-pointer',
|
|
waitTime <= 0 ? 'grid grid-cols-6' : 'grid grid-cols-7',
|
|
'items-center font-bold text-liquid-white',
|
|
type == 'first'
|
|
? ' bg-liquid-lighter'
|
|
: ' bg-liquid-background',
|
|
)}
|
|
onClick={() => {
|
|
navigate(`/contest/${id}`);
|
|
}}
|
|
>
|
|
<div className="text-left font-bold text-[18px]">{name}</div>
|
|
<div className="text-center text-liquid-brightmain font-normal ">
|
|
{/* {authors.map((v, i) => <p key={i}>{v}</p>)} */}
|
|
valavshonok
|
|
</div>
|
|
<div className="text-center text-nowrap whitespace-pre-line">
|
|
{formatDate(startAt)}
|
|
</div>
|
|
<div className="text-center">{formatWaitTime(duration)}</div>
|
|
{waitTime > 0 && (
|
|
<div className="text-center whitespace-pre-line ">
|
|
{'До начала\n' + formatWaitTime(waitTime)}
|
|
</div>
|
|
)}
|
|
<div className="items-center justify-center flex gap-[10px] flex-row w-full">
|
|
<div>{members}</div>
|
|
<img src={Account} className="h-[24px] w-[24px]" />
|
|
</div>
|
|
<div className="flex items-center justify-end">
|
|
{statusRegister == 'reg' ? (
|
|
<>
|
|
{' '}
|
|
<PrimaryButton onClick={() => {}} text="Регистрация" />
|
|
</>
|
|
) : (
|
|
<>
|
|
{' '}
|
|
<ReverseButton onClick={() => {}} text="Вы записаны" />
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ContestItem;
|