diff options
| -rw-r--r-- | app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx | 29 | ||||
| -rw-r--r-- | lib/swp/table/swp-table-columns.tsx | 25 | ||||
| -rw-r--r-- | lib/swp/table/swp-table.tsx | 22 |
3 files changed, 75 insertions, 1 deletions
diff --git a/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx b/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx index dc6fbe7c..34ad562f 100644 --- a/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx +++ b/app/[lng]/partners/(partners)/swp-document-upload/vendor-document-page.tsx @@ -70,6 +70,34 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP noKeyboard: true, }); + // 커버페이지 다운로드 핸들러 + const handleCoverDownload = useCallback(async (document: DocumentListItem) => { + try { + toast.info("커버 페이지를 다운로드합니다..."); + + const res = await fetch(`/api/projects/${document.PROJ_NO}/cover`, { + method: "GET" + }); + + if (!res.ok) { + const error = await res.json(); + throw new Error(error.message || "커버 페이지를 가져올 수 없습니다"); + } + + const { fileUrl, fileName } = await res.json(); + + // quickDownload 사용 + const quickDownload = (await import("@/lib/file-download")).quickDownload; + quickDownload(fileUrl, fileName || `${document.PROJ_NO}_cover.docx`); + + toast.success("커버 페이지 다운로드를 시작했습니다."); + + } catch (e) { + toast.error(e instanceof Error ? e.message : "커버 페이지 다운로드에 실패했습니다."); + console.error(e); + } + }, []); + const loadInitialData = useCallback(async () => { try { setIsLoading(true); @@ -275,6 +303,7 @@ export default function VendorDocumentPage({ searchParams }: VendorDocumentPageP projNo={projNo} vendorCode={vendorInfo?.vendorCode || ""} userId={String(vendorInfo?.vendorId || "")} + onCoverDownload={handleCoverDownload} /> </CardContent> </Card> diff --git a/lib/swp/table/swp-table-columns.tsx b/lib/swp/table/swp-table-columns.tsx index 48b2c90a..5334bd8c 100644 --- a/lib/swp/table/swp-table-columns.tsx +++ b/lib/swp/table/swp-table-columns.tsx @@ -2,6 +2,8 @@ import { ColumnDef } from "@tanstack/react-table"; import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Download } from "lucide-react"; import type { DocumentListItem } from "@/lib/swp/document-service"; export const swpDocumentColumns: ColumnDef<DocumentListItem>[] = [ @@ -125,4 +127,27 @@ export const swpDocumentColumns: ColumnDef<DocumentListItem>[] = [ ), size: 100, }, + { + id: "actions", + header: "액션", + cell: ({ row }) => ( + <Button + variant="ghost" + size="sm" + onClick={(e) => { + e.stopPropagation(); // 행 클릭 이벤트 방지 + // 커버페이지 다운로드 핸들러는 부모 컴포넌트에서 제공 + const event = new CustomEvent('coverDownload', { + detail: { document: row.original } + }); + window.dispatchEvent(event); + }} + className="h-8 px-2" + > + <Download className="h-4 w-4 mr-1" /> + 커버페이지 + </Button> + ), + size: 120, + }, ]; diff --git a/lib/swp/table/swp-table.tsx b/lib/swp/table/swp-table.tsx index 21a1c775..4d824f77 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, { useState, useEffect } from "react"; import { useReactTable, getCoreRowModel, @@ -17,12 +17,15 @@ import { import { swpDocumentColumns } from "./swp-table-columns"; import { SwpDocumentDetailDialog } from "./swp-document-detail-dialog"; import type { DocumentListItem } from "@/lib/swp/document-service"; +import { toast } from "sonner"; +import { quickDownload } from "@/lib/file-download"; interface SwpTableProps { documents: DocumentListItem[]; projNo: string; vendorCode: string; userId: string; + onCoverDownload?: (document: DocumentListItem) => void; } export function SwpTable({ @@ -30,6 +33,7 @@ export function SwpTable({ projNo, vendorCode, userId, + onCoverDownload, }: SwpTableProps) { const [dialogOpen, setDialogOpen] = useState(false); const [selectedDocument, setSelectedDocument] = useState<DocumentListItem | null>(null); @@ -46,6 +50,22 @@ export function SwpTable({ setDialogOpen(true); }; + // 커버페이지 다운로드 이벤트 리스너 + useEffect(() => { + const handleCoverDownload = (event: CustomEvent) => { + const { document } = event.detail; + if (onCoverDownload) { + onCoverDownload(document); + } + }; + + window.addEventListener('coverDownload', handleCoverDownload as EventListener); + + return () => { + window.removeEventListener('coverDownload', handleCoverDownload as EventListener); + }; + }, [onCoverDownload]); + return ( <div className="space-y-4"> {/* 테이블 */} |
