"use client"; import { useState, useEffect, useCallback } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { Plus, RefreshCw, Upload, Loader2 } from "lucide-react"; import { toast } from "sonner"; import { UnifiedDwgReceiptItem, DetailDwgReceiptItem, FileInfoItem, fetchDetailDwgReceiptList, fetchFileInfoList, } from "../actions"; import { DrawingListTable } from "../table/drawing-list-table"; import { detailDrawingColumns } from "../table/detail-drawing-columns"; import { createFileListColumns } from "../table/file-list-columns"; import { AddDetailDrawingDialog } from "./add-detail-drawing-dialog"; import { UploadFilesToDetailDialog } from "./upload-files-to-detail-dialog"; interface DetailDrawingDialogProps { drawing: UnifiedDwgReceiptItem | null; open: boolean; onOpenChange: (open: boolean) => void; vendorCode: string; userId: string; userName: string; userEmail: string; drawingKind: "B3" | "B4"; } export function DetailDrawingDialog({ drawing, open, onOpenChange, vendorCode, userId, userName, userEmail, drawingKind, }: DetailDrawingDialogProps) { const [detailDrawings, setDetailDrawings] = useState([]); const [selectedDetail, setSelectedDetail] = useState(null); const [files, setFiles] = useState([]); const [isLoading, setIsLoading] = useState(false); const [isLoadingFiles, setIsLoadingFiles] = useState(false); const [addDialogOpen, setAddDialogOpen] = useState(false); const [uploadFilesDialogOpen, setUploadFilesDialogOpen] = useState(false); // 상세도면 목록 로드 const loadDetailDrawings = useCallback(async () => { if (!drawing) return; try { setIsLoading(true); const data = await fetchDetailDwgReceiptList({ project: drawing.ProjectNo, drawingNo: drawing.DrawingNo, discipline: drawing.Discipline, drawingKind: drawing.DrawingKind, userId: "", // 조회 시 모든 사용자의 상세도면을 보기 위해 빈 문자열 전달 }); setDetailDrawings(data); // 첫 번째 상세도면 자동 선택 if (data.length > 0 && !selectedDetail) { setSelectedDetail(data[0]); } } catch (error) { console.error("상세도면 로드 실패:", error); toast.error("상세도면 로드에 실패했습니다"); } finally { setIsLoading(false); } }, [drawing, selectedDetail]); // 파일 목록 로드 const loadFiles = useCallback(async () => { if (!selectedDetail) { setFiles([]); return; } try { setIsLoadingFiles(true); const data = await fetchFileInfoList(selectedDetail.UploadId); setFiles(data); } catch (error) { console.error("파일 목록 로드 실패:", error); toast.error("파일 목록 로드에 실패했습니다"); } finally { setIsLoadingFiles(false); } }, [selectedDetail]); // 다이얼로그 열릴 때 데이터 로드 useEffect(() => { if (open && drawing) { loadDetailDrawings(); } else { setDetailDrawings([]); setSelectedDetail(null); setFiles([]); } }, [open, drawing, loadDetailDrawings]); // 선택된 상세도면 변경 시 파일 목록 로드 useEffect(() => { if (selectedDetail) { loadFiles(); } }, [selectedDetail, loadFiles]); const handleDownload = async (file: FileInfoItem) => { try { toast.info("파일 다운로드를 준비 중입니다..."); // 파일 생성자의 userId를 사용하여 다운로드 const response = await fetch("/api/dolce/download", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ fileId: file.FileId, userId: file.CreateUserId, // 파일 생성자의 ID 사용 fileName: file.FileName, }), }); if (!response.ok) { throw new Error("파일 다운로드 실패"); } const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = file.FileName; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); toast.success("파일 다운로드가 완료되었습니다"); } catch (error) { console.error("파일 다운로드 실패:", error); toast.error("파일 다운로드에 실패했습니다"); } }; const handleRefresh = () => { loadDetailDrawings(); }; const handleAddComplete = () => { setAddDialogOpen(false); loadDetailDrawings(); }; const handleUploadComplete = () => { setUploadFilesDialogOpen(false); loadFiles(); }; const fileColumns = createFileListColumns({ onDownload: handleDownload }); // RegisterId + UploadId 조합으로 고유 ID 생성 const getDetailDrawingId = (detail: DetailDwgReceiptItem) => { return `${detail.RegisterId}_${detail.UploadId}`; }; // B4인 경우 "도면입수"인 건만 상세도면 추가 및 파일 첨부 가능 // B3인 경우 모든 건에 대해 가능 const canAddDetailDrawing = drawingKind === "B3" || (drawingKind === "B4" && drawing && 'DrawingMoveGbn' in drawing && drawing.DrawingMoveGbn === "도면입수"); return ( <> 상세도면 정보 {drawing && ( {drawing.DrawingNo} | 프로젝트: {drawing.ProjectNo} | Discipline: {drawing.Discipline} | 종류: {drawing.DrawingKind} )}
{/* 상단: 상세도면 리스트 */} 상세도면 목록
{canAddDetailDrawing && ( )}
columns={detailDrawingColumns} data={detailDrawings} onRowClick={setSelectedDetail} selectedRow={selectedDetail || undefined} getRowId={(row) => getDetailDrawingId(row)} />
{/* 하단: 첨부파일 리스트 */} 첨부파일 목록 {selectedDetail && ` - Rev. ${selectedDetail.DrawingRevNo}`} {selectedDetail && canAddDetailDrawing && ( )} {!selectedDetail ? (
상세도면을 선택하세요
) : isLoadingFiles ? (
Loading files...
) : ( )}
{selectedDetail && ( )} ); }