From 4ee8b24cfadf47452807fa2af801385ed60ab47c Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 15 Sep 2025 14:41:01 +0000 Subject: (대표님) 작업사항 - rfqLast, tbeLast, pdfTron, userAuth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/tbe-last/vendor/tbe-table-columns.tsx | 335 ++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 lib/tbe-last/vendor/tbe-table-columns.tsx (limited to 'lib/tbe-last/vendor/tbe-table-columns.tsx') diff --git a/lib/tbe-last/vendor/tbe-table-columns.tsx b/lib/tbe-last/vendor/tbe-table-columns.tsx new file mode 100644 index 00000000..6e40fe27 --- /dev/null +++ b/lib/tbe-last/vendor/tbe-table-columns.tsx @@ -0,0 +1,335 @@ +// lib/vendor-rfq-response/vendor-tbe-table/tbe-table-columns.tsx + +"use client" + +import * as React from "react" +import { type ColumnDef } from "@tanstack/react-table" +import { FileText, ListChecks, Eye } from "lucide-react" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { Checkbox } from "@/components/ui/checkbox" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { formatDate } from "@/lib/utils" +import { TbeLastView } from "@/db/schema" + +interface GetColumnsProps { + onOpenEvaluationView: (session: TbeLastView) => void; + onOpenDocuments: (sessionId: number) => void; + onOpenPrItems: (rfqId: number) => void; +} + +export function getColumns({ + onOpenEvaluationView, + onOpenDocuments, + onOpenPrItems, +}: GetColumnsProps): ColumnDef[] { + + const columns: ColumnDef[] = [ + // Select Column + { + id: "select", + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + className="translate-y-0.5" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + className="translate-y-0.5" + /> + ), + size: 40, + enableSorting: false, + enableHiding: false, + }, + + // TBE Session Code + { + accessorKey: "sessionCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const sessionCode = row.original.sessionCode; + return ( + {sessionCode} + ); + }, + size: 120, + }, + + // RFQ Code + { + accessorKey: "rfqCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => row.original.rfqCode, + size: 120, + }, + + // RFQ Title + { + accessorKey: "rfqTitle", + header: ({ column }) => ( + + ), + cell: ({ row }) => row.original.rfqTitle || "-", + size: 200, + }, + + // RFQ Due Date + { + accessorKey: "rfqDueDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const date = row.original.rfqDueDate; + if (!date) return "-"; + + const daysUntilDue = Math.floor((new Date(date).getTime() - Date.now()) / (1000 * 60 * 60 * 24)); + const isOverdue = daysUntilDue < 0; + const isUrgent = daysUntilDue <= 3 && daysUntilDue >= 0; + + return ( +
+ + {formatDate(date, "KR")} + + {isOverdue && ( + Overdue + )} + {isUrgent && ( + {daysUntilDue}일 남음 + )} +
+ ); + }, + size: 100, + }, + + // Package Info + { + accessorKey: "packageNo", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const packageNo = row.original.packageNo; + const packageName = row.original.packageName; + + if (!packageNo) return "-"; + + return ( +
+ {packageNo} + {packageName && ( + {packageName} + )} +
+ ); + }, + size: 150, + }, + + // Project Info + { + accessorKey: "projectCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const projectCode = row.original.projectCode; + const projectName = row.original.projectName; + + if (!projectCode) return "-"; + + return ( +
+ {projectCode} + {projectName && ( + {projectName} + )} +
+ ); + }, + size: 150, + }, + + // 구매담당자 + { + accessorKey: "picName", + header: ({ column }) => ( + + ), + cell: ({ row }) => row.original.picName || "-", + size: 120, + }, + + // TBE Status + { + accessorKey: "sessionStatus", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const status = row.original.sessionStatus; + + let variant: "default" | "secondary" | "outline" | "destructive" = "outline"; + + switch (status) { + case "준비중": + variant = "outline"; + break; + case "진행중": + variant = "default"; + break; + case "검토중": + variant = "secondary"; + break; + case "완료": + variant = "default"; + break; + case "보류": + variant = "destructive"; + break; + } + + return {status}; + }, + size: 100, + }, + + // Evaluation Result + { + accessorKey: "evaluationResult", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const result = row.original.evaluationResult; + const session = row.original; + + if (!result) { + return ( + + Pending + + ); + } + + let variant: "default" | "secondary" | "destructive" = "default"; + let displayText = result; + + switch (result) { + case "Acceptable": + variant = "default"; + displayText = "Acceptable"; + break; + case "Acceptable with Comment": + variant = "secondary"; + displayText = "Conditional"; + break; + case "Not Acceptable": + variant = "destructive"; + displayText = "Not Acceptable"; + break; + } + + return ( +
+ {displayText} + {result && ( + + )} +
+ ); + }, + size: 150, + }, + + // PR Items + { + id: "prItems", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const rfqId = row.original.rfqId; + const totalCount = row.original.prItemsCount; + const majorCount = row.original.majorItemsCount; + + return ( + + ); + }, + size: 100, + enableSorting: false, + }, + + // Documents (클릭하면 Documents Sheet 열림) + { + id: "documents", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const sessionId = row.original.tbeSessionId; + const buyerDocs = Number(row.original.buyerDocumentsCount); + const vendorDocs = Number(row.original.vendorDocumentsCount); + const totalDocs = buyerDocs + vendorDocs; + const status = row.original.sessionStatus; + + // 진행중 상태면 강조 + const isActive = status === "진행중"; + + return ( + + ); + }, + size: 140, + enableSorting: false, + }, + ]; + + return columns; +} \ No newline at end of file -- cgit v1.2.3