"use client" import * as React from "react" import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Calendar, Users, FileText, ChevronDown, ChevronRight } from "lucide-react" import type { AvlListItem } from "@/lib/avl/types" interface AvlHistoryModalProps { isOpen: boolean onClose: () => void avlItem: AvlListItem | null historyData?: AvlHistoryRecord[] onLoadHistory?: (avlItem: AvlListItem) => Promise } export interface VendorSnapshot { id: number vendorName?: string avlVendorName?: string vendorCode?: string disciplineName?: string materialNameCustomerSide?: string materialGroupCode?: string materialGroupName?: string tier?: string hasAvl?: boolean faTarget?: boolean headquarterLocation?: string ownerSuggestion?: boolean shiSuggestion?: boolean [key: string]: unknown // 다른 모든 속성들 } export interface AvlHistoryRecord { id: number rev: number createdAt: string createdBy: string vendorInfoSnapshot: VendorSnapshot[] // JSON 데이터 changeDescription?: string } // 스냅샷 테이블 컴포넌트 interface SnapshotTableProps { snapshot: VendorSnapshot[] isOpen: boolean onToggle: () => void } function SnapshotTable({ snapshot, isOpen, onToggle }: SnapshotTableProps) { if (!snapshot || snapshot.length === 0) { return (
스냅샷 데이터가 없습니다.
) } return (
No. 설계공종 고객사 AVL 자재명 자재그룹 코드 자재그룹 명 AVL 등재업체명 협력업체 코드 협력업체 명 선주제안 SHI 제안 본사 위치 등급 AVL FA대상 {snapshot.map((item, index) => ( {index + 1} {item.disciplineName || '-'} {item.materialNameCustomerSide || '-'} {item.materialGroupCode || '-'} {item.materialGroupName || '-'} {item.avlVendorName || '-'} {item.vendorCode || '-'} {item.vendorName || '-'} {item.ownerSuggestion ? "예" : "아니오"} {item.shiSuggestion ? "예" : "아니오"} {item.headquarterLocation || '-'} {item.tier ? ( {item.tier} ) : '-'} {item.hasAvl ? "Y" : "N"} {item.faTarget ? "Y" : "N"} ))}
) } export function AvlHistoryModal({ isOpen, onClose, avlItem, historyData, onLoadHistory }: AvlHistoryModalProps) { const [loading, setLoading] = React.useState(false) const [history, setHistory] = React.useState([]) const [openSnapshots, setOpenSnapshots] = React.useState>({}) // 히스토리 데이터 로드 React.useEffect(() => { if (isOpen && avlItem && onLoadHistory) { setLoading(true) onLoadHistory(avlItem) .then(setHistory) .catch(console.error) .finally(() => setLoading(false)) } else if (historyData) { setHistory(historyData) } }, [isOpen, avlItem, onLoadHistory, historyData]) // 스냅샷 테이블 토글 함수 const toggleSnapshot = (recordId: number) => { setOpenSnapshots(prev => ({ ...prev, [recordId]: !prev[recordId] })) } if (!avlItem) return null return ( AVL 리비전 히스토리
{avlItem.isTemplate ? "표준 AVL" : "프로젝트 AVL"} - {avlItem.avlKind} {avlItem.projectCode && ` (${avlItem.projectCode})`}
{loading ? (
히스토리를 불러오는 중...
) : history.length === 0 ? (
히스토리 데이터가 없습니다.
) : (
{history.map((record, index) => (
{/* 리비전 헤더 */}
Rev {record.rev} {index === 0 && ( 현재 )}
{new Date(record.createdAt).toLocaleDateString('ko-KR')}
{/* 변경 설명 */} {record.changeDescription && (
{record.changeDescription}
)} {/* Vendor Info 요약 */}
{record.vendorInfoSnapshot?.length || 0}
총 협력업체
{record.vendorInfoSnapshot?.filter(v => v.hasAvl).length || 0}
AVL 등재
{record.vendorInfoSnapshot?.filter(v => v.faTarget).length || 0}
FA 대상
{/* 스냅샷 테이블 */}
toggleSnapshot(record.id)} />
))}
)}
) }