diff options
Diffstat (limited to 'lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx')
| -rw-r--r-- | lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx b/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx index 63d4674b..e1b82579 100644 --- a/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx +++ b/lib/techsales-rfq/vendor-response/table/vendor-quotations-table.tsx @@ -9,6 +9,9 @@ import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-adv import { TechSalesVendorQuotations, TECH_SALES_QUOTATION_STATUSES, TECH_SALES_QUOTATION_STATUS_CONFIG } from "@/db/schema" import { useRouter } from "next/navigation" import { getColumns } from "./vendor-quotations-table-columns" +import { TechSalesRfqAttachmentsSheet, ExistingTechSalesAttachment } from "../../table/tech-sales-rfq-attachments-sheet" +import { getTechSalesRfqAttachments } from "@/lib/techsales-rfq/service" +import { toast } from "sonner" interface QuotationWithRfqCode extends TechSalesVendorQuotations { rfqCode?: string; @@ -18,13 +21,14 @@ interface QuotationWithRfqCode extends TechSalesVendorQuotations { itemName?: string; projNm?: string; quotationCode?: string | null; - quotationVersion?: number | null; + quotationVersion: number | null; rejectionReason?: string | null; acceptedAt?: Date | null; + attachmentCount?: number; } interface VendorQuotationsTableProps { - promises: Promise<[{ data: any[], pageCount: number, total?: number }]>; + promises: Promise<[{ data: QuotationWithRfqCode[], pageCount: number, total?: number }]>; } export function VendorQuotationsTable({ promises }: VendorQuotationsTableProps) { @@ -34,16 +38,68 @@ export function VendorQuotationsTable({ promises }: VendorQuotationsTableProps) const [{ data, pageCount }] = React.use(promises); const router = useRouter(); + + // 첨부파일 시트 상태 + const [attachmentsOpen, setAttachmentsOpen] = React.useState(false) + const [selectedRfqForAttachments, setSelectedRfqForAttachments] = React.useState<{ id: number; rfqCode: string | null; status: string } | null>(null) + const [attachmentsDefault, setAttachmentsDefault] = React.useState<ExistingTechSalesAttachment[]>([]) // 데이터 안정성을 위한 메모이제이션 - 핵심 속성만 비교 const stableData = React.useMemo(() => { return data; }, [data.length, data.map(item => `${item.id}-${item.status}-${item.updatedAt}`).join(',')]); + // 첨부파일 시트 열기 함수 + const openAttachmentsSheet = React.useCallback(async (rfqId: number) => { + try { + // RFQ 정보 조회 (data에서 rfqId에 해당하는 데이터 찾기) + const quotationWithRfq = data.find(item => item.rfqId === rfqId) + if (!quotationWithRfq) { + toast.error("RFQ 정보를 찾을 수 없습니다.") + return + } + + // 실제 첨부파일 목록 조회 API 호출 + const result = await getTechSalesRfqAttachments(rfqId) + + if (result.error) { + toast.error(result.error) + return + } + + // API 응답을 ExistingTechSalesAttachment 형식으로 변환 + const attachments: ExistingTechSalesAttachment[] = result.data.map(att => ({ + id: att.id, + techSalesRfqId: att.techSalesRfqId || rfqId, + fileName: att.fileName, + originalFileName: att.originalFileName, + filePath: att.filePath, + fileSize: att.fileSize || undefined, + fileType: att.fileType || undefined, + attachmentType: att.attachmentType as "RFQ_COMMON" | "VENDOR_SPECIFIC", + description: att.description || undefined, + createdBy: att.createdBy, + createdAt: att.createdAt, + })) + + setAttachmentsDefault(attachments) + setSelectedRfqForAttachments({ + id: rfqId, + rfqCode: quotationWithRfq.rfqCode || null, + status: quotationWithRfq.rfqStatus || "Unknown" + }) + setAttachmentsOpen(true) + } catch (error) { + console.error("첨부파일 조회 오류:", error) + toast.error("첨부파일 조회 중 오류가 발생했습니다.") + } + }, [data]) + // 테이블 컬럼 정의 - router는 안정적이므로 한 번만 생성 const columns = React.useMemo(() => getColumns({ router, - }), [router]); + openAttachmentsSheet, + }), [router, openAttachmentsSheet]); // 필터 필드 - 중앙화된 상태 상수 사용 const filterFields = React.useMemo<DataTableFilterField<QuotationWithRfqCode>[]>(() => [ @@ -138,6 +194,16 @@ export function VendorQuotationsTable({ promises }: VendorQuotationsTableProps) </DataTableAdvancedToolbar> </DataTable> </div> + + {/* 첨부파일 관리 시트 (읽기 전용) */} + <TechSalesRfqAttachmentsSheet + open={attachmentsOpen} + onOpenChange={setAttachmentsOpen} + defaultAttachments={attachmentsDefault} + rfq={selectedRfqForAttachments} + onAttachmentsUpdated={() => {}} // 읽기 전용이므로 빈 함수 + readOnly={true} // 벤더 쪽에서는 항상 읽기 전용 + /> </div> ); }
\ No newline at end of file |
