From 53ad72732f781e6c6d5ddb3776ea47aec010af8e Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 4 Aug 2025 09:39:21 +0000
Subject: (최겸) PQ/실사 수정 및 개발
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/pq/table/pq-lists-columns.tsx | 216 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 216 insertions(+)
 create mode 100644 lib/pq/table/pq-lists-columns.tsx

(limited to 'lib/pq/table/pq-lists-columns.tsx')

diff --git a/lib/pq/table/pq-lists-columns.tsx b/lib/pq/table/pq-lists-columns.tsx
new file mode 100644
index 00000000..1c401fac
--- /dev/null
+++ b/lib/pq/table/pq-lists-columns.tsx
@@ -0,0 +1,216 @@
+"use client"
+
+import { ColumnDef } from "@tanstack/react-table"
+import { Badge } from "@/components/ui/badge"
+// import { DataTableColumnHeader } from "@/components/data-table/data-table-column-header"
+import { DataTableRowAction } from "@/types/table"
+import { Ellipsis } from "lucide-react"
+import { formatDate } from "@/lib/utils"
+import { 
+  DropdownMenu, 
+  DropdownMenuContent,
+  DropdownMenuItem,
+  DropdownMenuTrigger 
+} from "@/components/ui/dropdown-menu"
+import { Button } from "@/components/ui/button"
+import React from "react"
+import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
+import { Checkbox } from "@/components/ui/checkbox"
+
+export interface PQList {
+  id: number
+  name: string
+  type: "GENERAL" | "PROJECT" | "NON_INSPECTION"
+  projectId?: number | null
+  projectCode?: string | null
+  projectName?: string | null
+  isDeleted: boolean
+  validTo?: Date | null
+  createdBy?: string | null // 이제 사용자 이름(users.name)
+  createdAt: Date
+  updatedAt: Date
+  updatedBy?: string | null
+  criteriaCount?: number
+}
+
+const typeLabels = {
+  GENERAL: "일반 PQ",
+  PROJECT: "프로젝트 PQ", 
+  NON_INSPECTION: "미실사 PQ"
+}
+
+const typeColors = {
+  GENERAL: "bg-blue-100 text-blue-800",
+  PROJECT: "bg-green-100 text-green-800",
+  NON_INSPECTION: "bg-orange-100 text-orange-800"
+}
+
+interface GetColumnsProps {
+  setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<PQList> | null>>
+}
+export function createPQListsColumns({
+  setRowAction
+}: GetColumnsProps): ColumnDef<PQList>[] {
+  return [
+    {
+      id: "select",
+      header: ({ table }) => (
+        <Checkbox
+          checked={
+            table.getIsAllPageRowsSelected() ||
+            (table.getIsSomePageRowsSelected() && "indeterminate")
+          }
+          onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
+          aria-label="Select all"
+          className="translate-y-0.5"
+        />
+      ),
+      cell: ({ row }) => (
+        <Checkbox
+          checked={row.getIsSelected()}
+          onCheckedChange={(value) => row.toggleSelected(!!value)}
+          aria-label="Select row"
+          className="translate-y-0.5"
+        />
+      ),
+      size:40,
+      enableSorting: false,
+      enableHiding: false,
+    },
+    {
+      accessorKey: "name",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="PQ 리스트명" />
+      ),
+      cell: ({ row }) => (
+        <div className="max-w-[200px] truncate font-medium">
+          {row.getValue("name")}
+        </div>
+      ),
+    },
+    {
+      accessorKey: "type",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="PQ 종류" />
+      ),
+      cell: ({ row }) => {
+        const type = row.getValue("type") as keyof typeof typeLabels
+        return (
+          <Badge className={typeColors[type]}>
+            {typeLabels[type]}
+          </Badge>
+        )
+      },
+      filterFn: (row, id, value) => {
+        return value.includes(row.getValue(id))
+      },
+    },
+    {
+      accessorKey: "projectCode",
+      header: "프로젝트",
+      cell: ({ row }) => row.original.projectCode ?? "-",
+    },
+    {
+      accessorKey: "projectName",
+      header: "프로젝트명",
+      cell: ({ row }) => row.original.projectName ?? "-",
+    },
+    {
+      accessorKey: "validTo",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="유효일" />
+      ),
+      cell: ({ row }) => {
+        const validTo = row.getValue("validTo") as Date | null
+        const now = new Date()
+        const isExpired = validTo && validTo < now
+        
+        const formattedDate = validTo ? formatDate(validTo, "ko-KR") : "-"
+        
+        return (
+          <div className="text-sm">
+            <span className={isExpired ? "text-red-600 font-medium" : ""}>
+              {formattedDate}
+            </span>
+            {isExpired && (
+              <Badge variant="destructive" className="ml-2 text-xs">
+                만료
+              </Badge>
+            )}
+          </div>
+        )
+      },
+    },
+    {
+      accessorKey: "isDeleted",
+      header: "상태",
+      cell: ({ row }) => {
+        const isDeleted = row.getValue("isDeleted") as boolean;
+        return (
+          <Badge variant={isDeleted ? "destructive" : "success"}>
+            {isDeleted ? "비활성" : "활성"}
+          </Badge>
+        );
+      },
+    },
+    {
+      accessorKey: "createdBy",
+      header: "생성자",
+      cell: ({ row }) => row.original.createdBy ?? "-",
+    },
+    {
+      accessorKey: "updatedBy",
+      header: "변경자",
+      cell: ({ row }) => row.original.updatedBy ?? "-",
+    },
+    {
+      accessorKey: "createdAt",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="생성일" />
+      ),
+      cell: ({ row }) => formatDate(row.getValue("createdAt"), "ko-KR"),
+    },
+    {
+      accessorKey: "updatedAt",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="변경일" />
+      ),
+      cell: ({ row }) => formatDate(row.getValue("updatedAt"), "ko-KR"),
+    },
+    {
+      id: "actions",
+      cell: ({ row }) => (
+        <DropdownMenu>
+          <DropdownMenuTrigger asChild>
+          <Button
+                aria-label="Open menu"
+                variant="ghost"
+                className="flex size-7 p-0 data-[state=open]:bg-muted"
+              >
+                <Ellipsis className="size-4" aria-hidden="true" />
+              </Button>
+            </DropdownMenuTrigger>
+            <DropdownMenuContent align="end" className="w-40">
+            <DropdownMenuItem
+              onSelect={() => setRowAction({ row, type: "view" })}
+            >
+              상세보기
+            </DropdownMenuItem>
+            {/* <DropdownMenuSeparator />
+            <DropdownMenuItem
+              onSelect={() => setRowAction({ row, type: "delete" })}
+              className="text-destructive"
+            >
+              삭제
+              <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
+            </DropdownMenuItem> */}
+          </DropdownMenuContent>
+        </DropdownMenu>
+      ),
+      size: 40,
+      enableSorting: false,
+      enableHiding: false,
+    }
+  
+  ]
+} 
\ No newline at end of file
-- 
cgit v1.2.3

