diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-04 09:39:21 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-04 09:39:21 +0000 |
| commit | 53ad72732f781e6c6d5ddb3776ea47aec010af8e (patch) | |
| tree | e676287827f8634be767a674b8ad08b6ed7eb3e6 /lib/pq/table/pq-lists-columns.tsx | |
| parent | 3e4d15271322397764601dee09441af8a5b3adf5 (diff) | |
(최겸) PQ/실사 수정 및 개발
Diffstat (limited to 'lib/pq/table/pq-lists-columns.tsx')
| -rw-r--r-- | lib/pq/table/pq-lists-columns.tsx | 216 |
1 files changed, 216 insertions, 0 deletions
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 |
