summaryrefslogtreecommitdiff
path: root/lib/procurement-rfqs/vendor-response/table/vendor-quotations-table-columns.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/procurement-rfqs/vendor-response/table/vendor-quotations-table-columns.tsx')
-rw-r--r--lib/procurement-rfqs/vendor-response/table/vendor-quotations-table-columns.tsx239
1 files changed, 239 insertions, 0 deletions
diff --git a/lib/procurement-rfqs/vendor-response/table/vendor-quotations-table-columns.tsx b/lib/procurement-rfqs/vendor-response/table/vendor-quotations-table-columns.tsx
new file mode 100644
index 00000000..9eecc72f
--- /dev/null
+++ b/lib/procurement-rfqs/vendor-response/table/vendor-quotations-table-columns.tsx
@@ -0,0 +1,239 @@
+"use client"
+
+import * as React from "react"
+import { type DataTableRowAction } from "@/types/table"
+import { type ColumnDef } from "@tanstack/react-table"
+import { Ellipsis, FileText, Pencil, Edit, Trash2 } from "lucide-react"
+import { formatCurrency, formatDate, formatDateTime } 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 {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip"
+import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
+import Link from "next/link"
+import { ProcurementVendorQuotations } from "@/db/schema"
+import { useRouter } from "next/navigation"
+
+// 상태에 따른 배지 컴포넌트
+function StatusBadge({ status }: { status: string }) {
+ switch (status) {
+ case "Draft":
+ return <Badge variant="outline">초안</Badge>
+ case "Submitted":
+ return <Badge variant="default">제출됨</Badge>
+ case "Revised":
+ return <Badge variant="secondary">수정됨</Badge>
+ case "Rejected":
+ return <Badge variant="destructive">반려됨</Badge>
+ case "Accepted":
+ return <Badge variant="default">승인됨</Badge>
+ default:
+ return <Badge>{status}</Badge>
+ }
+}
+
+interface QuotationWithRfqCode extends ProcurementVendorQuotations {
+ rfqCode?: string;
+ rfq?: {
+ rfqCode?: string;
+ dueDate?: Date | string | null;
+
+ } | null;
+}
+
+type NextRouter = ReturnType<typeof useRouter>;
+
+interface GetColumnsProps {
+ setRowAction: React.Dispatch<
+ React.SetStateAction<DataTableRowAction<QuotationWithRfqCode> | null>
+ >
+ router: NextRouter
+}
+
+/**
+ * tanstack table 컬럼 정의
+ */
+export function getColumns({
+ setRowAction,
+ router,
+}: GetColumnsProps): ColumnDef<QuotationWithRfqCode>[] {
+ // ----------------------------------------------------------------
+ // 1) select 컬럼 (체크박스)
+ // ----------------------------------------------------------------
+ const selectColumn: ColumnDef<QuotationWithRfqCode> = {
+ 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,
+ }
+
+
+ // ----------------------------------------------------------------
+ // 3) 일반 컬럼들
+ // ----------------------------------------------------------------
+
+ // 견적서 액션 컬럼 (아이콘 버튼으로 변경)
+ const quotationActionColumn: ColumnDef<QuotationWithRfqCode> = {
+ id: "actions",
+ enableHiding: false,
+ cell: ({ row }) => {
+ const id = row.original.id
+ const code = row.getValue("quotationCode") as string
+ const tooltipText = `${code} 작성하기`
+
+ return (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger asChild>
+ <Button
+ variant="ghost"
+ size="icon"
+ onClick={() => router.push(`/partners/rfq-all/${id}`)}
+ className="h-8 w-8"
+ >
+ <Edit className="h-4 w-4" />
+ <span className="sr-only">견적서 작성</span>
+ </Button>
+ </TooltipTrigger>
+ <TooltipContent>
+ <p>{tooltipText}</p>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )
+ },
+ size: 50, // 아이콘으로 변경했으므로 크기 줄임
+ }
+
+ // RFQ 번호 컬럼
+ const rfqCodeColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "quotationCode",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="RFQ 번호" />
+ ),
+ cell: ({ row }) => row.original.quotationCode || "-",
+ size: 150,
+ }
+
+ // RFQ 버전 컬럼
+ const quotationVersionColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "quotationVersion",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="RFQ 버전" />
+ ),
+ cell: ({ row }) => row.original.quotationVersion || "-",
+ size: 100,
+ }
+
+ const dueDateColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "dueDate",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="RFQ 마감일" />
+ ),
+ cell: ({ row }) => {
+ // 타입 단언 사용
+ const rfq = row.original.rfq as any;
+ const date = rfq?.dueDate as string | null;
+ return date ? formatDateTime(new Date(date)) : "-";
+ },
+ size: 100,
+ }
+
+ // 상태 컬럼
+ const statusColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "status",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="상태" />
+ ),
+ cell: ({ row }) => <StatusBadge status={row.getValue("status") as string} />,
+ size: 100,
+ }
+
+ // 총액 컬럼
+ const totalPriceColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "totalPrice",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="총액" />
+ ),
+ cell: ({ row }) => {
+ const price = parseFloat(row.getValue("totalPrice") as string || "0")
+ const currency = row.original.currency
+
+ return formatCurrency(price, currency)
+ },
+ size: 120,
+ }
+
+ // 제출일 컬럼
+ const submittedAtColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "submittedAt",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="제출일" />
+ ),
+ cell: ({ row }) => {
+ const date = row.getValue("submittedAt") as string | null
+ return date ? formatDate(new Date(date)) : "-"
+ },
+ size: 120,
+ }
+
+ // 유효기간 컬럼
+ const validUntilColumn: ColumnDef<QuotationWithRfqCode> = {
+ accessorKey: "validUntil",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="유효기간" />
+ ),
+ cell: ({ row }) => {
+ const date = row.getValue("validUntil") as string | null
+ return date ? formatDate(new Date(date)) : "-"
+ },
+ size: 120,
+ }
+
+ // ----------------------------------------------------------------
+ // 4) 최종 컬럼 배열
+ // ----------------------------------------------------------------
+ return [
+ selectColumn,
+ rfqCodeColumn,
+ quotationVersionColumn,
+ dueDateColumn,
+ statusColumn,
+ totalPriceColumn,
+ submittedAtColumn,
+ validUntilColumn,
+ quotationActionColumn // 이름을 변경하고 마지막에 배치
+ ]
+} \ No newline at end of file