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

View File

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

View File

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