118 lines
4.2 KiB
TypeScript
118 lines
4.2 KiB
TypeScript
import MissionItem from './MissionItem';
|
||
import { SecondaryButton } from '../../../components/button/SecondaryButton';
|
||
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
|
||
import { useEffect, useState } from 'react';
|
||
import {
|
||
setMenuActivePage,
|
||
setMissionsNameFilter,
|
||
setMissionsTagFilter,
|
||
} from '../../../redux/slices/store';
|
||
import { fetchMissions } from '../../../redux/slices/missions';
|
||
import ModalCreate from './ModalCreate';
|
||
import Filters from './Filter';
|
||
import { toastWarning } from '../../../lib/toastNotification';
|
||
|
||
export interface Mission {
|
||
id: number;
|
||
authorId: number;
|
||
name: string;
|
||
difficulty: 'Easy' | 'Medium' | 'Hard';
|
||
tags: string[];
|
||
timeLimit: number;
|
||
memoryLimit: number;
|
||
createdAt: string;
|
||
updatedAt: string;
|
||
}
|
||
|
||
const Missions = () => {
|
||
const dispatch = useAppDispatch();
|
||
const [modalActive, setModalActive] = useState<boolean>(false);
|
||
|
||
const missions = useAppSelector((state) => state.missions.missions);
|
||
|
||
const jwt = useAppSelector((state) => state.auth.jwt);
|
||
const nameFilter = useAppSelector(
|
||
(state) => state.store.missions.filterName,
|
||
);
|
||
const tagsFilter = useAppSelector(
|
||
(state) => state.store.articles.articleTagFilter,
|
||
);
|
||
|
||
const calcDifficulty = (d: number) => {
|
||
if (d <= 1200) return 'Easy';
|
||
if (d <= 2000) return 'Medium';
|
||
return 'Hard';
|
||
};
|
||
|
||
useEffect(() => {
|
||
dispatch(setMenuActivePage('missions'));
|
||
dispatch(fetchMissions({ tags: tagsFilter }));
|
||
}, []);
|
||
const filterTagsHandler = (value: string[]) => {
|
||
dispatch(setMissionsTagFilter(value));
|
||
dispatch(fetchMissions({ tags: value }));
|
||
};
|
||
|
||
return (
|
||
<div className=" h-full w-full box-border p-[20px] pt-[20px]">
|
||
<div className="h-full box-border">
|
||
<div className="relative flex items-center mb-[20px]">
|
||
<div className="h-[50px] text-[40px] font-bold text-liquid-white flex items-center">
|
||
Задачи
|
||
</div>
|
||
<SecondaryButton
|
||
onClick={() => {
|
||
|
||
if (!jwt){
|
||
toastWarning("Для загрузки задачи необходимо авторизоваться")
|
||
return;
|
||
}
|
||
setModalActive(true);
|
||
}}
|
||
text="Добавить задачу"
|
||
className="absolute right-0"
|
||
/>
|
||
</div>
|
||
|
||
<Filters
|
||
onChangeTags={(value: string[]) => {
|
||
filterTagsHandler(value);
|
||
}}
|
||
onChangeName={(value: string) => {
|
||
dispatch(setMissionsNameFilter(value));
|
||
}}
|
||
/>
|
||
|
||
<div>
|
||
{missions
|
||
.filter((v) =>
|
||
v.name
|
||
.toLowerCase()
|
||
.includes(nameFilter.toLocaleLowerCase()),
|
||
)
|
||
.map((v, i) => (
|
||
<MissionItem
|
||
key={i}
|
||
id={v.id}
|
||
authorId={v.authorId}
|
||
name={v.name}
|
||
difficulty={calcDifficulty(v.difficulty)}
|
||
tags={v.tags}
|
||
timeLimit={1000}
|
||
memoryLimit={256 * 1024 * 1024}
|
||
createdAt={v.createdAt}
|
||
updatedAt={v.updatedAt}
|
||
type={i % 2 == 0 ? 'first' : 'second'}
|
||
status={'empty'}
|
||
/>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<ModalCreate setActive={setModalActive} active={modalActive} />
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Missions;
|