diff options
| author | joonhoekim <26rote@gmail.com> | 2025-10-27 17:14:44 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-10-27 17:14:44 +0900 |
| commit | 02062af723f1a3c2994c3e80148da47b07712713 (patch) | |
| tree | fa9e27d9b0d9a9f87ef7ccf05edfb9c2806c06bd /lib/swp/table | |
| parent | 2e92d5f83ae5f0f39090552b46c519982e9279c9 (diff) | |
(김준회) SWP 다운로드, 업로드 api route 처리, 옥프로 컬럼 순서 조정 처리, 환경변수 오타 수정
Diffstat (limited to 'lib/swp/table')
| -rw-r--r-- | lib/swp/table/swp-table-columns.tsx | 66 | ||||
| -rw-r--r-- | lib/swp/table/swp-table-toolbar.tsx | 38 |
2 files changed, 55 insertions, 49 deletions
diff --git a/lib/swp/table/swp-table-columns.tsx b/lib/swp/table/swp-table-columns.tsx index 9954ab73..9aecea96 100644 --- a/lib/swp/table/swp-table-columns.tsx +++ b/lib/swp/table/swp-table-columns.tsx @@ -7,7 +7,6 @@ import { ChevronDown, ChevronRight, FileIcon, Download, Loader2 } from "lucide-r import { formatDistanceToNow } from "date-fns"; import { ko } from "date-fns/locale"; import type { SwpDocumentWithStats } from "../actions"; -import { downloadSwpFile } from "../actions"; import { useState } from "react"; import { toast } from "sonner"; @@ -29,6 +28,28 @@ export const swpDocumentColumns: ColumnDef<SwpDocumentWithStats>[] = [ size: 50, }, { + accessorKey: "LTST_ACTV_STAT", + header: "상태 (최신 액티비티)", + cell: ({ row }) => { + const status = row.original.LTST_ACTV_STAT; + if (!status) return "-"; + + // 상태에 따른 색상 설정 (필요에 따라 조정 가능) + const color = + status === "Complete" ? "bg-green-100 text-green-800" : + status === "In Progress" ? "bg-blue-100 text-blue-800" : + status === "Pending" ? "bg-yellow-100 text-yellow-800" : + "bg-gray-100 text-gray-800"; + + return ( + <Badge variant="outline" className={color}> + {status} + </Badge> + ); + }, + size: 100, + }, + { accessorKey: "DOC_NO", header: "문서번호", cell: ({ row }) => ( @@ -90,12 +111,12 @@ export const swpDocumentColumns: ColumnDef<SwpDocumentWithStats>[] = [ cell: ({ row }) => { const stage = row.original.STAGE; if (!stage) return "-"; - - const color = + + const color = stage === "IFC" ? "bg-green-100 text-green-800" : stage === "IFA" ? "bg-blue-100 text-blue-800" : "bg-gray-100 text-gray-800"; - + return ( <Badge variant="outline" className={color}> {stage} @@ -123,28 +144,6 @@ export const swpDocumentColumns: ColumnDef<SwpDocumentWithStats>[] = [ size: 100, }, { - accessorKey: "LTST_ACTV_STAT", - header: "상태 (최신 액티비티)", - cell: ({ row }) => { - const status = row.original.LTST_ACTV_STAT; - if (!status) return "-"; - - // 상태에 따른 색상 설정 (필요에 따라 조정 가능) - const color = - status === "Complete" ? "bg-green-100 text-green-800" : - status === "In Progress" ? "bg-blue-100 text-blue-800" : - status === "Pending" ? "bg-yellow-100 text-yellow-800" : - "bg-gray-100 text-gray-800"; - - return ( - <Badge variant="outline" className={color}> - {status} - </Badge> - ); - }, - size: 100, - }, - { accessorKey: "last_synced_at", header: "동기화", cell: ({ row }) => ( @@ -399,26 +398,27 @@ function DownloadButton({ fileId, fileName }: DownloadButtonProps) { try { setIsDownloading(true); - // 서버 액션 호출 - const result = await downloadSwpFile(fileId); + // API Route 호출 (바이너리 직접 전송) + const response = await fetch(`/api/swp/download/${fileId}`); - if (!result.success || !result.data) { - toast.error(result.error || "파일 다운로드 실패"); + if (!response.ok) { + const errorData = await response.json().catch(() => ({ error: "다운로드 실패" })); + toast.error(errorData.error || "파일 다운로드 실패"); return; } // Blob 생성 및 다운로드 - const blob = new Blob([result.data as unknown as BlobPart], { type: result.mimeType }); + const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; - link.download = result.fileName || fileName; + link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); - toast.success(`파일 다운로드 완료: ${result.fileName}`); + toast.success(`파일 다운로드 완료: ${fileName}`); } catch (error) { console.error("다운로드 오류:", error); toast.error("파일 다운로드 중 오류가 발생했습니다."); diff --git a/lib/swp/table/swp-table-toolbar.tsx b/lib/swp/table/swp-table-toolbar.tsx index e7a2ef30..fefff091 100644 --- a/lib/swp/table/swp-table-toolbar.tsx +++ b/lib/swp/table/swp-table-toolbar.tsx @@ -10,7 +10,7 @@ import { } from "@/components/ui/popover"; import { Label } from "@/components/ui/label"; import { RefreshCw, Search, X, Check, ChevronsUpDown, Upload } from "lucide-react"; -import { syncSwpProjectAction, uploadSwpFilesAction, type SwpTableFilters } from "../actions"; +import { syncSwpProjectAction, type SwpTableFilters } from "../actions"; import { useToast } from "@/hooks/use-toast"; import { useRouter } from "next/navigation"; import { cn } from "@/lib/utils"; @@ -137,27 +137,33 @@ export function SwpTableToolbar({ description: `${selectedFiles.length}개 파일을 업로드합니다...`, }); - // 파일을 Buffer로 변환 - const fileInfos = await Promise.all( - Array.from(selectedFiles).map(async (file) => { - const arrayBuffer = await file.arrayBuffer(); - return { - fileName: file.name, - fileBuffer: Buffer.from(arrayBuffer), - }; - }) - ); + // FormData 생성 (바이너리 직접 전송) + const formData = new FormData(); + formData.append("projNo", projectNo); + formData.append("vndrCd", vndrCd); + + Array.from(selectedFiles).forEach((file) => { + formData.append("files", file); + }); + + // API Route 호출 + const response = await fetch("/api/swp/upload", { + method: "POST", + body: formData, + }); + + if (!response.ok) { + throw new Error(`업로드 실패: ${response.statusText}`); + } - // 서버 액션 호출 - const result = await uploadSwpFilesAction(projectNo, vndrCd, fileInfos); + const result = await response.json(); // 결과 저장 및 다이얼로그 표시 - setUploadResults(result.details); + setUploadResults(result.details || []); setShowResultDialog(true); // 성공한 파일이 있으면 페이지 새로고침 - const successCount = result.details.filter((d) => d.success).length; - if (successCount > 0) { + if (result.successCount > 0) { router.refresh(); } } catch (error) { |
