"use client" import * as React from "react" import { useState, useEffect, useCallback } from "react" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { ScrollArea } from "@/components/ui/scroll-area" import { CalendarIcon, FileTextIcon, PackageIcon, HashIcon, DollarSignIcon, } from "lucide-react" import { BiddingListItem } from "@/db/schema" import { formatFileSize } from "@/lib/file-download" import { getPRDetailsAction, type PRDetails } from "../service" // 파일 다운로드 컴포넌트 const FileDownloadLink = ({ filePath, fileName, fileSize, title, className = "" }: { filePath: string; fileName: string; fileSize: number; title?: string | null; className?: string; }) => { return ( {title || fileName} ({formatFileSize(fileSize)}) ); }; const FileDownloadButton = ({ filePath, fileName, variant = "download", size = "sm" }: { filePath: string; fileName: string; variant?: "download" | "preview"; size?: "sm" | "default"; }) => { return ( {variant === "download" ? "다운로드" : "미리보기"} ); }; // PR 문서 다이얼로그 interface PrDocumentsDialogProps { open: boolean; onOpenChange: (open: boolean) => void; bidding: BiddingListItem | null; } export function PrDocumentsDialog({ open, onOpenChange, bidding }: PrDocumentsDialogProps) { const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const fetchPRData = useCallback(async () => { if (!bidding) return; setLoading(true); setError(null); try { const result = await getPRDetailsAction(bidding.id); if (result.success && result.data) { setData(result.data as PRDetails); } else { setError(result.error || "PR 문서 정보를 불러올 수 없습니다."); } } catch (err) { setError("데이터 로딩 중 오류가 발생했습니다."); console.error("Failed to fetch PR data:", err); } finally { setLoading(false); } }, [bidding]); useEffect(() => { if (open && bidding) { fetchPRData(); } }, [open, bidding, fetchPRData]); const formatCurrency = (amount: number | null, currency: string | null) => { if (amount == null) return "-"; return `${amount.toLocaleString()} ${currency || ""}`; }; return ( PR 및 문서 정보 {bidding?.title}의 PR 문서 및 아이템 정보입니다. {loading ? ( 로딩 중... ) : error ? ( {error} 다시 시도 ) : data ? ( {/* PR 문서 목록 */} {data.documents.length > 0 && ( PR 문서 ({data.documents.length}개) 문서명 파일명 버전 크기 등록일 등록자 다운로드 {data.documents.map((doc) => ( {doc.documentName} {doc.description && ( {doc.description} )} {doc.version ? ( {doc.version} ) : "-"} {formatFileSize(doc.fileSize)} {new Date(doc.registeredAt).toLocaleDateString('ko-KR')} {doc.registeredBy || "-"} ))} )} {/* PR 아이템 테이블 */} {data.items.length > 0 && ( PR 아이템 ({data.items.length}개) 아이템 번호 PR 번호 자재그룹 자재 품목정보 수량 구매단위 내정단가 내정금액 예산금액 실적금액 WBS코드 요청 납기 스펙 문서 {data.items.map((item) => ( {item.itemNumber || "-"} {item.prNumber || "-"} {item.materialGroupNumber && ( {item.materialGroupNumber} )} {item.materialGroupInfo && ( {item.materialGroupInfo} )} {!item.materialGroupNumber && !item.materialGroupInfo && "-"} {item.materialNumber && ( {item.materialNumber} )} {item.materialInfo && ( {item.materialInfo} )} {!item.materialNumber && !item.materialInfo && "-"} {item.itemInfo || "-"} {item.quantity ? `${item.quantity.toLocaleString()} ${item.quantityUnit || ""}` : "-"} {item.purchaseUnit || "-"} {formatCurrency(item.targetUnitPrice, item.targetCurrency)} {formatCurrency(item.targetAmount, item.targetCurrency)} {formatCurrency(item.budgetAmount, item.budgetCurrency)} {formatCurrency(item.actualAmount, item.actualCurrency)} {item.wbsCode && ( {item.wbsCode} )} {item.wbsName && ( {item.wbsName} )} {!item.wbsCode && !item.wbsName && "-"} {item.requestedDeliveryDate ? ( {new Date(item.requestedDeliveryDate).toLocaleDateString('ko-KR')} ) : "-"} {item.hasSpecDocument ? "있음" : "없음"} {item.specDocuments.length > 0 && ( ({item.specDocuments.length}개) )} {item.specDocuments.length > 0 && ( {item.specDocuments.map((doc) => ( ))} )} ))} )} {/* 데이터가 없는 경우 */} {data.documents.length === 0 && data.items.length === 0 && ( PR 문서가 없습니다. )} ) : null} ); }
로딩 중...
{error}
PR 문서가 없습니다.