feat: добавлена возможность установить дедлайн при создании и при изменении задачи

- изменён стиль скроллбаров
- fix: изменено назначение пользхователя при создании задачи(не список пользователей, а один)
This commit is contained in:
Vladiysss
2026-03-15 19:07:52 +03:00
parent aba66ca0bc
commit 4e4e49f3b3
4 changed files with 88 additions and 31 deletions

View File

@@ -6,7 +6,7 @@ export const loadBoardDataAPI = async (boardId) => {
export const createTaskAPI = async (taskCateg, taskTitle, taskDescription, taskDedline, memberId) => { export const createTaskAPI = async (taskCateg, taskTitle, taskDescription, taskDedline, memberId) => {
return axios.post('/api/boards/categories/tasks/create', { return axios.post('/api/boards/categories/tasks/create', {
category_id: taskCateg, title: taskTitle, description: taskDescription, deadline: taskDedline, assigned_users: memberId category_id: taskCateg, title: taskTitle, description: taskDescription, deadline: taskDedline, assigned_user: memberId
}); });
}; };

View File

@@ -58,14 +58,13 @@ export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading,
} }
}, [id, loadBoardData, setLoading, setError]); }, [id, loadBoardData, setLoading, setError]);
const createTask = useCallback(async (taskCategori, taskTitle, taskDescription, modalCrTask) => { const createTask = useCallback(async (taskCategori, taskTitle, taskDescription, modalCrTask, taskDedline, memberId) => {
setLoading(true); setLoading(true);
try { try {
await createTaskAPI(taskCategori, taskTitle, taskDescription); await createTaskAPI(taskCategori, taskTitle, taskDescription, taskDedline, memberId);
await loadBoardData(); await loadBoardData();
modalCrTask(null)(); modalCrTask(null)();
} catch (err) { } catch (err) {
console.error('Ошибка создания задачи:', err);
setError('Ошибка создания задачи'); setError('Ошибка создания задачи');
} finally { } finally {
setLoading(false); setLoading(false);
@@ -103,12 +102,16 @@ export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading,
} }
}, [loadBoardData, setLoading, setError]); }, [loadBoardData, setLoading, setError]);
const editTask = useCallback(async (editedTaskId, taskTitle, taskDescription, taskCategory, modalEditTask) => { const editTask = useCallback(async (editedTaskId, taskTitle, taskDescription, taskCategory, taskDeadline, modalEditTask) => {
setLoading(true); setLoading(true);
try { try {
await updateTaskAPI( editedTaskId, 'title', taskTitle ); await updateTaskAPI( editedTaskId, 'title', taskTitle );
await updateTaskAPI( editedTaskId, 'description', taskDescription ); await updateTaskAPI( editedTaskId, 'description', taskDescription );
await updateTaskAPI( editedTaskId, 'category', Number(taskCategory) ); await updateTaskAPI( editedTaskId, 'category', Number(taskCategory) );
if (typeof taskDeadline != "string") {
taskDeadline = null
}
await updateTaskAPI( editedTaskId, 'deadline', taskDeadline );
await loadBoardData(); await loadBoardData();
modalEditTask({}, null)(); modalEditTask({}, null)();
} catch (err) { } catch (err) {

View File

@@ -36,6 +36,8 @@ const KBBoard = () => {
const [taskDescription, setTaskDescription] = useState(''); const [taskDescription, setTaskDescription] = useState('');
const [taskCategory, setTaskCategory] = useState(null); const [taskCategory, setTaskCategory] = useState(null);
const [taskCategori, setTaskCategori] = useState(null); const [taskCategori, setTaskCategori] = useState(null);
const [taskDeadline, setTaskDeadline] = useState('');
const [assignedMembers, setAssignedMembers] = useState(null);
const [editedTask, setEditedTask] = useState({}); const [editedTask, setEditedTask] = useState({});
const [editedCateg, setEditedCateg] = useState({}); const [editedCateg, setEditedCateg] = useState({});
const [taskPosition, setTaskPosition] = useState(null); const [taskPosition, setTaskPosition] = useState(null);
@@ -57,19 +59,21 @@ const KBBoard = () => {
addMember, addMember,
deleteBoards, deleteBoards,
quitMember, quitMember,
deleteMember deleteMember,
} = useBoardLogic(id, setError, setInfo, setCategories, setLoading, setItems); } = useBoardLogic(id, setError, setInfo, setCategories, setLoading, setItems);
function ListItem({ item }) { function ListItem({ item }) {
if (!item) return null; if (!item) return null;
const user = () => { navigate('/profile/' + item.id); }; const user = () => { navigate('/profile/' + item.id); };
return ( return (
<>
<button onClick={user}> <button onClick={user}>
<div className="row"> <div className="row">
<h3>{item.display_name}<img className='members-avatar' src={item.avatar_url} alt=''></img></h3> <h3>{item.display_name}<img className='members-avatar' src={item.avatar_url} alt=''></img></h3>
<p><strong>Описание:</strong> {item.description ? item.description : 'Отсутствует'}</p> <p><strong>Описание:</strong> {item.description ? item.description : 'Отсутствует'}</p>
</div> </div>
</button> </button>
</>
); );
}; };
@@ -89,6 +93,7 @@ const KBBoard = () => {
setTaskCategori(categori); setTaskCategori(categori);
setTaskTitle(''); setTaskTitle('');
setTaskDescription(''); setTaskDescription('');
setTaskDeadline('')
} }
const modalCrCateg = () => { const modalCrCateg = () => {
setCrCateg(!crCateg); setCrCateg(!crCateg);
@@ -107,6 +112,7 @@ const KBBoard = () => {
setTaskDescription(task.description); setTaskDescription(task.description);
setTaskPosition(task.position); setTaskPosition(task.position);
setTaskCategory(task.category_id); setTaskCategory(task.category_id);
setTaskDeadline(task.deadline)
} }
const modalEditCateg = (categ) => () => { const modalEditCateg = (categ) => () => {
setEdCateg(!edCateg); setEdCateg(!edCateg);
@@ -144,7 +150,7 @@ const KBBoard = () => {
}; };
const handleCreateTask = async (e) => { const handleCreateTask = async (e) => {
e.preventDefault(); e.preventDefault();
await createTask(taskCategori, taskTitle, taskDescription, modalCrTask); await createTask(taskCategori, taskTitle, taskDescription, modalCrTask, taskDeadline, assignedMembers);
}; };
const handleEditBoard = async (e) => { const handleEditBoard = async (e) => {
e.preventDefault(); e.preventDefault();
@@ -156,7 +162,7 @@ const KBBoard = () => {
}; };
const handleEditTask = async (e) => { const handleEditTask = async (e) => {
e.preventDefault(); e.preventDefault();
await editTask(editedTask.id, taskTitle, taskDescription, taskCategory, modalEditTask); await editTask(editedTask.id, taskTitle, taskDescription, taskCategory, taskDeadline, modalEditTask);
}; };
const handleDeleteTask = async (e) => { const handleDeleteTask = async (e) => {
e.preventDefault(); e.preventDefault();
@@ -202,11 +208,13 @@ const KBBoard = () => {
<button onClick={modalMemList}> <button onClick={modalMemList}>
<strong>Участники: </strong> <strong>Участники: </strong>
{(info.members || []).map((member) => ( {(info.members || []).map((member) => (
(member.id !== info.owner.id) ? ( <div key={member.id}>
<img key={member.id} className='members-avatar' src={member.avatar_url} alt=''></img> {(member.id !== info.owner?.id) ? (
<img className='members-avatar' src={member.avatar_url} alt={member.display_name || 'Участник'}></img>
) : ( ) : (
<></> <></>
) )}
</div>
))} ))}
</button> </button>
</p> </p>
@@ -268,11 +276,23 @@ const KBBoard = () => {
<button className='task' onClick={modalEditTask(task, category.id)} key={task.id}> <button className='task' onClick={modalEditTask(task, category.id)} key={task.id}>
<div>{task.title}</div> <div>{task.title}</div>
<div>{task.description}</div> <div>{task.description}</div>
{task.deadline && (
<div>Дедлайн: {new Date(task.deadline).toLocaleString('ru-RU', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZone: 'UTC'})}
</div>
)}
{task.assigned_users[0] !== undefined && (
<div>Исполнители: <div>Исполнители:
{task.assigned_users.map((member) => ( {task.assigned_users.map((member) => (
<img key={member.id} className='members-avatar' src={member.avatar_url} alt=''></img> <img key={member.id} className='members-avatar' src={member.avatar_url} alt=''></img>
))} ))}
</div> </div>
)}
</button> </button>
)) ))
) : ( ) : (
@@ -360,6 +380,28 @@ const KBBoard = () => {
onChange={(e) => setTaskDescription(e.target.value)} onChange={(e) => setTaskDescription(e.target.value)}
/> />
</div> </div>
<div>
<label>Дедлайн:</label>
<input
type="datetime-local"
value={taskDeadline}
onChange={(e) => setTaskDeadline(e.target.value)}
step="1" // для секунд
/>
</div>
<div>
<label>Исполнитель:</label>
<select value={assignedMembers} onChange={(e) => setAssignedMembers(e.target.value)}>
<option value={null}>
Выберите пользователя
</option>
{info.members.map((member) => (
<option key={member.display_name} value={member.id}>
{member.display_name}
</option>
))}
</select>
</div>
<button type="submit" disabled={loading}> <button type="submit" disabled={loading}>
{loading ? 'Создание...' : 'Создать'} {loading ? 'Создание...' : 'Создать'}
</button> </button>
@@ -442,6 +484,16 @@ const KBBoard = () => {
onChange={(e) => setTaskDescription(e.target.value)} onChange={(e) => setTaskDescription(e.target.value)}
required required
/> />
<div>
<label>Дедлайн: {new Date(editedTask.deadline).toLocaleString()}</label>
<input
type="datetime-local"
value={taskDeadline}
onChange={(e) => setTaskDeadline(e.target.value)}
step="1" // для секунд
/>
</div>
<div> <div>
<label >Категория:</label> <label >Категория:</label>
<select value={taskCategory} onChange={(e) => setTaskCategory(e.target.value)}> <select value={taskCategory} onChange={(e) => setTaskCategory(e.target.value)}>

View File

@@ -279,19 +279,21 @@ label {
.task-list::-webkit-scrollbar-track , .task-list::-webkit-scrollbar-track ,
.board-panel::-webkit-scrollbar-track { .board-panel::-webkit-scrollbar-track {
background: #fff; background:#1f2430 ;
border-radius: 8px; border-radius: 8px;
margin-left: 8px; }
.task-list::-webkit-scrollbar-track {
background:#2b3245 ;
} }
.task-list::-webkit-scrollbar-thumb, .task-list::-webkit-scrollbar-thumb,
.board-panel::-webkit-scrollbar-thumb { .board-panel::-webkit-scrollbar-thumb {
background: #aaa; background: #617099;
border-radius: 8px; border-radius: 8px;
margin-left: 8px;
} }
.task-list::-webkit-scrollbar-thumb:hover, .task-list::-webkit-scrollbar-track ,
.board-panel::-webkit-scrollbar-thumb:hover { .task-list::-webkit-scrollbar-thumb {
background: #888; margin-left: 8px;
} }