From 7a1524ba54f43d0f2a19e4bca2c6a2e0b01c5ef1 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 17 Jun 2025 09:02:32 +0000 Subject: (대표님) 20250617 18시 작업사항 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/b-rfq/initial/initial-rfq-detail-columns.tsx | 358 +++++++++++++---------- 1 file changed, 209 insertions(+), 149 deletions(-) (limited to 'lib/b-rfq/initial/initial-rfq-detail-columns.tsx') diff --git a/lib/b-rfq/initial/initial-rfq-detail-columns.tsx b/lib/b-rfq/initial/initial-rfq-detail-columns.tsx index f7ac0960..02dfd765 100644 --- a/lib/b-rfq/initial/initial-rfq-detail-columns.tsx +++ b/lib/b-rfq/initial/initial-rfq-detail-columns.tsx @@ -3,8 +3,9 @@ import * as React from "react" import { type ColumnDef } from "@tanstack/react-table" +import { type Row } from "@tanstack/react-table" import { - Ellipsis, Building, Calendar, Eye, + Ellipsis, Building, Eye, Edit, Trash, MessageSquare, Settings, CheckCircle2, XCircle } from "lucide-react" @@ -14,17 +15,27 @@ import { Button } from "@/components/ui/button" import { Checkbox } from "@/components/ui/checkbox" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, - DropdownMenuSeparator, DropdownMenuTrigger + DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuShortcut } from "@/components/ui/dropdown-menu" import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { InitialRfqDetailView } from "@/db/schema" + + +// RowAction 타입 정의 +export interface DataTableRowAction { + row: Row + type: "update" | "delete" +} interface GetInitialRfqDetailColumnsProps { onSelectDetail?: (detail: any) => void + setRowAction?: React.Dispatch | null>> } export function getInitialRfqDetailColumns({ - onSelectDetail -}: GetInitialRfqDetailColumnsProps = {}): ColumnDef[] { + onSelectDetail, + setRowAction +}: GetInitialRfqDetailColumnsProps = {}): ColumnDef[] { return [ /** ───────────── 체크박스 ───────────── */ @@ -55,53 +66,6 @@ export function getInitialRfqDetailColumns({ }, /** ───────────── RFQ 정보 ───────────── */ - { - accessorKey: "rfqCode", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - size: 120, - }, - { - accessorKey: "rfqStatus", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const status = row.getValue("rfqStatus") as string - const getStatusColor = (status: string) => { - switch (status) { - case "DRAFT": return "secondary" - case "Doc. Received": return "outline" - case "PIC Assigned": return "default" - case "Doc. Confirmed": return "default" - case "Init. RFQ Sent": return "default" - case "Init. RFQ Answered": return "success" - case "TBE started": return "warning" - case "TBE finished": return "warning" - case "Final RFQ Sent": return "default" - case "Quotation Received": return "success" - case "Vendor Selected": return "success" - default: return "secondary" - } - } - return ( - - {status} - - ) - }, - size: 140 - }, { accessorKey: "initialRfqStatus", header: ({ column }) => ( @@ -111,11 +75,10 @@ export function getInitialRfqDetailColumns({ const status = row.getValue("initialRfqStatus") as string const getInitialStatusColor = (status: string) => { switch (status) { - case "PENDING": return "outline" - case "SENT": return "default" - case "RESPONDED": return "success" - case "EXPIRED": return "destructive" - case "CANCELLED": return "secondary" + case "DRAFT": return "outline" + case "Init. RFQ Sent": return "default" + case "Init. RFQ Answered": return "success" + case "S/L Decline": return "destructive" default: return "secondary" } } @@ -127,6 +90,30 @@ export function getInitialRfqDetailColumns({ }, size: 120 }, + { + accessorKey: "rfqCode", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.getValue("rfqCode") as string} +
+ ), + size: 120, + }, + { + accessorKey: "rfqRevision", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ Rev. {row.getValue("rfqRevision") as number} +
+ ), + size: 120, + }, /** ───────────── 벤더 정보 ───────────── */ { @@ -137,7 +124,8 @@ export function getInitialRfqDetailColumns({ cell: ({ row }) => { const vendorName = row.original.vendorName as string const vendorCode = row.original.vendorCode as string - const vendorCountry = row.original.vendorCountry as string + const vendorType = row.original.vendorCategory as string + const vendorCountry = row.original.vendorCountry === "KR" ? "D":"F" const businessSize = row.original.vendorBusinessSize as string return ( @@ -147,7 +135,7 @@ export function getInitialRfqDetailColumns({
{vendorName}
- {vendorCode} • {vendorCountry} + {vendorCode} • {vendorType} • {vendorCountry}
{businessSize && ( @@ -160,42 +148,67 @@ export function getInitialRfqDetailColumns({ size: 200, }, - /** ───────────── 날짜 정보 ───────────── */ { - accessorKey: "dueDate", + accessorKey: "cpRequestYn", header: ({ column }) => ( - + ), cell: ({ row }) => { - const dueDate = row.getValue("dueDate") as Date - const isOverdue = dueDate && new Date(dueDate) < new Date() - - return dueDate ? ( -
- -
-
{formatDate(dueDate)}
- {isOverdue && ( -
지연
- )} -
-
+ const cpRequest = row.getValue("cpRequestYn") as boolean + return cpRequest ? ( + + Yes + ) : ( - - + - ) }, - size: 120, + size: 60, }, { - accessorKey: "validDate", + accessorKey: "prjectGtcYn", header: ({ column }) => ( - + ), cell: ({ row }) => { - const validDate = row.getValue("validDate") as Date - return validDate ? ( + const projectGtc = row.getValue("prjectGtcYn") as boolean + return projectGtc ? ( + + Yes + + ) : ( + - + ) + }, + size: 100, + }, + { + accessorKey: "gtcYn", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const gtc = row.getValue("gtcYn") as boolean + return gtc ? ( + + Yes + + ) : ( + - + ) + }, + size: 60, + }, + { + accessorKey: "gtcValidDate", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const gtcValidDate = row.getValue("gtcValidDate") as string + return gtcValidDate ? (
- {formatDate(validDate)} + {gtcValidDate}
) : ( - @@ -204,7 +217,42 @@ export function getInitialRfqDetailColumns({ size: 100, }, - /** ───────────── Incoterms ───────────── */ + { + accessorKey: "classification", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const classification = row.getValue("classification") as string + return classification ? ( +
+ {classification} +
+ ) : ( + - + ) + }, + size: 120, + }, + + { + accessorKey: "sparepart", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const sparepart = row.getValue("sparepart") as string + return sparepart ? ( + + {sparepart} + + ) : ( + - + ) + }, + size: 100, + }, + { id: "incoterms", header: ({ column }) => ( @@ -230,84 +278,71 @@ export function getInitialRfqDetailColumns({ size: 120, }, - /** ───────────── 플래그 정보 ───────────── */ + /** ───────────── 날짜 정보 ───────────── */ { - id: "flags", + accessorKey: "validDate", header: ({ column }) => ( - + ), cell: ({ row }) => { - const shortList = row.original.shortList as boolean - const returnYn = row.original.returnYn as boolean - const cpRequestYn = row.original.cpRequestYn as boolean - const prjectGtcYn = row.original.prjectGtcYn as boolean - - return ( -
- {shortList && ( - - - Short List - - )} - {returnYn && ( - - Return - - )} - {cpRequestYn && ( - - CP Request - - )} - {prjectGtcYn && ( - - GTC - - )} + const validDate = row.getValue("validDate") as Date + return validDate ? ( +
+ {formatDate(validDate)}
+ ) : ( + - ) }, - size: 150, + size: 100, }, - - /** ───────────── 분류 정보 ───────────── */ { - id: "classification", + accessorKey: "dueDate", header: ({ column }) => ( - + ), cell: ({ row }) => { - const classification = row.original.classification as string - const sparepart = row.original.sparepart as string + const dueDate = row.getValue("dueDate") as Date + const isOverdue = dueDate && new Date(dueDate) < new Date() - return ( -
- {classification && ( -
- {classification} -
- )} - {sparepart && ( - - {sparepart} - + return dueDate ? ( +
+
{formatDate(dueDate)}
+ {isOverdue && ( +
지연
)}
+ ) : ( + - ) }, size: 120, }, - - /** ───────────── 리비전 정보 ───────────── */ + { + accessorKey: "returnYn", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const returnFlag = row.getValue("returnYn") as boolean + return returnFlag ? ( + + Yes + + ) : ( + - + ) + }, + size: 70, + }, { accessorKey: "returnRevision", header: ({ column }) => ( - + ), cell: ({ row }) => { const revision = row.getValue("returnRevision") as number - return revision ? ( + return revision > 0 ? ( Rev. {revision} @@ -318,6 +353,25 @@ export function getInitialRfqDetailColumns({ size: 80, }, + { + accessorKey: "shortList", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const shortList = row.getValue("shortList") as boolean + return shortList ? ( + + + Yes + + ) : ( + - + ) + }, + size: 90, + }, + /** ───────────── 등록/수정 정보 ───────────── */ { accessorKey: "createdAt", @@ -333,7 +387,7 @@ export function getInitialRfqDetailColumns({
{formatDate(created)}
{updated && new Date(updated) > new Date(created) && (
- 수정: {formatDate(updated)} + 수정: {formatDate(updated, "KR")}
)}
@@ -346,7 +400,7 @@ export function getInitialRfqDetailColumns({ { id: "actions", enableHiding: false, - cell: ({ row }) => { + cell: function Cell({ row }) { return ( @@ -359,23 +413,29 @@ export function getInitialRfqDetailColumns({ - onSelectDetail?.(row.original)}> - - 상세 보기 - 벤더 응답 보기 - - - 설정 수정 - - - - 삭제 - + {setRowAction && ( + <> + setRowAction({ row, type: "update" })} + > + + 수정 + + setRowAction({ row, type: "delete" })} + > + + 삭제 + ⌘⌫ + + + )} + ) -- cgit v1.2.3