// lib/vendor-rfq-response/vendor-tbe-table/vendor-document-upload-dialog.tsx "use client" import * as React from "react" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Badge } from "@/components/ui/badge" import { ScrollArea } from "@/components/ui/scroll-area" import { toast } from "sonner" import { Upload, FileText, X, Loader2 } from "lucide-react" import { uploadVendorDocument } from "@/lib/tbe-last/service" interface VendorDocumentUploadDialogProps { open: boolean onOpenChange: (open: boolean) => void sessionId: number | null sessionDetail: any onUploadSuccess: () => void } interface FileUpload { id: string file: File documentType: string description: string status: "pending" | "uploading" | "success" | "error" errorMessage?: string } export function VendorDocumentUploadDialog({ open, onOpenChange, sessionId, sessionDetail, onUploadSuccess }: VendorDocumentUploadDialogProps) { const [files, setFiles] = React.useState([]) const [isUploading, setIsUploading] = React.useState(false) const fileInputRef = React.useRef(null) // Document types for vendor const documentTypes = [ { value: "technical_spec", label: "Technical Specification" }, { value: "compliance_cert", label: "Compliance Certificate" }, { value: "test_report", label: "Test Report" }, { value: "drawing", label: "Drawing" }, { value: "datasheet", label: "Datasheet" }, { value: "quality_doc", label: "Quality Document" }, { value: "warranty", label: "Warranty Document" }, { value: "other", label: "Other" }, ] // Handle file selection const handleFileSelect = (e: React.ChangeEvent) => { const selectedFiles = Array.from(e.target.files || []) const newFiles: FileUpload[] = selectedFiles.map(file => ({ id: Math.random().toString(36).substr(2, 9), file, documentType: "technical_spec", description: "", status: "pending" as const })) setFiles(prev => [...prev, ...newFiles]) // Reset input if (fileInputRef.current) { fileInputRef.current.value = "" } } // Remove file const handleRemoveFile = (id: string) => { setFiles(prev => prev.filter(f => f.id !== id)) } // Update file details const handleUpdateFile = (id: string, field: keyof FileUpload, value: string) => { setFiles(prev => prev.map(f => f.id === id ? { ...f, [field]: value } : f )) } // Upload all files const handleUploadAll = async () => { if (!sessionId || files.length === 0) return setIsUploading(true) try { for (const fileUpload of files) { if (fileUpload.status === "success") continue // Update status to uploading setFiles(prev => prev.map(f => f.id === fileUpload.id ? { ...f, status: "uploading" } : f )) try { // Create FormData for upload const formData = new FormData() formData.append("file", fileUpload.file) formData.append("sessionId", sessionId.toString()) formData.append("documentType", fileUpload.documentType) formData.append("description", fileUpload.description) // Upload file (API call) const response = await fetch("/api/tbe/vendor-documents/upload", { method: "POST", body: formData }) if (!response.ok) throw new Error("Upload failed") // Update status to success setFiles(prev => prev.map(f => f.id === fileUpload.id ? { ...f, status: "success" } : f )) } catch (error) { // Update status to error setFiles(prev => prev.map(f => f.id === fileUpload.id ? { ...f, status: "error", errorMessage: error instanceof Error ? error.message : "Upload failed" } : f )) } } // Check if all files uploaded successfully const allSuccess = files.every(f => f.status === "success") if (allSuccess) { toast.success("모든 문서가 업로드되었습니다") onUploadSuccess() onOpenChange(false) setFiles([]) } else { const failedCount = files.filter(f => f.status === "error").length toast.error(`${failedCount}개 문서 업로드 실패`) } } catch (error) { console.error("Upload error:", error) toast.error("문서 업로드 중 오류가 발생했습니다") } finally { setIsUploading(false) } } // Get file size in readable format const formatFileSize = (bytes: number) => { if (bytes < 1024) return bytes + " B" if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB" return (bytes / (1024 * 1024)).toFixed(1) + " MB" } return ( Upload Documents for TBE {sessionDetail?.session?.sessionCode} - Technical Bid Evaluation 문서 업로드
{/* File Upload Area */}

파일을 드래그하거나 클릭하여 선택하세요

{/* Selected Files List */} {files.length > 0 && (
{files.map(fileUpload => (

{fileUpload.file.name}

{formatFileSize(fileUpload.file.size)}

{fileUpload.status === "uploading" && ( )} {fileUpload.status === "success" && ( Uploaded )} {fileUpload.status === "error" && ( Failed )}
{fileUpload.status !== "success" && ( <>