"use client"; import React, { useState, useRef, useCallback } from "react"; import { Button } from "@/components/ui/button"; import { Upload, X, Loader2, FileText, ExternalLink } from "lucide-react"; import { cn } from "@/lib/utils"; import { apiClient } from "@/lib/api/client"; import { toast } from "sonner"; interface PdfUploadProps { value?: string; onChange?: (value: string) => void; tableName?: string; recordId?: string; columnName?: string; height?: string; disabled?: boolean; className?: string; } export function PdfUpload({ value, onChange, tableName, recordId, columnName, height = "h-40", disabled = false, className, }: PdfUploadProps) { const [uploading, setUploading] = useState(false); const [dragOver, setDragOver] = useState(false); const fileRef = useRef(null); const apiBase = typeof window !== "undefined" ? (process.env.NEXT_PUBLIC_API_URL || "").replace(/\/api\/?$/, "") : ""; const pdfUrl = value ? (value.startsWith("http") || value.startsWith("/")) ? value : `${apiBase}/api/files/preview/${value}` : null; const handleUpload = useCallback(async (file: File) => { const isPdf = file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf"); if (!isPdf) { toast.error("PDF 파일만 업로드 가능합니다."); return; } if (file.size > 20 * 1024 * 1024) { toast.error("파일 크기는 20MB 이하만 가능합니다."); return; } setUploading(true); try { const formData = new FormData(); formData.append("files", file); formData.append("docType", "PDF"); formData.append("docTypeName", "도면PDF"); if (tableName) formData.append("linkedTable", tableName); if (recordId) formData.append("recordId", recordId); if (columnName) formData.append("columnName", columnName); if (tableName && recordId) { formData.append("autoLink", "true"); if (columnName) formData.append("isVirtualFileColumn", "true"); } const res = await apiClient.post("/files/upload", formData, { headers: { "Content-Type": "multipart/form-data" }, }); if (res.data?.success && (res.data.files?.length > 0 || res.data.data?.length > 0)) { const uploaded = res.data.files?.[0] || res.data.data?.[0]; const objid = uploaded.objid; onChange?.(objid); toast.success("PDF가 업로드되었습니다."); } else { toast.error(res.data?.message || "업로드에 실패했습니다."); } } catch (err: any) { console.error("PDF 업로드 실패:", err); toast.error(err.response?.data?.message || "업로드에 실패했습니다."); } finally { setUploading(false); } }, [tableName, recordId, columnName, onChange]); const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) handleUpload(file); e.target.value = ""; }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); setDragOver(false); const file = e.dataTransfer.files?.[0]; if (file) handleUpload(file); }; const handleRemove = () => onChange?.(""); const handleOpen = (e: React.MouseEvent) => { e.stopPropagation(); if (pdfUrl) window.open(pdfUrl, "_blank", "noopener,noreferrer"); }; return (
!disabled && !uploading && fileRef.current?.click()} onDragOver={(e) => { e.preventDefault(); if (!disabled) setDragOver(true); }} onDragLeave={() => setDragOver(false)} onDrop={!disabled ? handleDrop : undefined} > {uploading ? (
업로드 중...
) : pdfUrl ? (
PDF 업로드됨
) : (
PDF 클릭 또는 드래그하여 업로드
)}
{pdfUrl && !disabled && ( )}
); }