// lib/tbe-last/table/tbe-last-table.tsx "use client" import * as React from "react" import { useRouter } from "next/navigation" import { type DataTableFilterField } 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-last-table-columns" import { TbeLastView } from "@/db/schema" import { getAllTBELast, getTBESessionDetail } from "@/lib/tbe-last/service" import { Button } from "@/components/ui/button" import { Download, RefreshCw } from "lucide-react" import { exportTableToExcel } from "@/lib/export" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog" import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from "@/components/ui/sheet" import { Badge } from "@/components/ui/badge" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { ScrollArea } from "@/components/ui/scroll-area" import { formatDate } from "@/lib/utils" interface TbeLastTableProps { promises: Promise<[ Awaited>, ]> } export function TbeLastTable({ promises }: TbeLastTableProps) { const router = useRouter() const [{ data, pageCount }] = React.use(promises) // Dialog states const [sessionDetailOpen, setSessionDetailOpen] = React.useState(false) const [documentsOpen, setDocumentsOpen] = React.useState(false) const [prItemsOpen, setPrItemsOpen] = React.useState(false) const [evaluationOpen, setEvaluationOpen] = React.useState(false) const [selectedSessionId, setSelectedSessionId] = React.useState(null) const [selectedRfqId, setSelectedRfqId] = React.useState(null) const [selectedSession, setSelectedSession] = React.useState(null) const [sessionDetail, setSessionDetail] = React.useState(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 handleOpenSessionDetail = React.useCallback((sessionId: number) => { setSelectedSessionId(sessionId) setSessionDetailOpen(true) loadSessionDetail(sessionId) }, [loadSessionDetail]) const handleOpenDocuments = React.useCallback((sessionId: number) => { setSelectedSessionId(sessionId) setDocumentsOpen(true) loadSessionDetail(sessionId) }, [loadSessionDetail]) const handleOpenPrItems = React.useCallback((rfqId: number) => { setSelectedRfqId(rfqId) setPrItemsOpen(true) loadSessionDetail(rfqId) }, [loadSessionDetail]) const handleOpenEvaluation = React.useCallback((session: TbeLastView) => { setSelectedSession(session) setEvaluationOpen(true) }, []) const handleRefresh = React.useCallback(() => { router.refresh() }, [router]) // Table columns const columns = React.useMemo( () => getColumns({ onOpenSessionDetail: handleOpenSessionDetail, onOpenDocuments: handleOpenDocuments, onOpenPrItems: handleOpenPrItems, onOpenEvaluation: handleOpenEvaluation, }), [handleOpenSessionDetail, handleOpenDocuments, handleOpenPrItems, handleOpenEvaluation] ) // Filter fields const filterFields: DataTableFilterField[] = [ { 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" }, ], }, ] // Data table const { table } = useDataTable({ data, columns, pageCount, filterFields, enablePinning: true, enableAdvancedFilter: true, initialState: { sorting: [{ id: "createdAt", desc: true }], columnPinning: { right: ["documents", "comments"] }, }, getRowId: (originalRow) => String(originalRow.tbeSessionId), shallow: false, clearOnDefault: true, }) return ( <>
{/* Session Detail Dialog */} TBE Session Detail {sessionDetail?.session?.sessionCode} - {sessionDetail?.session?.vendorName} {isLoadingDetail ? (
Loading...
) : sessionDetail ? (
{/* Session info */}

RFQ Code

{sessionDetail.session.rfqCode}

Status

{sessionDetail.session.sessionStatus}

Project

{sessionDetail.session.projectCode} - {sessionDetail.session.projectName}

Package

{sessionDetail.session.packageNo} - {sessionDetail.session.packageName}

{/* PR Items */} {sessionDetail.prItems?.length > 0 && (

PR Items

{sessionDetail.prItems.map((item: any) => ( ))}
PR No Material Code Description Qty Delivery
{item.prNo} {item.materialCode} {item.materialDescription} {item.quantity} {item.uom} {item.deliveryDate ? formatDate(item.deliveryDate, "KR") : "-"}
)}
) : null}
{/* Documents Sheet */} Documents & Comments Review documents and PDFTron comments {isLoadingDetail ? (
Loading...
) : sessionDetail?.documents ? ( Buyer Documents Vendor Documents
{sessionDetail.documents .filter((doc: any) => doc.documentSource === "buyer") .map((doc: any) => (

{doc.documentName}

Type: {doc.documentType} | Status: {doc.reviewStatus}

{doc.comments.totalCount > 0 && ( 0 ? "destructive" : "secondary"}> {doc.comments.openCount}/{doc.comments.totalCount} comments )}
))}
{sessionDetail.documents .filter((doc: any) => doc.documentSource === "vendor") .map((doc: any) => (

{doc.documentName}

Type: {doc.documentType} | Status: {doc.reviewStatus}

{doc.submittedAt && (

Submitted: {formatDate(doc.submittedAt, "KR")}

)}
))}
) : null}
{/* PR Items Dialog */} PR Items Purchase Request items for this RFQ {sessionDetail?.prItems && (
{sessionDetail.prItems.map((item: any) => ( ))}
PR No Material Code Description Size Qty Unit Delivery Major
{item.prNo} {item.materialCode} {item.materialDescription} {item.size || "-"} {item.quantity} {item.uom} {item.deliveryDate ? formatDate(item.deliveryDate, "KR") : "-"} {item.majorYn && Major}
)}
{/* Evaluation Dialog */} TBE Evaluation Enter evaluation result for {selectedSession?.sessionCode}
{/* Evaluation form would go here */}

Evaluation form to be implemented...

) }