"use client" import * as React from "react" import { ColumnDef } from "@tanstack/react-table" import { formatDate, formatDateTime } from "@/lib/utils" import { Checkbox } from "@/components/ui/checkbox" import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" import { DataTableRowAction } from "@/types/table" import { StageSubmissionView } from "@/db/schema" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Progress } from "@/components/ui/progress" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Ellipsis, Upload, Eye, RefreshCw, CheckCircle2, XCircle, AlertCircle, Clock, Download } from "lucide-react" interface GetColumnsProps { setRowAction: React.Dispatch | null>> } export function getColumns({ setRowAction, }: GetColumnsProps): ColumnDef[] { return [ { id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label="Select all" /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label="Select row" /> ), size: 40, enableSorting: false, enableHiding: false, }, { accessorKey: "docNumber", header: ({ column }) => ( ), cell: ({ row }) => { const vendorDocNumber = row.original.vendorDocNumber return (
{row.getValue("docNumber")}
{vendorDocNumber && (
{vendorDocNumber}
)}
) }, size: 150, }, { accessorKey: "documentTitle", header: ({ column }) => ( ), cell: ({ row }) => (
{row.getValue("documentTitle")}
), size: 250, }, { accessorKey: "projectCode", header: ({ column }) => ( ), cell: ({ row }) => ( {row.getValue("projectCode")} ), size: 100, }, { accessorKey: "stageName", header: ({ column }) => ( ), cell: ({ row }) => { const stageName = row.getValue("stageName") as string const stageStatus = row.original.stageStatus const stageOrder = row.original.stageOrder return (
{stageOrder ? `#${stageOrder}` : ""} {stageName}
{stageStatus && ( {stageStatus} )}
) }, size: 200, }, { accessorKey: "stagePlanDate", header: ({ column }) => ( ), cell: ({ row }) => { const planDate = row.getValue("stagePlanDate") as Date | null const isOverdue = row.original.isOverdue const daysUntilDue = row.original.daysUntilDue if (!planDate) return - return (
{formatDate(planDate)}
{daysUntilDue !== null && (
{isOverdue ? ( {Math.abs(daysUntilDue)} days overdue ) : daysUntilDue === 0 ? ( Due today ) : ( {daysUntilDue} days remaining )}
)}
) }, size: 150, }, { accessorKey: "latestSubmissionStatus", header: ({ column }) => ( ), cell: ({ row }) => { const status = row.getValue("latestSubmissionStatus") as string | null const reviewStatus = row.original.latestReviewStatus const revisionNumber = row.original.latestRevisionNumber const revisionCode = row.original.latestRevisionCode if (!status) { return ( Not submitted ) } return (
{reviewStatus || status} {revisionCode !== null && (
{revisionCode}
)}
) }, size: 150, }, { id: "syncStatus", accessorKey: "latestSyncStatus", header: ({ column }) => ( ), cell: ({ row }) => { const syncStatus = row.getValue("latestSyncStatus") as string | null const syncProgress = row.original.syncProgress const requiresSync = row.original.requiresSync if (!syncStatus || syncStatus === "pending") { if (requiresSync) { return ( Pending ) } return - } return (
{syncStatus === "syncing" && } {syncStatus === "synced" && } {syncStatus === "failed" && } {syncStatus} {syncProgress !== null && syncProgress !== undefined && syncStatus === "syncing" && ( )}
) }, size: 120, }, { accessorKey: "totalFiles", header: ({ column }) => ( ), cell: ({ row }) => { const totalFiles = row.getValue("totalFiles") as number const syncedFiles = row.original.syncedFilesCount if (!totalFiles) return 0 return (
{syncedFiles !== null && syncedFiles !== undefined ? ( {syncedFiles}/{totalFiles} ) : ( {totalFiles} )}
) }, size: 80, }, // { // accessorKey: "vendorName", // header: ({ column }) => ( // // ), // cell: ({ row }) => { // const vendorName = row.getValue("vendorName") as string // const vendorCode = row.original.vendorCode // return ( //
//
{vendorName}
// {vendorCode && ( //
{vendorCode}
// )} //
// ) // }, // size: 150, // }, // columns.tsx { id: "actions", enableHiding: false, cell: function Cell({ row }) { const requiresSubmission = row.original.requiresSubmission const requiresSync = row.original.requiresSync const latestSubmissionId = row.original.latestSubmissionId const projectCode = row.original.projectCode // 프로젝트 코드 가져오기 return ( {requiresSubmission && ( setRowAction({ row, type: "upload" })} className="gap-2" > Upload Documents )} {latestSubmissionId && ( <> setRowAction({ row, type: "view" })} className="gap-2" > View Submission {requiresSync && ( setRowAction({ row, type: "sync" })} className="gap-2" > Retry Sync )} )} {/* ✅ 커버 페이지 다운로드 - projectCode가 있을 때만 표시 */} {projectCode && ( <> setRowAction({ row, type: "downloadCover" })} className="gap-2" > Download Cover Page )} setRowAction({ row, type: "history" })} className="gap-2" > View History ) }, size: 40, } ] }