'use client'; import { useState } from "react"; import { Box, Button, Typography, Paper, LinearProgress, Stack, TextField, MenuItem, IconButton, Tooltip, Divider, InputAdornment } from "@mui/material"; import CloudUploadIcon from "@mui/icons-material/CloudUpload"; import CreateNewFolderIcon from "@mui/icons-material/CreateNewFolder"; import FolderIcon from "@mui/icons-material/Folder"; import AssignmentIcon from '@mui/icons-material/Assignment'; import { useRouter } from "next/navigation"; import { uploadFileAction, createFolderAction } from "./_actions"; /** * Format bytes to human readable string (MiB/KiB) */ const formatFileSize = (bytes: number) => { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; interface Folder { id: string; name: string; parentId: string | null; } interface UploadViewProps { user: any; folders?: Folder[]; } export default function UploadView({ user, folders = [] }: UploadViewProps) { const router = useRouter(); // Form State const [file, setFile] = useState(null); const [description, setDescription] = useState(""); const [parentId, setParentId] = useState(""); const [status, setStatus] = useState<'idle' | 'uploading' | 'success'>('idle'); // Folder Creation State const [showFolderInput, setShowFolderInput] = useState(false); const [newFolderName, setNewFolderName] = useState(""); const [isCreatingFolder, setIsCreatingFolder] = useState(false); const MAX_FILE_SIZE = 150 * 1024 * 1024; // 150MB Limit const handleCreateFolder = async () => { if (!newFolderName.trim()) return; setIsCreatingFolder(true); try { // Creates folder nested under current selection if parentId exists await createFolderAction(newFolderName, parentId || null); setNewFolderName(""); setShowFolderInput(false); router.refresh(); } catch (err) { alert("Error creating folder"); } finally { setIsCreatingFolder(false); } }; const handleUpload = async () => { if (!file) return; if (file.size > MAX_FILE_SIZE) { alert(`File is too large! Max allowed: ${formatFileSize(MAX_FILE_SIZE)}.`); return; } setStatus('uploading'); const formData = new FormData(); formData.append("file", file); formData.append("description", description); formData.append("parentId", parentId); try { const result = await uploadFileAction(formData); if (result.success) { setStatus('success'); setFile(null); setDescription(""); router.refresh(); } } catch (err) { console.error(err); alert("Upload failed. Check server logs."); setStatus('idle'); } }; return ( Add to Library {/* Section 1: Destination Folder */} 1. Destination setParentId(e.target.value)} disabled={status === 'uploading'} helperText="Files will be virtually organized into this folder." > -- Root (Main Library) -- {folders.map((f) => ( {f.parentId ? `↳ ${f.name}` : f.name} ))} setShowFolderInput(!showFolderInput)} sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 1, width: 56, height: 56 }} > {showFolderInput && ( setNewFolderName(e.target.value)} autoFocus disabled={isCreatingFolder} /> )} {/* Section 2: File Upload Area */} 2. Upload File { setFile(e.target.files?.[0] || null); setStatus('idle'); }} /> {file && ( {file.name} {formatFileSize(file.size)} )} {/* Section 3: Notes */} 3. Metadata setDescription(e.target.value)} disabled={status === 'uploading'} /> {/* Progress & Actions */} {status === 'uploading' && ( Transferring to OneDrive and updating Library... )} {status === 'success' && ( ✅ File processed and assigned to project! )} ); }