From 1a8bf9c1c98454bd0e961b84d14299155ad67e7f Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Tue, 18 Nov 2025 12:15:43 +0900
Subject: (김준회) swp: 그룹핑 로직 수정요청사항 반영, 대용량 파일업로드
 formidable 사용한 스트리밍 방식으로 오류 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/swp/table/swp-table.tsx | 64 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 2 deletions(-)

(limited to 'lib/swp/table/swp-table.tsx')

diff --git a/lib/swp/table/swp-table.tsx b/lib/swp/table/swp-table.tsx
index 21a1c775..b6c3558b 100644
--- a/lib/swp/table/swp-table.tsx
+++ b/lib/swp/table/swp-table.tsx
@@ -1,6 +1,6 @@
 "use client";
 
-import React, { useState } from "react";
+import React, { useMemo, useState } from "react";
 import {
   useReactTable,
   getCoreRowModel,
@@ -14,6 +14,7 @@ import {
   TableHeader,
   TableRow,
 } from "@/components/ui/table";
+import { Button } from "@/components/ui/button";
 import { swpDocumentColumns } from "./swp-table-columns";
 import { SwpDocumentDetailDialog } from "./swp-document-detail-dialog";
 import type { DocumentListItem } from "@/lib/swp/document-service";
@@ -25,6 +26,12 @@ interface SwpTableProps {
   userId: string;
 }
 
+// Status 집계 타입
+interface StatusCount {
+  status: string;
+  count: number;
+}
+
 export function SwpTable({
   documents,
   projNo,
@@ -33,9 +40,39 @@ export function SwpTable({
 }: SwpTableProps) {
   const [dialogOpen, setDialogOpen] = useState(false);
   const [selectedDocument, setSelectedDocument] = useState<DocumentListItem | null>(null);
+  const [selectedStatus, setSelectedStatus] = useState<string | null>(null);
+
+  // Status 집계
+  const statusCounts = useMemo(() => {
+    const statusMap = new Map<string, number>();
+    
+    documents.forEach((doc) => {
+      const status = doc.LTST_ACTV_STAT || "UNKNOWN";
+      statusMap.set(status, (statusMap.get(status) || 0) + 1);
+    });
+
+    const counts: StatusCount[] = [];
+    statusMap.forEach((count, status) => {
+      counts.push({
+        status,
+        count,
+      });
+    });
+
+    // 개수 순으로 정렬
+    return counts.sort((a, b) => b.count - a.count);
+  }, [documents]);
+
+  // Status 필터링된 문서 목록
+  const filteredDocuments = useMemo(() => {
+    if (!selectedStatus) {
+      return documents;
+    }
+    return documents.filter((doc) => doc.LTST_ACTV_STAT === selectedStatus);
+  }, [documents, selectedStatus]);
 
   const table = useReactTable({
-    data: documents,
+    data: filteredDocuments,
     columns: swpDocumentColumns,
     getCoreRowModel: getCoreRowModel(),
   });
@@ -48,6 +85,29 @@ export function SwpTable({
 
   return (
     <div className="space-y-4">
+      {/* Status 필터 UI */}
+      <div className="flex flex-wrap gap-2 p-4 bg-muted/30 rounded-lg">
+        <Button
+          variant={selectedStatus === null ? "default" : "outline"}
+          size="sm"
+          onClick={() => setSelectedStatus(null)}
+          className="h-9"
+        >
+          전체 ({documents.length})
+        </Button>
+        {statusCounts.map((statusCount) => (
+          <Button
+            key={statusCount.status}
+            variant={selectedStatus === statusCount.status ? "default" : "outline"}
+            size="sm"
+            onClick={() => setSelectedStatus(statusCount.status)}
+            className="h-9"
+          >
+            {statusCount.status} ({statusCount.count})
+          </Button>
+        ))}
+      </div>
+
       {/* 테이블 */}
       <div className="rounded-md border">
         <Table>
-- 
cgit v1.2.3

