import React, { useState, useRef } from "react"; import { Box, Paper, Typography, CircularProgress, Button, Snackbar, Alert, Grid, IconButton, Tooltip, } from "@mui/material"; import { alpha } from "@mui/material/styles"; import CloudUploadIcon from "@mui/icons-material/CloudUpload"; import AutoFixHighIcon from "@mui/icons-material/AutoFixHigh"; import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; import DescriptionIcon from "@mui/icons-material/Description"; import ArticleIcon from "@mui/icons-material/Article"; import MenuBookIcon from "@mui/icons-material/MenuBook"; import DownloadIcon from "@mui/icons-material/Download"; import { useThemeMode } from "../hooks/useThemeMode"; import getTheme from "../config/theme"; import API_CONFIG from "../config/api"; /** * Component for creating a new benchmark, including file upload and generation initiation * * @param {Object} props - Component props * @param {Function} props.onStartGeneration - Callback when generation starts with sessionId * @returns {JSX.Element} BenchmarkCreateForm component */ function BenchmarkCreateForm({ onStartGeneration }) { const { mode } = useThemeMode(); const theme = getTheme(mode); const [isDragging, setIsDragging] = useState(false); const [uploadStatus, setUploadStatus] = useState(null); const [isLoading, setIsLoading] = useState(false); const [sessionId, setSessionId] = useState(null); const [openSnackbar, setOpenSnackbar] = useState(false); const [selectedDocument, setSelectedDocument] = useState(null); const [isDefaultDocument, setIsDefaultDocument] = useState(false); const [isDownloading, setIsDownloading] = useState(false); const fileInputRef = useRef(null); const defaultDocuments = [ { id: "the-bitter-lesson", name: "The Bitter Lesson", icon: , description: "A seminal paper on AI development by Rich Sutton", }, { id: "hurricane-faq", name: "Hurricane FAQ", icon: , description: "Frequently asked questions about hurricanes", }, { id: "pokemon-guide", name: "Pokemon Guide", icon: , description: "A comprehensive guide for Pokemon enthusiasts", }, ]; const handleCloseSnackbar = () => { setOpenSnackbar(false); }; const handleDragOver = (e) => { e.preventDefault(); setIsDragging(true); }; const handleDragLeave = () => { setIsDragging(false); }; const handleClick = () => { fileInputRef.current.click(); }; const handleFileChange = (e) => { const file = e.target.files[0]; if (!file) return; // Check if it's a PDF, TXT, HTML or MD if ( !file.name.endsWith(".pdf") && !file.name.endsWith(".txt") && !file.name.endsWith(".html") && !file.name.endsWith(".md") ) { setUploadStatus({ success: false, message: "Only PDF, TXT, HTML and MD files are accepted", }); return; } handleFileUpload(file); }; const handleFileUpload = async (file) => { setIsLoading(true); setUploadStatus(null); setIsDefaultDocument(false); setSelectedDocument(null); try { const formData = new FormData(); formData.append("file", file); const response = await fetch(`${API_CONFIG.BASE_URL}/upload`, { method: "POST", body: formData, }); const result = await response.json(); if (response.ok) { setUploadStatus({ success: true, message: `File ${result.filename} uploaded successfully`, }); setOpenSnackbar(true); setSessionId(result.session_id); setSelectedDocument({ name: file.name }); } else { setUploadStatus({ success: false, message: result.error || "Upload failed", }); setOpenSnackbar(true); } } catch (error) { setUploadStatus({ success: false, message: "Server connection error", }); setOpenSnackbar(true); } finally { setIsLoading(false); } }; const handleDrop = async (e) => { e.preventDefault(); setIsDragging(false); const file = e.dataTransfer.files[0]; if (!file) { setUploadStatus({ success: false, message: "No file detected" }); return; } // Check if it's a PDF, TXT, HTML or MD if ( !file.name.endsWith(".pdf") && !file.name.endsWith(".txt") && !file.name.endsWith(".html") && !file.name.endsWith(".md") ) { setUploadStatus({ success: false, message: "Only PDF, TXT, HTML and MD files are accepted", }); return; } handleFileUpload(file); }; const handleDefaultDocClick = (doc) => { setSelectedDocument(doc); setSessionId(doc.id); setIsDefaultDocument(true); }; const handleGenerateClick = () => { if (onStartGeneration && sessionId) { onStartGeneration(sessionId, isDefaultDocument); } }; const handleDownloadDocument = async (doc) => { setIsDownloading(true); try { const link = document.createElement("a"); link.href = `/${doc.id}.${ doc.id === "the-bitter-lesson" ? "html" : doc.id === "hurricane-faq" ? "md" : "txt" }`; link.setAttribute( "download", `${doc.name}.${ doc.id === "the-bitter-lesson" ? "html" : doc.id === "hurricane-faq" ? "md" : "txt" }` ); document.body.appendChild(link); link.click(); document.body.removeChild(link); } catch (error) { console.error("Error downloading document:", error); setUploadStatus({ success: false, message: "Error downloading document", }); setOpenSnackbar(true); } finally { setIsDownloading(false); } }; return ( To create a benchmark, choose a sample document {defaultDocuments.map((doc) => ( handleDefaultDocClick(doc)} > { e.stopPropagation(); handleDownloadDocument(doc); }} sx={{ position: "absolute", top: 4, right: 4, color: "text.secondary", opacity: 0.6, "&:hover": { opacity: 1, backgroundColor: alpha(theme.palette.primary.main, 0.05), }, padding: 0.5, "& .MuiSvgIcon-root": { fontSize: 18, }, }} disabled={isDownloading} > {isDownloading ? ( ) : ( )} {doc.icon} {doc.name} {doc.description} ))} Or upload your own ... {selectedDocument?.name && !isDefaultDocument ? ( <> {selectedDocument.name} Click to upload a different file ) : ( <> {isLoading ? ( ) : ( )} {isLoading ? "Uploading your file..." : "Drag and drop your file here or click to browse"} Accepted formats: PDF, TXT, HTML, MD )} {uploadStatus?.message} ); } export default BenchmarkCreateForm;