import { useEffect, useMemo, useState } from 'react';
import { ProjectsApi } from '../../api/projects';
import { CardsSkeleton } from '../../components/common/Skeleton';
import SearchComponent from '../../components/common/SearchComponent';
import { ProjectCardComponent } from './ProjectCard';
import { HeaderSwitch } from '../../components/HeaderMenu/HeaderSwitch';
import { PageContainer, TasksContainer } from '../StyledForPage';
import {
Box,
FormControl,
Button,
Stack,
Pagination,
PaginationItem,
Select,
MenuItem,
Typography,
IconButton,
Tooltip,
TextField,
Autocomplete,
} from '@mui/material';
import { toast } from 'react-toastify';
import { ModalCreateProject } from './ModalCreateProject';
import {
ROLES_NAME_ID,
} from '../../constants/constants';
import { useAuth } from '../../app/context/AuthProvider';
import { PrimaryButton, PrimaryOutlinedButton } from '../../components/common/Buttons/Buttons';
import {
ExportExitButton,
ExportWithTextButton,
} from '../../components/common/Buttons/ButtonsActions';
import { exportBulkForms, exportSingleForm } from '../../utils/exportFile';
import { WhitePlus } from '../../components/common/icons/icons';
import { useNavigate } from 'react-router-dom';
import { PaginatedList } from '../../components/common/PaginatedList';
import { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig';
import { SspApi } from '../../api/ssp';
import NavigationToggle from '../../components/common/NavigationToggle';
export { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig';
export default function ProjectsPage() {
const navigate = useNavigate();
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
// Новые фильтры
const [yearFilter, setYearFilter] = useState('');
const [branchFilter, setBranchFilter] = useState('');
// Pagination state
const [page, setPage] = useState(1);
const [limit, setLimit] = useState(20);
const [totalCount, setTotalCount] = useState(0);
const { user } = useAuth();
const [exportMode, setExportMode] = useState(false);
const [exportList, setExportList] = useState([]);
const [projectData, setProjectData] = useState(DEFAULT_PROJECT_CONFIG);
// Получаем список годов для фильтра (можно динамически или задать диапазон)
const yearOptions = useMemo(() => {
const currentYear = new Date().getFullYear();
const years = [];
for (let year = currentYear - 5; year <= currentYear + 2; year++) {
years.push(year);
}
return years;
}, []);
useEffect(() => {
if (!user) return;
if (user.role_id == ROLES_NAME_ID.admin) {
SspApi.getAll().then(data => {
if (data.success) {
setProjectData(prev => ({
...prev, 'ССП/РФ': {
...prev['ССП/РФ'],
options: data.result
}
}))
return;
}
toast.error('Ошибка при получении ССП/РФ');
});
return;
}
setProjectData(prev => ({
...prev, 'ССП/РФ': {
...prev['ССП/РФ'],
options: user.org_units,
}
}))
}, [user])
const openModal = () => {
setModalOpen(true);
};
const mapFormDataToApi = (formData) => {
const apiData = {
name: formData['Название проекта'] || '',
project_type: formData['Тип проекта развития'] || null,
vsp_format: formData['Формат ВСП'] || null,
object_address: formData['Адрес объекта'] || '',
staff_count: formData['Целевая численность, чел.'] || 0,
placement_type: formData['Тип размещения'] || null,
total_area: formData['Площадь размещения, м2'] || 0,
year: formData['Год'] || null,
branch_id: formData['ССП/РФ'] || null,
};
return apiData;
};
const handleCreateProject = async (formData) => {
try {
const apiData = mapFormDataToApi(formData);
await ProjectsApi.create(apiData);
setPage(1);
loadProjects(1, limit);
setModalOpen(false);
toast.success('Проект успешно создан');
} catch (error) {
toast.error(
error.response?.data?.detail ||
error.response?.data?.message ||
'Ошибка при создании проекта',
);
}
};
const loadProjects = async (currentPage = page, currentLimit = limit) => {
setLoading(true);
try {
const skip = (currentPage - 1) * currentLimit;
const params = {
offset: skip,
limit: currentLimit,
// Добавляем фильтры в параметры запроса
...(yearFilter && { year: parseInt(yearFilter) }),
...(branchFilter && { branch_id: parseInt(branchFilter.id) }),
};
const res = await ProjectsApi.list(params);
const data = res.result;
setItems(data);
setTotalCount(res.count);
} catch (error) {
toast.error('Ошибка загрузки проектов');
} finally {
setLoading(false);
}
};
// Сбрасываем страницу при изменении любых фильтров
useEffect(() => {
setPage(1);
loadProjects(1, limit);
}, [yearFilter, branchFilter]);
const handlePageChange = (event, value) => {
setPage(value);
loadProjects(value, limit);
};
const handleLimitChange = (event) => {
const newLimit = event.target.value;
setLimit(newLimit);
setPage(1);
loadProjects(1, newLimit);
};
// Сброс всех фильтров
const handleClearFilters = () => {
setYearFilter('');
setBranchFilter('');
setPage(1);
};
useEffect(() => {
loadProjects(page, limit);
}, []);
useEffect(() => {
setExportList([]);
}, [exportMode]);
const handleChangeToExportList = (projectId, checked) => {
if (checked) {
setExportList((prev) => [...prev, projectId]);
} else {
const newExportList = exportList.filter((t) => t != projectId);
setExportList(newExportList);
}
};
const handleBulkExport = async () => {
await exportBulkForms(exportList);
setExportMode(false);
};
const handleSingleExport = (projectId, projectTitle) => {
exportSingleForm(projectId, projectTitle);
};
const handleRefresh = () => {
loadProjects(page, limit);
toast.info('Список проектов обновлен');
};
if (!user) return null;
return (
<>
navigate(path)} />
(
)}
getItemId={(project) => project.id}
getItemTitle={(project) => project.name || 'Проект'}
extraActions={
user.role_id === ROLES_NAME_ID.admin && (
} height='2.5rem' >
Создать проект
)
}
filterActions={
option.title || option.name || '-'}
value={branchFilter}
onChange={(event, newValue) => setBranchFilter(newValue)}
sx={{ width: 200 }}
renderInput={(params) => (
)}
/>
Сбросить
}
/>
setModalOpen(false)}
onCreate={handleCreateProject}
config={projectData}
/>
>
);
}