From 10f90dc68dec42e9a64e081cc0dce6a484447290 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 29 Jul 2025 11:48:59 +0000
Subject: (대표님, 박서영, 최겸) document-list-only, gtc, vendorDocu,
 docu-list-rule
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../table/gtc-clauses-table-toolbar-actions.tsx    | 200 +++++++++++++++++----
 1 file changed, 164 insertions(+), 36 deletions(-)

(limited to 'lib/gtc-contract/gtc-clauses/table/gtc-clauses-table-toolbar-actions.tsx')

diff --git a/lib/gtc-contract/gtc-clauses/table/gtc-clauses-table-toolbar-actions.tsx b/lib/gtc-contract/gtc-clauses/table/gtc-clauses-table-toolbar-actions.tsx
index 2a7452ef..ea516f49 100644
--- a/lib/gtc-contract/gtc-clauses/table/gtc-clauses-table-toolbar-actions.tsx
+++ b/lib/gtc-contract/gtc-clauses/table/gtc-clauses-table-toolbar-actions.tsx
@@ -32,42 +32,170 @@ import { type GtcClauseTreeView } from "@/db/schema/gtc"
 import { CreateGtcClauseDialog } from "./create-gtc-clause-dialog"
 import { PreviewDocumentDialog } from "./preview-document-dialog"
 import { DeleteGtcClausesDialog } from "./delete-gtc-clauses-dialog"
+import { exportTableToExcel } from "@/lib/export"
+import { exportFullDataToExcel, type ExcelColumnDef } from "@/lib/export"
+import { getAllGtcClausesForExport, importGtcClausesFromExcel } from "../../service"
+import { ImportExcelDialog } from "./import-excel-dialog"
+import { toast } from "@/hooks/use-toast"
 
 interface GtcClausesTableToolbarActionsProps {
   table: Table<GtcClauseTreeView>
   documentId: number
   document: any
+  currentUserId?: number // 현재 사용자 ID 추가
 }
 
