summaryrefslogtreecommitdiff
path: root/lib/vendors/contract-history/contract-history-table-columns.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-09-18 15:29:09 +0900
committerjoonhoekim <26rote@gmail.com>2025-09-18 15:29:09 +0900
commit26a3c3489e068bcebbbeaa49ca2cf67a06893c03 (patch)
treea3a4b87da05cd41145f78d75081d9b7f7fbeba20 /lib/vendors/contract-history/contract-history-table-columns.tsx
parent801978235ada1a336601c370fe07859f2b10a549 (diff)
(김준회) PO/계약 히스토리
Diffstat (limited to 'lib/vendors/contract-history/contract-history-table-columns.tsx')
-rw-r--r--lib/vendors/contract-history/contract-history-table-columns.tsx412
1 files changed, 412 insertions, 0 deletions
diff --git a/lib/vendors/contract-history/contract-history-table-columns.tsx b/lib/vendors/contract-history/contract-history-table-columns.tsx
new file mode 100644
index 00000000..a25f8f33
--- /dev/null
+++ b/lib/vendors/contract-history/contract-history-table-columns.tsx
@@ -0,0 +1,412 @@
+/**
+ * 계약히스토리 테이블 컬럼 설정
+ *
+ *
+ * 컬럼목록:
+ * - 선택
+ * - PO/계약번호
+ * - Rev. / 품번
+ * - 계약상태
+ * - 프로젝트
+ * - PKG No.
+ * - PKG 명
+ * - 자재그룹코드
+ * - 자재그룹명
+ * - 지불조건
+ * - Incoterms
+ * - 선적지
+ * - 계약납기일
+ * - L/C No.
+ * - 연동제대상
+ * - 통화
+ * - 계약금액
+ * - 선급금
+ * - 납품대금
+ * - 유보금
+ * - PO/계약발송일
+ * - PO/계약체결일
+ * - 계약서
+ * - 계약담당자
+ * - 계약상세
+ */
+
+"use client"
+
+import * as React from "react"
+import { type DataTableRowAction } from "@/types/table"
+import { type ColumnDef } from "@tanstack/react-table"
+import { Ellipsis, FileText, User, Eye } from "lucide-react"
+
+import { formatDate } from "@/lib/utils"
+
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import { Checkbox } from "@/components/ui/checkbox"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+
+import { ContractDetailParsed } from "@/db/schema/contract"
+import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
+
+
+
+
+// 간단한 숫자 포맷팅 함수
+const formatNumber = (value: number): string => {
+ return new Intl.NumberFormat('ko-KR').format(value)
+}
+
+interface GetColumnsProps {
+ setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<ContractDetailParsed> | null>>;
+}
+
+/**
+ * 계약 히스토리 테이블 컬럼 정의 (간단 버전)
+ */
+export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<ContractDetailParsed>[] {
+ 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,
+ },
+
+ // PO/계약번호
+ {
+ accessorKey: "contractNo",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="PO/계약번호" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // Rev. / 품번 (contract.contractVersion 사용)
+ {
+ accessorKey: "contractVersion",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="Rev. / 품번" />
+ ),
+ cell: ({ cell }) => {
+ const value = cell.getValue()
+ return value ? `Rev.${value}` : <span className="text-muted-foreground">-</span>
+ },
+ },
+
+ // 계약상태
+ {
+ accessorKey: "status",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약상태" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 프로젝트
+ {
+ accessorKey: "projectName",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="프로젝트" />
+ ),
+ cell: ({ row }) => (
+ <div className="flex flex-col">
+ <span className="font-medium">{row.original.projectName}</span>
+ <span className="text-xs text-muted-foreground">{row.original.projectCode}</span>
+ </div>
+ ),
+ },
+
+ // PKG No.
+ {
+ accessorKey: "projectCode",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="PKG No." />
+ ),
+ cell: ({ row }) => row.original.projectCode ? <Badge variant="outline">{row.original.projectCode}</Badge> : <span className="text-muted-foreground">-</span>,
+ },
+
+ // 벤더명
+ {
+ accessorKey: "vendorName",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="협력업체" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 계약명
+ {
+ accessorKey: "contractName",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약명" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 자재그룹코드 (지원되지 않음)
+ {
+ accessorKey: "materialGroupCode",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="자재그룹코드" />
+ ),
+ cell: () => <span className="text-muted-foreground">-</span>,
+ },
+
+ // 자재그룹명 (지원되지 않음)
+ {
+ accessorKey: "materialGroupName",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="자재그룹명" />
+ ),
+ cell: () => <span className="text-muted-foreground">-</span>,
+ },
+
+ // 지불조건
+ {
+ accessorKey: "paymentTerms",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="지불조건" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // Incoterms
+ {
+ accessorKey: "deliveryTerms",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="Incoterms" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 선적지
+ {
+ accessorKey: "shippmentPlace",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="선적지" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 계약납기일
+ {
+ accessorKey: "deliveryDate",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약납기일" />
+ ),
+ cell: ({ cell }) => {
+ const value = cell.getValue()
+ if (value instanceof Date) return formatDate(value, "KR")
+ if (typeof value === "string") return formatDate(new Date(value), "KR")
+ return ""
+ },
+ },
+
+ // L/C No.
+ {
+ accessorKey: "lcNo",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="L/C No." />
+ ),
+ cell: () => <span className="text-muted-foreground">-</span>,
+ },
+
+ // 연동제대상
+ {
+ accessorKey: "priceIndexYn",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="연동제대상" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 통화
+ {
+ accessorKey: "currency",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="통화" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 계약금액
+ {
+ accessorKey: "totalAmount",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약금액" />
+ ),
+ cell: ({ cell }) => {
+ const value = cell.getValue()
+ return typeof value === "number" ? formatNumber(value) : value ?? ""
+ },
+ },
+
+ // 선급금
+ {
+ accessorKey: "advancePaymentYn",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="선급금" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 납품장소
+ {
+ accessorKey: "deliveryLocation",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="납품장소" />
+ ),
+ cell: ({ cell }) => cell.getValue() ?? "",
+ },
+
+ // 유보금
+ {
+ accessorKey: "retentionAmount",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="유보금" />
+ ),
+ cell: () => <span className="text-muted-foreground">-</span>,
+ },
+
+ // PO/계약발송일
+ {
+ accessorKey: "startDate",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="PO/계약발송일" />
+ ),
+ cell: ({ cell }) => {
+ const value = cell.getValue()
+ if (value instanceof Date) return formatDate(value, "KR")
+ if (typeof value === "string") return formatDate(new Date(value), "KR")
+ return ""
+ },
+ },
+
+ // PO/계약체결일
+ {
+ accessorKey: "electronicApprovalDate",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="PO/계약체결일" />
+ ),
+ cell: ({ cell }) => {
+ const value = cell.getValue()
+ if (value instanceof Date) return formatDate(value, "KR")
+ if (typeof value === "string") return formatDate(new Date(value), "KR")
+ return ""
+ },
+ },
+
+ // 전자서명상태
+ {
+ accessorKey: "hasSignature",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="전자서명상태" />
+ ),
+ cell: ({ cell }) => {
+ const hasSignature = cell.getValue()
+ return hasSignature ?
+ <Badge variant="default">서명완료</Badge> :
+ <Badge variant="secondary">미서명</Badge>
+ },
+ },
+
+ // 계약서 (지원되지 않음)
+ {
+ accessorKey: "contractDocument",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약서" />
+ ),
+ cell: () => (
+ <Button variant="ghost" size="sm" className="h-8 px-2" disabled>
+ <FileText className="size-4 mr-1" />
+ 보기
+ </Button>
+ ),
+ },
+
+ // 계약담당자 (지원되지 않음)
+ {
+ accessorKey: "contractManager",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약담당자" />
+ ),
+ cell: () => (
+ <div className="flex items-center text-muted-foreground">
+ <User className="size-4 mr-2" />
+ <span>-</span>
+ </div>
+ ),
+ },
+
+ // 계약상세 (Actions)
+ {
+ accessorKey: "contractDetail",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="계약상세" />
+ ),
+ cell: ({ row }) => (
+ <DropdownMenu>
+ <DropdownMenuTrigger asChild>
+ <Button
+ aria-label="Open menu"
+ variant="ghost"
+ className="flex size-8 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" })}
+ >
+ <Eye className="size-4 mr-2" />
+ 상세보기
+ </DropdownMenuItem>
+ <DropdownMenuSeparator />
+ <DropdownMenuItem
+ onSelect={() => setRowAction({ row, type: "update" })}
+ >
+ 수정
+ </DropdownMenuItem>
+ <DropdownMenuSeparator />
+ <DropdownMenuItem
+ onSelect={() => setRowAction({ row, type: "delete" })}
+ >
+ 삭제
+ <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
+ </DropdownMenuItem>
+ </DropdownMenuContent>
+ </DropdownMenu>
+ ),
+ size: 40,
+ enableSorting: false,
+ enableHiding: false,
+ },
+ ]
+} \ No newline at end of file