import styled from '@emotion/styled'; import { Box, Button, FormControl, FormLabel, Stack, TextField } from '@mui/material'; import { useEffect, useRef, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { rememberListVisit } from '../../utils/listNavigation'; import { toast } from 'react-toastify'; import { FormsApi } from '../../api/forms'; import { TasksApi } from '../../api/tasks'; import { FORM_TYPE_TRANSLATE } from '../../constants/constants'; import { ExportButton } from '../common/Buttons/ButtonsActions'; import { Chip } from '../styles/StyledChip'; import { DeletionMarkChip } from './DeletionMarkChip'; import { LastOpenedBadge } from './LastOpenedBadge'; import { IconWithContent } from './IconWithContent'; import Modal from './Modal/Modal'; import { CheckBoxCheckSvg, CheckBoxUncheckSvg, DateIcon, TableIcon } from './icons/icons'; import { TaskCard } from '../styles/TaskCard.style'; const CardHeader = styled.div` width: 100%; display: flex; justify-content: space-between; align-items: center; `; const TaskId = styled.div` font-size: 0.75rem; font-weight: 400; line-height: 1rem; letter-spacing: 0rem; text-align: left; `; const CardBody = styled.div` flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.5rem; justify-content: flex-start; `; const TaskTitle = styled.div` font-size: 1rem; font-weight: 500; color: var(--Text-Primary, #333); line-height: 1.4; margin: 0.375rem 0 0; padding: 0; `; export const TaskCardComponent = ({ taskForm, isForm = false, fluidWidth = false, exportMode = false, isLoadingFile = false, onAddForExport, onExportClick, isLastOpened = false, isAdmin = false, onChanged, currentUserId = null, usersById = {}, }) => { const navigate = useNavigate(); const location = useLocation(); const cardRef = useRef(null); useEffect(() => { if (isLastOpened) cardRef.current?.scrollIntoView({ block: 'nearest' }); }, [isLastOpened]); const { id, title, org_unit, form_type_code, year } = taskForm; const canHardDelete = taskForm.to_delete && taskForm.deleted_by !== currentUserId; const [isEditModalOpen, setEditModalOpen] = useState(false); const [editedTitle, setEditedTitle] = useState(''); const [currentTypeCode, setCurrentTypeCode] = useState(FORM_TYPE_TRANSLATE[form_type_code] || ''); const [isChecked, setIsChecked] = useState(false); const [confirmAction, setConfirmAction] = useState(null); const [actionLoading, setActionLoading] = useState(false); useEffect(() => { setIsChecked(false); }, [exportMode]); const handleOpenEdit = (event) => { event.stopPropagation(); setEditedTitle(currentTypeCode); setEditModalOpen(true); }; const handleCloseEdit = () => { setEditModalOpen(false); }; const handleCheckboxClick = (event) => { event.stopPropagation(); if (!isLoadingFile) { setIsChecked(!isChecked); onAddForExport(!isChecked); } else { toast.warning('Файл формируется!'); } }; const handleExportTask = (event) => { event.stopPropagation(); onExportClick?.(id, title); }; const openConfirmAction = (event, action) => { event.stopPropagation(); setConfirmAction(action); }; const closeConfirmAction = () => { if (!actionLoading) setConfirmAction(null); }; const runConfirmedAction = async () => { if (!confirmAction) return; try { setActionLoading(true); if (confirmAction === 'mark') { await TasksApi.markForDeletion(id); toast.success('Задача помечена на удаление'); } if (confirmAction === 'restore') { await TasksApi.restore(id); toast.success('Задача возвращена'); } if (confirmAction === 'hardDelete') { await TasksApi.hardDelete(id); toast.success('Задача полностью удалена'); } setConfirmAction(null); onChanged?.(); } catch (error) { toast.error(error?.response?.data?.detail || 'Не удалось выполнить действие'); } finally { setActionLoading(false); } }; const actionTitle = { mark: 'Удалить задачу', restore: 'Вернуть задачу', hardDelete: 'Полностью удалить задачу', }[confirmAction]; const actionText = { mark: 'Задача будет скрыта от пользователей. Админы смогут вернуть её или удалить окончательно.', restore: 'Задача снова станет доступна пользователям.', hardDelete: 'Будут удалены задача и все связанные данные. Это действие нельзя отменить.', }[confirmAction]; const updateTask = async (nextTitle) => { try { await TasksApi.editTask(id, { title: nextTitle }); setCurrentTypeCode(nextTitle); setEditModalOpen(false); toast.success('Название задачи обновлено'); } catch (error) { toast.error(error?.response?.data?.detail || 'Не удалось обновить название задачи'); } }; const updateForm = async (nextTitle) => { try { await FormsApi.updateForm(id, { title: nextTitle }); setCurrentTypeCode(nextTitle); setEditModalOpen(false); } catch (error) { toast.error(error?.response?.data?.detail || 'Не удалось обновить название формы'); } }; const handleSaveTitle = async () => { const nextTitle = editedTitle.trim(); if (!nextTitle) { toast.error('Название не может быть пустым'); return; } if (nextTitle === currentTypeCode) { setEditModalOpen(false); return; } if (isForm) { await updateForm(nextTitle); return; } await updateTask(nextTitle); }; return ( <> { if (exportMode) { handleCheckboxClick(event); } else { if (!isForm && location.pathname === '/tasks') rememberListVisit('tasks', id, `${location.pathname}${location.search}`); navigate(`/${isForm ? 'form' : 'task'}/${id}`); } }} key={id}> ID: {id} {taskForm.to_delete && } {isLastOpened && Последняя открытая} {org_unit?.title || 'Подразделение не указано'} }>{year} }> {currentTypeCode} event.stopPropagation()}> {isAdmin && !isForm && !exportMode && !taskForm.to_delete && ( )} {isAdmin && !isForm && !exportMode && taskForm.to_delete && ( <> {canHardDelete && ( )} )} {!isForm && !exportMode && !taskForm.to_delete && } {exportMode &&
{isChecked ? : }
}
}> {actionText} ); };