fix: пофикшен Mainpage.css, в частности адаптивность и отображение всего что есть на странице
116 lines
5.6 KiB
JavaScript
116 lines
5.6 KiB
JavaScript
import {useEffect, useState} from 'react';
|
|
import axios from 'axios';
|
|
import Header from './Header';
|
|
import {useNavigate} from 'react-router-dom';
|
|
import './css/Mainpage.css';
|
|
|
|
const Mainpage = () => {
|
|
const [tasks, setTasks] = useState([]);
|
|
const [error_message, setErrorMessage] = useState(null);
|
|
const [count, setCount] = useState(0);
|
|
const [loading, setLoading] = useState(true);
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
const checkSession = async () => {
|
|
try {
|
|
const response = await axios.get('/api/users/my_tasks');
|
|
setTasks(response.data.tasks || []);
|
|
setCount(response.data.count || 0);
|
|
setErrorMessage(null);
|
|
} catch (err) {
|
|
const message = err.response?.data?.message || 'Ошибка авторизации';
|
|
setErrorMessage(message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
checkSession();
|
|
}, []);
|
|
|
|
const isAuthenticated = !error_message;
|
|
|
|
const formatDeadline = (deadline) => {
|
|
if (!deadline) return 'Отсутствует';
|
|
const d = new Date(deadline);
|
|
const day = String(d.getDate()).padStart(2, '0');
|
|
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
const year = d.getFullYear();
|
|
const hours = String(d.getHours()).padStart(2, '0');
|
|
const minutes = String(d.getMinutes()).padStart(2, '0');
|
|
// Формат: 01.04.2026 · 12:00
|
|
return `${day}.${month}.${year} ${hours}:${minutes}`;
|
|
};
|
|
|
|
const handleTaskClick = (boardId) => {
|
|
navigate(`/kanban-board/${boardId}`);
|
|
};
|
|
|
|
const showScrollbar = count > 3;
|
|
|
|
return (
|
|
<>
|
|
<Header />
|
|
<div className="mainpage">
|
|
<div className="mainpage__intro">
|
|
<div className="left-content">
|
|
<h1>Добро пожаловать в Kanban!</h1>
|
|
<p>
|
|
Kanban-доска помогает видеть весь процесс целиком: что запланировано,
|
|
что уже в работе и что готово. Перетаскивайте карточки между колонками, фиксируйте договорённости и не теряйте контекст — всё в одном месте.
|
|
</p>
|
|
</div>
|
|
<div className="tasks-container">
|
|
<h2 className="tasks-title">Мои задачи ({count})</h2>
|
|
{loading ? (
|
|
<p className="tasks-loading">Загрузка...</p>
|
|
) : isAuthenticated ? (
|
|
<>
|
|
{tasks.length === 0 ? (
|
|
<p className="tasks-empty">Нет задач</p>
|
|
) : (
|
|
<ul className={`tasks-list${showScrollbar ? ' tasks-list--scroll' : ''}`}>
|
|
{tasks.map((task) => (
|
|
<li
|
|
key={task.id}
|
|
className="task-item"
|
|
onClick={() => handleTaskClick(task.board_id)}
|
|
>
|
|
<div className="task-item__title">{task.title}</div>
|
|
|
|
{task.category_title && (
|
|
<div className="task-item__meta">
|
|
<span className="task-item__label">Статус:</span>
|
|
<span className="task-item__badge">{task.category_title}</span>
|
|
</div>
|
|
)}
|
|
|
|
{task.board_title && (
|
|
<div className="task-item__meta">
|
|
<span className="task-item__label">Доска:</span>
|
|
<span className="task-item__value task-item__value--truncate">{task.board_title}</span>
|
|
</div>
|
|
)}
|
|
|
|
<div className="task-item__meta">
|
|
<span className="task-item__label">Дедлайн:</span>
|
|
<span className={`task-item__value${!task.deadline ? ' task-item__value--muted' : ''}`}>
|
|
{formatDeadline(task.deadline)}
|
|
</span>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</>
|
|
) : (
|
|
<p className="tasks-empty">Войдите, чтобы увидеть свои задачи.</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Mainpage; |