"use client"; import { Modal } from "@/components/ui"; import { defaultStatusMeta, formatRequestPeriod, requestTypeLabels, statusMeta, type RequestAttachmentPreview, } from "@/hooks/useRequestsPage"; import { CommentComposer, CommentDeleteButton } from "@/components/shared/CommentControls"; import TaskLinkPill from "@/components/tasks/TaskLinkPill"; import { displayUserName, formatDate, formatDateTime } from "@/lib/shared"; import type { Request, RequestComment } from "@/types/api"; import { Ban, Link2, Paperclip, Pencil, ThumbsDown, ThumbsUp, Trash2 } from "lucide-react"; import { getRequestActionState } from "./requestActions"; import { RequestUserBadge } from "./RequestUserBadge"; type RequestDetailModalProps = { actionError?: string | null; busyKey: string | null; commentDraft: string; comments: RequestComment[]; commentsLoading: boolean; currentUserId?: number | null; departmentNameMap: Map; isFinal: (status?: string) => boolean; onAddComment: (requestId: number) => void | Promise; onApprove: (requestId: number) => void | Promise; onCancel: (requestId: number) => void | Promise; onClose: () => void; onDelete: (requestId: number) => void | Promise; onDeleteComment: (requestId: number, commentId: number) => void | Promise; onEdit: (request: Request) => void; onLinkTask: (request: Request) => void; onPreviewAttachment: (preview: RequestAttachmentPreview) => void; onReject: (requestId: number) => void | Promise; onSetCommentDraft: (requestId: number, value: string) => void; request: Request | null; }; export function RequestDetailModal({ actionError, busyKey, commentDraft, comments, commentsLoading, currentUserId, departmentNameMap, isFinal, onAddComment, onApprove, onCancel, onClose, onDelete, onDeleteComment, onEdit, onLinkTask, onPreviewAttachment, onReject, onSetCommentDraft, request, }: RequestDetailModalProps) { if (!request) return null; const author = request.employee || request.created_by; const approver = request.approver || request.assigned_to; const actionState = getRequestActionState(request, currentUserId, isFinal); const { canCancel, canComment, canDelete, canEdit, canProcess } = actionState; const status = statusMeta[String(request.status || "").toLowerCase()] ?? defaultStatusMeta; const typeLabel = requestTypeLabels[String(request.type || request.request_type || "").toLowerCase()] || String(request.type || request.request_type || "Другое"); const attachmentUrl = request.attachment_url || request.attachment || ""; const attachmentName = attachmentUrl ? decodeURIComponent(attachmentUrl.split("/").pop() || "Вложение") : ""; const commentCount = request.comments_count ?? comments.length; const linkedTasks = request.linked_tasks || []; return ( {actionError ? (
{actionError}
) : null} {(canProcess || canCancel || canEdit || canDelete) ? (
{canProcess ? ( <> ) : null} {canCancel ? ( ) : null} {canEdit ? ( ) : null} {canDelete ? ( ) : null}
) : null} )} >
{typeLabel} {status.label}

{request.display_title || request.title || "Без заголовка"}

{(request.comment || request.description) ? (
{request.comment || request.description}
) : (

Описание отсутствует

)}
Связанные задачи {linkedTasks.length}
{linkedTasks.length > 0 ? (
{linkedTasks.map((task) => ( ))}
) : (

Связанных задач нет

)}

Комментарии

{commentCount}
{!canComment ? (

Комментарии будут доступны после отправки заявления.

) : (
{commentsLoading ? (
Загрузка комментариев...
) : comments.length > 0 ? ( comments.map((comment) => (

{displayUserName(comment.author)}

{formatDateTime(comment.created_at) || formatDate(comment.created_at)}

{Boolean(comment.author?.id && currentUserId === comment.author.id) ? ( onDeleteComment(request.id, comment.id)} /> ) : null}

{comment.text}

)) ) : (

Комментариев пока нет

)}
onSetCommentDraft(request.id, value)} onSubmit={() => onAddComment(request.id)} placeholder="Добавить комментарий" />
)}

Даты

{String(request.type || request.request_type) === "short_day_off" ? "Время" : "Период"}

{formatRequestPeriod(request)}

Создано

{formatDateTime(request.created_at) || "—"}

Обновлено

{formatDateTime(request.updated_at) || "—"}

Участники

Автор

{author ? ( ) : ( — )}

Принял решение

{approver ? ( ) : ( — )}

Отделы

{(request.departments || []).length > 0 ? (
{(request.departments || []).map((id) => ( {departmentNameMap.get(Number(id)) || `Отдел #${id}`} ))}
) : (

Отделы не указаны

)}

Получатели

{(request.recipients || []).length > 0 ? (
{(request.recipients || []).map((recipient) => ( ))}
) : (

Получатели не указаны

)}

В копии

{(request.cc_users || []).length > 0 ? (
{(request.cc_users || []).map((ccUser) => ( ))}
) : (

Копия не указана

)}

Вложение

{attachmentUrl ? (
Открыть в новой вкладке
) : (

Вложение отсутствует

)}
); }