guild_front/src/pages/ProjectTracker/ProjectTracker.js
2023-12-04 18:00:12 +03:00

1100 lines
41 KiB
JavaScript
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 React, { useEffect, useRef, useState } from "react";
import { HexColorPicker } from "react-colorful";
import { useDispatch, useSelector } from "react-redux";
import { Link, useParams } from "react-router-dom";
import {
activeLoader,
addNewTagToProject,
deletePersonOnProject,
deleteTagProject,
filterCreatedByMe,
filteredExecutorTasks,
filteredParticipateTasks,
getBoarderLoader,
getProjectBoard,
modalToggle,
movePositionProjectTask,
moveProjectTask,
setColumnId,
setColumnName,
setColumnPriority,
setProjectBoardFetch,
setToggleTab,
} from "@redux/projectsTrackerSlice";
import { urlForLocal } from "@utils/helper";
import { caseOfNum } from "@utils/helper";
import { apiRequest } from "@api/request";
import { useNotification } from "@hooks/useNotification";
import BaseButton from "@components/Common/BaseButton/BaseButton";
import { Footer } from "@components/Common/Footer/Footer";
import { Loader } from "@components/Common/Loader/Loader";
import AcceptModal from "@components/Modal/AcceptModal/AcceptModal";
import ModalTicket from "@components/Modal/Tracker/ModalTicket/ModalTicket";
import TrackerModal from "@components/Modal/Tracker/TrackerModal/TrackerModal";
import { Navigation } from "@components/Navigation/Navigation";
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
import TrackerSelectColumn from "@components/TrackerSelectColumn/TrackerSelectColumn";
import arrow from "assets/icons/arrows/arrowCalendar.png";
import arrowDown from "assets/icons/arrows/selectArrow.png";
import close from "assets/icons/close.png";
import commentsBoard from "assets/icons/commentsBoard.svg";
import del from "assets/icons/delete.svg";
import edit from "assets/icons/edit.svg";
import filesBoard from "assets/icons/filesBoard.svg";
import trackerNoTasks from "assets/icons/trackerNoTasks.svg";
import project from "assets/icons/trackerProject.svg";
import tasks from "assets/icons/trackerTasks.svg";
import accept from "assets/images/accept.png";
import archive from "assets/images/archiveIcon.png";
import avatarMok from "assets/images/avatarMok.png";
import { getCorrectDate } from "../../components/Calendar/calendarHelper";
export const ProjectTracker = () => {
const dispatch = useDispatch();
const projectId = useParams();
const [openColumnSelect, setOpenColumnSelect] = useState({});
const [selectedTab, setSelectedTab] = useState(0);
const [priorityTask, setPriorityTask] = useState(0);
const [wrapperHover, setWrapperHover] = useState({});
const [taskHover, setTaskHover] = useState({});
const [modalAdd, setModalAdd] = useState(false);
const [modalActiveTicket, setModalActiveTicket] = useState(false);
const [selectedTicket, setSelectedTicket] = useState({});
const [personListOpen, setPersonListOpen] = useState(false);
const [tags, setTags] = useState({
open: false,
add: false,
edit: false,
});
const [acceptModalOpen, setAcceptModalOpen] = useState(false);
const [currentColumnDelete, setCurrentColumnDelete] = useState(null);
const [color, setColor] = useState("#aabbcc");
const [tagInfo, setTagInfo] = useState({ description: "", name: "" });
const [checkBoxParticipateTasks, setCheckBoxParticipateTasks] =
useState(false);
const [filteredNoTasks, setFilteredNoTasks] = useState(false);
const [checkBoxMyTasks, setCheckBoxMyTasks] = useState(false);
const [selectedExecutor, setSelectedExecutor] = useState(null);
const [selectExecutorOpen, setSelectedExecutorOpen] = useState(false);
const startWrapperIndexTest = useRef({});
const projectBoard = useSelector(getProjectBoard);
const loader = useSelector(getBoarderLoader);
const { showNotification } = useNotification();
const priority = {
2: "Высокий",
1: "Средний",
0: "Низкий",
};
const priorityClass = {
2: "high",
1: "middle",
0: "low",
};
useEffect(() => {
dispatch(activeLoader());
dispatch(setProjectBoardFetch(projectId.id));
initListeners();
}, []);
useEffect(() => {
const tasksHover = {};
const columnHover = {};
let columnsTasksEmpty = true;
if (Object.keys(projectBoard).length) {
projectBoard.columns.forEach((column) => {
if (column.tasks.length) columnsTasksEmpty = false;
setOpenColumnSelect((prevState) => ({
...prevState,
[column.id]: false,
}));
columnHover[column.id] = false;
column.tasks.forEach((task) => (tasksHover[task.id] = false));
});
}
if (
columnsTasksEmpty &&
(checkBoxMyTasks || selectedExecutor || checkBoxParticipateTasks)
) {
setFilteredNoTasks(true);
} else {
setFilteredNoTasks(false);
}
setWrapperHover(columnHover);
setTaskHover(tasksHover);
}, [projectBoard]);
function dragStartHandler(e, task, columnId) {
startWrapperIndexTest.current = { task: task, index: columnId };
}
function dragOverTaskHandler(e, task) {
e.preventDefault();
if (startWrapperIndexTest.current.task.id === task.id) {
return;
}
setTaskHover((prevState) => ({ [prevState]: false, [task.id]: true }));
}
function dragLeaveTaskHandler() {
setTaskHover((prevState) => ({ [prevState]: false }));
}
function dragEndTaskHandler() {
setTaskHover((prevState) => ({ [prevState]: false }));
setWrapperHover((prevState) => ({
[prevState]: false,
}));
}
function dragDropTaskHandler(e, task, column) {
e.preventDefault();
if (task.id === startWrapperIndexTest.current.task.id) {
return;
}
const finishTask = column.tasks.indexOf(task);
dispatch(
movePositionProjectTask({
startTask: startWrapperIndexTest.current.task,
finishTask: task,
finishIndex: finishTask,
})
);
}
function dragOverHandler(e) {
e.preventDefault();
}
function dragEnterHandler(columnId) {
if (columnId === startWrapperIndexTest.current.index) {
return;
}
setWrapperHover((prevState) => ({
[prevState]: false,
[columnId]: true,
}));
}
function dragDropHandler(e, columnId) {
e.preventDefault();
setWrapperHover((prevState) => ({
[prevState]: false,
}));
if (
startWrapperIndexTest.current.index === columnId ||
e.target.className.includes("__item")
) {
return;
}
if (columnId !== startWrapperIndexTest.current.index) {
dispatch(
moveProjectTask({
startWrapperIndex: startWrapperIndexTest.current,
columnId,
})
);
}
}
function selectedTabTask(columnId, length) {
setSelectedTab(columnId);
dispatch(modalToggle("createTiketProject"));
setModalAdd(true);
setPriorityTask(length);
}
function openTicket(e, task) {
if (window.innerWidth < 985) {
return;
}
setSelectedTicket(task);
setModalActiveTicket(true);
}
function deleteColumn(column) {
const priorityColumns = [];
apiRequest("/project-column/update-column", {
method: "PUT",
data: {
column_id: column.id,
project_id: projectBoard.id,
status: 0,
},
}).then(() => {
if (column.priority < projectBoard.columns.length) {
for (let i = column.priority; i < projectBoard.columns.length; i++) {
const currentColumn = {
column_id: projectBoard.columns[i].id,
priority: i,
};
priorityColumns.push(currentColumn);
}
apiRequest("/project-column/set-priority", {
method: "POST",
data: {
project_id: projectBoard.id,
data: JSON.stringify(priorityColumns),
},
}).then(() => {
dispatch(setProjectBoardFetch(projectBoard.id));
});
} else {
dispatch(setProjectBoardFetch(projectBoard.id));
}
showNotification({ show: true, text: "Колонка удалена", type: "error" });
});
}
function deletePerson(userId) {
apiRequest("/project/del-user", {
method: "DELETE",
data: {
project_id: projectBoard.id,
user_id: userId,
},
}).then(() => {
dispatch(deletePersonOnProject(userId));
});
}
function filterParticipateTasks() {
if (!checkBoxParticipateTasks) {
dispatch(filteredParticipateTasks(Number(localStorage.getItem("id"))));
} else {
dispatch(setProjectBoardFetch(projectId.id));
setCheckBoxParticipateTasks(false);
setCheckBoxMyTasks(false);
setSelectedExecutor(null);
}
setCheckBoxParticipateTasks(!checkBoxParticipateTasks);
}
function filterMyTask() {
if (!checkBoxMyTasks) {
dispatch(filterCreatedByMe(Number(localStorage.getItem("id"))));
} else {
dispatch(setProjectBoardFetch(projectId.id));
setCheckBoxParticipateTasks(false);
setCheckBoxMyTasks(false);
setSelectedExecutor(null);
}
setCheckBoxMyTasks(!checkBoxMyTasks);
}
function executorFilter(user) {
dispatch(filteredExecutorTasks(user.user_id));
setSelectedExecutor(user);
}
function deleteSelectedExecutorFilter() {
setSelectedExecutor(null);
setCheckBoxParticipateTasks(false);
setCheckBoxMyTasks(false);
dispatch(setProjectBoardFetch(projectId.id));
}
function addNewTag() {
apiRequest("/mark/create", {
method: "POST",
data: {
title: tagInfo.description,
slug: tagInfo.name,
color: color,
status: 1,
},
}).then((data) => {
apiRequest("/mark/attach", {
method: "POST",
data: {
mark_id: data.id,
entity_type: 1,
entity_id: projectId.id,
},
}).then((data) => {
dispatch(addNewTagToProject(data.mark));
setTags((prevState) => ({
...prevState,
add: false,
}));
});
});
}
function editTag() {
apiRequest("/mark/update", {
method: "PUT",
data: {
mark_id: tagInfo.editMarkId,
title: tagInfo.description,
slug: tagInfo.name,
color: color,
},
}).then(() => {
dispatch(setProjectBoardFetch(projectId.id));
setTags((prevState) => ({
...prevState,
edit: false,
}));
setTagInfo({ description: "", name: "" });
setColor("#aabbcc");
});
}
function deleteTag(tagId) {
apiRequest("/mark/detach", {
method: "DELETE",
data: {
mark_id: tagId,
entity_type: 1,
entity_id: projectId.id,
},
}).then(() => {
dispatch(deleteTagProject(tagId));
});
}
const initListeners = () => {
document.addEventListener("click", closeByClickingOut);
};
const closeByClickingOut = (event) => {
const path = event.path || (event.composedPath && event.composedPath());
if (
event &&
!path.find(
(div) =>
div.classList &&
(div.classList.contains("addPerson") ||
div.classList.contains("persons__list"))
)
) {
setPersonListOpen(false);
}
if (
event &&
!path.find(
(div) =>
div.classList &&
(div.classList.contains("tasks__head__executor") ||
div.classList.contains("tasks__head__executorDropdown"))
)
) {
setSelectedExecutorOpen(false);
}
if (
event &&
!path.find(
(div) =>
div.classList &&
(div.classList.contains("tasks__head__tags") ||
div.classList.contains("tags__list"))
)
) {
setTags({
open: false,
add: false,
edit: false,
});
setTagInfo({
description: "",
name: "",
});
setColor("#aabbcc");
}
if (
event &&
!path.find(
(div) =>
div.classList &&
(div.classList.contains("board__head__more") ||
div.classList.contains("column__select"))
)
) {
setOpenColumnSelect((prevState) => {
const newState = {};
for (const key in prevState) {
newState[key] = false;
}
return newState;
});
}
};
function closeAcceptModal() {
setAcceptModalOpen(false);
}
return (
<div className="tracker">
<ProfileHeader />
<Navigation />
<div className="container">
<div className="tracker__content">
<ProfileBreadcrumbs
links={[
{ name: "Главная", link: "/profile" },
{ name: "Трекер", link: "/profile/tracker" },
]}
/>
<h2 className="tracker__title">Управление проектами с трекером</h2>
</div>
</div>
<div className="tracker__tabs">
<div className="tracker__tabs__head">
<Link
to="/profile/tracker"
className="tab active-tab tab projectsTab"
onClick={() => dispatch(setToggleTab(1))}
>
<img src={project} alt="img" />
<p>Проекты </p>
</Link>
<Link
to="/profile/tracker"
className="tab tasksTab"
onClick={() => dispatch(setToggleTab(2))}
>
<img src={tasks} alt="img" />
<p>Все мои задачи</p>
</Link>
<Link
to="/profile/tracker"
className="tab archiveTab"
onClick={() => dispatch(setToggleTab(3))}
>
<img src={archive} alt="img" />
<p>Архив</p>
</Link>
</div>
<div className="tracker__tabs__content">
<TrackerModal
active={modalAdd}
setActive={setModalAdd}
selectedTab={selectedTab}
priorityTask={priorityTask}
projectUsers={projectBoard.projectUsers}
projectMarks={projectBoard.mark}
/>
{loader && <Loader style="green" />}
{!loader && (
<div className="tracker__tabs__content__tasks tasks active__content">
<div className="tasks__head">
<div className="tasks__head__wrapper">
<h5>Проект : {projectBoard.name}</h5>
<div className="tasks__head__add">
<BaseButton
onClick={() => {
dispatch(modalToggle("createColumn"));
setModalAdd(true);
}}
styles={"button-add-column"}
>
+
</BaseButton>
{/* <span
onClick={() => {
dispatch(modalToggle("createColumn"));
setModalAdd(true);
}}
>
+
</span> */}
<p>добавить колонку</p>
</div>
<div
className={
projectBoard.projectUsers?.length
? "tasks__head__persons"
: "tasks__head__persons noProjectUsers"
}
>
{Boolean(projectBoard.projectUsers?.length) && (
<div
className={
projectBoard.projectUsers?.length == 1
? "onePerson"
: "projectPersons"
}
>
{projectBoard.projectUsers.slice(0, 3).map((person) => {
return (
<img
key={person.user_id}
src={
person.user?.avatar
? urlForLocal(person.user.avatar)
: avatarMok
}
alt="avatar"
/>
);
})}
</div>
)}
{projectBoard.projectUsers?.length > 3 && (
<span className="countPersons">+1</span>
)}
<span
className="addPerson"
onClick={() => {
setPersonListOpen(true);
}}
>
+
</span>
<p>добавить участника</p>
{personListOpen && (
<div className="persons__list">
<img
className="persons__list__close"
src={close}
alt="close"
onClick={() => setPersonListOpen(false)}
/>
<div className="persons__list__count">
<span>{projectBoard.projectUsers?.length}</span>
{caseOfNum(
projectBoard.projectUsers?.length,
"persons"
)}
</div>
<div className="persons__list__info">
<span>В проекте - </span>
<p>{projectBoard.name}</p>
</div>
<div className="persons__list__items">
{projectBoard.projectUsers?.map((person) => {
return (
<div
className="persons__list__item"
key={person.user_id}
>
<img
className="avatar"
src={
person.user?.avatar
? urlForLocal(person.user.avatar)
: avatarMok
}
alt="avatar"
/>
<span>{person.user.fio}</span>
<img
className="delete"
src={close}
alt="delete"
onClick={() => deletePerson(person.user_id)}
/>
</div>
);
})}
</div>
<div
className="persons__list__add"
onClick={() => {
dispatch(modalToggle("addWorker"));
setModalAdd(true);
setPersonListOpen(false);
}}
>
<span className="addPerson">+</span>
<p>Добавить участников</p>
</div>
</div>
)}
</div>
<div
className="tasks__head__checkBox"
onClick={filterParticipateTasks}
>
<span>Участвую</span>
<div className="tasks__head__checkBox__box">
{checkBoxParticipateTasks && (
<img src={accept} alt="accept" />
)}
</div>
</div>
<div className="tasks__head__checkBox" onClick={filterMyTask}>
<span>Мои</span>
<div className="tasks__head__checkBox__box">
{checkBoxMyTasks && <img src={accept} alt="accept" />}
</div>
</div>
{selectedExecutor ? (
<div className="tasks__head__executorSelected">
<p>{selectedExecutor.user.fio}</p>
<img
className="avatar"
src={
selectedExecutor.user?.avatar
? urlForLocal(selectedExecutor.user.avatar)
: avatarMok
}
alt="avatar"
/>
<img
className="delete"
src={close}
alt="delete"
onClick={deleteSelectedExecutorFilter}
/>
</div>
) : (
<div
className="tasks__head__executor"
onClick={() =>
setSelectedExecutorOpen(!selectExecutorOpen)
}
>
<p>Выберите исполнителя</p>
<img
className={selectExecutorOpen ? "open" : ""}
src={arrowDown}
alt="arrow"
/>
{selectExecutorOpen && (
<div className="tasks__head__executorDropdown">
{projectBoard.projectUsers.map((user) => {
return (
<div
className="executorDropdown__person"
key={user.user_id}
onClick={() => executorFilter(user)}
>
<p>{user.user?.fio}</p>
<img
src={
user.user?.avatar
? urlForLocal(user.user.avatar)
: avatarMok
}
alt="avatar"
/>
</div>
);
})}
</div>
)}
</div>
)}
<div className="tasks__head__tags">
<div
className="tags__add"
onClick={() => {
setTags((prevState) => ({
...prevState,
open: !tags.open,
}));
}}
>
<p>Список тегов</p>
<span>+</span>
</div>
{tags.open && (
<div className="tags__list">
<div
className="addNewTag"
onClick={() =>
setTags((prevState) => ({
...prevState,
add: true,
}))
}
>
<p>Добавить новый тег</p>
<span>+</span>
</div>
{!tags.add && !tags.edit && (
<div className="tags__list__created">
{projectBoard.mark.map((tag) => {
return (
<div className="tagItem" key={tag.id}>
<p className="tagItem__description">
{tag.title}
</p>
<div className="tagItem__info">
<span className="tagItem__info__name">
{tag.slug}
</span>
<span
className="tagItem__info__color"
style={{ background: tag.color }}
/>
<div className="tagItem__info__images">
<img
src={edit}
alt="edit"
onClick={() => {
setTags((prevState) => ({
...prevState,
edit: true,
}));
setTagInfo({
description: tag.title,
name: tag.slug,
editMarkId: tag.id,
});
setColor(tag.color);
}}
/>
<img
onClick={() => deleteTag(tag.id)}
className="delete"
src={close}
alt="delete"
/>
</div>
</div>
</div>
);
})}
</div>
)}
{(tags.add || tags.edit) && (
<div className="formTag">
<img
src={arrow}
className="arrow"
alt="arrow"
onClick={() => {
setTags((prevState) => ({
...prevState,
add: false,
edit: false,
}));
setTagInfo({
description: "",
name: "",
});
setColor("#aabbcc");
}}
/>
<input
className="formTag__input"
placeholder="Описание метки"
maxLength="25"
value={tagInfo.description}
onChange={(e) =>
setTagInfo((prevState) => ({
...prevState,
description: e.target.value,
}))
}
/>
<input
className="formTag__input"
placeholder="Тег"
value={tagInfo.name}
maxLength="10"
onChange={(e) =>
setTagInfo((prevState) => ({
...prevState,
name: e.target.value,
}))
}
/>
<HexColorPicker color={color} onChange={setColor} />
<button
onClick={() => {
tags.add ? addNewTag() : editTag();
}}
className={
tagInfo.name && tagInfo.description
? "formTag__btn"
: "formTag__btn disable"
}
>
{tags.add ? "Добавить" : "Изменить"}
</button>
</div>
)}
</div>
)}
</div>
<Link to="/profile/tracker" className="tasks__head__back">
<p>Вернуться на проекты</p>
<img src={arrow} alt="arrow" />
</Link>
</div>
</div>
{Boolean(modalActiveTicket) && (
<ModalTicket
active={modalActiveTicket}
setActive={setModalActiveTicket}
task={selectedTicket}
projectId={projectBoard.id}
projectName={projectBoard.name}
projectUsers={projectBoard.projectUsers}
projectOwnerId={projectBoard.owner_id}
projectMarks={projectBoard.mark}
/>
)}
<div className="tasks__container">
{Boolean(projectBoard?.columns) &&
!filteredNoTasks &&
Boolean(projectBoard.columns.length) &&
projectBoard.columns.map((column) => {
return (
<div
key={column.id}
onDragOver={(e) => dragOverHandler(e)}
onDragEnter={() => dragEnterHandler(column.id)}
onDrop={(e) => dragDropHandler(e, column.id)}
className={`tasks__board ${
wrapperHover[column.id] ? "tasks__board__hover" : ""
}`}
>
<div className="board__head">
<span>{column.title}</span>
<div className="board__head__more">
<span
className="add"
onClick={() => {
selectedTabTask(
column.id,
projectBoard?.columns && column.tasks.length
? column.tasks[0].priority - 1
: 1
);
}}
>
+
</span>
<span
onClick={() => {
setOpenColumnSelect((prevState) => ({
...prevState,
[column.id]: true,
}));
}}
className="more"
>
...
</span>
</div>
</div>
{openColumnSelect[column.id] && (
<div className="column__select">
<div
className="column__select__item"
onClick={() => {
setOpenColumnSelect((prevState) => ({
...prevState,
[column.id]: false,
}));
dispatch(modalToggle("editColumn"));
dispatch(setColumnName(column.title));
dispatch(setColumnId(column.id));
dispatch(setColumnPriority(column.priority));
setModalAdd(true);
}}
>
<img src={edit} alt="edit" />
<span>Изменить</span>
</div>
<div
className="column__select__item"
onClick={() => {
if (column.tasks.length) {
setAcceptModalOpen(true);
setCurrentColumnDelete(column);
} else {
deleteColumn(column);
}
}}
>
<img src={del} alt="delete" />
<span>Удалить</span>
</div>
</div>
)}
<div className="tasksContainer">
{column.tasks.map((task) => {
return (
<div
key={task.id}
className={`tasks__board__item ${
taskHover[task.id] ? "task__hover" : ""
}`}
draggable={true}
onDragStart={(e) =>
dragStartHandler(e, task, column.id)
}
onDragOver={(e) => dragOverTaskHandler(e, task)}
onDragLeave={(e) => dragLeaveTaskHandler(e)}
onDragEnd={() => dragEndTaskHandler()}
onDrop={(e) =>
dragDropTaskHandler(e, task, column)
}
onClick={(e) => openTicket(e, task)}
>
<div
className="tasks__board__item__title"
onClick={() => {
if (window.innerWidth < 985) {
window.location.replace(
`/tracker/task/${task.id}`
);
}
}}
>
<p className="task__board__item__title">
{task.title}
</p>
</div>
<p
dangerouslySetInnerHTML={{
__html: task.description,
}}
className="tasks__board__item__description"
></p>
<div className="tasks__board__item__executor">
<span>
{task.executor?.fio
? task.executor?.fio
: "Исполнитель не назначен"}
</span>
{task.executor?.avatar && (
<img
src={
task.executor?.avatar
? urlForLocal(task.executor?.avatar)
: avatarMok
}
alt="avatar"
/>
)}
</div>
{Boolean(task.mark.length) && (
<div className="tasks__board__item__tags">
{task.mark.map((tag) => {
return (
<div
className="tagItem"
key={tag.id}
style={{ background: tag.color }}
>
<p>{tag.slug}</p>
</div>
);
})}
</div>
)}
{typeof task.execution_priority ===
"number" && (
<div className="tasks__board__item__priority">
<p>Приоритет:</p>
<span
className={
priorityClass[task.execution_priority]
}
>
{priority[task.execution_priority]}
</span>
</div>
)}
{task.dead_line && (
<div className="tasks__board__item__deadLine">
<p>Срок исполнения:</p>
<span>
{getCorrectDate(task.dead_line)}
</span>
</div>
)}
<div className="tasks__board__item__info">
<div className="tasks__board__item__info__more">
<img
src={commentsBoard}
alt="commentsImg"
/>
<span>
{task.comment_count}{" "}
{caseOfNum(
task.comment_count,
"comments"
)}
</span>
</div>
<div className="tasks__board__item__info__more">
<img src={filesBoard} alt="filesImg" />
<span>
{task.files ? task.files : 0}{" "}
{caseOfNum(0, "files")}
</span>
</div>
</div>
<TrackerSelectColumn
columns={projectBoard.columns.filter(
(item) => item.id !== column.id
)}
currentColumn={column}
task={task}
/>
</div>
);
})}
</div>
</div>
);
})}
{Boolean(projectBoard?.columns) &&
!Boolean(projectBoard.columns.length) && (
<div className="tasks__board__noItems">
В проекте нет задач.
</div>
)}
{filteredNoTasks && (
<div className="tasks__board__noTasks">
<div className="tasks__board__noTasksInfo">
<img src={trackerNoTasks} alt="noTasks" />
<p>Пока нет подходящих задач</p>
</div>
<p className="tasks__board__noTasksMore">
Ставьте задачи, следите за прогрессом, ведите учёт
рабочего времени
</p>
</div>
)}
</div>
</div>
)}
</div>
</div>
{acceptModalOpen && (
<AcceptModal
title={"В колонке ещё есть задачи, Вы точно хотите удалить её ?"}
closeModal={closeAcceptModal}
agreeHandler={() => deleteColumn(currentColumnDelete)}
/>
)}
<Footer />
</div>
);
};