From 7a1524ba54f43d0f2a19e4bca2c6a2e0b01c5ef1 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
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<TData> {
+  row: Row<TData>
+  type: "update" | "delete"
+}
 
 interface GetInitialRfqDetailColumnsProps {
   onSelectDetail?: (detail: any) => void
+  setRowAction?: React.Dispatch<React.SetStateAction<DataTableRowAction<InitialRfqDetailView> | null>>
 }
 
 export function getInitialRfqDetailColumns({
-  onSelectDetail
-}: GetInitialRfqDetailColumnsProps = {}): ColumnDef<any>[] {
+  onSelectDetail,
+  setRowAction
+}: GetInitialRfqDetailColumnsProps = {}): ColumnDef<InitialRfqDetailView>[] {
 
   return [
     /** ───────────── 체크박스 ───────────── */
@@ -55,53 +66,6 @@ export function getInitialRfqDetailColumns({
     },
 
     /** ───────────── RFQ 정보 ───────────── */
-    {
-      accessorKey: "rfqCode",
-      header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="RFQ 코드" />
-      ),
-      cell: ({ row }) => (
-        <Button
-          variant="link"
-          className="p-0 h-auto font-medium text-blue-600 hover:text-blue-800"
-          onClick={() => onSelectDetail?.(row.original)}
-        >
-          {row.getValue("rfqCode") as string}
-        </Button>
-      ),
-      size: 120,
-    },
-    {
-      accessorKey: "rfqStatus",
-      header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="RFQ 상태" />
-      ),
-      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 (
-          <Badge variant={getStatusColor(status) as any}>
-            {status}
-          </Badge>
-        )
-      },
-      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 }) => (
+        <DataTableColumnHeaderSimple column={column} title="RFQ 코드" />
+      ),
+      cell: ({ row }) => (
+        <div className="text-sm">
+          {row.getValue("rfqCode") as string}
+        </div>
+      ),
+      size: 120,
+    },
+    {
+      accessorKey: "rfqRevision",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="RFQ 리비전" />
+      ),
+      cell: ({ row }) => (
+        <div className="text-sm">
+          Rev. {row.getValue("rfqRevision") as number}
+        </div>
+      ),
+      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({
               <div className="font-medium">{vendorName}</div>
             </div>
             <div className="text-sm text-muted-foreground">
-              {vendorCode} • {vendorCountry}
+              {vendorCode} • {vendorType} • {vendorCountry}
             </div>
             {businessSize && (
               <Badge variant="outline" className="text-xs">
@@ -160,42 +148,67 @@ export function getInitialRfqDetailColumns({
       size: 200,
     },
 
-    /** ───────────── 날짜 정보 ───────────── */
     {
-      accessorKey: "dueDate",
+      accessorKey: "cpRequestYn",
       header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="마감일" />
+        <DataTableColumnHeaderSimple column={column} title="CP" />
       ),
       cell: ({ row }) => {
-        const dueDate = row.getValue("dueDate") as Date
-        const isOverdue = dueDate && new Date(dueDate) < new Date()
-        
-        return dueDate ? (
-          <div className={`flex items-center gap-2 ${isOverdue ? 'text-red-600' : ''}`}>
-            <Calendar className="h-4 w-4" />
-            <div>
-              <div className="font-medium">{formatDate(dueDate)}</div>
-              {isOverdue && (
-                <div className="text-xs text-red-600">지연</div>
-              )}
-            </div>
-          </div>
+        const cpRequest = row.getValue("cpRequestYn") as boolean
+        return cpRequest ? (
+          <Badge variant="outline" className="text-xs">
+            Yes
+          </Badge>
         ) : (
-          <span className="text-muted-foreground">-</span>
+          <span className="text-muted-foreground text-xs">-</span>
         )
       },
-      size: 120,
+      size: 60,
     },
     {
-      accessorKey: "validDate",
+      accessorKey: "prjectGtcYn",
       header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="유효일" />
+        <DataTableColumnHeaderSimple column={column} title="Project GTC" />
       ),
       cell: ({ row }) => {
-        const validDate = row.getValue("validDate") as Date
-        return validDate ? (
+        const projectGtc = row.getValue("prjectGtcYn") as boolean
+        return projectGtc ? (
+          <Badge variant="outline" className="text-xs">
+            Yes
+          </Badge>
+        ) : (
+          <span className="text-muted-foreground text-xs">-</span>
+        )
+      },
+      size: 100,
+    },
+    {
+      accessorKey: "gtcYn",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="GTC" />
+      ),
+      cell: ({ row }) => {
+        const gtc = row.getValue("gtcYn") as boolean
+        return gtc ? (
+          <Badge variant="outline" className="text-xs">
+            Yes
+          </Badge>
+        ) : (
+          <span className="text-muted-foreground text-xs">-</span>
+        )
+      },
+      size: 60,
+    },
+    {
+      accessorKey: "gtcValidDate",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="GTC 유효일" />
+      ),
+      cell: ({ row }) => {
+        const gtcValidDate = row.getValue("gtcValidDate") as string
+        return gtcValidDate ? (
           <div className="text-sm">
-            {formatDate(validDate)}
+            {gtcValidDate}
           </div>
         ) : (
           <span className="text-muted-foreground">-</span>
@@ -204,7 +217,42 @@ export function getInitialRfqDetailColumns({
       size: 100,
     },
 
-    /** ───────────── Incoterms ───────────── */
+    {
+      accessorKey: "classification",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="선급" />
+      ),
+      cell: ({ row }) => {
+        const classification = row.getValue("classification") as string
+        return classification ? (
+          <div className="text-sm font-medium max-w-[120px] truncate" title={classification}>
+            {classification}
+          </div>
+        ) : (
+          <span className="text-muted-foreground">-</span>
+        )
+      },
+      size: 120,
+    },
+
+    {
+      accessorKey: "sparepart",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="Spare Part" />
+      ),
+      cell: ({ row }) => {
+        const sparepart = row.getValue("sparepart") as string
+        return sparepart ? (
+          <Badge variant="outline" className="text-xs">
+            {sparepart}
+          </Badge>
+        ) : (
+          <span className="text-muted-foreground">-</span>
+        )
+      },
+      size: 100,
+    },
+  
     {
       id: "incoterms",
       header: ({ column }) => (
@@ -230,84 +278,71 @@ export function getInitialRfqDetailColumns({
       size: 120,
     },
 
-    /** ───────────── 플래그 정보 ───────────── */
+    /** ───────────── 날짜 정보 ───────────── */
     {
-      id: "flags",
+      accessorKey: "validDate",
       header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="플래그" />
+        <DataTableColumnHeaderSimple column={column} title="유효일" />
       ),
       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 (
-          <div className="flex flex-wrap gap-1">
-            {shortList && (
-              <Badge variant="secondary" className="text-xs">
-                <CheckCircle2 className="h-3 w-3 mr-1" />
-                Short List
-              </Badge>
-            )}
-            {returnYn && (
-              <Badge variant="outline" className="text-xs">
-                Return
-              </Badge>
-            )}
-            {cpRequestYn && (
-              <Badge variant="outline" className="text-xs">
-                CP Request
-              </Badge>
-            )}
-            {prjectGtcYn && (
-              <Badge variant="outline" className="text-xs">
-                GTC
-              </Badge>
-            )}
+        const validDate = row.getValue("validDate") as Date
+        return validDate ? (
+          <div className="text-sm">
+            {formatDate(validDate)}
           </div>
+        ) : (
+          <span className="text-muted-foreground">-</span>
         )
       },
-      size: 150,
+      size: 100,
     },
-
-    /** ───────────── 분류 정보 ───────────── */
     {
-      id: "classification",
+      accessorKey: "dueDate",
       header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="분류" />
+        <DataTableColumnHeaderSimple column={column} title="마감일" />
       ),
       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 (
-          <div className="space-y-1">
-            {classification && (
-              <div className="text-sm font-medium max-w-[120px] truncate" title={classification}>
-                {classification}
-              </div>
-            )}
-            {sparepart && (
-              <Badge variant="outline" className="text-xs">
-                {sparepart}
-              </Badge>
+        return dueDate ? (
+          <div className={`${isOverdue ? 'text-red-600' : ''}`}>
+            <div className="font-medium">{formatDate(dueDate)}</div>
+            {isOverdue && (
+              <div className="text-xs text-red-600">지연</div>
             )}
           </div>
+        ) : (
+          <span className="text-muted-foreground">-</span>
         )
       },
       size: 120,
     },
-
-    /** ───────────── 리비전 정보 ───────────── */
+    {
+      accessorKey: "returnYn",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="RFQ 회신여부" />
+      ),
+      cell: ({ row }) => {
+        const returnFlag = row.getValue("returnYn") as boolean
+        return returnFlag ? (
+          <Badge variant="outline" className="text-xs">
+            Yes
+          </Badge>
+        ) : (
+          <span className="text-muted-foreground text-xs">-</span>
+        )
+      },
+      size: 70,
+    },
     {
       accessorKey: "returnRevision",
       header: ({ column }) => (
-        <DataTableColumnHeaderSimple column={column} title="리비전" />
+        <DataTableColumnHeaderSimple column={column} title="회신 리비전" />
       ),
       cell: ({ row }) => {
         const revision = row.getValue("returnRevision") as number
-        return revision ? (
+        return revision > 0 ? (
           <Badge variant="outline">
             Rev. {revision}
           </Badge>
@@ -318,6 +353,25 @@ export function getInitialRfqDetailColumns({
       size: 80,
     },
 
+    {
+      accessorKey: "shortList",
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title="Short List" />
+      ),
+      cell: ({ row }) => {
+        const shortList = row.getValue("shortList") as boolean
+        return shortList ? (
+          <Badge variant="secondary" className="text-xs">
+            <CheckCircle2 className="h-3 w-3 mr-1" />
+            Yes
+          </Badge>
+        ) : (
+          <span className="text-muted-foreground text-xs">-</span>
+        )
+      },
+      size: 90,
+    },
+
     /** ───────────── 등록/수정 정보 ───────────── */
     {
       accessorKey: "createdAt",
@@ -333,7 +387,7 @@ export function getInitialRfqDetailColumns({
             <div className="text-sm">{formatDate(created)}</div>
             {updated && new Date(updated) > new Date(created) && (
               <div className="text-xs text-blue-600">
-                수정: {formatDate(updated)}
+                수정: {formatDate(updated, "KR")}
               </div>
             )}
           </div>
@@ -346,7 +400,7 @@ export function getInitialRfqDetailColumns({
     {
       id: "actions",
       enableHiding: false,
-      cell: ({ row }) => {
+      cell: function Cell({ row }) {
         return (
           <DropdownMenu>
             <DropdownMenuTrigger asChild>
@@ -359,23 +413,29 @@ export function getInitialRfqDetailColumns({
               </Button>
             </DropdownMenuTrigger>
             <DropdownMenuContent align="end" className="w-48">
-              <DropdownMenuItem onClick={() => onSelectDetail?.(row.original)}>
-                <Eye className="mr-2 h-4 w-4" />
-                상세 보기
-              </DropdownMenuItem>
               <DropdownMenuItem>
                 <MessageSquare className="mr-2 h-4 w-4" />
                 벤더 응답 보기
               </DropdownMenuItem>
               <DropdownMenuSeparator />
-              <DropdownMenuItem>
-                <Settings className="mr-2 h-4 w-4" />
-                설정 수정
-              </DropdownMenuItem>
-              <DropdownMenuItem className="text-red-600">
-                <XCircle className="mr-2 h-4 w-4" />
-                삭제
-              </DropdownMenuItem>
+              {setRowAction && (
+                <>
+                  <DropdownMenuItem
+                    onSelect={() => setRowAction({ row, type: "update" })}
+                  >
+                    <Edit className="mr-2 h-4 w-4" />
+                    수정
+                  </DropdownMenuItem>
+                  <DropdownMenuItem
+                    onSelect={() => setRowAction({ row, type: "delete" })}
+                  >
+                    <Trash className="mr-2 h-4 w-4" />
+                    삭제
+                    <DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
+                  </DropdownMenuItem>
+                </>
+              )}
+
             </DropdownMenuContent>
           </DropdownMenu>
         )
-- 
cgit v1.2.3

