polymer-aging-with-ml / frontend /src /components /StandardAnalysis.tsx
devjas1
Initial Release: Polymer Aging With ML [Standalone Appliance]
4a0e21d
Raw
History Blame Contribute Delete
5.68 kB
import React, { useState, useCallback } from "react";
import { useDropzone } from "react-dropzone";
import { apiClient, SpectrumData, PredictionResult } from "../apiClient";
import SpectrumChart from "./SpectrumChart";
import ResultsDisplay from "./ResultsDisplay";
import "../static/style.css";
interface StandardAnalysisProps {
selectedModel: string;
modality: "raman" | "ftir";
onSpectrumChange: (data: SpectrumData | null) => void;
}
const StandardAnalysis: React.FC<StandardAnalysisProps> = ({
selectedModel,
modality,
onSpectrumChange,
}) => {
const [spectrum, setSpectrum] = useState<SpectrumData | null>(null);
const [result, setResult] = useState<PredictionResult | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const onDrop = useCallback(
async (acceptedFiles: File[]) => {
if (acceptedFiles.length === 0) return;
const file = acceptedFiles[0];
setResult(null);
setError(null);
setLoading(true);
try {
const uploadedSpectrum = await apiClient.uploadSpectrum(file);
setSpectrum(uploadedSpectrum);
onSpectrumChange(uploadedSpectrum);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to upload file");
} finally {
setLoading(false);
}
},
[onSpectrumChange]
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: { "text/plain": [".txt", ".csv"], "application/json": [".json"] },
multiple: false,
});
const handleAnalyze = async () => {
if (!spectrum) return;
setError(null);
setLoading(true);
try {
const analysisResult = await apiClient.analyzeSpectrum({
spectrum,
model_name: selectedModel,
modality,
include_provenance: true,
});
setResult(analysisResult);
} catch (err) {
setError(err instanceof Error ? err.message : "Analysis failed");
} finally {
setLoading(false);
}
};
const handleReset = () => {
setSpectrum(null);
onSpectrumChange(null);
setResult(null);
setError(null);
};
return (
<div className="analysis-layout">
{/* --- LEFT COLUMN --- */}
<div className="analysis-column">
<div className="card">
<h3 className="card__title">Upload Spectrum</h3>
<div
{...getRootProps()}
className={`dropzone ${isDragActive ? "dropzone--active" : ""}`}
title="Upload a spectrum file by dragging it here or clicking to select. Supported formats: .txt, .csv, .json"
aria-label="Spectrum file upload dropzone"
tabIndex={0}
>
<input {...getInputProps()} />
{/* Updated Dropzone Text */}
<div className="dropzone-content">
<p className="dropzone__text">
{isDragActive
? "Drop file to upload"
: "Drag & drop, or click to select"}
</p>
<p className="dropzone__subtext">
Supports .txt, .csv, and .json files
</p>
<span className="dropzone-tooltip" role="tooltip">
Upload a spectrum file for analysis. You can drag and drop or
click to select. Supported formats: .txt, .csv, .json
</span>
</div>
</div>
{/* New Sample Data Link Section */}
<div className="sample-data-prompt">
<span>New to PolymerOS?</span>
<a
href="https://data.mendeley.com/datasets/kpygrf9fg6/1"
target="_blank"
rel="noopener noreferrer"
className="sample-data-link"
>
Try a Sample Dataset
</a>
</div>
{error && <div className="error-message">{error}</div>}
{loading && (
<div className="loading-indicator">
<div className="spinner"></div>
<span>Processing...</span>
</div>
)}
{spectrum && !loading && (
<div className="spectrum-info">
<p>
<strong>Loaded:</strong> {spectrum.filename || "Unknown"}
</p>
<div className="button-group">
<button
className="btn btn--primary"
onClick={handleAnalyze}
disabled={loading}
>
Analyze
</button>
<button
className="btn btn--secondary"
onClick={handleReset}
disabled={loading}
>
Reset
</button>
</div>
</div>
)}
</div>
</div>
{/* --- RIGHT COLUMN --- */}
<div className="analysis-column">
<div className="card">
<h3 className="card__title">Analysis Results</h3>
{spectrum && (
<div className="chart-container">
<SpectrumChart spectrum={spectrum} />
</div>
)}
{result ? (
<ResultsDisplay result={result} />
) : (
<div className="placeholder">
<p>Upload a spectrum to view analysis results</p>
</div>
)}
</div>
</div>
</div>
);
};
export default StandardAnalysis;