"use client" import { useState, useEffect } from "react" import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Download, FileText, ChevronDown, ChevronUp, Search } from "lucide-react" import { Input } from "@/components/ui/input" import { toast } from "sonner" import { getPQProjectsByVendorId, ProjectPQ, getPQDataByVendorId, PQGroupData } from "@/lib/pq/service" import { downloadFile } from "@/lib/file-download" interface PQSimpleDialogProps { open: boolean onOpenChange: (open: boolean) => void vendorId: string } interface PQItemData { groupName: string code: string checkPoint: string description: string answer: string | null inputFormat: string fileName?: string | null filePath?: string | null } export function PQSimpleDialog({ open, onOpenChange, vendorId, }: PQSimpleDialogProps) { const [projects, setProjects] = useState([]) const [selectedProject, setSelectedProject] = useState(null) const [pqData, setPqData] = useState([]) const [loading, setLoading] = useState(false) const [expandedGroups, setExpandedGroups] = useState>(new Set()) const [searchTerm, setSearchTerm] = useState("") // vendorId를 숫자로 변환 const numericVendorId = parseInt(vendorId) useEffect(() => { if (open && !isNaN(numericVendorId)) { loadProjects() } }, [open, numericVendorId]) const loadProjects = async () => { try { setLoading(true) const projectList = await getPQProjectsByVendorId(numericVendorId) setProjects(projectList) if (projectList.length > 0) { setSelectedProject(projectList[0]) await loadPQData(projectList[0].projectId) } } catch (error) { console.error("프로젝트 목록 로드 실패:", error) toast.error("PQ 프로젝트 목록을 불러오는데 실패했습니다.") } finally { setLoading(false) } } const loadPQData = async (projectId: number | null) => { if (projectId === null) return try { setLoading(true) const data = await getPQDataByVendorId(numericVendorId, projectId) setPqData(data) } catch (error) { console.error("PQ 데이터 로드 실패:", error) toast.error("PQ 데이터를 불러오는데 실패했습니다.") } finally { setLoading(false) } } const handleProjectChange = async (project: ProjectPQ) => { setSelectedProject(project) await loadPQData(project.projectId) } const handleFileDownload = async (filePath: string, fileName: string) => { try { const result = await downloadFile(filePath, fileName) if (result.success) { toast.success(`${fileName} 파일이 다운로드되었습니다.`) } else { toast.error(result.error || "파일 다운로드에 실패했습니다.") } } catch (error) { console.error("파일 다운로드 오류:", error) toast.error("파일 다운로드에 실패했습니다.") } } // 코드 순서로 정렬하는 함수 (1-1-1, 1-1-2, 1-2-1 순서) const sortByCode = (items: any[]) => { return [...items].sort((a, b) => { const parseCode = (code: string) => { return code.split('-').map(part => parseInt(part, 10)) } const aCode = parseCode(a.code) const bCode = parseCode(b.code) for (let i = 0; i < Math.max(aCode.length, bCode.length); i++) { const aPart = aCode[i] || 0 const bPart = bCode[i] || 0 if (aPart !== bPart) { return aPart - bPart } } return 0 }) } // 검색 필터링 함수 const filterItems = (items: any[], searchTerm: string) => { if (!searchTerm.trim()) return items const search = searchTerm.toLowerCase() return items.filter(item => item.checkPoint?.toLowerCase().includes(search) || item.description?.toLowerCase().includes(search) || item.code?.toLowerCase().includes(search) ) } // 그룹별로 정렬 및 필터링된 데이터 계산 const processedPQData = pqData.map(group => ({ ...group, items: filterItems(sortByCode(group.items), searchTerm) })).filter(group => group.items.length > 0) // 검색 결과가 없는 그룹은 제외 const toggleGroup = (groupName: string) => { setExpandedGroups(prev => { const newSet = new Set(prev) if (newSet.has(groupName)) { newSet.delete(groupName) } else { newSet.add(groupName) } return newSet }) } const renderPQContent = (groupData: PQGroupData) => { const isExpanded = expandedGroups.has(groupData.groupName) const itemCount = groupData.items.length return ( toggleGroup(groupData.groupName)} >
{groupData.groupName} {itemCount}개 항목
{isExpanded ? ( ) : ( )}
{isExpanded && (
{groupData.items.map((item, index) => (
{item.code} {item.inputFormat}

{item.checkPoint}

{item.description && (

{item.description}

)}

{item.answer || "답변 없음"}

{item.attachments && item.attachments.length > 0 && (
{item.attachments.map((attachment, idx) => ( ))}
)}
))}
)}
) } if (projects.length === 0 && !loading) { return ( PQ 조회

제출된 PQ가 없습니다.

) } return ( PQ 조회 {loading ? (

로딩 중...

) : selectedProject ? (
{/* 프로젝트 선택 */} {projects.length > 1 && (
)} {/* 프로젝트 정보 카드 */}
{selectedProject.projectName} {selectedProject.status}
프로젝트 코드: {selectedProject.projectCode} • 제출일: {selectedProject.submittedAt ? new Date(selectedProject.submittedAt).toLocaleDateString('ko-KR') : '-'}
{/* 검색 및 PQ 그룹 데이터 */}

PQ 항목

{/* 검색 박스 */}
setSearchTerm(e.target.value)} className="pl-10" /> {searchTerm && ( )}
{/* 검색 결과 카운트 */} {searchTerm && (
검색 결과: {processedPQData.reduce((total, group) => total + group.items.length, 0)}개 항목 ({processedPQData.length}개 그룹)
)} {/* PQ 그룹 목록 */} {processedPQData.length > 0 ? ( processedPQData.map((groupData) => renderPQContent(groupData)) ) : (

{searchTerm ? "검색 결과가 없습니다." : "PQ 데이터가 없습니다."}

)}
) : null}
) }