"use client" import React, { useEffect, useState, useMemo } from "react" import { ScrollArea } from "@/components/ui/scroll-area" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { Building2, FileIcon, Loader2 } from "lucide-react" import { Button } from "@/components/ui/button" import { AddDocumentDialog } from "./add-document-dialog" import { ViewDocumentDialog } from "./view-document-dialog" import { getDocumentVersionsByDocId, getStageNamesByDocumentId } from "@/lib/vendor-document/service" import { Badge } from "@/components/ui/badge" import { Checkbox } from "@/components/ui/checkbox" import { formatDate } from "@/lib/utils" type StageListProps = { document: { id: number docNumber: string title: string // ... } } // 인터페이스 interface Attachment { id: number fileName: string filePath: string fileType?: string } interface Version { id: number stage: string revision: string uploaderType: string uploaderName: string | null comment: string | null status: string | null planDate: string | null actualDate: string | null approvedDate: string | null DocumentSubmitDate: Date attachments: Attachment[] selected?: boolean } export default function StageList({ document }: StageListProps) { const [versions, setVersions] = useState([]) const [stageOptions, setStageOptions] = useState([]) const [isLoading, setIsLoading] = useState(false) useEffect(() => { if (!document?.id) return // 로딩 상태 시작 setIsLoading(true) // 데이터 로딩 프로미스들 const loadVersions = getDocumentVersionsByDocId(document.id) .then((data) => { setVersions(data.map(c => {{return {...c, selected: false}}})) }) .catch((error) => { console.error("Failed to load document versions:", error) }) const loadStageOptions = getStageNamesByDocumentId(document.id) .then((stageNames) => { setStageOptions(stageNames) }) .catch((error) => { console.error("Failed to load stage options:", error) }) // 모든 데이터 로딩이 완료되면 로딩 상태 종료 Promise.all([loadVersions, loadStageOptions]) .finally(() => { setIsLoading(false) }) }, [document]) // Handle file download with original filename const handleDownload = (attachmentPath: string, fileName: string) => { if (attachmentPath) { // Use window.document to avoid collision with the document prop const link = window.document.createElement('a'); link.href = attachmentPath; link.download = fileName || 'download'; // Use the original filename or a default window.document.body.appendChild(link); link.click(); window.document.body.removeChild(link); } } // 파일 확장자에 따른 아이콘 색상 반환 const getFileIconColor = (fileName: string) => { const ext = fileName.split('.').pop()?.toLowerCase(); switch(ext) { case 'pdf': return 'text-red-500'; case 'doc': case 'docx': return 'text-blue-500'; case 'xls': case 'xlsx': return 'text-green-500'; case 'dwg': return 'text-amber-500'; default: return 'text-gray-500'; } } const selectItems = useMemo(() => { return versions.filter(c => c.selected && c.attachments && c.attachments.length > 0) }, [versions]) return ( <>

{/* */} Document: {document.docNumber} {document.title}

{selectItems.length > 0 && } { // 새 데이터 생성 후 목록을 다시 불러오려면 getDocumentVersionsByDocId(document.id).then((data) => { setVersions(data.map(c => {{return {...c, selected: false}}})) }) }} buttonLabel="업체 문서 추가" />
{isLoading ? (

문서 로딩 중...

) : ( Stage Revision 첨부파일 등록자 Comment 생성일 계획일 실제일 {versions.length ? ( versions.map((ver) => ( { setVersions(prev => prev.map(c => { if(c.id === ver.id){ return {...c, selected: !c.selected} } return {...c} })) }} aria-label="Select row" className="translate-y-0.5" /> {ver.uploaderType} {ver.stage} {ver.revision}
{ver.attachments && ver.attachments.length > 0 ? ( ver.attachments.map((file) => (

{file.fileName || "Download file"}

)) ) : ( 파일 없음 )}
{ver.uploaderName} {ver.comment} {formatDate(ver.DocumentSubmitDate) ?? "-"} {ver.planDate ?? "-"} {ver.actualDate ?? "-"}
)) ) : ( 업체 문서가 없습니다. )}
)}
) }