summaryrefslogtreecommitdiff
path: root/lib/b-rfq/attachment/attachment-columns.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/b-rfq/attachment/attachment-columns.tsx')
-rw-r--r--lib/b-rfq/attachment/attachment-columns.tsx286
1 files changed, 0 insertions, 286 deletions
diff --git a/lib/b-rfq/attachment/attachment-columns.tsx b/lib/b-rfq/attachment/attachment-columns.tsx
deleted file mode 100644
index b726ebc8..00000000
--- a/lib/b-rfq/attachment/attachment-columns.tsx
+++ /dev/null
@@ -1,286 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { type ColumnDef } from "@tanstack/react-table"
-import {
- Ellipsis, FileText, Download, Eye,
- MessageSquare, Upload
-} from "lucide-react"
-
-import { formatDate, formatBytes } 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, DropdownMenuTrigger
-} from "@/components/ui/dropdown-menu"
-import { Progress } from "@/components/ui/progress"
-import { RevisionDialog } from "./revision-dialog"
-import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
-import { AddRevisionDialog } from "./add-revision-dialog"
-
-interface GetAttachmentColumnsProps {
- onSelectAttachment: (attachment: any) => void
-}
-
-export function getAttachmentColumns({
- onSelectAttachment
-}: GetAttachmentColumnsProps): ColumnDef<any>[] {
-
- 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: "serialNo",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="시리얼 번호" />
- ),
- cell: ({ row }) => (
- <Button
- variant="link"
- className="p-0 h-auto font-medium text-blue-600 hover:text-blue-800"
- onClick={() => onSelectAttachment(row.original)}
- >
- {row.getValue("serialNo") as string}
- </Button>
- ),
- size: 100,
- },
- {
- accessorKey: "attachmentType",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="문서 타입" />
- ),
- cell: ({ row }) => {
- const type = row.getValue("attachmentType") as string
- return (
- <Badge variant={type === "구매" ? "default" : "secondary"}>
- {type}
- </Badge>
- )
- },
- size:100
- },
- {
- accessorKey: "originalFileName",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="파일명" />
- ),
- cell: ({ row }) => {
- const fileName = row.getValue("originalFileName") as string
- return (
- <div className="flex items-center gap-2">
- <FileText className="h-4 w-4 text-muted-foreground" />
- <div className="min-w-0 flex-1">
- <div className="truncate font-medium" title={fileName}>
- {fileName}
- </div>
- </div>
- </div>
- )
- },
- size:250
- },
- {
- id: "currentRevision",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="리비전" />
- ),
- cell: ({ row }) => (
- <RevisionDialog
- attachmentId={row.original.id}
- currentRevision={row.original.currentRevision}
- originalFileName={row.original.originalFileName}
- />
- ),
- size: 100,
- },
- {
- accessorKey: "description",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="설명" />
- ),
- cell: ({ row }) => {
- const description = row.getValue("description") as string
- return description
- ? <div className="max-w-[200px] truncate" title={description}>{description}</div>
- : <span className="text-muted-foreground">-</span>
- },
- },
-
- /** ───────────── 파일 정보 ───────────── */
- // {
- // accessorKey: "fileSize",
- // header: ({ column }) => (
- // <DataTableColumnHeaderSimple column={column} title="파일 크기" />
- // ),
- // cell: ({ row }) => {
- // const size = row.getValue("fileSize") as number
- // return size ? formatBytes(size) : "-"
- // },
- // },
- {
- accessorKey: "createdAt",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="등록일" />
- ),
- cell: ({ row }) => {
- const created = row.getValue("createdAt") as Date
- const updated = row.original.updatedAt as Date
- return (
- <div>
- <div>{formatDate(created, "KR")}</div>
- <div className="text-xs text-muted-foreground">
- {row.original.createdByName}
- </div>
- {updated && new Date(updated) > new Date(created) && (
- <div className="text-xs text-blue-600">
- 수정: {formatDate(updated, "KR")}
- </div>
- )}
- </div>
- )
- },
- maxSize:150
- },
-
- /** ───────────── 벤더 응답 현황 ───────────── */
- {
- id: "vendorCount",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="벤더 수" />
- ),
- cell: ({ row }) => {
- const stats = row.original.responseStats
- return stats
- ? (
- <div className="text-center">
- <div className="font-medium">{stats.totalVendors}</div>
- <div className="text-xs text-muted-foreground">
- 활성: {stats.totalVendors - stats.waivedCount}
- </div>
- </div>
- )
- : <span className="text-muted-foreground">-</span>
- },
- },
- {
- id: "responseStatus",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="응답 현황" />
- ),
- cell: ({ row }) => {
- const stats = row.original.responseStats
- return stats
- ? (
- <div className="space-y-1">
- <div className="flex items-center gap-2">
- <div className="flex-1">
- <Progress value={stats.responseRate} className="h-2" />
- </div>
- <span className="text-sm font-medium">
- {stats.responseRate}%
- </span>
- </div>
- <div className="flex gap-2 text-xs">
- <span className="text-green-600">
- 응답: {stats.respondedCount}
- </span>
- <span className="text-orange-600">
- 대기: {stats.pendingCount}
- </span>
- {stats.waivedCount > 0 && (
- <span className="text-gray-500">
- 면제: {stats.waivedCount}
- </span>
- )}
- </div>
- </div>
- )
- : <span className="text-muted-foreground">-</span>
- },
- },
-
- /** ───────────── 액션 ───────────── */
- {
- id: "actions",
- enableHiding: false,
- cell: ({ row }) => {
- const [isAddRevisionOpen, setIsAddRevisionOpen] = React.useState(false)
-
- return (
- <>
- <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-48">
- <DropdownMenuItem onClick={() => onSelectAttachment(row.original)}>
- <MessageSquare className="mr-2 h-4 w-4" />
- 벤더 응답 보기
- </DropdownMenuItem>
- <DropdownMenuItem
- onClick={() => row.original.filePath && window.open(row.original.filePath, "_blank")}
- >
- <Download className="mr-2 h-4 w-4" />
- 다운로드
- </DropdownMenuItem>
- <DropdownMenuSeparator />
- <DropdownMenuItem onClick={() => setIsAddRevisionOpen(true)}>
- <Upload className="mr-2 h-4 w-4" />
- 새 리비전 추가
- </DropdownMenuItem>
- <DropdownMenuItem className="text-red-600">
- 삭제
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
-
- <AddRevisionDialog
- open={isAddRevisionOpen}
- onOpenChange={setIsAddRevisionOpen}
- attachmentId={row.original.id}
- currentRevision={row.original.currentRevision}
- originalFileName={row.original.originalFileName}
- onSuccess={() => window.location.reload()}
- />
- </>
- )
- },
- size: 40,
- },
- ]
-}