+// GTC 조항을 위한 Excel 컬럼 정의 (실용적으로 간소화)
+const gtcClauseExcelColumns: ExcelColumnDef[] = [
+  {
+    id: "itemNumber",
+    header: "채번",
+    accessor: "itemNumber",
+    group: "필수 정보"
+  },
+  {
+    id: "subtitle",
+    header: "소제목",
+    accessor: "subtitle",
+    group: "필수 정보"
+  },
+  {
+    id: "content",
+    header: "상세항목",
+    accessor: "content",
+    group: "기본 정보"
+  },
+  {
+    id: "category",
+    header: "분류",
+    accessor: "category",
+    group: "기본 정보"
+  },
+  {
+    id: "sortOrder",
+    header: "순서",
+    accessor: "sortOrder",
+    group: "순서"
+  },
+  {
+    id: "parentId",
+    header: "상위 조항 ID",
+    accessor: "parentId",
+    group: "계층 구조"
+  },
+  {
+    id: "isActive",
+    header: "활성 상태",
+    accessor: (row) => row.isActive ? "활성" : "비활성",
+    group: "상태"
+  },
+  {
+    id: "editReason",
+    header: "편집 사유",
+    accessor: "editReason",
+    group: "추가 정보"
+  }
+]
+
 export function GtcClausesTableToolbarActions({
   table,
   documentId,
   document,
+  currentUserId = 1, // 기본값 설정 (실제로는 auth에서 가져와야 함)
 }: GtcClausesTableToolbarActionsProps) {
   const [showCreateDialog, setShowCreateDialog] = React.useState(false)
   const [showReorderDialog, setShowReorderDialog] = React.useState(false)
   const [showBulkUpdateDialog, setShowBulkUpdateDialog] = React.useState(false)
   const [showGenerateVariablesDialog, setShowGenerateVariablesDialog] = React.useState(false)
-  const [showPreviewDialog, setShowPreviewDialog] = React.useState(false) // ✅ 미리보기 다이얼로그 상태
+  const [showPreviewDialog, setShowPreviewDialog] = React.useState(false)
+  const [isExporting, setIsExporting] = React.useState(false)
 
   const selectedRows = table.getSelectedRowModel().rows
   const selectedCount = selectedRows.length
   
-  // ✅ 테이블의 모든 데이터 가져오기
+  // 테이블의 모든 데이터 가져오기 (현재 페이지만)
   const allClauses = table.getRowModel().rows.map(row => row.original)
 
-  const handleExportToExcel = () => {
-    // Excel 내보내기 로직
-    console.log("Export to Excel")
+  // 현재 페이지 데이터만 Excel로 내보내기
+  const handleExportCurrentPageToExcel = () => {
+    exportTableToExcel(table, {
+      filename: `gtc-clauses-page-${new Date().toISOString().split('T')[0]}`,
+      excludeColumns: ["select", "actions"],
+    })
+  }
+
+  // 전체 데이터를 Excel로 내보내기
+  const handleExportAllToExcel = async () => {
+    try {
+      setIsExporting(true)
+      
+      // 서버에서 전체 데이터 가져오기
+      const allData = await getAllGtcClausesForExport(documentId)
+      
+      // 전체 데이터를 Excel로 내보내기
+      await exportFullDataToExcel(
+        allData,
+        gtcClauseExcelColumns,
+        {
+          filename: `gtc-clauses-all-${new Date().toISOString().split('T')[0]}`,
+          useGroupHeader: true
+        }
+      )
+      
+      toast({
+        title: "내보내기 완료",
+        description: `총 ${allData.length}개의 조항이 Excel 파일로 내보내졌습니다.`,
+      })
+    } catch (error) {
+      console.error("Excel export failed:", error)
+      toast({
+        title: "내보내기 실패",
+        description: "Excel 파일 내보내기 중 오류가 발생했습니다.",
+        variant: "destructive"
+      })
+    } finally {
+      setIsExporting(false)
+    }
   }
 
-  const handleImportFromExcel = () => {
-    // Excel 가져오기 로직
-    console.log("Import from Excel")
+  // Excel 데이터 가져오기 처리
+  const handleImportExcelData = async (data: Partial<GtcClauseTreeView>[]) => {
+    try {
+      const result = await importGtcClausesFromExcel(documentId, data, currentUserId)
+      
+      if (result.success) {
+        toast({
+          title: "가져오기 성공",
+          description: `${result.importedCount}개의 조항이 성공적으로 가져와졌습니다.`,
+        })
+        
+        // 테이블 새로고침
+        handleRefreshTable()
+      } else {
+        const errorMessage = result.errors.length > 0 
+          ? `오류: ${result.errors.slice(0, 3).join(', ')}${result.errors.length > 3 ? '...' : ''}`
+          : "알 수 없는 오류가 발생했습니다."
+          
+        toast({
+          title: "가져오기 실패",
+          description: errorMessage,
+          variant: "destructive"
+        })
+        
+        // 오류가 있어도 일부는 성공했을 수 있음
+        if (result.importedCount > 0) {
+          handleRefreshTable()
+        }
+        
+        throw new Error("Import failed with errors")
+      }
+    } catch (error) {
+      console.error("Excel import failed:", error)
+      throw error // ImportExcelDialog에서 처리하도록 다시 throw
+    }
   }
 
   const handlePreviewDocument = () => {
-    // ✅ 미리보기 다이얼로그 열기
     setShowPreviewDialog(true)
   }
 
@@ -108,9 +236,8 @@ export function GtcClausesTableToolbarActions({
         {selectedCount > 0 && (
           <>
             <DeleteGtcClausesDialog
-                gtcClauses={allClauses}
-          onSuccess={() => table.toggleAllRowsSelected(false)}
-
+              gtcClauses={allClauses}
+              onSuccess={() => table.toggleAllRowsSelected(false)}
             />
           </>
         )}
@@ -118,33 +245,39 @@ export function GtcClausesTableToolbarActions({
         {/* 관리 도구 드롭다운 */}
         <DropdownMenu>
           <DropdownMenuTrigger asChild>
-            <Button variant="outline" size="sm">
+            <Button variant="outline" size="sm" disabled={isExporting}>
               <Settings2 className="mr-2 h-4 w-4" />
               관리 도구
             </Button>
           </DropdownMenuTrigger>
-          <DropdownMenuContent align="end" className="w-56">
-            {/* <DropdownMenuItem onClick={handleReorderClauses}>
-              <ArrowUpDown className="mr-2 h-4 w-4" />
-              조항 순서 변경
+          <DropdownMenuContent align="end" className="w-64">
+            <DropdownMenuItem onClick={handleExportCurrentPageToExcel}>
+              <Download className="mr-2 h-4 w-4" />
+              현재 페이지 Excel로 내보내기
             </DropdownMenuItem>
             
-            <DropdownMenuItem onClick={handleGenerateVariables}>
-              <Wand2 className="mr-2 h-4 w-4" />
-              PDFTron 변수명 일괄 생성
-            </DropdownMenuItem> */}
-
-            <DropdownMenuSeparator />
-            
-            <DropdownMenuItem onClick={handleExportToExcel}>
+            <DropdownMenuItem 
+              onClick={handleExportAllToExcel}
+              disabled={isExporting}
+            >
               <Download className="mr-2 h-4 w-4" />
-              Excel로 내보내기
+              {isExporting ? "내보내는 중..." : "전체 데이터 Excel로 내보내기"}
             </DropdownMenuItem>
             
-            <DropdownMenuItem onClick={handleImportFromExcel}>
-              <Upload className="mr-2 h-4 w-4" />
-              Excel에서 가져오기
-            </DropdownMenuItem>
+            <DropdownMenuSeparator />
+            
+            <ImportExcelDialog
+              documentId={documentId}
+              columns={gtcClauseExcelColumns}
+              onSuccess={handleRefreshTable}
+              onImport={handleImportExcelData}
+              trigger={
+                <DropdownMenuItem onSelect={(e) => e.preventDefault()}>
+                  <Upload className="mr-2 h-4 w-4" />
+                  Excel에서 가져오기
+                </DropdownMenuItem>
+              }
+            />
 
             <DropdownMenuSeparator />
             
@@ -152,11 +285,6 @@ export function GtcClausesTableToolbarActions({
               <Eye className="mr-2 h-4 w-4" />
               문서 미리보기
             </DropdownMenuItem>
-            
-            {/* <DropdownMenuItem onClick={handleGenerateDocument}>
-              <FileText className="mr-2 h-4 w-4" />
-              최종 문서 생성
-            </DropdownMenuItem> */}
           </DropdownMenuContent>
         </DropdownMenu>
 
@@ -180,7 +308,7 @@ export function GtcClausesTableToolbarActions({
         )}
       </div>
 
-      {/* ✅ 미리보기 다이얼로그 */}
+      {/* 미리보기 다이얼로그 */}
       <PreviewDocumentDialog
         open={showPreviewDialog}
         onOpenChange={setShowPreviewDialog}
-- 
cgit v1.2.3

