"use client" import * as React from "react" import { type Table } from "@tanstack/react-table" import { ClipboardList, Download, Send, Lock, Upload } from "lucide-react" import { toast } from "sonner" import { exportTableToExcel } from "@/lib/export" import { Button } from "@/components/ui/button" import { ProcurementRfqsView } from "@/db/schema" import { PrDetailsDialog } from "./pr-item-dialog" import { sealRfq, sendRfq, getPORfqs, fetchExternalRfqs } from "../services" // total 필드 추가하여 타입 정의 수정 type PORfqsReturn = Awaited> interface RFQTableToolbarActionsProps { table: Table; // 타입 수정 localData?: PORfqsReturn; setLocalData?: React.Dispatch>; onSuccess?: () => void; } export function RFQTableToolbarActions({ table, localData, setLocalData, onSuccess }: RFQTableToolbarActionsProps) { // 다이얼로그 열림/닫힘 상태 관리 const [dialogOpen, setDialogOpen] = React.useState(false) const [isProcessing, setIsProcessing] = React.useState(false) // 선택된 RFQ 가져오기 const getSelectedRfq = (): ProcurementRfqsView | null => { const selectedRows = table.getFilteredSelectedRowModel().rows if (selectedRows.length === 1) { return selectedRows[0].original } return null } // 선택된 RFQ const selectedRfq = getSelectedRfq() // PR 상세보기 버튼 클릭 핸들러 const handleViewPrDetails = () => { const rfq = getSelectedRfq() if (!rfq) { toast.warning("RFQ를 선택해주세요") return } if (!rfq.prItemsCount || rfq.prItemsCount <= 0) { toast.warning("선택한 RFQ에 PR 항목이 없습니다") return } setDialogOpen(true) } // RFQ 밀봉 버튼 클릭 핸들러 const handleSealRfq = async () => { const rfq = getSelectedRfq() if (!rfq) { toast.warning("RFQ를 선택해주세요") return } // 이미 밀봉된 RFQ인 경우 if (rfq.rfqSealedYn) { toast.warning("이미 밀봉된 RFQ입니다") return } try { setIsProcessing(true) // 낙관적 UI 업데이트 (로컬 데이터 먼저 갱신) if (localData?.data && setLocalData) { // 로컬 데이터에서 해당 행 찾기 const rowIndex = localData.data.findIndex(row => row.id === rfq.id); if (rowIndex >= 0) { // 불변성을 유지하면서 로컬 데이터 업데이트 - 타입 안전하게 복사 const newData = [...localData.data] as ProcurementRfqsView[]; newData[rowIndex] = { ...newData[rowIndex], rfqSealedYn: "Y" }; // 전체 데이터 구조 복사하여 업데이트, total 필드가 있다면 유지 setLocalData({ ...localData, data: newData ?? [], pageCount: localData.pageCount, total: localData.total ?? 0 }); } } const result = await sealRfq(rfq.id) if (result.success) { toast.success("RFQ가 성공적으로 밀봉되었습니다") // 데이터 리프레시 onSuccess?.() } else { toast.error(result.message || "RFQ 밀봉 중 오류가 발생했습니다") // 서버 요청 실패 시 낙관적 업데이트 되돌리기 if (localData?.data && setLocalData) { const rowIndex = localData.data.findIndex(row => row.id === rfq.id); if (rowIndex >= 0) { const newData = [...localData.data] as ProcurementRfqsView[]; newData[rowIndex] = { ...newData[rowIndex], rfqSealedYn: rfq.rfqSealedYn }; // 원래 값으로 복원 setLocalData({ ...localData, data: newData ?? [], pageCount: localData.pageCount, total: localData.total ?? 0 }); } } } } catch (error) { console.error("RFQ 밀봉 오류:", error) toast.error("RFQ 밀봉 중 오류가 발생했습니다") // 에러 발생 시 낙관적 업데이트 되돌리기 if (localData?.data && setLocalData) { const rowIndex = localData.data.findIndex(row => row.id === rfq.id); if (rowIndex >= 0) { const newData = [...localData.data] as ProcurementRfqsView[]; newData[rowIndex] = { ...newData[rowIndex], rfqSealedYn: rfq.rfqSealedYn }; // 원래 값으로 복원 setLocalData({ ...localData, data: newData ?? [], pageCount: localData.pageCount, total: localData.total ?? 0 }); } } } finally { setIsProcessing(false) } } // RFQ 전송 버튼 클릭 핸들러 const handleSendRfq = async () => { const rfq = getSelectedRfq() if (!rfq) { toast.warning("RFQ를 선택해주세요") return } // 전송 가능한 상태인지 확인 if (rfq.status !== "RFQ Vendor Assignned" && rfq.status !== "RFQ Sent") { toast.warning("벤더가 할당된 RFQ이거나 전송한 적이 있는 RFQ만 전송할 수 있습니다") return } try { setIsProcessing(true) const result = await sendRfq(rfq.id) if (result.success) { toast.success("RFQ가 성공적으로 전송되었습니다") // 데이터 리프레시 onSuccess?.() } else { toast.error(result.message || "RFQ 전송 중 오류가 발생했습니다") } } catch (error) { console.error("RFQ 전송 오류:", error) toast.error("RFQ 전송 중 오류가 발생했습니다") } finally { setIsProcessing(false) } } const handleFetchExternalRfqs = async () => { try { setIsProcessing(true); const result = await fetchExternalRfqs(); if (result.success) { toast.success(result.message || "외부 RFQ를 성공적으로 가져왔습니다"); // 데이터 리프레시 onSuccess?.() } else { toast.error(result.message || "외부 RFQ를 가져오는 중 오류가 발생했습니다"); } } catch (error) { console.error("외부 RFQ 가져오기 오류:", error); toast.error("외부 RFQ를 가져오는 중 오류가 발생했습니다"); } finally { setIsProcessing(false); } }; return ( <>
{/* RFQ 가져오기 버튼 */} {/* PR 상세보기 버튼 */} {/* RFQ 밀봉 버튼 */} {/* RFQ 전송 버튼 */}
{/* PR 상세정보 다이얼로그 */} ) }