// frontend/src/App.jsx
import React, { useState, useCallback, useMemo } from 'react';
// Inline SVG Icons
const IconUpload = (props) => ;
const IconCpu = (props) => ;
const IconCheckCircle = (props) => ;
const IconXCircle = (props) => ;
const IconLoader = (props) => ;
const IconBrain = (props) => ;
const IconAlertTriangle = (props) => ;
const App = () => {
const [selectedFile, setSelectedFile] = useState(null);
const [previewUrl, setPreviewUrl] = useState('');
const [prediction, setPrediction] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
// API URL - use relative path since frontend and backend are served together
const API_URL = ''; // Empty string means same origin
const CLASS_INFO = useMemo(() => ({
glioma: { name: "Glioma Tumor (Malignant)", color: "#dc2626", bg: "#fef2f2", icon: },
meningioma: { name: "Meningioma Tumor (Benign)", color: "#ea580c", bg: "#fff7ed", icon: },
pituitary: { name: "Pituitary Tumor (Benign)", color: "#ca8a04", bg: "#fefce8", icon: },
notumor: { name: "No Tumor Detected", color: "#16a34a", bg: "#f0fdf4", icon: },
}), []);
const handleFileChange = useCallback((event) => {
const file = event.target.files[0];
if (file) {
setSelectedFile(file);
setPreviewUrl(URL.createObjectURL(file));
setPrediction(null);
setError('');
}
}, []);
const handleSubmit = async (event) => {
event.preventDefault();
if (!selectedFile) {
setError('Please select an MRI image file.');
return;
}
setLoading(true);
setPrediction(null);
setError('');
const formData = new FormData();
formData.append('mriImage', selectedFile);
try {
const response = await fetch(`${API_URL}/api/predict`, {
method: 'POST',
body: formData,
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.detail || data.error || 'Unknown server error.');
}
setPrediction(data);
} catch (err) {
console.error('Prediction failed:', err);
setError(`Prediction failed: ${err.message}`);
} finally {
setLoading(false);
}
};
const ResultDisplay = ({ result }) => {
const info = CLASS_INFO[result.predicted_class.toLowerCase()] || CLASS_INFO.notumor;
const confidencePercent = (result.confidence * 100).toFixed(2);
return (
{info.icon}
Diagnosis Result
Predicted Class:
{info.name}
Confidence Score:
{confidencePercent}%
);
};
return (
);
};
export default App;