From 74843fe598702a9a55f914f2d2d291368a5abb13 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Wed, 1 Oct 2025 10:31:23 +0000
Subject: (대표님) dolce 수정, spreadjs 수정 등
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../ship/enhanced-documents-table.tsx              | 184 +++++++++++++++++++--
 1 file changed, 174 insertions(+), 10 deletions(-)

(limited to 'lib/vendor-document-list/ship/enhanced-documents-table.tsx')

diff --git a/lib/vendor-document-list/ship/enhanced-documents-table.tsx b/lib/vendor-document-list/ship/enhanced-documents-table.tsx
index 24ab42fb..cae0fe06 100644
--- a/lib/vendor-document-list/ship/enhanced-documents-table.tsx
+++ b/lib/vendor-document-list/ship/enhanced-documents-table.tsx
@@ -1,4 +1,4 @@
-// simplified-documents-table.tsx - 최적화된 버전
+// simplified-documents-table.tsx - Project Code 필터 기능 추가
 "use client"
 
 import React from "react"
@@ -13,7 +13,8 @@ import { getUserVendorDocuments, getUserVendorDocumentStats } from "@/lib/vendor
 import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
 import { toast } from "sonner"
 import { Badge } from "@/components/ui/badge"
-import { FileText } from "lucide-react"
+import { Button } from "@/components/ui/button"
+import { FileText, FileInput, FileOutput, FolderOpen, Building2 } from "lucide-react"
 
 import { Label } from "@/components/ui/label"
 import { DataTable } from "@/components/data-table/data-table"
@@ -21,6 +22,15 @@ import { SimplifiedDocumentsView } from "@/db/schema"
 import { getSimplifiedDocumentColumns } from "./enhanced-doc-table-columns"
 import { EnhancedDocTableToolbarActions } from "./enhanced-doc-table-toolbar-actions"
 
