From 14f61e24947fb92dd71ec0a7196a6e815f8e66da Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 21 Jul 2025 07:54:26 +0000
Subject: (최겸)기술영업 RFQ 담당자 초대, 요구사항 반영
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../table/tech-vendors-table-toolbar-actions.tsx   | 396 +++++++++++----------
 1 file changed, 200 insertions(+), 196 deletions(-)

(limited to 'lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx')

diff --git a/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx b/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx
index ac7ee184..c5380140 100644
--- a/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx
+++ b/lib/tech-vendors/table/tech-vendors-table-toolbar-actions.tsx
@@ -1,197 +1,201 @@
-"use client"
-
-import * as React from "react"
-import { type Table } from "@tanstack/react-table"
-import { Download, FileSpreadsheet, FileText } from "lucide-react"
-import { toast } from "sonner"
-
-import { exportTableToExcel } from "@/lib/export"
-import { Button } from "@/components/ui/button"
-import {
-  DropdownMenu,
-  DropdownMenuContent,
-  DropdownMenuItem,
-  DropdownMenuSeparator,
-  DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu"
-
-import { exportVendorsWithRelatedData } from "./vendor-all-export"
-import { TechVendor } from "@/db/schema/techVendors"
-import { ImportTechVendorButton } from "./import-button"
-import { exportTechVendorTemplate } from "./excel-template-download"
-import { AddVendorDialog } from "./add-vendor-dialog"
-import { InviteTechVendorDialog } from "./invite-tech-vendor-dialog"
-
-interface TechVendorsTableToolbarActionsProps {
-  table: Table<TechVendor>
-  onRefresh?: () => void
-}
-
-export function TechVendorsTableToolbarActions({ table, onRefresh }: TechVendorsTableToolbarActionsProps) {
-  const [isExporting, setIsExporting] = React.useState(false);
-  
-  // 선택된 모든 벤더 가져오기
-  const selectedVendors = React.useMemo(() => {
-    return table
-      .getFilteredSelectedRowModel()
-      .rows
-      .map(row => row.original);
-  }, [table.getFilteredSelectedRowModel().rows]);
-
-  // 초대 가능한 벤더들 (PENDING_INVITE 상태 + 이메일 있음)
-  const invitableVendors = React.useMemo(() => {
-    return selectedVendors.filter(vendor => 
-      vendor.status === "PENDING_INVITE" && vendor.email
-    );
-  }, [selectedVendors]);
-  
-  // 테이블의 모든 벤더 가져오기 (필터링된 결과)
-  const allFilteredVendors = React.useMemo(() => {
-    return table
-      .getFilteredRowModel()
-      .rows
-      .map(row => row.original);
-  }, [table.getFilteredRowModel().rows]);
-  
-  // 선택된 벤더 통합 내보내기 함수 실행
-  const handleSelectedExport = async () => {
-    if (selectedVendors.length === 0) {
-      toast.warning("내보낼 협력업체를 선택해주세요.");
-      return;
-    }
-    
-    try {
-      setIsExporting(true);
-      toast.info(`선택된 ${selectedVendors.length}개 업체의 정보를 내보내는 중입니다...`);
-      await exportVendorsWithRelatedData(selectedVendors, "selected-vendors-detailed");
-      toast.success(`${selectedVendors.length}개 업체 정보 내보내기가 완료되었습니다.`);
-    } catch (error) {
-      console.error("상세 정보 내보내기 오류:", error);
-      toast.error("상세 정보 내보내기 중 오류가 발생했습니다.");
-    } finally {
-      setIsExporting(false);
-    }
-  };
-
-  // 모든 벤더 통합 내보내기 함수 실행
-  const handleAllFilteredExport = async () => {
-    if (allFilteredVendors.length === 0) {
-      toast.warning("내보낼 협력업체가 없습니다.");
-      return;
-    }
-    
-    try {
-      setIsExporting(true);
-      toast.info(`총 ${allFilteredVendors.length}개 업체의 정보를 내보내는 중입니다...`);
-      await exportVendorsWithRelatedData(allFilteredVendors, "all-vendors-detailed");
-      toast.success(`${allFilteredVendors.length}개 업체 정보 내보내기가 완료되었습니다.`);
-    } catch (error) {
-      console.error("상세 정보 내보내기 오류:", error);
-      toast.error("상세 정보 내보내기 중 오류가 발생했습니다.");
-    } finally {
-      setIsExporting(false);
-    }
-  };
-
-  // 벤더 추가 성공 시 테이블 새로고침을 위한 핸들러
-  const handleVendorAddSuccess = () => {
-    // 테이블 데이터 리프레시
-    if (onRefresh) {
-      onRefresh();
-    } else {
-      window.location.reload(); // 간단한 새로고침 방법
-    }
-  };
-  
-  return (
-    <div className="flex items-center gap-2">
-      {/* 초대 버튼 - 선택된 PENDING_REVIEW 벤더들이 있을 때만 표시 */}
-      {invitableVendors.length > 0 && (
-        <InviteTechVendorDialog
-          vendors={invitableVendors}
-          onSuccess={handleVendorAddSuccess}
-        />
-      )}
-
-      {/* 벤더 추가 다이얼로그 추가 */}
-      <AddVendorDialog onSuccess={handleVendorAddSuccess} />
-
-      {/* Import 버튼 추가 */}
-      <ImportTechVendorButton 
-        onSuccess={() => {
-          // 성공 시 테이블 새로고침
-          toast.success("업체 정보 가져오기가 완료되었습니다.");
-        }} 
-      />
-
-      {/* Export 드롭다운 메뉴로 변경 */}
-      <DropdownMenu>
-        <DropdownMenuTrigger asChild>
-          <Button
-            variant="outline"
-            size="sm"
-            className="gap-2"
-            disabled={isExporting}
-          >
-            <Download className="size-4" aria-hidden="true" />
-            <span className="hidden sm:inline">
-              {isExporting ? "내보내는 중..." : "Export"}
-            </span>
-          </Button>
-        </DropdownMenuTrigger>
-        <DropdownMenuContent align="end">
-          {/* 템플릿 다운로드 추가 */}
-          <DropdownMenuItem
-            onClick={() => exportTechVendorTemplate()}
-            disabled={isExporting}
-          >
-            <FileText className="mr-2 size-4" />
-            <span>Excel 템플릿 다운로드</span>
-          </DropdownMenuItem>
-
-          <DropdownMenuSeparator />
-          
-          {/* 기본 내보내기 - 현재 테이블에 보이는 데이터만 */}
-          <DropdownMenuItem
-            onClick={() =>
-              exportTableToExcel(table, {
-                filename: "vendors",
-                excludeColumns: ["select", "actions"],
-              })
-            }
-            disabled={isExporting}
-          >
-            <FileText className="mr-2 size-4" />
-            <span>현재 테이블 데이터 내보내기</span>
-          </DropdownMenuItem>
-          
-          <DropdownMenuSeparator />
-          
-          {/* 선택된 벤더만 상세 내보내기 */}
-          <DropdownMenuItem 
-            onClick={handleSelectedExport}
-            disabled={selectedVendors.length === 0 || isExporting}
-          >
-            <FileSpreadsheet className="mr-2 size-4" />
-            <span>선택한 업체 상세 정보 내보내기</span>
-            {selectedVendors.length > 0 && (
-              <span className="ml-1 text-xs text-muted-foreground">({selectedVendors.length}개)</span>
-            )}
-          </DropdownMenuItem>
-          
-          {/* 모든 필터링된 벤더 상세 내보내기 */}
-          <DropdownMenuItem 
-            onClick={handleAllFilteredExport}
-            disabled={allFilteredVendors.length === 0 || isExporting}
-          >
-            <Download className="mr-2 size-4" />
-            <span>모든 업체 상세 정보 내보내기</span>
-            {allFilteredVendors.length > 0 && (
-              <span className="ml-1 text-xs text-muted-foreground">({allFilteredVendors.length}개)</span>
-            )}
-          </DropdownMenuItem>
-        </DropdownMenuContent>
-      </DropdownMenu>
-    </div>
-  )
+"use client"
+
+import * as React from "react"
+import { type Table } from "@tanstack/react-table"
+import { Download, FileSpreadsheet, FileText } from "lucide-react"
+import { toast } from "sonner"
+
+import { exportTableToExcel } from "@/lib/export"
+import { Button } from "@/components/ui/button"
+import {
+  DropdownMenu,
+  DropdownMenuContent,
+  DropdownMenuItem,
+  DropdownMenuSeparator,
+  DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
+
+// import { exportVendorsWithRelatedData } from "./vendor-all-export"
+import { TechVendor } from "@/db/schema/techVendors"
+import { ImportTechVendorButton } from "./import-button"
+import { exportTechVendorTemplate } from "./excel-template-download"
+import { AddVendorDialog } from "./add-vendor-dialog"
+import { InviteTechVendorDialog } from "./invite-tech-vendor-dialog"
+
+interface TechVendorsTableToolbarActionsProps {
+  table: Table<TechVendor>
+  onRefresh?: () => void
+}
+
+export function TechVendorsTableToolbarActions({ 
+  table, 
+  onRefresh
+}: TechVendorsTableToolbarActionsProps) {
+  const [isExporting, setIsExporting] = React.useState(false);
+  
+  // 선택된 모든 벤더 가져오기
+  const selectedVendors = React.useMemo(() => {
+    return table
+      .getFilteredSelectedRowModel()
+      .rows
+      .map(row => row.original);
+  }, [table.getFilteredSelectedRowModel().rows]);
+
+  // 초대 가능한 벤더들 (PENDING_INVITE 상태 + 이메일 있음)
+  const invitableVendors = React.useMemo(() => {
+    return selectedVendors.filter(vendor => 
+      vendor.status === "PENDING_INVITE" && vendor.email
+    );
+  }, [selectedVendors]);
+  
+  // // 테이블의 모든 벤더 가져오기 (필터링된 결과)
+  // const allFilteredVendors = React.useMemo(() => {
+  //   return table
+  //     .getFilteredRowModel()
+  //     .rows
+  //     .map(row => row.original);
+  // }, [table.getFilteredRowModel().rows]);
+  
+  // // 선택된 벤더 통합 내보내기 함수 실행
+  // const handleSelectedExport = async () => {
+  //   if (selectedVendors.length === 0) {
+  //     toast.warning("내보낼 협력업체를 선택해주세요.");
+  //     return;
+  //   }
+    
+  //   try {
+  //     setIsExporting(true);
+  //     toast.info(`선택된 ${selectedVendors.length}개 업체의 정보를 내보내는 중입니다...`);
+  //     await exportVendorsWithRelatedData(selectedVendors, "selected-vendors-detailed");
+  //     toast.success(`${selectedVendors.length}개 업체 정보 내보내기가 완료되었습니다.`);
+  //   } catch (error) {
+  //     console.error("상세 정보 내보내기 오류:", error);
+  //     toast.error("상세 정보 내보내기 중 오류가 발생했습니다.");
+  //   } finally {
+  //     setIsExporting(false);
+  //   }
+  // };
+
+  // // 모든 벤더 통합 내보내기 함수 실행
+  // const handleAllFilteredExport = async () => {
+  //   if (allFilteredVendors.length === 0) {
+  //     toast.warning("내보낼 협력업체가 없습니다.");
+  //     return;
+  //   }
+    
+  //   try {
+  //     setIsExporting(true);
+  //     toast.info(`총 ${allFilteredVendors.length}개 업체의 정보를 내보내는 중입니다...`);
+  //     await exportVendorsWithRelatedData(allFilteredVendors, "all-vendors-detailed");
+  //     toast.success(`${allFilteredVendors.length}개 업체 정보 내보내기가 완료되었습니다.`);
+  //   } catch (error) {
+  //     console.error("상세 정보 내보내기 오류:", error);
+  //     toast.error("상세 정보 내보내기 중 오류가 발생했습니다.");
+  //   } finally {
+  //     setIsExporting(false);
+  //   }
+  // };
+
+  // 벤더 추가 성공 시 테이블 새로고침을 위한 핸들러
+  const handleVendorAddSuccess = () => {
+    // 테이블 데이터 리프레시
+    if (onRefresh) {
+      onRefresh();
+    } else {
+      window.location.reload(); // 간단한 새로고침 방법
+    }
+  };
+  
+  return (
+    <div className="flex items-center gap-2">
+      {/* 초대 버튼 - 선택된 PENDING_REVIEW 벤더들이 있을 때만 표시 */}
+      {invitableVendors.length > 0 && (
+        <InviteTechVendorDialog
+          vendors={invitableVendors}
+          onSuccess={handleVendorAddSuccess}
+        />
+      )}
+
+      {/* 벤더 추가 다이얼로그 추가 */}
+      <AddVendorDialog onSuccess={handleVendorAddSuccess} />
+
+      {/* Import 버튼 추가 */}
+      <ImportTechVendorButton 
+        onSuccess={() => {
+          // 성공 시 테이블 새로고침
+          toast.success("업체 정보 가져오기가 완료되었습니다.");
+        }} 
+      />
+
+      {/* Export 드롭다운 메뉴로 변경 */}
+      <DropdownMenu>
+        <DropdownMenuTrigger asChild>
+          <Button
+            variant="outline"
+            size="sm"
+            className="gap-2"
+            disabled={isExporting}
+          >
+            <Download className="size-4" aria-hidden="true" />
+            <span className="hidden sm:inline">
+              {isExporting ? "내보내는 중..." : "Export"}
+            </span>
+          </Button>
+        </DropdownMenuTrigger>
+        <DropdownMenuContent align="end">
+          {/* 템플릿 다운로드 추가 */}
+          <DropdownMenuItem
+            onClick={() => exportTechVendorTemplate()}
+            disabled={isExporting}
+          >
+            <FileText className="mr-2 size-4" />
+            <span>Excel 템플릿 다운로드</span>
+          </DropdownMenuItem>
+
+          <DropdownMenuSeparator />
+          
+          {/* 기본 내보내기 - 현재 테이블에 보이는 데이터만 */}
+          <DropdownMenuItem
+            onClick={() =>
+              exportTableToExcel(table, {
+                filename: "vendors",
+                excludeColumns: ["select", "actions"],
+              })
+            }
+            disabled={isExporting}
+          >
+            <FileText className="mr-2 size-4" />
+            <span>현재 테이블 데이터 내보내기</span>
+          </DropdownMenuItem>
+          
+          <DropdownMenuSeparator />
+          
+          {/* 선택된 벤더만 상세 내보내기 */}
+          {/* <DropdownMenuItem 
+            onClick={handleSelectedExport}
+            disabled={selectedVendors.length === 0 || isExporting}
+          >
+            <FileSpreadsheet className="mr-2 size-4" />
+            <span>선택한 업체 상세 정보 내보내기</span>
+            {selectedVendors.length > 0 && (
+              <span className="ml-1 text-xs text-muted-foreground">({selectedVendors.length}개)</span>
+            )}
+          </DropdownMenuItem> */}
+          
+          {/* 모든 필터링된 벤더 상세 내보내기 */}
+          {/* <DropdownMenuItem 
+            onClick={handleAllFilteredExport}
+            disabled={allFilteredVendors.length === 0 || isExporting}
+          >
+            <Download className="mr-2 size-4" />
+            <span>모든 업체 상세 정보 내보내기</span>
+            {allFilteredVendors.length > 0 && (
+              <span className="ml-1 text-xs text-muted-foreground">({allFilteredVendors.length}개)</span>
+            )}
+          </DropdownMenuItem> */}
+        </DropdownMenuContent>
+      </DropdownMenu>
+    </div>
+  )
 }
\ No newline at end of file
-- 
cgit v1.2.3

