diff options
Diffstat (limited to 'lib/vendor-rfq-response/vendor-rfq-table/rfqs-table-columns.tsx')
| -rw-r--r-- | lib/vendor-rfq-response/vendor-rfq-table/rfqs-table-columns.tsx | 435 |
1 files changed, 0 insertions, 435 deletions
diff --git a/lib/vendor-rfq-response/vendor-rfq-table/rfqs-table-columns.tsx b/lib/vendor-rfq-response/vendor-rfq-table/rfqs-table-columns.tsx deleted file mode 100644 index 70b91176..00000000 --- a/lib/vendor-rfq-response/vendor-rfq-table/rfqs-table-columns.tsx +++ /dev/null @@ -1,435 +0,0 @@ -"use client" - -import * as React from "react" -import { useRouter } from "next/navigation" -import { ColumnDef } from "@tanstack/react-table" -import { - Ellipsis, - MessageSquare, - Package, - Paperclip, -} from "lucide-react" -import { toast } from "sonner" - -import { Button } from "@/components/ui/button" -import { Checkbox } from "@/components/ui/checkbox" -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger -} from "@/components/ui/dropdown-menu" -import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" -import { Badge } from "@/components/ui/badge" - -import { getErrorMessage } from "@/lib/handle-error" -import { formatDate, formatDateTime } from "@/lib/utils" -import { modifyRfqVendor } from "../../rfqs/service" -import type { RfqWithAll } from "../types" -import type { DataTableRowAction } from "@/types/table" - -type NextRouter = ReturnType<typeof useRouter> - -interface GetColumnsProps { - setRowAction: React.Dispatch< - React.SetStateAction<DataTableRowAction<RfqWithAll> | null> - > - router: NextRouter - openAttachmentsSheet: (rfqId: number) => void - openCommentSheet: (rfqId: number) => void -} - -/** - * tanstack table 컬럼 정의 (Nested Header) - */ -export function getColumns({ - setRowAction, - router, - openAttachmentsSheet, - openCommentSheet, -}: GetColumnsProps): ColumnDef<RfqWithAll>[] { - // 1) 체크박스(Select) 컬럼 - const selectColumn: ColumnDef<RfqWithAll> = { - id: "select", - header: ({ table }) => ( - <Checkbox - checked={ - table.getIsAllPageRowsSelected() || - (table.getIsSomePageRowsSelected() && "indeterminate") - } - onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - <Checkbox - checked={row.getIsSelected()} - onCheckedChange={(value) => row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - size: 40, - enableSorting: false, - enableHiding: false, - } - - // 2) Actions (Dropdown) - const actionsColumn: ColumnDef<RfqWithAll> = { - id: "actions", - enableHiding: false, - cell: ({ row }) => { - const [isUpdatePending, startUpdateTransition] = React.useTransition() - - return ( - <DropdownMenu> - <DropdownMenuTrigger asChild> - <Button variant="ghost" size="icon"> - <Ellipsis className="h-4 w-4" aria-hidden="true" /> - </Button> - </DropdownMenuTrigger> - <DropdownMenuContent align="end" className="w-56"> - <DropdownMenuSub> - <DropdownMenuSubTrigger>RFQ Response</DropdownMenuSubTrigger> - <DropdownMenuSubContent> - <DropdownMenuRadioGroup - value={row.original.responseStatus} - onValueChange={(value) => { - startUpdateTransition(async () => { - let newStatus: - | "ACCEPTED" - | "DECLINED" - | "REVIEWING" - - switch (value) { - case "ACCEPTED": - newStatus = "ACCEPTED" - break - case "DECLINED": - newStatus = "DECLINED" - break - default: - newStatus = "REVIEWING" - } - - await toast.promise( - modifyRfqVendor({ - id: row.original.responseId, - status: newStatus, - }), - { - loading: "Updating response status...", - success: "Response status updated", - error: (err) => getErrorMessage(err), - } - ) - }) - }} - > - {[ - { value: "ACCEPTED", label: "Accept RFQ" }, - { value: "DECLINED", label: "Decline RFQ" }, - ].map((rep) => ( - <DropdownMenuRadioItem - key={rep.value} - value={rep.value} - className="capitalize" - disabled={isUpdatePending} - > - {rep.label} - </DropdownMenuRadioItem> - ))} - </DropdownMenuRadioGroup> - </DropdownMenuSubContent> - </DropdownMenuSub> - {/* <DropdownMenuItem - onClick={() => { - router.push(`/vendor/rfqs/${row.original.rfqId}`) - }} - > - View Details - </DropdownMenuItem> */} - {/* <DropdownMenuItem onClick={() => openAttachmentsSheet(row.original.rfqId)}> - View Attachments - </DropdownMenuItem> - <DropdownMenuItem onClick={() => openCommentSheet(row.original.rfqId)}> - View Comments - </DropdownMenuItem> - <DropdownMenuItem onClick={() => setRowAction({ row, type: "items" })}> - View Items - </DropdownMenuItem> */} - </DropdownMenuContent> - </DropdownMenu> - ) - }, - size: 40, - } - - // 3) RFQ Code 컬럼 - const rfqCodeColumn: ColumnDef<RfqWithAll> = { - id: "rfqCode", - accessorKey: "rfqCode", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="RFQ Code" /> - ), - // cell: ({ row }) => { - // return ( - // <Button - // variant="link" - // className="p-0 h-auto font-medium" - // onClick={() => router.push(`/vendor/rfqs/${row.original.rfqId}`)} - // > - // {row.original.rfqCode} - // </Button> - // ) - // }, - cell: ({ row }) => row.original.rfqCode || "-", - size: 150, - } - - const rfqTypeColumn: ColumnDef<RfqWithAll> = { - id: "rfqType", - accessorKey: "rfqType", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="RFQ Type" /> - ), - cell: ({ row }) => row.original.rfqType || "-", - size: 150, - } - - - // 4) 응답 상태 컬럼 - const responseStatusColumn: ColumnDef<RfqWithAll> = { - id: "responseStatus", - accessorKey: "responseStatus", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Response Status" /> - ), - cell: ({ row }) => { - const status = row.original.responseStatus; - let variant: "default" | "secondary" | "destructive" | "outline"; - - switch (status) { - case "REVIEWING": - variant = "default"; - break; - case "ACCEPTED": - variant = "secondary"; - break; - case "DECLINED": - variant = "destructive"; - break; - default: - variant = "outline"; - } - - return <Badge variant={variant}>{status}</Badge>; - }, - size: 150, - } - - // 5) 프로젝트 이름 컬럼 - const projectNameColumn: ColumnDef<RfqWithAll> = { - id: "projectName", - accessorKey: "projectName", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Project" /> - ), - cell: ({ row }) => row.original.projectName || "-", - size: 150, - } - - // 6) RFQ Description 컬럼 - const descriptionColumn: ColumnDef<RfqWithAll> = { - id: "rfqDescription", - accessorKey: "rfqDescription", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Description" /> - ), - cell: ({ row }) => row.original.rfqDescription || "-", - size: 200, - } - - // 7) Due Date 컬럼 - const dueDateColumn: ColumnDef<RfqWithAll> = { - id: "rfqDueDate", - accessorKey: "rfqDueDate", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Due Date" /> - ), - cell: ({ row }) => { - const date = row.original.rfqDueDate; - return date ? formatDate(date) : "-"; - }, - size: 120, - } - - // 8) Last Updated 컬럼 - const updatedAtColumn: ColumnDef<RfqWithAll> = { - id: "respondedAt", - accessorKey: "respondedAt", - enableResizing: true, - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Last Updated" /> - ), - cell: ({ row }) => { - const date = row.original.respondedAt; - return date ? formatDateTime(date) : "-"; - }, - size: 150, - } - - // 9) Items 컬럼 - 뱃지로 아이템 개수 표시 - const itemsColumn: ColumnDef<RfqWithAll> = { - id: "items", - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Items" /> - ), - cell: ({ row }) => { - const rfq = row.original - const count = rfq.items?.length ?? 0 - - function handleClick() { - setRowAction({ row, type: "items" }) - } - - return ( - <Button - variant="ghost" - size="sm" - className="relative h-8 w-8 p-0 group" - onClick={handleClick} - aria-label={count > 0 ? `View ${count} items` : "No items"} - > - <Package className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" /> - {count > 0 && ( - <Badge - variant="secondary" - className="pointer-events-none absolute -top-1 -right-1 h-4 min-w-[1rem] p-0 text-[0.625rem] leading-none flex items-center justify-center" - > - {count} - </Badge> - )} - - <span className="sr-only"> - {count > 0 ? `${count} Items` : "No Items"} - </span> - </Button> - ) - }, - enableSorting: false, - maxSize: 80, - } - - // 10) Attachments 컬럼 - 뱃지로 파일 개수 표시 - const attachmentsColumn: ColumnDef<RfqWithAll> = { - id: "attachments", - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Attachments" /> - ), - cell: ({ row }) => { - const attachCount = row.original.attachments?.length ?? 0 - - function handleClick(e: React.MouseEvent<HTMLButtonElement>) { - e.preventDefault() - openAttachmentsSheet(row.original.rfqId) - } - - return ( - <Button - variant="ghost" - size="sm" - className="relative h-8 w-8 p-0 group" - onClick={handleClick} - aria-label={ - attachCount > 0 ? `View ${attachCount} files` : "No files" - } - > - <Paperclip className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" /> - {attachCount > 0 && ( - <Badge - variant="secondary" - className="pointer-events-none absolute -top-1 -right-1 h-4 min-w-[1rem] p-0 text-[0.625rem] leading-none flex items-center justify-center" - > - {attachCount} - </Badge> - )} - <span className="sr-only"> - {attachCount > 0 ? `${attachCount} Files` : "No Files"} - </span> - </Button> - ) - }, - enableSorting: false, - maxSize: 80, - } - - // 11) Comments 컬럼 - 뱃지로 댓글 개수 표시 - const commentsColumn: ColumnDef<RfqWithAll> = { - id: "comments", - header: ({ column }) => ( - <DataTableColumnHeaderSimple column={column} title="Comments" /> - ), - cell: ({ row }) => { - const commCount = row.original.comments?.length ?? 0 - - function handleClick() { - setRowAction({ row, type: "comments" }) - openCommentSheet(row.original.rfqId) - } - - return ( - <Button - variant="ghost" - size="sm" - className="relative h-8 w-8 p-0 group" - onClick={handleClick} - aria-label={ - commCount > 0 ? `View ${commCount} comments` : "No comments" - } - > - <MessageSquare className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" /> - {commCount > 0 && ( - <Badge - variant="secondary" - className="pointer-events-none absolute -top-1 -right-1 h-4 min-w-[1rem] p-0 text-[0.625rem] leading-none flex items-center justify-center" - > - {commCount} - </Badge> - )} - <span className="sr-only"> - {commCount > 0 ? `${commCount} Comments` : "No Comments"} - </span> - </Button> - ) - }, - enableSorting: false, - maxSize: 80, - } - - // 최종 컬럼 구성 - TBE/CBE 관련 컬럼 제외 - return [ - selectColumn, - rfqCodeColumn, - rfqTypeColumn, - responseStatusColumn, - projectNameColumn, - descriptionColumn, - dueDateColumn, - itemsColumn, - attachmentsColumn, - commentsColumn, - updatedAtColumn, - actionsColumn, - ] -}
\ No newline at end of file |
