Add attempts

This commit is contained in:
Виталий Лавшонок
2025-12-03 13:33:59 +03:00
parent 95f7479375
commit 8f337e6f7b
9 changed files with 6971 additions and 6794 deletions

View File

@@ -3,6 +3,12 @@ import { Account } from '../../../assets/icons/auth';
import { PrimaryButton } from '../../../components/button/PrimaryButton';
import { ReverseButton } from '../../../components/button/ReverseButton';
import { useNavigate } from 'react-router-dom';
import { toastSuccess, toastWarning } from '../../../lib/toastNotification';
import { useEffect, useState } from 'react';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { addOrUpdateContestMember } from '../../../redux/slices/contests';
export type Role = "None" | "Participant" | "Organizer";
export interface ContestItemProps {
id: number;
@@ -10,7 +16,6 @@ export interface ContestItemProps {
startAt: string;
duration: number;
members: number;
statusRegister: 'reg' | 'nonreg';
type: 'first' | 'second';
}
@@ -53,15 +58,41 @@ const ContestItem: React.FC<ContestItemProps> = ({
startAt,
duration,
members,
statusRegister,
type,
}) => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const now = new Date();
const waitTime = new Date(startAt).getTime() - now.getTime();
const [myRole, setMyRole] = useState<Role>("None");
const userId = useAppSelector((state) => state.auth.id);
const {contests: contestsRegistered} = useAppSelector((state) => state.contests.fetchParticipating);
const {contests: contestsMy} = useAppSelector((state) => state.contests.fetchMyContests);
useEffect(() => {
if (!contestsRegistered || contestsRegistered.length === 0) {
setMyRole("None");
return;
}
const reg = contestsRegistered.find(c => c.id === id);
const my = contestsMy.find(c => c.id === id);
if (my)
setMyRole("Organizer");
else if (reg)
setMyRole("Participant");
else
setMyRole("None");
}, [contestsRegistered])
return (
<div
className={cn(
@@ -73,6 +104,10 @@ const ContestItem: React.FC<ContestItemProps> = ({
: ' bg-liquid-background',
)}
onClick={() => {
if (myRole == 'None'){
toastWarning("Зарегистрируйтесь на контест");
return;
}
navigate(`/contest/${id}`);
}}
>
@@ -95,15 +130,18 @@ const ContestItem: React.FC<ContestItemProps> = ({
<img src={Account} className="h-[24px] w-[24px]" />
</div>
<div className="flex items-center justify-end">
{statusRegister == 'reg' ? (
{myRole == 'None' ? (
<>
{' '}
<PrimaryButton onClick={() => {}} text="Регистрация" />
<PrimaryButton onClick={() => {
dispatch(addOrUpdateContestMember({contestId: id, member: {userId: Number(userId), role:"Participant"}}))
}} text="Регистрация" />
</>
) : (
<>
{' '}
<ReverseButton onClick={() => {}} text="Вы записаны" />
<ReverseButton onClick={() => {
navigate(`/contest/${id}`);}} text="Войти" />
</>
)}
</div>

View File

@@ -4,7 +4,7 @@ import { cn } from '../../../lib/cn';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import ContestsBlock from './ContestsBlock';
import { setMenuActivePage } from '../../../redux/slices/store';
import { fetchContests } from '../../../redux/slices/contests';
import { fetchContests, fetchMyContests, fetchParticipatingContests } from '../../../redux/slices/contests';
import ModalCreateContest from './ModalCreate';
import Filters from './Filter';
@@ -23,10 +23,13 @@ const Contests = () => {
);
const error = useAppSelector((state) => state.contests.fetchContests.error);
// При загрузке страницы — выставляем активную вкладку и подгружаем контесты
useEffect(() => {
dispatch(setMenuActivePage('contests'));
dispatch(fetchContests({}));
dispatch(fetchParticipatingContests({pageSize:100}));
dispatch(fetchMyContests());
}, []);
return (

View File

@@ -3,6 +3,7 @@ import { cn } from '../../../lib/cn';
import { ChevroneDown } from '../../../assets/icons/groups';
import ContestItem from './ContestItem';
import { Contest } from '../../../redux/slices/contests';
import { useAppSelector } from '../../../redux/hooks';
interface ContestsBlockProps {
contests: Contest[];
@@ -56,7 +57,6 @@ const ContestsBlock: FC<ContestsBlockProps> = ({
id={v.id}
name={v.name}
startAt={v.startsAt ?? new Date().toString()}
statusRegister={'reg'}
duration={
new Date(v.endsAt ?? new Date().toString()).getTime() -
new Date(v.startsAt ?? new Date().toString()).getTime()