fix: изменение структуры кода страницы канбан доски
разделение на 3 файла: - UI - Бизнес логика - Обращение к бэку
This commit is contained in:
@@ -7,7 +7,7 @@ import Profile from './Profile';
|
|||||||
import Registration from './Registration';
|
import Registration from './Registration';
|
||||||
import Mainpage from './Mainpage';
|
import Mainpage from './Mainpage';
|
||||||
import KBBoardsList from './KBBoardsList';
|
import KBBoardsList from './KBBoardsList';
|
||||||
import KBBoard from './KBBoard';
|
import KBBoard from './KBBoard/KBBoard';
|
||||||
import OtherProfile from './OtherProfile';
|
import OtherProfile from './OtherProfile';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|||||||
33
src/KBBoard/BoardAPI.js
Normal file
33
src/KBBoard/BoardAPI.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export const loadBoardDataAPI = async (boardId) => {
|
||||||
|
return axios.post('/api/boards/load', { id: boardId });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createTaskAPI = async (taskData) => {
|
||||||
|
return axios.post('/api/boards/categories/tasks/create', taskData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createCategoryAPI = async (categoryData) => {
|
||||||
|
return axios.post('/api/boards/categories/create', categoryData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateTaskAPI = async (updateData) => {
|
||||||
|
return axios.put('/api/boards/categories/tasks/update', updateData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateCategoryAPI = async (updateData) => {
|
||||||
|
return axios.put('/api/boards/categories/update', updateData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteCategoryAPI = async (categoryId) => {
|
||||||
|
return axios.delete('/api/boards/categories/delete', {
|
||||||
|
data: { id: categoryId }
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteTaskAPI = async (taskId) => {
|
||||||
|
return axios.delete('/api/boards/categories/tasks/delete', {
|
||||||
|
data: { id: taskId }
|
||||||
|
});
|
||||||
|
};
|
||||||
159
src/KBBoard/BoardLogic.js
Normal file
159
src/KBBoard/BoardLogic.js
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
loadBoardDataAPI,
|
||||||
|
createTaskAPI,
|
||||||
|
createCategoryAPI,
|
||||||
|
updateTaskAPI,
|
||||||
|
updateCategoryAPI,
|
||||||
|
deleteCategoryAPI,
|
||||||
|
deleteTaskAPI
|
||||||
|
} from './BoardAPI';
|
||||||
|
|
||||||
|
export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const loadBoardData = useCallback(async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
setError('');
|
||||||
|
const response = await loadBoardDataAPI(id);
|
||||||
|
setInfo(response.data);
|
||||||
|
setCategories(response.data.categories || []);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.response?.data?.message === 'Token Error' ||
|
||||||
|
err.response?.data?.message === 'Invalid Token') {
|
||||||
|
setError('Вы не авторизованы');
|
||||||
|
setTimeout(() => navigate('/login'), 1000);
|
||||||
|
} else {
|
||||||
|
setError('Ошибка загрузки доски');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [id, setError, setInfo, setCategories, setLoading, navigate]);
|
||||||
|
|
||||||
|
const createTask = useCallback(async (taskCategori, taskTitle, taskDescription, modalCrTask) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const newTask = {
|
||||||
|
category_id: taskCategori,
|
||||||
|
title: taskTitle,
|
||||||
|
description: taskDescription
|
||||||
|
};
|
||||||
|
await createTaskAPI(newTask);
|
||||||
|
await loadBoardData();
|
||||||
|
modalCrTask(null)();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Ошибка создания задачи:', err);
|
||||||
|
setError('Ошибка создания задачи');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const createCategory = useCallback(async (categoryTitle, modalCrCateg) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const newCategory = {
|
||||||
|
board_id: id,
|
||||||
|
title: categoryTitle
|
||||||
|
};
|
||||||
|
await createCategoryAPI(newCategory);
|
||||||
|
await loadBoardData();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Ошибка создания категории:', err);
|
||||||
|
setError(err.response?.data?.message || 'Ошибка создания категории');
|
||||||
|
} finally {
|
||||||
|
modalCrCateg();
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [id, loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const editTask = useCallback(async (editedTaskId, taskTitle, taskDescription, taskCategory, modalEditTask) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
await updateTaskAPI({
|
||||||
|
id: editedTaskId,
|
||||||
|
update_method: 'title',
|
||||||
|
value: taskTitle
|
||||||
|
});
|
||||||
|
await updateTaskAPI({
|
||||||
|
id: editedTaskId,
|
||||||
|
update_method: 'description',
|
||||||
|
value: taskDescription
|
||||||
|
});
|
||||||
|
await updateTaskAPI({
|
||||||
|
id: editedTaskId,
|
||||||
|
update_method: 'category',
|
||||||
|
value: Number(taskCategory)
|
||||||
|
});
|
||||||
|
await loadBoardData();
|
||||||
|
modalEditTask({}, null)();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Ошибка редактирования задачи:', err);
|
||||||
|
setError('Ошибка редактирования задачи');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const editCategory = useCallback(async (editedCategId, categoryTitle, modalEditCateg) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const updateData = {
|
||||||
|
id: editedCategId,
|
||||||
|
update_method: 'title',
|
||||||
|
value: categoryTitle
|
||||||
|
};
|
||||||
|
await updateCategoryAPI(updateData);
|
||||||
|
await loadBoardData();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Ошибка редактирования категории:', err);
|
||||||
|
setError(err.response?.data?.message || 'Ошибка редактирования категории');
|
||||||
|
} finally {
|
||||||
|
modalEditCateg({})();
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const deleteCategory = useCallback(async (categoryId, modalDelCateg, modalEditCateg) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
await deleteCategoryAPI(categoryId);
|
||||||
|
await loadBoardData();
|
||||||
|
modalDelCateg();
|
||||||
|
modalEditCateg({})();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Ошибка удаления категории:', err);
|
||||||
|
setError('Ошибка удаления категории');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const deleteTask = useCallback(async (taskId, modalDelTask, modalEditTask) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
await deleteTaskAPI(taskId);
|
||||||
|
await loadBoardData();
|
||||||
|
modalDelTask();
|
||||||
|
modalEditTask({}, null)();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Ошибка удаления задачи:', err);
|
||||||
|
setError('Ошибка удаления задачи');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
loadBoardData,
|
||||||
|
createTask,
|
||||||
|
createCategory,
|
||||||
|
editTask,
|
||||||
|
editCategory,
|
||||||
|
deleteCategory,
|
||||||
|
deleteTask
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import axios from 'axios';
|
import { useBoardLogic } from './BoardLogic';
|
||||||
import Header from './Header';
|
import Header from './../Header';
|
||||||
import './css/Board.css';
|
import './../css/Board.css';
|
||||||
|
|
||||||
const KBBoard = () => {
|
const KBBoard = () => {
|
||||||
const navigate = useNavigate();
|
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false);
|
||||||
const [info, setInfo] = useState({});
|
const [info, setInfo] = useState({});
|
||||||
const [categories, setCategories] = useState([]);
|
const [categories, setCategories] = useState([]);
|
||||||
|
|
||||||
@@ -20,39 +19,29 @@ const KBBoard = () => {
|
|||||||
const [delCateg, setDelCateg] = useState(false);
|
const [delCateg, setDelCateg] = useState(false);
|
||||||
|
|
||||||
const [categoryTitle, setCategoryTitle] = useState('');
|
const [categoryTitle, setCategoryTitle] = useState('');
|
||||||
const [categoryPosition, setCategoryPosition] = useState(null);
|
|
||||||
const [taskTitle, setTaskTitle] = useState('');
|
const [taskTitle, setTaskTitle] = useState('');
|
||||||
const [taskDescription, setTaskDescription] = useState('');
|
const [taskDescription, setTaskDescription] = useState('');
|
||||||
const [taskPosition, setTaskPosition] = useState(null);
|
|
||||||
const [taskCategory, setTaskCategory] = useState(null);
|
const [taskCategory, setTaskCategory] = useState(null);
|
||||||
const [taskCategori, setTaskCategori] = useState(null);
|
const [taskCategori, setTaskCategori] = useState(null);
|
||||||
const [editedTask, setEditedTask] = useState({});
|
const [editedTask, setEditedTask] = useState({});
|
||||||
const [editedCateg, setEditedCateg] = useState({});
|
const [editedCateg, setEditedCateg] = useState({});
|
||||||
|
const [taskPosition, setTaskPosition] = useState(null);
|
||||||
|
const [categoryPosition, setCategoryPosition] = useState(null);
|
||||||
|
|
||||||
|
const {
|
||||||
|
loadBoardData,
|
||||||
|
createTask,
|
||||||
|
createCategory,
|
||||||
|
editTask,
|
||||||
|
editCategory,
|
||||||
|
deleteCategory,
|
||||||
|
deleteTask
|
||||||
|
} = useBoardLogic(id, setError, setInfo, setCategories, setLoading);
|
||||||
|
|
||||||
|
|
||||||
const loadBoardData = useCallback(async () => {
|
|
||||||
try {
|
|
||||||
setError('')
|
|
||||||
const response = await axios.post('/api/boards/load', { id });
|
|
||||||
setInfo(response.data);
|
|
||||||
setCategories(response.data.categories);
|
|
||||||
} catch (err) {
|
|
||||||
if (err.response?.data?.message === 'Token Error' || err.response?.data?.message === 'Invalid Token') {
|
|
||||||
setError('Вы не авторизованы');
|
|
||||||
setTimeout(() => {
|
|
||||||
navigate('/login');
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
|
||||||
setError('Ошибка загрузки доски');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [id, navigate]);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id) loadBoardData();
|
if (id) loadBoardData();
|
||||||
}, [id, loadBoardData]);
|
}, [id, loadBoardData]);
|
||||||
|
|
||||||
|
|
||||||
const modalCrTask = (categori) => () => {
|
const modalCrTask = (categori) => () => {
|
||||||
setCrTask(!crTask);
|
setCrTask(!crTask);
|
||||||
setTaskCategori(categori);
|
setTaskCategori(categori);
|
||||||
@@ -85,80 +74,30 @@ const KBBoard = () => {
|
|||||||
setDelCateg(!delCateg);
|
setDelCateg(!delCateg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleCreateCategory = async (e) => {
|
||||||
|
|
||||||
const createTask = async (e) => {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
await createCategory(categoryTitle, modalCrCateg);
|
||||||
const newTask = { category_id: taskCategori, title: taskTitle, description: taskDescription };
|
|
||||||
await axios.post('/api/boards/categories/tasks/create', newTask);
|
|
||||||
await loadBoardData();
|
|
||||||
modalCrTask(null)();
|
|
||||||
setLoading(false);
|
|
||||||
};
|
};
|
||||||
const createCategory = async (e) => {
|
const handleCreateTask = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
await createTask(taskCategori, taskTitle, taskDescription, modalCrTask);
|
||||||
try {
|
|
||||||
const newCategory = { board_id: id, title: categoryTitle};
|
|
||||||
await axios.post('/api/boards/categories/create', newCategory);
|
|
||||||
await loadBoardData();
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.response.data.message)
|
|
||||||
} finally {
|
|
||||||
modalCrCateg();
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
const handleEditCategory = async (e) => {
|
||||||
const editTask = async (e) => {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
await editCategory(editedCateg.id, categoryTitle, modalEditCateg);
|
||||||
var newTask = { id: editedTask.id, update_method: "title", value: taskTitle };
|
|
||||||
await axios.put('/api/boards/categories/tasks/update', newTask);
|
|
||||||
newTask = { id: editedTask.id, update_method: "description", value: taskDescription };
|
|
||||||
await axios.put('/api/boards/categories/tasks/update', newTask);
|
|
||||||
newTask = { id: editedTask.id, update_method: "category", value: Number(taskCategory) };
|
|
||||||
await axios.put('/api/boards/categories/tasks/update', newTask);
|
|
||||||
await loadBoardData();
|
|
||||||
modalEditTask({}, null)();
|
|
||||||
setLoading(false);
|
|
||||||
};
|
};
|
||||||
const editCategory = async (e) => {
|
const handleEditTask = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
await editTask(editedTask.id, taskTitle, taskDescription, taskCategory, modalEditTask);
|
||||||
try {
|
|
||||||
const newCategory = { id: editedCateg.id, update_method: "title", value: categoryTitle};
|
|
||||||
await axios.put('/api/boards/categories/update', newCategory);
|
|
||||||
await loadBoardData();
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.response.data.message)
|
|
||||||
} finally {
|
|
||||||
modalEditCateg({})();
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
const handleDeleteTask = async (e) => {
|
||||||
|
|
||||||
const deleteCategory = async (e) => {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
await deleteTask(editedTask.id, modalDelTask, modalEditTask);
|
||||||
await axios.delete('/api/boards/categories/delete', { data: {id: editedCateg.id} });
|
};
|
||||||
await loadBoardData();
|
const handleDeleteCategory = async (e) => {
|
||||||
modalDelCateg();
|
|
||||||
modalEditCateg({})();
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
const deleteTask = async (e) => {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
await deleteCategory(editedCateg.id, modalDelCateg, modalEditCateg);
|
||||||
await axios.delete('/api/boards/categories/tasks/delete', { data: { id: editedTask.id } });
|
};
|
||||||
await loadBoardData();
|
|
||||||
modalDelTask();
|
|
||||||
modalEditTask({},null)();
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-container">
|
<div className="app-container">
|
||||||
@@ -228,12 +167,11 @@ const KBBoard = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{crCateg && (
|
{crCateg && (
|
||||||
<div className="confirm-modal">
|
<div className="confirm-modal">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div><h3>Новая категория</h3></div>
|
<div><h3>Новая категория</h3></div>
|
||||||
<form onSubmit={createCategory}>
|
<form onSubmit={handleCreateCategory}>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -255,7 +193,7 @@ const KBBoard = () => {
|
|||||||
<div className="confirm-modal">
|
<div className="confirm-modal">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div><h3>Новая задача</h3></div>
|
<div><h3>Новая задача</h3></div>
|
||||||
<form onSubmit={createTask}>
|
<form onSubmit={handleCreateTask}>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -282,7 +220,7 @@ const KBBoard = () => {
|
|||||||
<div className="confirm-modal">
|
<div className="confirm-modal">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div><h3>Изменение категории</h3></div>
|
<div><h3>Изменение категории</h3></div>
|
||||||
<form onSubmit={editCategory}>
|
<form onSubmit={handleEditCategory}>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -305,7 +243,7 @@ const KBBoard = () => {
|
|||||||
<div className="confirm-modal">
|
<div className="confirm-modal">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div><h3>Изменение задачи</h3></div>
|
<div><h3>Изменение задачи</h3></div>
|
||||||
<form onSubmit={editTask}>
|
<form onSubmit={handleEditTask}>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -344,7 +282,7 @@ const KBBoard = () => {
|
|||||||
<div className="confirm-modal">
|
<div className="confirm-modal">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div><h3>Удаление задачи</h3></div>
|
<div><h3>Удаление задачи</h3></div>
|
||||||
<form onSubmit={deleteTask}>
|
<form onSubmit={handleDeleteTask}>
|
||||||
<label >Вы точно хотите удалить задачу {editedTask.title}</label>
|
<label >Вы точно хотите удалить задачу {editedTask.title}</label>
|
||||||
<button onClick={modalDelTask}>Отменить</button>
|
<button onClick={modalDelTask}>Отменить</button>
|
||||||
<button className="Important-button" type="submit" disabled={loading}>
|
<button className="Important-button" type="submit" disabled={loading}>
|
||||||
@@ -359,7 +297,7 @@ const KBBoard = () => {
|
|||||||
<div className="confirm-modal">
|
<div className="confirm-modal">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div><h3>Удаление категории</h3></div>
|
<div><h3>Удаление категории</h3></div>
|
||||||
<form onSubmit={deleteCategory}>
|
<form onSubmit={handleDeleteCategory}>
|
||||||
<label >Вы точно хотите удалить эту категорию</label>
|
<label >Вы точно хотите удалить эту категорию</label>
|
||||||
<button onClick={modalDelCateg}>Отменить</button>
|
<button onClick={modalDelCateg}>Отменить</button>
|
||||||
<button className="Important-button" type="submit" disabled={loading}>
|
<button className="Important-button" type="submit" disabled={loading}>
|
||||||
@@ -369,7 +307,6 @@ const KBBoard = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
Reference in New Issue
Block a user