This commit is contained in:
Виталий Лавшонок
2025-11-03 11:57:24 +03:00
parent fbe441c654
commit db8828e32b
9 changed files with 368 additions and 130 deletions

View File

@@ -1,128 +1,69 @@
import { useEffect } from "react";
import { SecondaryButton } from "../../../components/button/SecondaryButton";
import { cn } from "../../../lib/cn";
import { useAppDispatch } from "../../../redux/hooks";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
import ContestsBlock from "./ContestsBlock";
import { setMenuActivePage } from "../../../redux/slices/store";
interface Contest {
id: number;
name: string;
authors: string[];
startAt: string;
registerAt: string;
duration: number;
members: number;
statusRegister: "reg" | "nonreg";
}
import { fetchContests } from "../../../redux/slices/contests";
const Contests = () => {
const dispatch = useAppDispatch();
const now = new Date();
const contests: Contest[] = [
// === Прошедшие контесты ===
{
id: 1,
name: "Code Marathon 2025",
authors: ["tourist", "Petr", "Semen", "Rotar"],
startAt: "2025-09-15T10:00:00.000Z",
registerAt: "2025-09-10T10:00:00.000Z",
duration: 180,
members: 4821,
statusRegister: "reg",
},
{
id: 2,
name: "Autumn Cup 2025",
authors: ["awoo", "Benq"],
startAt: "2025-09-25T17:00:00.000Z",
registerAt: "2025-09-20T17:00:00.000Z",
duration: 150,
members: 3670,
statusRegister: "nonreg",
},
// === Контесты, которые сейчас идут ===
{
id: 3,
name: "Halloween Challenge",
authors: ["Errichto", "Radewoosh"],
startAt: "2025-10-29T10:00:00.000Z", // начался сегодня
registerAt: "2025-10-25T10:00:00.000Z",
duration: 240,
members: 5123,
statusRegister: "reg",
},
{
id: 4,
name: "October Blitz",
authors: ["neal", "Um_nik"],
startAt: "2025-10-29T12:00:00.000Z",
registerAt: "2025-10-24T12:00:00.000Z",
duration: 300,
members: 2890,
statusRegister: "nonreg",
},
// === Контесты, которые еще не начались ===
{
id: 5,
name: "Winter Warmup",
authors: ["tourist", "rng_58"],
startAt: "2025-11-05T18:00:00.000Z",
registerAt: "2025-11-01T18:00:00.000Z",
duration: 180,
members: 2100,
statusRegister: "reg",
},
{
id: 6,
name: "Global Coding Cup",
authors: ["maroonrk", "kostka"],
startAt: "2025-11-12T15:00:00.000Z",
registerAt: "2025-11-08T15:00:00.000Z",
duration: 240,
members: 1520,
statusRegister: "nonreg",
},
];
// Берём данные из Redux
const contests = useAppSelector((state) => state.contests.contests);
const loading = useAppSelector((state) => state.contests.status);
const error = useAppSelector((state) => state.contests.error);
// При загрузке страницы — выставляем активную вкладку и подгружаем контесты
useEffect(() => {
dispatch(setMenuActivePage("contests"))
dispatch(setMenuActivePage("contests"));
dispatch(fetchContests({}));
}, []);
return (
<div className=" h-full w-[calc(100%+250px)] box-border p-[20px] pt-[20p]">
<div className="h-full box-border">
if (loading == "loading") {
return <div className="text-liquid-white p-4">Загрузка контестов...</div>;
}
if (error) {
return <div className="text-red-500 p-4">Ошибка: {error}</div>;
}
return (
<div className="h-full w-[calc(100%+250px)] box-border p-[20px] pt-[20p]">
<div className="h-full box-border">
<div className="relative flex items-center mb-[20px]">
<div className={cn("h-[50px] text-[40px] font-bold text-liquid-white flex items-center")}>
Контесты
</div>
<SecondaryButton
onClick={() => { }}
onClick={() => {}}
text="Создать группу"
className="absolute right-0"
/>
</div>
<div className="bg-liquid-lighter h-[50px] mb-[20px]">
<div className="bg-liquid-lighter h-[50px] mb-[20px]" />
</div>
<ContestsBlock
className="mb-[20px]"
title="Текущие"
contests={contests.filter((contest) => {
const endTime =
new Date(contest.endsAt).getTime()
return endTime >= now.getTime();
})}
/>
<ContestsBlock className="mb-[20px]" title="Текущие" contests={contests.filter(contest => {
const endTime = new Date(contest.startAt).getTime() + contest.duration * 60 * 1000;
return endTime >= now.getTime();
})} />
<ContestsBlock className="mb-[20px]" title="Прошедшие" contests={contests.filter(contest => {
const endTime = new Date(contest.startAt).getTime() + contest.duration * 60 * 1000;
return endTime < now.getTime();
})} />
<ContestsBlock
className="mb-[20px]"
title="Прошедшие"
contests={contests.filter((contest) => {
const endTime =
new Date(contest.endsAt).getTime()
return endTime < now.getTime();
})}
/>
</div>
</div>
);