contests update
This commit is contained in:
@@ -6,48 +6,71 @@ import { useAppDispatch, useAppSelector } from '../redux/hooks';
|
|||||||
import {
|
import {
|
||||||
createContest,
|
createContest,
|
||||||
CreateContestBody,
|
CreateContestBody,
|
||||||
|
deleteContest,
|
||||||
fetchContestById,
|
fetchContestById,
|
||||||
|
setContestStatus,
|
||||||
|
updateContest,
|
||||||
} from '../redux/slices/contests';
|
} from '../redux/slices/contests';
|
||||||
import DateRangeInput from '../components/input/DateRangeInput';
|
import DateRangeInput from '../components/input/DateRangeInput';
|
||||||
import { useQuery } from '../hooks/useQuery';
|
import { useQuery } from '../hooks/useQuery';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { Navigate, useNavigate } from 'react-router-dom';
|
||||||
import { fetchMissionById, Mission } from '../redux/slices/missions';
|
import { fetchMissionById } from '../redux/slices/missions';
|
||||||
import { ReverseButton } from '../components/button/ReverseButton';
|
import { ReverseButton } from '../components/button/ReverseButton';
|
||||||
|
|
||||||
|
|
||||||
|
interface Mission {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Страница создания / редактирования контеста
|
* Страница создания / редактирования контеста
|
||||||
*/
|
*/
|
||||||
const ContestEditor = () => {
|
const ContestEditor = () => {
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const status = useAppSelector(
|
|
||||||
(state) => state.contests.createContest.status,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [missionIdInput, setMissionIdInput] = useState<string>('');
|
|
||||||
|
|
||||||
const query = useQuery();
|
const query = useQuery();
|
||||||
const back = query.get('back') ?? undefined;
|
const back = query.get('back') ?? undefined;
|
||||||
const contestId = Number(query.get('contestId') ?? undefined);
|
const contestId = Number(query.get('contestId') ?? undefined);
|
||||||
const refactor = !!contestId;
|
const refactor = !!contestId;
|
||||||
|
|
||||||
|
if (!refactor){
|
||||||
|
return <Navigate to="/home/account/acontest" />
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const status = useAppSelector(
|
||||||
|
(state) => state.contests.createContest.status,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [missionIdInput, setMissionIdInput] = useState<string>('');
|
||||||
|
|
||||||
|
|
||||||
const [contest, setContest] = useState<CreateContestBody>({
|
const [contest, setContest] = useState<CreateContestBody>({
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
scheduleType: 'AlwaysOpen',
|
scheduleType: 'AlwaysOpen',
|
||||||
visibility: 'Public',
|
visibility: 'Public',
|
||||||
startsAt: null,
|
startsAt: '',
|
||||||
endsAt: null,
|
endsAt: '',
|
||||||
attemptDurationMinutes: null,
|
attemptDurationMinutes: 60,
|
||||||
maxAttempts: null,
|
maxAttempts: 1,
|
||||||
allowEarlyFinish: false,
|
allowEarlyFinish: true,
|
||||||
groupId: null,
|
groupIds: [],
|
||||||
missionIds: [],
|
missionIds: [],
|
||||||
articleIds: [],
|
articleIds: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const [missions, setMissions] = useState<Mission[]>([]);
|
const [missions, setMissions] = useState<Mission[]>([]);
|
||||||
|
|
||||||
|
|
||||||
|
const statusDelete = useAppSelector((state) => state.contests.deleteContest.status)
|
||||||
|
|
||||||
const { contest: contestById, status: contestByIdstatus } = useAppSelector(
|
const { contest: contestById, status: contestByIdstatus } = useAppSelector(
|
||||||
(state) => state.contests.fetchContestById,
|
(state) => state.contests.fetchContestById,
|
||||||
);
|
);
|
||||||
@@ -61,9 +84,15 @@ const ContestEditor = () => {
|
|||||||
setContest((prev) => ({ ...prev, [key]: value }));
|
setContest((prev) => ({ ...prev, [key]: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleUpdateContest = () => {
|
||||||
dispatch(createContest(contest));
|
dispatch(updateContest({...contest, contestId}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDeleteContest = () => {
|
||||||
|
dispatch(deleteContest(contestId));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const addMission = () => {
|
const addMission = () => {
|
||||||
const id = Number(missionIdInput.trim());
|
const id = Number(missionIdInput.trim());
|
||||||
@@ -91,6 +120,13 @@ const ContestEditor = () => {
|
|||||||
setMissions(missions.filter((v) => v.id != removeId));
|
setMissions(missions.filter((v) => v.id != removeId));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (statusDelete == "successful"){
|
||||||
|
dispatch(setContestStatus({key: "deleteContest", status: "idle"}))
|
||||||
|
navigate('/home/account/contests')
|
||||||
|
}
|
||||||
|
}, [statusDelete])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (refactor) {
|
if (refactor) {
|
||||||
dispatch(fetchContestById(contestId));
|
dispatch(fetchContestById(contestId));
|
||||||
@@ -101,10 +137,14 @@ const ContestEditor = () => {
|
|||||||
if (refactor && contestByIdstatus == 'successful' && contestById) {
|
if (refactor && contestByIdstatus == 'successful' && contestById) {
|
||||||
setContest({
|
setContest({
|
||||||
...contestById,
|
...contestById,
|
||||||
missionIds: [],
|
// groupIds: contestById.groups.map(group => group.groupId),
|
||||||
|
groupIds: [],
|
||||||
|
missionIds: contestById.missions?.map(mission => mission.id),
|
||||||
|
articleIds: contestById.articles?.map(article => article.articleId),
|
||||||
visibility: 'Public',
|
visibility: 'Public',
|
||||||
scheduleType: 'AlwaysOpen',
|
scheduleType: 'AlwaysOpen',
|
||||||
});
|
});
|
||||||
|
setMissions(contestById.missions ?? []);
|
||||||
}
|
}
|
||||||
}, [contestById]);
|
}, [contestById]);
|
||||||
|
|
||||||
@@ -253,27 +293,19 @@ const ContestEditor = () => {
|
|||||||
|
|
||||||
{/* Кнопки */}
|
{/* Кнопки */}
|
||||||
<div className="flex flex-row w-full items-center justify-end mt-[20px] gap-[20px]">
|
<div className="flex flex-row w-full items-center justify-end mt-[20px] gap-[20px]">
|
||||||
{refactor ? (
|
|
||||||
<>
|
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
onClick={handleSubmit}
|
onClick={handleUpdateContest}
|
||||||
text="Сохранить"
|
text="Сохранить"
|
||||||
disabled={status === 'loading'}
|
disabled={status === 'loading'}
|
||||||
/>
|
/>
|
||||||
<ReverseButton
|
<ReverseButton
|
||||||
color="error"
|
color="error"
|
||||||
onClick={handleSubmit}
|
onClick={handleDeleteContest}
|
||||||
text="Удалить"
|
text="Удалить"
|
||||||
disabled={status === 'loading'}
|
disabled={statusDelete === 'loading'}
|
||||||
/>
|
/>
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<PrimaryButton
|
|
||||||
onClick={handleSubmit}
|
|
||||||
text="Создать"
|
|
||||||
disabled={status === 'loading'}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ export interface Mission {
|
|||||||
name: string;
|
name: string;
|
||||||
difficulty: number;
|
difficulty: number;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
timeLimitMilliseconds: number;
|
timeLimitMilliseconds: number;
|
||||||
memoryLimitBytes: number;
|
memoryLimitBytes: number;
|
||||||
statements: string;
|
statements: string;
|
||||||
@@ -32,17 +30,18 @@ export interface Group {
|
|||||||
export interface Contest {
|
export interface Contest {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description?: string;
|
||||||
scheduleType: 'AlwaysOpen' | 'FixedWindow' | 'RollingWindow';
|
scheduleType: 'AlwaysOpen' | 'FixedWindow' | 'RollingWindow';
|
||||||
startsAt: string;
|
visibility: 'Public' | 'GroupPrivate';
|
||||||
endsAt: string;
|
startsAt?: string;
|
||||||
attemptDurationMinutes: number;
|
endsAt?: string;
|
||||||
maxAttempts: number;
|
attemptDurationMinutes?: number;
|
||||||
allowEarlyFinish: boolean;
|
maxAttempts?: number;
|
||||||
groups: Group[];
|
allowEarlyFinish?: boolean;
|
||||||
missions: Mission[];
|
groups?: Group[];
|
||||||
articles: any[];
|
missions?: Mission[];
|
||||||
members: Member[];
|
articles?: any[];
|
||||||
|
members?: Member[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ContestsResponse {
|
interface ContestsResponse {
|
||||||
@@ -52,17 +51,17 @@ interface ContestsResponse {
|
|||||||
|
|
||||||
export interface CreateContestBody {
|
export interface CreateContestBody {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description?: string;
|
||||||
scheduleType: 'AlwaysOpen' | 'FixedWindow' | 'RollingWindow';
|
scheduleType: 'AlwaysOpen' | 'FixedWindow' | 'RollingWindow';
|
||||||
visibility: 'Public' | 'GroupPrivate';
|
visibility: 'Public' | 'GroupPrivate';
|
||||||
startsAt: string;
|
startsAt?: string;
|
||||||
endsAt: string;
|
endsAt?: string;
|
||||||
attemptDurationMinutes: number;
|
attemptDurationMinutes?: number;
|
||||||
maxAttempts: number;
|
maxAttempts?: number;
|
||||||
allowEarlyFinish: boolean;
|
allowEarlyFinish?: boolean;
|
||||||
groupId: number;
|
groupIds?: number[];
|
||||||
missionIds: number[];
|
missionIds?: number[];
|
||||||
articleIds: number[];
|
articleIds?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// =====================
|
// =====================
|
||||||
@@ -76,38 +75,38 @@ interface ContestsState {
|
|||||||
contests: Contest[];
|
contests: Contest[];
|
||||||
hasNextPage: boolean;
|
hasNextPage: boolean;
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
fetchContestById: {
|
fetchContestById: {
|
||||||
contest: Contest;
|
contest: Contest;
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
createContest: {
|
createContest: {
|
||||||
contest: Contest;
|
contest: Contest;
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
// 🆕 Добавляем updateContest и deleteContest
|
// 🆕 Добавляем updateContest и deleteContest
|
||||||
updateContest: {
|
updateContest: {
|
||||||
contest: Contest;
|
contest: Contest;
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
deleteContest: {
|
deleteContest: {
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
fetchMyContests: {
|
fetchMyContests: {
|
||||||
contests: Contest[];
|
contests: Contest[];
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
fetchRegisteredContests: {
|
fetchRegisteredContests: {
|
||||||
contests: Contest[];
|
contests: Contest[];
|
||||||
hasNextPage: boolean;
|
hasNextPage: boolean;
|
||||||
status: Status;
|
status: Status;
|
||||||
error: string | null;
|
error?: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +115,7 @@ const initialState: ContestsState = {
|
|||||||
contests: [],
|
contests: [],
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
fetchContestById: {
|
fetchContestById: {
|
||||||
contest: {
|
contest: {
|
||||||
@@ -124,6 +123,7 @@ const initialState: ContestsState = {
|
|||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
scheduleType: 'AlwaysOpen',
|
scheduleType: 'AlwaysOpen',
|
||||||
|
visibility: 'Public',
|
||||||
startsAt: '',
|
startsAt: '',
|
||||||
endsAt: '',
|
endsAt: '',
|
||||||
attemptDurationMinutes: 0,
|
attemptDurationMinutes: 0,
|
||||||
@@ -135,7 +135,7 @@ const initialState: ContestsState = {
|
|||||||
members: [],
|
members: [],
|
||||||
},
|
},
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
createContest: {
|
createContest: {
|
||||||
contest: {
|
contest: {
|
||||||
@@ -143,6 +143,7 @@ const initialState: ContestsState = {
|
|||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
scheduleType: 'AlwaysOpen',
|
scheduleType: 'AlwaysOpen',
|
||||||
|
visibility: 'Public',
|
||||||
startsAt: '',
|
startsAt: '',
|
||||||
endsAt: '',
|
endsAt: '',
|
||||||
attemptDurationMinutes: 0,
|
attemptDurationMinutes: 0,
|
||||||
@@ -154,7 +155,7 @@ const initialState: ContestsState = {
|
|||||||
members: [],
|
members: [],
|
||||||
},
|
},
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
updateContest: {
|
updateContest: {
|
||||||
contest: {
|
contest: {
|
||||||
@@ -162,6 +163,7 @@ const initialState: ContestsState = {
|
|||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
scheduleType: 'AlwaysOpen',
|
scheduleType: 'AlwaysOpen',
|
||||||
|
visibility: 'Public',
|
||||||
startsAt: '',
|
startsAt: '',
|
||||||
endsAt: '',
|
endsAt: '',
|
||||||
attemptDurationMinutes: 0,
|
attemptDurationMinutes: 0,
|
||||||
@@ -173,22 +175,22 @@ const initialState: ContestsState = {
|
|||||||
members: [],
|
members: [],
|
||||||
},
|
},
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
deleteContest: {
|
deleteContest: {
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
fetchMyContests: {
|
fetchMyContests: {
|
||||||
contests: [],
|
contests: [],
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
fetchRegisteredContests: {
|
fetchRegisteredContests: {
|
||||||
contests: [],
|
contests: [],
|
||||||
hasNextPage: false,
|
hasNextPage: false,
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: undefined,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -265,7 +267,7 @@ export const updateContest = createAsyncThunk(
|
|||||||
{ rejectWithValue },
|
{ rejectWithValue },
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.patch<Contest>(
|
const response = await axios.put<Contest>(
|
||||||
`/contests/${contestId}`,
|
`/contests/${contestId}`,
|
||||||
contestData,
|
contestData,
|
||||||
);
|
);
|
||||||
@@ -354,7 +356,7 @@ const contestsSlice = createSlice({
|
|||||||
// fetchContests
|
// fetchContests
|
||||||
builder.addCase(fetchContests.pending, (state) => {
|
builder.addCase(fetchContests.pending, (state) => {
|
||||||
state.fetchContests.status = 'loading';
|
state.fetchContests.status = 'loading';
|
||||||
state.fetchContests.error = null;
|
state.fetchContests.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
fetchContests.fulfilled,
|
fetchContests.fulfilled,
|
||||||
@@ -372,7 +374,7 @@ const contestsSlice = createSlice({
|
|||||||
// fetchContestById
|
// fetchContestById
|
||||||
builder.addCase(fetchContestById.pending, (state) => {
|
builder.addCase(fetchContestById.pending, (state) => {
|
||||||
state.fetchContestById.status = 'loading';
|
state.fetchContestById.status = 'loading';
|
||||||
state.fetchContestById.error = null;
|
state.fetchContestById.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
fetchContestById.fulfilled,
|
fetchContestById.fulfilled,
|
||||||
@@ -389,7 +391,7 @@ const contestsSlice = createSlice({
|
|||||||
// createContest
|
// createContest
|
||||||
builder.addCase(createContest.pending, (state) => {
|
builder.addCase(createContest.pending, (state) => {
|
||||||
state.createContest.status = 'loading';
|
state.createContest.status = 'loading';
|
||||||
state.createContest.error = null;
|
state.createContest.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
createContest.fulfilled,
|
createContest.fulfilled,
|
||||||
@@ -406,7 +408,7 @@ const contestsSlice = createSlice({
|
|||||||
// 🆕 updateContest
|
// 🆕 updateContest
|
||||||
builder.addCase(updateContest.pending, (state) => {
|
builder.addCase(updateContest.pending, (state) => {
|
||||||
state.updateContest.status = 'loading';
|
state.updateContest.status = 'loading';
|
||||||
state.updateContest.error = null;
|
state.updateContest.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
updateContest.fulfilled,
|
updateContest.fulfilled,
|
||||||
@@ -423,7 +425,7 @@ const contestsSlice = createSlice({
|
|||||||
// 🆕 deleteContest
|
// 🆕 deleteContest
|
||||||
builder.addCase(deleteContest.pending, (state) => {
|
builder.addCase(deleteContest.pending, (state) => {
|
||||||
state.deleteContest.status = 'loading';
|
state.deleteContest.status = 'loading';
|
||||||
state.deleteContest.error = null;
|
state.deleteContest.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
deleteContest.fulfilled,
|
deleteContest.fulfilled,
|
||||||
@@ -448,7 +450,7 @@ const contestsSlice = createSlice({
|
|||||||
// fetchMyContests
|
// fetchMyContests
|
||||||
builder.addCase(fetchMyContests.pending, (state) => {
|
builder.addCase(fetchMyContests.pending, (state) => {
|
||||||
state.fetchMyContests.status = 'loading';
|
state.fetchMyContests.status = 'loading';
|
||||||
state.fetchMyContests.error = null;
|
state.fetchMyContests.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
fetchMyContests.fulfilled,
|
fetchMyContests.fulfilled,
|
||||||
@@ -465,7 +467,7 @@ const contestsSlice = createSlice({
|
|||||||
// fetchRegisteredContests
|
// fetchRegisteredContests
|
||||||
builder.addCase(fetchRegisteredContests.pending, (state) => {
|
builder.addCase(fetchRegisteredContests.pending, (state) => {
|
||||||
state.fetchRegisteredContests.status = 'loading';
|
state.fetchRegisteredContests.status = 'loading';
|
||||||
state.fetchRegisteredContests.error = null;
|
state.fetchRegisteredContests.error = undefined;
|
||||||
});
|
});
|
||||||
builder.addCase(
|
builder.addCase(
|
||||||
fetchRegisteredContests.fulfilled,
|
fetchRegisteredContests.fulfilled,
|
||||||
|
|||||||
@@ -28,16 +28,6 @@ const Contests = () => {
|
|||||||
dispatch(fetchContests({}));
|
dispatch(fetchContests({}));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (status == 'loading') {
|
|
||||||
return (
|
|
||||||
<div className="text-liquid-white p-4">Загрузка контестов...</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return <div className="text-red-500 p-4">Ошибка: {error}</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full w-[calc(100%+250px)] box-border p-[20px] pt-[20p]">
|
<div className="h-full w-[calc(100%+250px)] box-border p-[20px] pt-[20p]">
|
||||||
<div className="h-full box-border">
|
<div className="h-full box-border">
|
||||||
@@ -59,24 +49,29 @@ const Contests = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="bg-liquid-lighter h-[50px] mb-[20px]" />
|
<div className="bg-liquid-lighter h-[50px] mb-[20px]" />
|
||||||
|
{status == 'loading' && <div className="text-liquid-white p-4">Загрузка контестов...</div>}
|
||||||
|
{status == 'failed' && <div className="text-red-500 p-4">Ошибка: {error}</div>}
|
||||||
|
{status == 'successful' &&
|
||||||
|
<>
|
||||||
|
<ContestsBlock
|
||||||
|
className="mb-[20px]"
|
||||||
|
title="Текущие"
|
||||||
|
contests={contests.filter((contest) => {
|
||||||
|
const endTime = new Date(contest.endsAt ?? new Date().toDateString()).getTime();
|
||||||
|
return endTime >= now.getTime();
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
|
||||||
<ContestsBlock
|
<ContestsBlock
|
||||||
className="mb-[20px]"
|
className="mb-[20px]"
|
||||||
title="Текущие"
|
title="Прошедшие"
|
||||||
contests={contests.filter((contest) => {
|
contests={contests.filter((contest) => {
|
||||||
const endTime = new Date(contest.endsAt).getTime();
|
const endTime = new Date(contest.endsAt ?? new Date().toDateString()).getTime();
|
||||||
return endTime >= now.getTime();
|
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>
|
||||||
|
|
||||||
<ModalCreateContest
|
<ModalCreateContest
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ const ContestsBlock: FC<ContestsBlockProps> = ({
|
|||||||
key={i}
|
key={i}
|
||||||
id={v.id}
|
id={v.id}
|
||||||
name={v.name}
|
name={v.name}
|
||||||
startAt={v.startsAt}
|
startAt={v.startsAt ?? new Date().toString()}
|
||||||
statusRegister={'reg'}
|
statusRegister={'reg'}
|
||||||
duration={
|
duration={
|
||||||
new Date(v.endsAt).getTime() -
|
new Date(v.endsAt ?? new Date().toString()).getTime() -
|
||||||
new Date(v.startsAt).getTime()
|
new Date(v.startsAt ?? new Date().toString()).getTime()
|
||||||
}
|
}
|
||||||
members={v.members.length}
|
members={v.members?.length ?? 0}
|
||||||
type={i % 2 ? 'second' : 'first'}
|
type={i % 2 ? 'second' : 'first'}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const ModalCreateContest: FC<ModalCreateContestProps> = ({
|
|||||||
attemptDurationMinutes: 0,
|
attemptDurationMinutes: 0,
|
||||||
maxAttempts: 0,
|
maxAttempts: 0,
|
||||||
allowEarlyFinish: false,
|
allowEarlyFinish: false,
|
||||||
groupId: 0,
|
groupIds: [],
|
||||||
missionIds: [],
|
missionIds: [],
|
||||||
articleIds: [],
|
articleIds: [],
|
||||||
});
|
});
|
||||||
@@ -48,13 +48,12 @@ const ModalCreateContest: FC<ModalCreateContestProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (status === 'successful') {
|
if (status === 'successful') {
|
||||||
console.log('navigate');
|
|
||||||
navigate(
|
|
||||||
`/contest/create?back=/home/account/contests&contestId=${contest.id}`,
|
|
||||||
);
|
|
||||||
dispatch(
|
dispatch(
|
||||||
setContestStatus({ key: 'createContest', status: 'idle' }),
|
setContestStatus({ key: 'createContest', status: 'idle' }),
|
||||||
);
|
);
|
||||||
|
navigate(
|
||||||
|
`/contest/create?back=/home/account/contests&contestId=${contest.id}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [status]);
|
}, [status]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user