Files
Kanban-Front/src/KBBoard/KBBoard.js
Vladiysss 5ac938b9ef feat: добавлена возможность покинуть доску
fix: исправлена ошибка при добавлении участника в доску
2026-03-07 19:12:56 +03:00

565 lines
26 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 { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useBoardLogic } from './BoardLogic';
import Header from './../Header';
import './../css/Board.css';
const KBBoard = () => {
const { id } = useParams();
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const [info, setInfo] = useState({});
const [categories, setCategories] = useState([]);
const [isOwner, setIsOwner] = useState(null);
const [crTask, setCrTask] = useState(false);
const [crCateg, setCrCateg] = useState(false);
const [edTask, setEdTask] = useState(false);
const [edCateg, setEdCateg] = useState(false);
const [edBoard, setEdBoard] = useState(false);
const [delTask, setDelTask] = useState(false);
const [delCateg, setDelCateg] = useState(false);
const [asgnMember, setAsgnMember] = useState(false);
const [assignAction, setAssignAction] = useState(false);
const [addMemb, setAddMemb] = useState(false);
const [delBoards, setDelBoards] = useState(false);
const [qtMember, setQtMember] = useState(false);
const [boardTitle, setBoardTitle] = useState('');
const [boardDescription, setBoardDescription] = useState('');
const [categoryTitle, setCategoryTitle] = useState('');
const [taskTitle, setTaskTitle] = useState('');
const [taskDescription, setTaskDescription] = useState('');
const [taskCategory, setTaskCategory] = useState(null);
const [taskCategori, setTaskCategori] = useState(null);
const [editedTask, setEditedTask] = useState({});
const [editedCateg, setEditedCateg] = useState({});
const [taskPosition, setTaskPosition] = useState(null);
const [categoryPosition, setCategoryPosition] = useState(null);
const [assignedMember, setAssignedMember] = useState(0);
const [addedUsername, setAddedUsername] = useState('');
const {
loadBoardData,
createTask,
checkOwner,
createCategory,
editBoard,
editTask,
editCategory,
deleteCategory,
deleteTask,
assignMember,
addMember,
deleteBoards,
quitMember
} = useBoardLogic(id, setError, setInfo, setCategories, setLoading);
useEffect(() => {
if (id) loadBoardData();
}, [id, loadBoardData]);
useEffect(() => {
if (info?.owner?.id !== undefined) checkOwner(info?.owner?.id, setIsOwner);
}, [info?.owner?.id, checkOwner, setIsOwner]);
const modalCrTask = (categori) => () => {
setCrTask(!crTask);
setTaskCategori(categori);
setTaskTitle('');
setTaskDescription('');
}
const modalCrCateg = () => {
setCrCateg(!crCateg);
setCategoryTitle('');
}
const modalEditBoard = () => {
setEdBoard(!edBoard);
setBoardTitle(info.title);
setBoardDescription(info.description);
}
const modalEditTask = (task, id_categ) => () => {
setEdTask(!edTask);
setTaskCategori(id_categ);
setEditedTask(task);
setTaskTitle(task.title);
setTaskDescription(task.description);
setTaskPosition(task.position);
setTaskCategory(task.category_id);
//setAssignedMember(task.assigned_users.id)
}
const modalEditCateg = (categ) => () => {
setEdCateg(!edCateg);
setEditedCateg(categ);
setCategoryTitle(categ.title);
setCategoryPosition(categ.position);
}
const modalDelTask = () => {
setDelTask(!delTask);
}
const modalDelCateg = () => {
setDelCateg(!delCateg);
}
const modalAssignMember = (action) => () => {
setAsgnMember(!asgnMember);
setAssignAction(action)
}
const modalAddMember = () => {
setAddMemb(!addMemb);
}
const modalDeleteBoards = () => {
setDelBoards(!delBoards);
}
const modalQuitMember = () => {
setQtMember(!qtMember);
}
const handleCreateCategory = async (e) => {
e.preventDefault();
await createCategory(categoryTitle, modalCrCateg);
};
const handleCreateTask = async (e) => {
e.preventDefault();
await createTask(taskCategori, taskTitle, taskDescription, modalCrTask);
};
const handleEditBoard = async (e) => {
e.preventDefault();
await editBoard(id, boardTitle, boardDescription, modalEditBoard);
};
const handleEditCategory = async (e) => {
e.preventDefault();
await editCategory(editedCateg.id, categoryTitle, modalEditCateg);
};
const handleEditTask = async (e) => {
e.preventDefault();
await editTask(editedTask.id, taskTitle, taskDescription, taskCategory, modalEditTask);
};
const handleDeleteTask = async (e) => {
e.preventDefault();
await deleteTask(editedTask.id, modalDelTask, modalEditTask);
};
const handleDeleteCategory = async (e) => {
e.preventDefault();
await deleteCategory(editedCateg.id, modalDelCateg, modalEditCateg);
};
const handleAssignMember = async (e) => {
e.preventDefault();
await assignMember(editedTask.id, assignedMember, assignAction, modalAssignMember);
};
const handleAddMember = async (e) => {
e.preventDefault();
await addMember(addedUsername, id, modalAddMember);
};
const handleDeleteBoards = async (e) => {
e.preventDefault();
await deleteBoards(id, modalDeleteBoards);
};
const handleQuitMember = async (e) => {
e.preventDefault();
await quitMember(id, modalQuitMember);
};
return (
<div className="app-container">
<Header />
<div className="page-container">
{
error && <div className="error">{error}</div>
}
<div className="inf-panel" >
<div className="row">
<h3>{info.title}</h3>
<p>
<strong>Участники: </strong> В разработке
</p>
<p>
<strong>Владелец: </strong> {" "+info.owner?.display_name}
<img className="nav-avatar" src={info.owner?.avatar_url} alt=''></img>
</p>
</div>
<div className="row">
<p><strong>Описание: </strong> {info.description ? info.description : 'Отсутствует'}</p>
</div>
</div>
<div className="set-panel" >
{loading ? (
<>
</>
) : isOwner ? (
<>
<button onClick={modalAddMember}>
Добавить участника
</button>
<button onClick={null}>
Выгнать участника
</button>
<button onClick={modalEditBoard}>
Настройки доски
</button>
<button className='Important-button' onClick={modalDeleteBoards}>
Удаление доски
</button>
</>
) : (
<>
<button onClick={modalQuitMember}>
Покинуть доску
</button>
</>
)}
</div>
<div className="board-panel" >
{categories.map((category) => (
<div className="categori" key={category.position}>
<button onClick={modalEditCateg(category)}><h3>{category.title}</h3></button>
<div className="categ-h">
<p>Позиция: {category.position}</p>
<p>Задач: {category.tasks.length}</p>
</div>
<div className='task create'>
<button onClick={modalCrTask(category.id)}>
Новая задача
</button>
</div>
<div className='task-list'>
{category.tasks.length > 0 ? (
category.tasks.map((task) => (
<button className='task' onClick={modalEditTask(task, category.id)} key={task.id}>
<div>{task.title}</div>
<div>{task.description}</div>
<div>Исполнители
{task.assigned_users.map((member) => (
<img key={member.id} className='members-avatar' src={member.avatar_url}></img>
))}
</div>
</button>
))
) : (
<p>Нет задач</p>
)}
</div>
</div>
))}
{categories.length < 10 ? (
<div className="categori create">
<div className="bib">
<button onClick={modalCrCateg}>
<div>
+
</div>
Новая категория
</button>
</div>
</div>
) : (
<></>
)}
</div>
{crCateg && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Новая категория</h3></div>
<form onSubmit={handleCreateCategory}>
<div>
<label >Название:</label>
<input
type="text"
value={categoryTitle}
onChange={(e) => setCategoryTitle(e.target.value)}
required
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Создание...' : 'Создать'}
</button>
</form>
<button onClick={modalCrCateg}>Отменить</button>
</div>
</div>
)}
{crTask && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Новая задача</h3></div>
<form onSubmit={handleCreateTask}>
<div>
<label >Название:</label>
<input
type="text"
value={taskTitle}
onChange={(e) => setTaskTitle(e.target.value)}
required
/>
<label >Описание:</label>
<input
type="text"
value={taskDescription}
onChange={(e) => setTaskDescription(e.target.value)}
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Создание...' : 'Создать'}
</button>
</form>
<button onClick={modalCrTask(null)}>Отменить</button>
</div>
</div>
)}
{edBoard && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Изменение доски</h3></div>
<form onSubmit={handleEditBoard}>
<div>
<label >Название:</label>
<input
type="text"
value={boardTitle}
onChange={(e) => setBoardTitle(e.target.value)}
required
/>
<label >Описание:</label>
<input
type="text"
value={boardDescription}
onChange={(e) => setBoardDescription(e.target.value)}
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Изменение...' : 'Изменить'}
</button>
</form>
<button onClick={modalEditBoard}>Отменить</button>
</div>
</div>
)}
{edCateg && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Изменение категории</h3></div>
<form onSubmit={handleEditCategory}>
<div>
<label >Название:</label>
<input
type="text"
value={categoryTitle}
onChange={(e) => setCategoryTitle(e.target.value)}
required
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Изменение...' : 'Изменить'}
</button>
</form>
<button onClick={modalEditCateg({})}>Отменить</button>
<button className="Important-button" onClick={modalDelCateg}>Удалить</button>
</div>
</div>
)}
{edTask && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Изменение задачи</h3></div>
<form onSubmit={handleEditTask}>
<div>
<label >Название:</label>
<input
type="text"
value={taskTitle}
onChange={(e) => setTaskTitle(e.target.value)}
required
/>
<label >Описание:</label>
<input
type="text"
value={taskDescription}
onChange={(e) => setTaskDescription(e.target.value)}
required
/>
<div>
<label >Категория:</label>
<select value={taskCategory} onChange={(e) => setTaskCategory(e.target.value)}>
{categories.map((category) => (
<option key={category.position} value={category.id}>
{category.title}
</option>
))}
</select>
</div>
<div>
<label >Исполнитель:</label>
<button type="button" onClick={modalAssignMember(true)}>Назначить</button>
<button type="button" onClick={modalAssignMember(false)}>Снять</button>
</div>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Изменение...' : 'Изменить'}
</button>
</form>
<button onClick={modalEditTask({},null)}>Отменить</button>
<button className="Important-button" onClick={modalDelTask}>Удалить</button>
</div>
</div>
)}
{delTask && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Удаление задачи</h3></div>
<form onSubmit={handleDeleteTask}>
<label >Вы точно хотите удалить задачу {editedTask.title}</label>
<button onClick={modalDelTask}>Отменить</button>
<button className="Important-button" type="submit" disabled={loading}>
{loading ? 'Удаление...' : 'Удалить'}
</button>
</form>
</div>
</div>
)}
{delCateg && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Удаление категории</h3></div>
<form onSubmit={handleDeleteCategory}>
<label >Вы точно хотите удалить эту категорию</label>
<button onClick={modalDelCateg}>Отменить</button>
<button className="Important-button" type="submit" disabled={loading}>
{loading ? 'Удаление...' : 'Удалить'}
</button>
</form>
</div>
</div>
)}
{delBoards && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Удаление доски</h3></div>
<form onSubmit={handleDeleteBoards}>
<label >Вы точно хотите удалить эту Канбан доску</label>
<button onClick={modalDeleteBoards} type='reset'>Отменить</button>
<button className="Important-button" type="submit" disabled={loading}>
{loading ? 'Удаление...' : 'Удалить'}
</button>
</form>
</div>
</div>
)}
{addMemb && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Добавление участников</h3></div>
<form onSubmit={handleAddMember}>
<label >Введите логин человека которого хотитепригласить</label>
<input
type="text"
placeholder="Поиск по логину..."
value={addedUsername}
onChange={(e) => setAddedUsername(e.target.value)}
/>
<button onClick={modalAddMember}>Отменить</button>
<button type="submit" disabled={loading}>
{loading ? 'Добавление...' : 'Добавить'}
</button>
</form>
</div>
</div>
)}
{asgnMember && (
<div className="confirm-modal">
{assignAction ? (
<div className="modal-content">
<div><h3>Назначение пользователя</h3></div>
<form onSubmit={handleAssignMember}>
<div>
<div>
<label >Исполнитель:</label>
<select value={assignedMember} onChange={(e) => setAssignedMember(e.target.value)}>
<option value={0}>
Выберите пользователя
</option>
{info.members.map((member) => (
<option key={member.display_name} value={member.id}>
{member.display_name}
</option>
))}
</select>
</div>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Назначение...' : 'Назначить'}
</button>
</form>
<button onClick={modalAssignMember(null)}>Отменить</button>
</div>
) : (
<div className="modal-content">
<div><h3>Снятие пользователя</h3></div>
<form onSubmit={handleAssignMember}>
<div>
<div>
<label >Исполнитель:</label>
<select value={assignedMember} onChange={(e) => setAssignedMember(e.target.value)}>
<option value={0}>
Выберите пользователя
</option>
{info.members.map((member) => (
<option key={member.display_name} value={member.id}>
{member.display_name}
</option>
))}
</select>
</div>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Снятие...' : 'Снять'}
</button>
</form>
<button onClick={modalAssignMember(null)}>Отменить</button>
</div>
)}
</div>
)}
{qtMember && (
<div className="confirm-modal">
<div className="modal-content">
<div><h3>Покинуть доску</h3></div>
<form onSubmit={handleQuitMember}>
<label >Вы точно хотите удалить эту Канбан доску</label>
<button onClick={modalQuitMember} type='reset'>Отменить</button>
<button className="Important-button" type="submit" disabled={loading}>
{loading ? 'Удаление...' : 'Удалить'}
</button>
</form>
</div>
</div>
)}
</div>
</div>
);
}
export default KBBoard;