From cf8dac0c6490469dab88a560004b0c07dbd48612 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Thu, 18 Sep 2025 00:23:40 +0000 Subject: (대표님) rfq, 계약, 서명 등 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/itb/table/purchase-request-columns.tsx | 380 +++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 lib/itb/table/purchase-request-columns.tsx (limited to 'lib/itb/table/purchase-request-columns.tsx') diff --git a/lib/itb/table/purchase-request-columns.tsx b/lib/itb/table/purchase-request-columns.tsx new file mode 100644 index 00000000..55321a21 --- /dev/null +++ b/lib/itb/table/purchase-request-columns.tsx @@ -0,0 +1,380 @@ +// components/purchase-requests/purchase-request-columns.tsx +"use client"; + +import { type ColumnDef } from "@tanstack/react-table"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Eye, + Edit, + Trash2, + CheckCircle, + XCircle, + FileText, + Package, + Send, + Clock +} from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { MoreHorizontal } from "lucide-react"; +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"; +import { format } from "date-fns"; +import { ko } from "date-fns/locale"; +import type { DataTableRowAction } from "@/types/table"; +import type { PurchaseRequestView } from "@/db/schema"; + +interface GetColumnsProps { + setRowAction: React.Dispatch | null>>; +} + +const statusConfig = { + "작성중": { + label: "작성중", + variant: "secondary" as const, + icon: Edit, + color: "text-gray-500" + }, + "요청완료": { + label: "요청완료", + variant: "default" as const, + icon: Send, + color: "text-blue-500" + }, + "검토중": { + label: "검토중", + variant: "warning" as const, + icon: Clock, + color: "text-yellow-500" + }, + "승인": { + label: "승인", + variant: "success" as const, + icon: CheckCircle, + color: "text-green-500" + }, + "반려": { + label: "반려", + variant: "destructive" as const, + icon: XCircle, + color: "text-red-500" + }, + "RFQ생성완료": { + label: "RFQ생성완료", + variant: "outline" as const, + icon: FileText, + color: "text-purple-500" + }, +}; + +export function getPurchaseRequestColumns({ + setRowAction +}: GetColumnsProps): ColumnDef[] { + return [ + { + id: "select", + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + size: 40, + }, + { + accessorKey: "requestCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( + + ), + size: 130, + }, + { + accessorKey: "status", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const status = row.getValue("status") as keyof typeof statusConfig; + const config = statusConfig[status]; + const Icon = config?.icon; + + return ( + + {Icon && } + {config?.label || status} + + ); + }, + filterFn: (row, id, value) => { + return value.includes(row.getValue(id)); + }, + size: 120, + }, + { + accessorKey: "requestTitle", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+
+ {row.getValue("requestTitle")} +
+ {row.original.requestDescription && ( +
+ {row.original.requestDescription} +
+ )} +
+ ), + size: 300, + }, + { + accessorKey: "projectName", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.original.projectCode && ( + + {row.original.projectCode} + + )} + + {row.original.projectName || "-"} + +
+ ), + size: 180, + }, + { + accessorKey: "packageName", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.original.packageNo && ( + + {row.original.packageNo} + + )} + + {row.original.packageName || "-"} + +
+ ), + size: 150, + }, + { + id: "attachments", + header: "첨부", + cell: ({ row }) => { + const count = Number(row.original.attachmentCount) || 0; + return count > 0 ? ( + + ) : ( + - + ); + }, + size: 70, + }, + { + id: "items", + header: "품목", + cell: ({ row }) => { + const count = row.original.itemCount || 0; + const totalQuantity = row.original.totalQuantity; + return count > 0 ? ( + + ) : ( + - + ); + }, + size: 90, + }, + { + accessorKey: "engPicName", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.getValue("engPicName") || "-"} +
+ ), + size: 100, + }, + { + accessorKey: "purchasePicName", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.getValue("purchasePicName") || "-"} +
+ ), + size: 100, + }, + { + accessorKey: "estimatedBudget", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.getValue("estimatedBudget") || "-"} +
+ ), + size: 100, + }, + { + accessorKey: "requestedDeliveryDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const date = row.getValue("requestedDeliveryDate") as Date | null; + return ( +
+ {date ? format(new Date(date), "yyyy-MM-dd", { locale: ko }) : "-"} +
+ ); + }, + size: 100, + }, + { + accessorKey: "createdAt", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const date = row.getValue("createdAt") as Date; + return ( +
+ {date ? format(new Date(date), "yyyy-MM-dd", { locale: ko }) : "-"} +
+ ); + }, + size: 100, + }, + { + id: "actions", + header: "작업", + cell: ({ row }) => { + const status = row.original.status; + + return ( + + + + + + 작업 + setRowAction({ row, type: "view" })} + > + + 상세보기 + + + + + + setRowAction({ row, type: "update" })} + > + + 수정 + + setRowAction({ row, type: "delete" })} + className="text-destructive" + > + + 삭제 + + + + + +{status ==="작성중" && +<> + + setRowAction({ row, type: "createRfq" })} + className="text-primary" + > + + RFQ 생성 + + + } + + + + + ); + }, + size: 80, + }, + ]; +} \ No newline at end of file -- cgit v1.2.3