Files
LiquidCode_Frontend/src/views/home/missions/Missions.tsx
Виталий Лавшонок 781945b358 fix
2025-12-14 17:24:02 +03:00

118 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;