diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-15 14:41:01 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-15 14:41:01 +0000 |
| commit | 4ee8b24cfadf47452807fa2af801385ed60ab47c (patch) | |
| tree | e1d1fb029f0cf5519c517494bf9a545505c35700 /lib/tbe-last/vendor/tbe-table.tsx | |
| parent | 265859d691a01cdcaaf9154f93c38765bc34df06 (diff) | |
(대표님) 작업사항 - rfqLast, tbeLast, pdfTron, userAuth
Diffstat (limited to 'lib/tbe-last/vendor/tbe-table.tsx')
| -rw-r--r-- | lib/tbe-last/vendor/tbe-table.tsx | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/lib/tbe-last/vendor/tbe-table.tsx b/lib/tbe-last/vendor/tbe-table.tsx new file mode 100644 index 00000000..d7ee0a06 --- /dev/null +++ b/lib/tbe-last/vendor/tbe-table.tsx @@ -0,0 +1,222 @@ +// lib/vendor-rfq-response/vendor-tbe-table/tbe-table.tsx + +"use client" + +import * as React from "react" +import { useRouter } from "next/navigation" +import { type DataTableAdvancedFilterField } from "@/types/table" +import { useDataTable } from "@/hooks/use-data-table" +import { DataTable } from "@/components/data-table/data-table" +import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar" +import { getColumns } from "./tbe-table-columns" +import { TbeLastView } from "@/db/schema" +import { getTBESessionDetail } from "@/lib/tbe-last/service" +import { Button } from "@/components/ui/button" +import { Download, RefreshCw, Upload } from "lucide-react" +import { exportTableToExcel } from "@/lib/export" + +// Import Vendor-specific Dialogs +import { VendorDocumentUploadDialog } from "./vendor-document-upload-dialog" +import { VendorQADialog } from "./vendor-comment-dialog" +import { VendorDocumentsSheet } from "./vendor-documents-sheet" +import { VendorPrItemsDialog } from "./vendor-pr-items-dialog" +import { getTBEforVendor } from "../vendor-tbe-service" + +interface TbeVendorTableProps { + promises: Promise<[ + Awaited<ReturnType<typeof getTBEforVendor>>, + ]> +} + +export function TbeVendorTable({ promises }: TbeVendorTableProps) { + const router = useRouter() + const [{ data, pageCount }] = React.use(promises) + + // Dialog states + const [documentUploadOpen, setDocumentUploadOpen] = React.useState(false) + const [qaDialogOpen, setQADialogOpen] = React.useState(false) + const [evaluationViewOpen, setEvaluationViewOpen] = React.useState(false) + const [documentsOpen, setDocumentsOpen] = React.useState(false) + const [prItemsOpen, setPrItemsOpen] = React.useState(false) + + const [selectedSessionId, setSelectedSessionId] = React.useState<number | null>(null) + const [selectedRfqId, setSelectedRfqId] = React.useState<number | null>(null) + const [selectedSession, setSelectedSession] = React.useState<TbeLastView | null>(null) + const [sessionDetail, setSessionDetail] = React.useState<any>(null) + const [isLoadingDetail, setIsLoadingDetail] = React.useState(false) + + // Load session detail when needed + const loadSessionDetail = React.useCallback(async (sessionId: number) => { + setIsLoadingDetail(true) + try { + const detail = await getTBESessionDetail(sessionId) + setSessionDetail(detail) + } catch (error) { + console.error("Failed to load session detail:", error) + } finally { + setIsLoadingDetail(false) + } + }, []) + + // Handlers + const handleOpenDocumentUpload = React.useCallback((sessionId: number) => { + setSelectedSessionId(sessionId) + setDocumentUploadOpen(true) + loadSessionDetail(sessionId) + }, [loadSessionDetail]) + + const handleOpenComment = React.useCallback((sessionId: number) => { + setSelectedSessionId(sessionId) + setQADialogOpen(true) + loadSessionDetail(sessionId) + }, [loadSessionDetail]) + + const handleOpenEvaluationView = React.useCallback((session: TbeLastView) => { + setSelectedSession(session) + setEvaluationViewOpen(true) + loadSessionDetail(session.tbeSessionId) + }, [loadSessionDetail]) + + const handleOpenDocuments = React.useCallback((sessionId: number) => { + setSelectedSessionId(sessionId) + setDocumentsOpen(true) + loadSessionDetail(sessionId) + }, [loadSessionDetail]) + + const handleOpenPrItems = React.useCallback((rfqId: number) => { + setSelectedRfqId(rfqId) + setPrItemsOpen(true) + }, []) + + const handleRefresh = React.useCallback(() => { + router.refresh() + }, [router]) + + // Table columns + const columns = React.useMemo( + () => + getColumns({ + onOpenDocumentUpload: handleOpenDocumentUpload, + onOpenComment: handleOpenComment, + onOpenEvaluationView: handleOpenEvaluationView, + onOpenDocuments: handleOpenDocuments, + onOpenPrItems: handleOpenPrItems, + }), + [handleOpenDocumentUpload, handleOpenComment, handleOpenEvaluationView, handleOpenDocuments, handleOpenPrItems] + ) + + // Filter fields + const filterFields: DataTableAdvancedFilterField<TbeLastView>[] = [ + { + id: "sessionStatus", + label: "Status", + type: "select", + options: [ + { label: "준비중", value: "준비중" }, + { label: "진행중", value: "진행중" }, + { label: "검토중", value: "검토중" }, + { label: "보류", value: "보류" }, + { label: "완료", value: "완료" }, + ], + }, + { + id: "evaluationResult", + label: "Result", + type: "select", + options: [ + { label: "Pass", value: "pass" }, + { label: "Conditional Pass", value: "conditional_pass" }, + { label: "Non-Pass", value: "non_pass" }, + { label: "Pending", value: "pending" }, + ], + }, + ] + + // Data table + const { table } = useDataTable({ + data, + columns, + pageCount, + filterFields, + enablePinning: true, + enableAdvancedFilter: true, + initialState: { + sorting: [{ id: "createdAt", desc: true }], + columnPinning: { right: ["actions"] }, + }, + getRowId: (originalRow) => String(originalRow.tbeSessionId), + shallow: false, + clearOnDefault: true, + }) + + return ( + <> + <DataTable table={table}> + <DataTableAdvancedToolbar + table={table} + filterFields={filterFields} + shallow={false} + > + <div className="flex items-center gap-2"> + <Button + variant="outline" + size="sm" + onClick={handleRefresh} + className="gap-2" + > + <RefreshCw className="size-4" /> + <span>Refresh</span> + </Button> + <Button + variant="outline" + size="sm" + onClick={() => + exportTableToExcel(table, { + filename: "vendor-tbe-sessions", + excludeColumns: ["select", "actions"], + }) + } + className="gap-2" + > + <Download className="size-4" /> + <span>Export</span> + </Button> + </div> + </DataTableAdvancedToolbar> + </DataTable> + + {/* Document Upload Dialog */} + <VendorDocumentUploadDialog + open={documentUploadOpen} + onOpenChange={setDocumentUploadOpen} + sessionId={selectedSessionId} + sessionDetail={sessionDetail} + onUploadSuccess={handleRefresh} + /> + + {/* Q&A Dialog */} + <VendorQADialog + open={qaDialogOpen} + onOpenChange={setQADialogOpen} + sessionId={selectedSessionId} + sessionDetail={sessionDetail} + onQuestionSubmit={handleRefresh} + /> + + {/* Documents Sheet */} + <VendorDocumentsSheet + open={documentsOpen} + onOpenChange={setDocumentsOpen} + sessionDetail={sessionDetail} + isLoading={isLoadingDetail} + /> + + {/* PR Items Dialog */} + <VendorPrItemsDialog + open={prItemsOpen} + onOpenChange={setPrItemsOpen} + rfqId={selectedRfqId} + /> + </> + ) +}
\ No newline at end of file |
