"use client" import * as React from "react" import { type Table } from "@tanstack/react-table" import { useRouter } from "next/navigation" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Download, Mail, RefreshCw, Settings, Trash2, FileText, CheckCircle2, Loader } from "lucide-react" import { AddInitialRfqDialog } from "./add-initial-rfq-dialog" import { DeleteInitialRfqDialog } from "./delete-initial-rfq-dialog" import { ShortListConfirmDialog } from "./short-list-confirm-dialog" import { InitialRfqDetailView } from "@/db/schema" import { sendBulkInitialRfqEmails } from "../service" interface InitialRfqDetailTableToolbarActionsProps { table: Table rfqId?: number onRefresh?: () => void // 데이터 새로고침 콜백 } export function InitialRfqDetailTableToolbarActions({ table, rfqId, onRefresh }: InitialRfqDetailTableToolbarActionsProps) { const router = useRouter() // 선택된 행들 가져오기 const selectedRows = table.getFilteredSelectedRowModel().rows const selectedDetails = selectedRows.map((row) => row.original) const selectedCount = selectedRows.length // 상태 관리 const [showDeleteDialog, setShowDeleteDialog] = React.useState(false) const [showShortListDialog, setShowShortListDialog] = React.useState(false) const [isEmailSending, setIsEmailSending] = React.useState(false) // 전체 벤더 리스트 가져오기 (ShortList 확정용) const allVendors = table.getRowModel().rows.map(row => row.original) const handleBulkEmail = async () => { if (selectedCount === 0) return setIsEmailSending(true) try { const initialRfqIds = selectedDetails .map(detail => detail.initialRfqId) .filter((id): id is number => id !== null); if (initialRfqIds.length === 0) { toast.error("유효한 RFQ ID가 없습니다.") return } const result = await sendBulkInitialRfqEmails({ initialRfqIds, language: "en" // 기본 영어, 필요시 사용자 설정으로 변경 }) if (result.success) { toast.success(result.message) // 에러가 있다면 별도 알림 if (result.errors && result.errors.length > 0) { setTimeout(() => { toast.warning(`일부 오류 발생: ${result.errors?.join(', ')}`) }, 1000) } // 선택 해제 table.toggleAllRowsSelected(false) // 데이터 새로고침 if (onRefresh) { onRefresh() } } else { toast.error(result.message || "RFQ 발송에 실패했습니다.") } } catch (error) { console.error("Email sending error:", error) toast.error("RFQ 발송 중 오류가 발생했습니다.") } finally { setIsEmailSending(false) } } const handleBulkDelete = () => { // DRAFT가 아닌 상태의 RFQ 확인 const nonDraftRfqs = selectedDetails.filter( detail => detail.initialRfqStatus !== "DRAFT" ) if (nonDraftRfqs.length > 0) { const statusMessages = { "Init. RFQ Sent": "이미 발송된", "S/L Decline": "Short List 거절 처리된", "Init. RFQ Answered": "답변 완료된" } const nonDraftStatuses = [...new Set(nonDraftRfqs.map(rfq => rfq.initialRfqStatus))] const statusText = nonDraftStatuses .map(status => statusMessages[status as keyof typeof statusMessages] || status) .join(", ") toast.error( `${statusText} RFQ는 삭제할 수 없습니다. DRAFT 상태의 RFQ만 삭제 가능합니다.` ) return } setShowDeleteDialog(true) } // S/L 확정 버튼 클릭 const handleSlConfirm = () => { if (!rfqId || allVendors.length === 0) { toast.error("S/L 확정할 벤더가 없습니다.") return } // 진행 가능한 상태 확인 const validVendors = allVendors.filter(vendor => vendor.initialRfqStatus === "Init. RFQ Answered" || vendor.initialRfqStatus === "Init. RFQ Sent" ) if (validVendors.length === 0) { toast.error("S/L 확정이 가능한 벤더가 없습니다. (RFQ 발송 또는 응답 완료된 벤더만 가능)") return } setShowShortListDialog(true) } // 초기 RFQ 추가 성공 시 처리 const handleAddSuccess = () => { // 선택 해제 table.toggleAllRowsSelected(false) // 데이터 새로고침 if (onRefresh) { onRefresh() } else { // fallback으로 페이지 새로고침 setTimeout(() => { window.location.reload() }, 1000) } } // 삭제 성공 시 처리 const handleDeleteSuccess = () => { // 선택 해제 table.toggleAllRowsSelected(false) setShowDeleteDialog(false) // 데이터 새로고침 if (onRefresh) { onRefresh() } } // Short List 확정 성공 시 처리 const handleShortListSuccess = () => { // 선택 해제 table.toggleAllRowsSelected(false) setShowShortListDialog(false) // 데이터 새로고침 if (onRefresh) { onRefresh() } // 최종 RFQ 페이지로 이동 if (rfqId) { toast.success("Short List가 확정되었습니다. 최종 RFQ 페이지로 이동합니다.") setTimeout(() => { router.push(`/evcp/b-rfq/${rfqId}`) }, 1500) } } // 선택된 항목 중 첫 번째를 기본값으로 사용 const defaultValues = selectedCount > 0 ? selectedDetails[0] : undefined const canDelete = selectedDetails.every(detail => detail.initialRfqStatus === "DRAFT") const draftCount = selectedDetails.filter(detail => detail.initialRfqStatus === "DRAFT").length // S/L 확정 가능한 벤더 수 const validForShortList = allVendors.filter(vendor => vendor.initialRfqStatus === "Init. RFQ Answered" || vendor.initialRfqStatus === "Init. RFQ Sent" ).length return ( <>
{/** 선택된 항목이 있을 때만 표시되는 액션들 */} {selectedCount > 0 && ( <> )} {/* S/L 확정 버튼 */} {rfqId && ( )} {/* 초기 RFQ 추가 버튼 */} {rfqId && ( )}
{/* 삭제 다이얼로그 */} {/* Short List 확정 다이얼로그 */} {rfqId && ( vendor.initialRfqStatus === "Init. RFQ Answered" || vendor.initialRfqStatus === "Init. RFQ Sent" )} onSuccess={handleShortListSuccess} /> )} ) }