anycoder-d1e17039 / components /NotebookParser.jsx
kizabgd123's picture
Upload components/NotebookParser.jsx with huggingface_hub
94bebf8 verified
import { useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Upload, FileText, AlertCircle } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from './ui/Card';
import { Button } from './ui/Button';
export default function NotebookParser() {
const [file, setFile] = useState(null);
const [parsing, setParsing] = useState(false);
const [results, setResults] = useState([]);
const [error, setError] = useState(null);
const onDrop = (acceptedFiles) => {
const notebookFile = acceptedFiles.find(f => f.name.endsWith('.ipynb'));
if (notebookFile) {
setFile(notebookFile);
setError(null);
} else {
setError('Please upload a valid .ipynb file');
}
};
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: { 'application/json': ['.ipynb'] },
maxFiles: 1,
});
const parseNotebook = async () => {
if (!file) return;
setParsing(true);
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/api/parse-notebook', {
method: 'POST',
body: formData,
});
if (!response.ok) throw new Error('Parse failed');
const data = await response.json();
setResults(data.parameters || []);
} catch (err) {
setError(err.message);
} finally {
setParsing(false);
}
};
return (
<div className="space-y-6">
<h2 className="text-3xl font-bold text-gray-800">Notebook Parser</h2>
<Card>
<CardHeader>
<CardTitle>Upload Jupyter Notebook</CardTitle>
</CardHeader>
<CardContent>
<div
{...getRootProps()}
className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${
isDragActive ? 'border-primary-500 bg-primary-50' : 'border-gray-300'
}`}
>
<input {...getInputProps()} />
<Upload className="w-12 h-12 mx-auto mb-4 text-gray-400" />
<p className="text-lg">Drag & drop your .ipynb file here</p>
<p className="text-sm text-gray-500 mt-2">or click to browse</p>
</div>
{file && (
<div className="mt-4 flex items-center">
<FileText className="w-5 h-5 mr-2 text-primary-500" />
<span>{file.name}</span>
</div>
)}
{error && (
<div className="mt-4 flex items-center text-red-500">
<AlertCircle className="w-5 h-5 mr-2" />
<span>{error}</span>
</div>
)}
<Button
onClick={parseNotebook}
disabled={!file || parsing}
className="mt-6 w-full"
>
{parsing ? 'Parsing...' : 'Parse Notebook'}
</Button>
</CardContent>
</Card>
{results.length > 0 && (
<Card>
<CardHeader>
<CardTitle>Extracted Parameters</CardTitle>
</CardHeader>
<CardContent>
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b">
<th className="text-left py-2">Parameter</th>
<th className="text-left py-2">Value</th>
<th className="text-left py-2">Confidence</th>
<th className="text-left py-2">Source</th>
</tr>
</thead>
<tbody>
{results.map((param, idx) => (
<tr key={idx} className="border-b">
<td className="py-2 font-mono">{param.param}</td>
<td className="py-2">{JSON.stringify(param.value)}</td>
<td className="py-2">
<div className="progress-container">
<div
className="progress-bar"
style={{ width: `${param.confidence * 100}%` }}
/>
</div>
<span className="text-sm">{(param.confidence * 100).toFixed(1)}%</span>
</td>
<td className="py-2 text-sm text-gray-600">{param.source}</td>
</tr>
))}
</tbody>
</table>
</div>
</CardContent>
</Card>
)}
</div>
);
}