From cbb4c7fe0b94459162ad5e998bc05cd293e0ff96 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 11 Aug 2025 09:02:00 +0000
Subject: (대표님) 입찰, EDP 변경사항 대응, spreadJS 오류 수정, 벤더실사 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../list/biddings-table-toolbar-actions.tsx        | 143 +++++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 lib/bidding/list/biddings-table-toolbar-actions.tsx

(limited to 'lib/bidding/list/biddings-table-toolbar-actions.tsx')

diff --git a/lib/bidding/list/biddings-table-toolbar-actions.tsx b/lib/bidding/list/biddings-table-toolbar-actions.tsx
new file mode 100644
index 00000000..81982a43
--- /dev/null
+++ b/lib/bidding/list/biddings-table-toolbar-actions.tsx
@@ -0,0 +1,143 @@
+"use client"
+
+import * as React from "react"
+import { type Table } from "@tanstack/react-table"
+import { 
+  Plus, Send, Gavel, Download, FileSpreadsheet,
+  Eye, Clock, CheckCircle 
+} from "lucide-react"
+import { toast } from "sonner"
+import { useRouter } from "next/navigation"
+
+import { exportTableToExcel } from "@/lib/export"
+import { Button } from "@/components/ui/button"
+import {
+  DropdownMenu,
+  DropdownMenuContent,
+  DropdownMenuItem,
+  DropdownMenuSeparator,
+  DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { BiddingListItem } from "@/db/schema"
+import { CreateBiddingDialog } from "./create-bidding-dialog"
+
+interface BiddingsTableToolbarActionsProps {
+  table: Table<BiddingListItem>
+}
+
+export function BiddingsTableToolbarActions({ table }: BiddingsTableToolbarActionsProps) {
+  const router = useRouter()
+  const [isExporting, setIsExporting] = React.useState(false)
+
+  // 선택된 입찰들
+  const selectedBiddings = React.useMemo(() => {
+    return table
+      .getFilteredSelectedRowModel()
+      .rows
+      .map(row => row.original)
+  }, [table.getFilteredSelectedRowModel().rows])
+
+  // 사전견적 요청 가능한 입찰들 (입찰생성 상태)
+  const preQuoteEligibleBiddings = React.useMemo(() => {
+    return selectedBiddings.filter(bidding => 
+      bidding.status === 'bidding_generated'
+    )
+  }, [selectedBiddings])
+
+  // 개찰 가능한 입찰들 (내정가 산정 완료)
+  const openEligibleBiddings = React.useMemo(() => {
+    return selectedBiddings.filter(bidding => 
+      bidding.status === 'set_target_price'
+    )
+  }, [selectedBiddings])
+
+
+  const handlePreQuoteRequest = () => {
+    if (preQuoteEligibleBiddings.length === 0) {
+      toast.warning("사전견적 요청 가능한 입찰을 선택해주세요.")
+      return
+    }
+
+    toast.success(`${preQuoteEligibleBiddings.length}개 입찰의 사전견적을 요청했습니다.`)
+    // TODO: 실제 사전견적 요청 로직 구현
+  }
+
+  const handleBiddingOpen = () => {
+    if (openEligibleBiddings.length === 0) {
+      toast.warning("개찰 가능한 입찰을 선택해주세요.")
+      return
+    }
+
+    toast.success(`${openEligibleBiddings.length}개 입찰을 개찰했습니다.`)
+    // TODO: 실제 개찰 로직 구현
+  }
+
+  const handleExport = async () => {
+    try {
+      setIsExporting(true)
+      await exportTableToExcel(table, {
+        filename: "biddings",
+        excludeColumns: ["select", "actions"],
+      })
+      toast.success("입찰 목록이 성공적으로 내보내졌습니다.")
+    } catch (error) {
+      toast.error("내보내기 중 오류가 발생했습니다.")
+    } finally {
+      setIsExporting(false)
+    }
+  }
+
+  return (
+    <div className="flex items-center gap-2">
+      {/* 신규 생성 */}
+    <CreateBiddingDialog/>
+
+      {/* 사전견적 요청 */}
+      {preQuoteEligibleBiddings.length > 0 && (
+        <Button 
+          variant="outline" 
+          size="sm"
+          onClick={handlePreQuoteRequest}
+        >
+          <Send className="mr-2 h-4 w-4" />
+          사전견적 요청 ({preQuoteEligibleBiddings.length})
+        </Button>
+      )}
+
+      {/* 개찰 (입찰 오픈) */}
+      {openEligibleBiddings.length > 0 && (
+        <Button 
+          variant="outline" 
+          size="sm"
+          onClick={handleBiddingOpen}
+        >
+          <Gavel className="mr-2 h-4 w-4" />
+          개찰 ({openEligibleBiddings.length})
+        </Button>
+      )}
+
+      {/* 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={handleExport} disabled={isExporting}>
+            <FileSpreadsheet className="mr-2 size-4" />
+            <span>입찰 목록 내보내기</span>
+          </DropdownMenuItem>
+        </DropdownMenuContent>
+      </DropdownMenu>
+    </div>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3