+// 🔥 Project Code 필터를 위한 Select 컴포넌트 import 추가
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+
 // DrawingKind별 설명 매핑
 const DRAWING_KIND_INFO = {
   B3: {
@@ -60,17 +70,61 @@ export function SimplifiedDocumentsTable({
   const { data, pageCount, total, drawingKind, vendorInfo } = React.useMemo(() => documentResult, [documentResult])
   const { stats, totalDocuments, primaryDrawingKind } = React.useMemo(() => statsResult, [statsResult])
 
+  // 🔥 B4 필터 상태 추가
+  const [b4FilterType, setB4FilterType] = React.useState<'all' | 'gtt_deliverable' | 'shi_input'>('all')
+
+  // 🔥 Project Code 필터 상태 추가
+  const [selectedProjectCode, setSelectedProjectCode] = React.useState<string>('all')
+
+  // 🔥 고유한 Project Code 목록 추출 및 카운트 메모이제이션
+  const projectCodeStats = React.useMemo(() => {
+    const projectMap = new Map<string, number>()
+    
+    data.forEach(doc => {
+      const projectCode = doc.projectCode || 'Unknown'
+      projectMap.set(projectCode, (projectMap.get(projectCode) || 0) + 1)
+    })
+
+    // 정렬된 배열로 변환 (프로젝트 코드 알파벳순)
+    return Array.from(projectMap.entries())
+      .sort((a, b) => a[0].localeCompare(b[0]))
+      .map(([code, count]) => ({ code, count }))
+  }, [data])
+
   // 🔥 데이터 로드 콜백을 useCallback으로 최적화
   const handleDataLoaded = React.useCallback((loadedData: SimplifiedDocumentsView[]) => {
     onDataLoaded?.(loadedData)
   }, [onDataLoaded])
 
-  // 🔥 데이터가 로드되면 콜백 호출 (의존성 최적화)
+  // 🔥 B4 및 Project Code 필터링된 데이터 메모이제이션
+  const filteredData = React.useMemo(() => {
+    let result = data
+
+    // B4 필터 적용
+    if (b4FilterType !== 'all') {
+      if (b4FilterType === 'gtt_deliverable') {
+        result = result.filter(doc => doc.drawingMoveGbn === '도면입수')
+      } else if (b4FilterType === 'shi_input') {
+        result = result.filter(doc => doc.drawingMoveGbn === '도면제출')
+      }
+    }
+
+    // Project Code 필터 적용
+    if (selectedProjectCode !== 'all') {
+      result = result.filter(doc => 
+        (doc.projectCode || 'Unknown') === selectedProjectCode
+      )
+    }
+
+    return result
+  }, [data, b4FilterType, selectedProjectCode])
+
+  // 🔥 데이터가 로드되면 콜백 호출 (필터링된 데이터 사용)
   React.useEffect(() => {
-    if (data && handleDataLoaded) {
-      handleDataLoaded(data)
+    if (filteredData && handleDataLoaded) {
+      handleDataLoaded(filteredData)
     }
-  }, [data, handleDataLoaded])
+  }, [filteredData, handleDataLoaded])
 
   // 🔥 상태들을 안정적으로 관리
   const [rowAction, setRowAction] = React.useState<DataTableRowAction<SimplifiedDocumentsView> | null>(null)
@@ -81,7 +135,7 @@ export function SimplifiedDocumentsTable({
     () => getSimplifiedDocumentColumns({ 
       setRowAction,
     }),
-    [] // setRowAction은 항상 동일한 함수이므로 의존성에서 제외
+    []
   )
 
   // 🔥 필터 필드들을 메모이제이션
@@ -238,7 +292,7 @@ export function SimplifiedDocumentsTable({
   const getRowId = React.useCallback((originalRow: SimplifiedDocumentsView) => String(originalRow.documentId), [])
 
   const { table } = useDataTable({
-    data,
+    data: filteredData,
     columns,
     pageCount,
     enablePinning: true,
@@ -260,6 +314,21 @@ export function SimplifiedDocumentsTable({
     return activeDrawingKind ? DRAWING_KIND_INFO[activeDrawingKind] : null
   }, [activeDrawingKind])
 
+  // 🔥 B4 문서 통계 계산
+  const b4Stats = React.useMemo(() => {
+    if (!hasB4Documents) return null
+    
+    const gttDeliverableCount = data.filter(doc => 
+      doc.drawingKind === 'B4' && doc.drawingMoveGbn === '도면입수'
+    ).length
+    
+    const shiInputCount = data.filter(doc => 
+      doc.drawingKind === 'B4' && doc.drawingMoveGbn === '도면제출'
+    ).length
+    
+    return { gttDeliverableCount, shiInputCount }
+  }, [data, hasB4Documents])
+
   return (
     <div className="w-full space-y-4">
       {/* DrawingKind 정보 간단 표시 */}
@@ -270,12 +339,107 @@ export function SimplifiedDocumentsTable({
           </div>
           <div className="flex items-center gap-2">
             <Badge variant="outline">
-              {total} documents
+              {filteredData.length} documents
             </Badge>
           </div>
         </div>
       )}
 
+      {/* 🔥 필터 섹션 - Project Code 필터와 B4 필터를 함께 배치 */}
+      <div className="space-y-3">
+        {/* Project Code 필터 드롭다운 */}
+        <div className="flex items-center gap-3 p-4 bg-muted/30 rounded-lg">
+          <div className="flex items-center gap-2">
+            <Building2 className="h-4 w-4 text-muted-foreground" />
+            <Label className="text-sm font-medium">Project:</Label>
+          </div>
+          <Select
+            value={selectedProjectCode}
+            onValueChange={setSelectedProjectCode}
+          >
+            <SelectTrigger className="w-[200px]">
+              <SelectValue placeholder="Select a project" />
+            </SelectTrigger>
+            <SelectContent>
+              <SelectItem value="all">
+                <div className="flex items-center justify-between w-full">
+                  <span>All Projects</span>
+                  <Badge variant="secondary" className="ml-2">
+                    {data.length}
+                  </Badge>
+                </div>
+              </SelectItem>
+              {projectCodeStats.map(({ code, count }) => (
+                <SelectItem key={code} value={code}>
+                  <div className="flex items-center justify-between w-full">
+                    <span className="font-mono">{code}</span>
+                    <Badge variant="secondary" className="ml-2">
+                      {count}
+                    </Badge>
+                  </div>
+                </SelectItem>
+              ))}
+            </SelectContent>
+          </Select>
+          
+          {selectedProjectCode !== 'all' && (
+            <Button
+              variant="ghost"
+              size="sm"
+              onClick={() => setSelectedProjectCode('all')}
+              className="h-8"
+            >
+              Clear filter
+            </Button>
+          )}
+        </div>
+
+        {/* B4 필터 버튼 - 기존 코드 유지 */}
+        {hasB4Documents && b4Stats && (
+          <div className="flex items-center gap-2 p-4 bg-muted/50 rounded-lg">
+            <Label className="text-sm font-medium">Document Type:</Label>
+            <div className="flex gap-2">
+              <Button
+                variant={b4FilterType === 'all' ? 'default' : 'outline'}
+                size="sm"
+                onClick={() => setB4FilterType('all')}
+                className="gap-2"
+              >
+                <FileText className="h-4 w-4" />
+                All
+                <Badge variant="secondary" className="ml-1">
+                  {b4Stats.gttDeliverableCount + b4Stats.shiInputCount}
+                </Badge>
+              </Button>
+              <Button
+                variant={b4FilterType === 'gtt_deliverable' ? 'default' : 'outline'}
+                size="sm"
+                onClick={() => setB4FilterType('gtt_deliverable')}
+                className="gap-2"
+              >
+                <FileInput className="h-4 w-4" />
+                GTT Deliverable
+                <Badge variant="secondary" className="ml-1">
+                  {b4Stats.gttDeliverableCount}
+                </Badge>
+              </Button>
+              <Button
+                variant={b4FilterType === 'shi_input' ? 'default' : 'outline'}
+                size="sm"
+                onClick={() => setB4FilterType('shi_input')}
+                className="gap-2"
+              >
+                <FileOutput className="h-4 w-4" />
+                SHI Input Document
+                <Badge variant="secondary" className="ml-1">
+                  {b4Stats.shiInputCount}
+                </Badge>
+              </Button>
+            </div>
+          </div>
+        )}
+      </div>
+
       {/* 테이블 */}
       <div className="overflow-x-auto">
         <DataTable table={table} compact>
@@ -287,7 +451,7 @@ export function SimplifiedDocumentsTable({
             <EnhancedDocTableToolbarActions
               table={table}
               projectType="ship"
-              b4={hasB4Documents}
+              b4={hasB4Documents && b4FilterType === 'gtt_deliverable'}
             />
           </DataTableAdvancedToolbar>
         </DataTable>
-- 
cgit v1.2.3

