From 9ecdfb23fe3df6a5df86782385002c562dfc1198 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 19 Sep 2025 07:51:27 +0000 Subject: (대표님) rfq 히스토리, swp 등 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plant/upload/toolbar-actions.tsx | 242 +++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 lib/vendor-document-list/plant/upload/toolbar-actions.tsx (limited to 'lib/vendor-document-list/plant/upload/toolbar-actions.tsx') diff --git a/lib/vendor-document-list/plant/upload/toolbar-actions.tsx b/lib/vendor-document-list/plant/upload/toolbar-actions.tsx new file mode 100644 index 00000000..072fd72d --- /dev/null +++ b/lib/vendor-document-list/plant/upload/toolbar-actions.tsx @@ -0,0 +1,242 @@ +"use client" + +import * as React from "react" +import { type Table } from "@tanstack/react-table" +import { Download, RefreshCw, Upload, Send, AlertCircle } from "lucide-react" +import { toast } from "sonner" + +import { exportTableToExcel } from "@/lib/export" +import { Button } from "@/components/ui/button" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog" +import { StageSubmissionView } from "@/db/schema" +import { DataTableRowAction } from "@/types/table" +import { MultiUploadDialog } from "./components/multi-upload-dialog" +import { useRouter, useSearchParams } from "next/navigation" + +interface StageSubmissionToolbarActionsProps { + table: Table + rowAction: DataTableRowAction | null + setRowAction: React.Dispatch | null>> +} + +export function StageSubmissionToolbarActions({ + table, + rowAction, + setRowAction +}: StageSubmissionToolbarActionsProps) { + const selectedRows = table.getFilteredSelectedRowModel().rows + const router = useRouter() + const searchParams = useSearchParams() + + const projectId = searchParams.get('projectId') + + + const [isSyncing, setIsSyncing] = React.useState(false) + const [showSyncDialog, setShowSyncDialog] = React.useState(false) + const [syncTargets, setSyncTargets] = React.useState([]) + + const handleUploadComplete = () => { + // Refresh table + router.refresh() + } + + const handleSyncClick = () => { + const rowsRequiringSync = selectedRows.filter( + row => row.original.requiresSync && row.original.latestSubmissionId + ) + setSyncTargets(rowsRequiringSync) + setShowSyncDialog(true) + } + + const handleSyncConfirm = async () => { + setShowSyncDialog(false) + setIsSyncing(true) + + try { + // Extract submission IDs + const submissionIds = syncTargets + .map(row => row.original.latestSubmissionId) + .filter((id): id is number => id !== null) + + if (submissionIds.length === 0) { + toast.error("No submissions to sync.") + return + } + + // API call + const response = await fetch('/api/stage-submissions/sync', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ submissionIds }), + }) + + const result = await response.json() + + if (result.success) { + toast.success(result.message) + + // Display detailed information for successful items + if (result.results?.details) { + const successCount = result.results.details.filter((d: any) => d.success).length + const failedCount = result.results.details.filter((d: any) => !d.success).length + + if (failedCount > 0) { + toast.warning(`${successCount} succeeded, ${failedCount} failed`) + } + } + + // Refresh table + router.refresh() + table.toggleAllPageRowsSelected(false) // Deselect all + } else { + toast.error(result.error || "Sync failed") + } + } catch (error) { + console.error("Sync error:", error) + toast.error("An error occurred during synchronization.") + } finally { + setIsSyncing(false) + } + } + + return ( + <> +
+ {projectId && ( + + )} + {selectedRows.length > 0 && ( + <> + {/* Bulk Upload for selected rows that require submission */} + {selectedRows.some(row => row.original.requiresSubmission) && ( + + )} + + {/* Bulk Sync for selected rows that need syncing */} + {selectedRows.some(row => row.original.requiresSync && row.original.latestSubmissionId) && ( + + )} + + )} + + {/* Export Button */} + +
+ + {/* Sync Confirmation Dialog */} + + + + + + Sync to Buyer System + + +
+ Are you sure you want to sync {syncTargets.length} selected submission(s) to the buyer system? +
+
+
Items to sync:
+
    + {syncTargets.slice(0, 3).map((row, idx) => ( +
  • + + {row.original.docNumber} + - + {row.original.stageName} + + (Rev.{row.original.latestRevisionNumber}) + +
  • + ))} + {syncTargets.length > 3 && ( +
  • + ... and {syncTargets.length - 3} more +
  • + )} +
+
+
+ +
+ Synchronized files will be sent to the SHI Buyer System and + cannot be recalled after transmission. +
+
+
+
+ + Cancel + + Start Sync + + +
+
+ + ) +} \ No newline at end of file -- cgit v1.2.3