// @/lib/rfq-last/attachment/revision-history-dialog.tsx "use client"; import * as React from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Skeleton } from "@/components/ui/skeleton"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Download, Eye, FileText, Clock, User, MessageSquare, AlertCircle, CheckCircle, } from "lucide-react"; import { format, formatDistanceToNow } from "date-fns"; import { ko } from "date-fns/locale"; import { toast } from "sonner"; import { downloadFile } from "@/lib/file-download"; import { getRevisionHistory, type AttachmentWithHistory, type RevisionHistory, } from "../service"; import { formatFileSize } from "@/lib/utils"; interface RevisionHistoryDialogProps { open: boolean; onOpenChange: (open: boolean) => void; attachmentId: number; attachmentName?: string; } export function RevisionHistoryDialog({ open, onOpenChange, attachmentId, attachmentName, }: RevisionHistoryDialogProps) { const [loading, setLoading] = React.useState(false); const [historyData, setHistoryData] = React.useState(null); const [error, setError] = React.useState(null); // 다이얼로그가 열릴 때 데이터 로드 React.useEffect(() => { if (open && attachmentId) { loadRevisionHistory(); } }, [open, attachmentId]); const loadRevisionHistory = async () => { setLoading(true); setError(null); try { const result = await getRevisionHistory(attachmentId); if (result.success && result.data) { setHistoryData(result.data); } else { setError(result.error || "리비전 히스토리를 불러올 수 없습니다."); } } catch (err) { console.error("Load revision history error:", err); setError("리비전 히스토리 조회 중 오류가 발생했습니다."); } finally { setLoading(false); } }; // 리비전 다운로드 const handleDownloadRevision = async (revision: RevisionHistory) => { try { await downloadFile(revision.filePath, revision.originalFileName, { action: 'download', showToast: true, }); } catch (err) { console.error("Download revision error:", err); toast.error("파일 다운로드 중 오류가 발생했습니다."); } }; // 리비전 미리보기 const handlePreviewRevision = async (revision: RevisionHistory) => { try { await downloadFile(revision.filePath, revision.originalFileName, { action: 'preview', showToast: true, }); } catch (err) { console.error("Preview revision error:", err); toast.error("파일 미리보기 중 오류가 발생했습니다."); } }; // 리비전 번호에 따른 색상 결정 const getRevisionBadgeVariant = (isLatest: boolean) => { return isLatest ? "default" : "secondary"; }; return ( 리비전 히스토리 {historyData?.originalFileName || attachmentName || "파일"}의 모든 버전 히스토리를 확인할 수 있습니다.
{loading ? (
) : error ? ( {error} ) : historyData ? ( <> {/* 파일 정보 헤더 */}
일련번호:{" "} {historyData.serialNo || "-"}
현재 리비전:{" "} Rev. {historyData.currentRevision || "A"}
{historyData.description && (
설명:{" "} {historyData.description}
)}
{/* 리비전 테이블 */} 리비전 파일명 크기 업로드자 업로드일시 코멘트 작업 {historyData.revisions.length > 0 ? ( historyData.revisions.map((revision) => ( Rev. {revision.revisionNo} {revision.isLatest && ( )}
{revision.originalFileName} {revision.fileName !== revision.originalFileName && ( ({revision.fileName}) )}
{formatFileSize(revision.fileSize)}
{revision.createdByName || "Unknown"}
{format(new Date(revision.createdAt), "yyyy-MM-dd HH:mm")}
{formatDistanceToNow(new Date(revision.createdAt), { addSuffix: true, locale: ko, })}
{revision.revisionComment ? (
{revision.revisionComment}
) : ( - )}
)) ) : ( 리비전 히스토리가 없습니다. )}
{/* 요약 정보 */}
총 {historyData.revisions.length}개의 리비전 최초 업로드:{" "} {historyData.revisions.length > 0 ? format( new Date( historyData.revisions[historyData.revisions.length - 1].createdAt ), "yyyy년 MM월 dd일" ) : "-"}
) : null}
); }