feat([2fd88f42]): initial setup of heatmap tool

This commit is contained in:
2026-02-04 11:30:47 +00:00
parent 3bf0c4f3b3
commit c5c3de12e7
24 changed files with 4433 additions and 920 deletions

View File

@@ -0,0 +1,70 @@
// src/components/FileUpload.tsx
import React, { useState } from 'react';
import axios from 'axios';
interface FilterOptions {
[key: string]: string[];
}
interface FileUploadProps {
onUploadSuccess: (filters: FilterOptions) => void;
setIsLoading: (isLoading: boolean) => void;
setError: (error: string | null) => void;
}
const FileUpload: React.FC<FileUploadProps> = ({ onUploadSuccess, setIsLoading, setError }) => {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
setSelectedFile(event.target.files[0]);
}
};
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!selectedFile) {
setError("Please select a file first.");
return;
}
if (!selectedFile.name.endsWith('.xlsx')) {
setError("Invalid file type. Please upload an .xlsx file.");
return;
}
const formData = new FormData();
formData.append('file', selectedFile);
setIsLoading(true);
setError(null);
try {
const response = await axios.post('http://localhost:8000/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
onUploadSuccess(response.data.filters);
} catch (error: any) {
if (axios.isAxiosError(error) && error.response) {
setError(`Upload failed: ${error.response.data.detail || error.message}`);
} else {
setError(`Upload failed: ${error.message}`);
}
} finally {
setIsLoading(false);
}
};
return (
<div className="file-upload">
<h3>Upload XLSX File</h3>
<form onSubmit={handleSubmit}>
<input type="file" accept=".xlsx" onChange={handleFileChange} />
<button type="submit" disabled={!selectedFile}>Upload</button>
</form>
</div>
);
};
export default FileUpload;