import React, { useRef, useState } from "react"; import { uploadCSV, uploadSchemaDB } from "../api"; export default function UploadView({ onUploadSuccess, onSchemaUploadSuccess }) { // CSV upload state const [csvDragActive, setCsvDragActive] = useState(false); const [csvState, setCsvState] = useState("idle"); // idle | uploading | success | error const [csvError, setCsvError] = useState(""); const [csvInfo, setCsvInfo] = useState(null); const csvInputRef = useRef(null); // SQL upload state const [sqlDragActive, setSqlDragActive] = useState(false); const [sqlState, setSqlState] = useState("idle"); // idle | uploading | success | error const [sqlError, setSqlError] = useState(""); const [sqlInfo, setSqlInfo] = useState(null); const [sqlFile, setSqlFile] = useState(null); const [erdFile, setErdFile] = useState(null); const sqlInputRef = useRef(null); const erdInputRef = useRef(null); // ===================== CSV handlers ===================== const handleCsvDrag = (e) => { e.preventDefault(); e.stopPropagation(); if (e.type === "dragenter" || e.type === "dragover") setCsvDragActive(true); else if (e.type === "dragleave") setCsvDragActive(false); }; const handleCsvDrop = async (e) => { e.preventDefault(); e.stopPropagation(); setCsvDragActive(false); if (e.dataTransfer.files && e.dataTransfer.files[0]) { await processCsvFile(e.dataTransfer.files[0]); } }; const handleCsvFileChange = async (e) => { if (e.target.files && e.target.files[0]) { await processCsvFile(e.target.files[0]); } }; const processCsvFile = async (file) => { if (!file.name.endsWith(".csv")) { setCsvState("error"); setCsvError("Only .csv files are supported."); return; } setCsvState("uploading"); setCsvError(""); try { const result = await uploadCSV(file); setCsvState("success"); setCsvInfo({ display_name: result.display_name, row_count: result.row_count, columns: result.columns.length }); setTimeout(() => { if (onUploadSuccess) onUploadSuccess(result); setCsvState("idle"); setCsvInfo(null); }, 1500); } catch (err) { setCsvState("error"); setCsvError(err.message || "Failed to upload CSV."); } }; // ===================== SQL handlers ===================== const handleSqlDrag = (e) => { e.preventDefault(); e.stopPropagation(); if (e.type === "dragenter" || e.type === "dragover") setSqlDragActive(true); else if (e.type === "dragleave") setSqlDragActive(false); }; const handleSqlDrop = async (e) => { e.preventDefault(); e.stopPropagation(); setSqlDragActive(false); if (e.dataTransfer.files && e.dataTransfer.files[0]) { const file = e.dataTransfer.files[0]; if (file.name.endsWith(".sql")) { setSqlFile(file); } else if (file.name.match(/\.(png|jpg|jpeg)$/i)) { setErdFile(file); } } }; const handleSqlFileChange = (e) => { if (e.target.files && e.target.files[0]) { setSqlFile(e.target.files[0]); } }; const handleErdFileChange = (e) => { if (e.target.files && e.target.files[0]) { setErdFile(e.target.files[0]); } }; const handleSqlUpload = async () => { if (!sqlFile) { setSqlState("error"); setSqlError("A .sql file is required."); return; } setSqlState("uploading"); setSqlError(""); try { const result = await uploadSchemaDB(sqlFile, erdFile); setSqlState("success"); setSqlInfo({ db_name: result.db_name, total_tables: result.total_tables, total_rows: result.total_rows }); setTimeout(() => { if (onSchemaUploadSuccess) onSchemaUploadSuccess(result); setSqlState("idle"); setSqlInfo(null); setSqlFile(null); setErdFile(null); }, 1500); } catch (err) { setSqlState("error"); setSqlError(err.message || "Failed to upload SQL schema."); } }; return (
Upload a dataset to get started. Choose a CSV file for single-table data, or a SQL schema file for multi-table relational databases.
{/* Two Side-by-Side Upload Cards */}Or select an existing sample dataset from the sidebar to start querying immediately.