import styled from '@emotion/styled'; import { Box, Chip, Stack } from '@mui/material'; // src/components/common/ProjectCardComponent/ProjectCardComponent.jsx import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { toast } from 'react-toastify'; import { ProjectsApi } from '../../api/projects'; import { IconWithContent } from '../../components/common/IconWithContent'; import { CheckBoxCheckSvg, CheckBoxUncheckSvg, DateIcon, UserIcon } from '../../components/common/icons/icons'; import { ModalCreateProject } from './ModalCreateProject'; const ProjectCard = styled.div` width: 26.8rem; height: 15rem; display: flex; padding: 1.25rem; flex-direction: column; justify-content: space-between; align-items: flex-start; box-sizing: border-box; border: 0.06rem solid var(--Stroke, rgba(0, 0, 0, 0.1)); border-radius: 1rem; box-shadow: 0rem 2rem 4rem -2rem rgba(0, 0, 0, 0.02), 0rem 4rem 6rem -1rem rgba(0, 0, 0, 0.02); background: var(--White, rgba(255, 255, 255, 1)); overflow: hidden; cursor: pointer; position: relative; &:hover { transform: translateY(-5px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12); } `; const CardHeader = styled.div` width: 100%; display: flex; justify-content: space-between; align-items: center; `; const ProjectId = styled.div` font-size: 0.75rem; font-weight: 400; line-height: 1rem; letter-spacing: 0rem; text-align: left; color: rgba(0, 0, 0, 0.6); `; const CardBody = styled.div` width: 100%; flex: 1; display: flex; flex-direction: column; gap: 0.8125rem; justify-content: flex-end; height: 100%; `; const ProjectTitle = styled.div` font-size: 1rem; font-weight: 500; color: var(--Text-Primary, #333); line-height: 1.63; margin: 0; padding: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; `; const StatusChip = styled(Chip)` font-size: 0.7rem; height: 1.5rem; background-color: ${({ status }) => { switch (status) { case 'active': return '#4caf50'; case 'completed': return '#2196f3'; case 'paused': return '#ff9800'; case 'archived': return '#9e9e9e'; default: return '#9e9e9e'; } }}; color: white; `; const LevelChip = styled(Chip)` font-size: 0.6rem; height: 1.25rem; background-color: rgba(0, 0, 0, 0.08); color: rgba(0, 0, 0, 0.7); `; const ProjectInfoGrid = styled.div` display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.25rem; `; const InfoChip = styled(Chip)` font-size: 0.6rem; height: 1.25rem; background-color: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.7); `; const getStatusLabel = (status) => { const statusMap = { active: 'Активный', completed: 'Завершен', paused: 'Приостановлен', archived: 'Архивирован', }; return statusMap[status] || status || 'Не указан'; }; export const ProjectCardComponent = ({ project, projectDataInit, exportMode = false, isLoadingFile = false, onAddForExport, onExportClick, }) => { const navigate = useNavigate(); const { id, name, org_unit_name, years, status, level, project_type, vsp_format, placement_type, object_address, staff_count, total_area, report_count, parent_id, } = project; const [isEditModalOpen, setEditModalOpen] = useState(false); const [currentName, setCurrentName] = useState(name || ''); const [isChecked, setIsChecked] = useState(false); const [editFormData, setEditFormData] = useState({}); const [projectData, setProjectData] = useState(projectDataInit); useEffect(() => { setIsChecked(false); }, [exportMode]); // Функция для подготовки данных проекта к редактированию const prepareProjectDataForEdit = () => { return { 'ССП/РФ': project.org_unit_id || null, Год: years || null, 'Тип проекта развития': project_type || null, 'Название проекта': currentName, 'Формат ВСП': vsp_format || null, 'Адрес объекта': object_address || '', 'Целевая численность, чел.': staff_count || 0, 'Тип размещения': placement_type || null, 'Площадь размещения, м2': total_area || 0, }; }; const handleOpenEdit = (event) => { event.stopPropagation(); setEditFormData(prepareProjectDataForEdit()); setEditModalOpen(true); }; const handleCloseEdit = () => { setEditModalOpen(false); setEditFormData({}); }; const handleCheckboxClick = (event) => { event.stopPropagation(); if (!isLoadingFile) { setIsChecked(!isChecked); onAddForExport(!isChecked); } else { toast.warning('Файл формируется!'); } }; const handleExportProject = (event) => { event.stopPropagation(); onExportClick?.(id, name); }; const handleNavigate = () => { if (!exportMode) { navigate(`/project/${id}`); } }; // Обновленная функция обновления проекта const updateProject = async (formData) => { try { const projectData = { name: formData['Название проекта'] || currentName, project_type: formData['Тип проекта развития'] || null, vsp_format: formData['Формат ВСП'] || null, object_address: formData['Адрес объекта'] || '', staff_count: Number(formData['Целевая численность, чел.']) || 0, placement_type: formData['Тип размещения'] || null, total_area: Number(formData['Площадь размещения, м2']) || 0, year: formData['Год'] ? Number(formData['Год']) : null, branch_id: formData['ССП/РФ'] || null, }; await ProjectsApi.update(id, projectData); // Обновляем локальные данные setCurrentName(projectData.name); setEditModalOpen(false); toast.success('Данные проекта успешно обновлены'); // Можно добавить рефреш данных или перезагрузку страницы window.location.reload(); // или используйте callback для обновления списка } catch (error) { toast.error(error?.response?.data?.detail || 'Не удалось обновить данные проекта'); } }; const handleSaveProject = async (formData) => { await updateProject(formData); }; const getInitials = (name) => { if (!name) return '?'; const words = name.split(' '); if (words.length >= 2) { return `${words[0][0]}${words[1][0]}`.toUpperCase(); } return name.substring(0, 2).toUpperCase(); }; return ( <> ID: {id} {!exportMode && ( <> {status && } {/* {Пока нет редактирование + экспорт} */} {/* */} )} {currentName} {project_type && } {report_count !== undefined && report_count !== null && } }>{years.join(', ') || 'Год не указан'} }>{org_unit_name || 'Организация не указана'} {exportMode &&
{isChecked ? : }
}
); };