"use client" import React from "react" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog" import { Textarea } from "@/components/ui/textarea" import { useToast } from "@/hooks/use-toast" import { PQGroupData, requestPqChangesAction, updateVendorStatusAction, getItemReviewLogsAction } from "@/lib/pq/service" import { Vendor } from "@/db/schema/vendors" import { Separator } from "@/components/ui/separator" import { ChevronsUpDown, MessagesSquare, Download, Loader2, X } from "lucide-react" import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Card } from "@/components/ui/card" import { formatDate } from "@/lib/utils" import { downloadFileAction } from "@/lib/downloadFile" // 코멘트 상태를 위한 인터페이스 정의 interface PendingComment { answerId: number; checkPoint: string; code: string; comment: string; createdAt: Date; } interface ReviewLog { id: number reviewerComment: string reviewerName: string | null createdAt: Date } export default function VendorPQAdminReview({ data, vendor, }: { data: PQGroupData[] vendor: Vendor }) { const { toast } = useToast() // 다이얼로그 상태들 const [showRequestDialog, setShowRequestDialog] = React.useState(false) const [showApproveDialog, setShowApproveDialog] = React.useState(false) const [showRejectDialog, setShowRejectDialog] = React.useState(false) // 코멘트 상태들 const [requestComment, setRequestComment] = React.useState("") const [approveComment, setApproveComment] = React.useState("") const [rejectComment, setRejectComment] = React.useState("") const [isLoading, setIsLoading] = React.useState(false) // 항목별 코멘트 상태 추적 (메모리에만 저장) const [pendingComments, setPendingComments] = React.useState([]) // 코멘트 추가 핸들러 - 실제 서버 저장이 아닌 메모리에 저장 const handleCommentAdded = (newComment: PendingComment) => { setPendingComments(prev => [...prev, newComment]); toast({ title: "Comment Added", description: `Comment added for ${newComment.code}. Please "Request Changes" to save.` }); } // 코멘트 삭제 핸들러 const handleRemoveComment = (index: number) => { setPendingComments(prev => prev.filter((_, i) => i !== index)); } // 1) 승인 다이얼로그 표시 const handleApprove = () => { // 코멘트가 있는데 승인하려고 하면 경고 if (pendingComments.length > 0) { if (!confirm('You have unsaved comments. Are you sure you want to approve without requesting changes?')) { return; } } setShowApproveDialog(true) } // 실제 승인 처리 const handleSubmitApprove = async () => { try { setIsLoading(true) setShowApproveDialog(false) const res = await updateVendorStatusAction(vendor.id, "APPROVED") if (res.ok) { toast({ title: "Approved", description: "Vendor PQ has been approved." }) // 코멘트 초기화 setPendingComments([]); } else { toast({ title: "Error", description: res.error, variant: "destructive" }) } } catch (error) { toast({ title: "Error", description: String(error), variant: "destructive" }) } finally { setIsLoading(false) setApproveComment("") } } // 2) 거부 다이얼로그 표시 const handleReject = () => { // 코멘트가 있는데 거부하려고 하면 경고 if (pendingComments.length > 0) { if (!confirm('You have unsaved comments. Are you sure you want to reject without requesting changes?')) { return; } } setShowRejectDialog(true) } // 실제 거부 처리 const handleSubmitReject = async () => { try { setIsLoading(true) setShowRejectDialog(false) const res = await updateVendorStatusAction(vendor.id, "REJECTED") if (res.ok) { toast({ title: "Rejected", description: "Vendor PQ has been rejected." }) // 코멘트 초기화 setPendingComments([]); } else { toast({ title: "Error", description: res.error, variant: "destructive" }) } } catch (error) { toast({ title: "Error", description: String(error), variant: "destructive" }) } finally { setIsLoading(false) setRejectComment("") } } // 3) 변경 요청 다이얼로그 표시 const handleRequestChanges = () => { setShowRequestDialog(true) } // 4) 변경 요청 처리 - 이제 모든 코멘트를 한 번에 저장 // 4) 변경 요청 처리 - 이제 모든 코멘트를 한 번에 저장 const handleSubmitRequestChanges = async () => { try { setIsLoading(true); setShowRequestDialog(false); // 항목별 코멘트 준비 - answerId와 함께 checkPoint와 code도 전송 const itemComments = pendingComments.map(pc => ({ answerId: pc.answerId, checkPoint: pc.checkPoint, // 추가: 체크포인트 정보 전송 code: pc.code, // 추가: 코드 정보 전송 comment: pc.comment })); // 서버 액션 호출 const res = await requestPqChangesAction({ vendorId: vendor.id, comment: itemComments, generalComment: requestComment || undefined }); if (res.ok) { toast({ title: "Changes Requested", description: "Vendor was notified of your comments.", }); // 코멘트 초기화 setPendingComments([]); } else { toast({ title: "Error", description: res.error, variant: "destructive" }); } } catch (error) { toast({ title: "Error", description: String(error), variant: "destructive" }); } finally { setIsLoading(false); setRequestComment(""); } }; return (
{/* Top header */}

{vendor.vendorCode} - {vendor.vendorName} PQ Review

Review the submitted PQ items below, then approve, reject, or request more info.

{/* 코멘트가 있을 때 알림 표시 */} {pendingComments.length > 0 && (

⚠️ You have {pendingComments.length} pending comments. Click "Request Changes" to save them.

)} {/* VendorPQReviewPage 컴포넌트 대신 직접 구현 */} {/* 변경 요청 다이얼로그 */} Request PQ Changes Review your comments and add any additional notes. The vendor will receive these changes. {/* 항목별 코멘트 목록 */} {pendingComments.length > 0 && (

Item Comments:

{pendingComments.map((comment, index) => (
{comment.code} {comment.checkPoint}

{comment.comment}

{formatDate(comment.createdAt)}

))}
)} {/* 추가 코멘트 입력 */}