MedicalAIWiki / frontend /src /pages /AlgorithmDetail.tsx
AleksanderObuchowski's picture
Initial commit for Hugging Face Spaces
e4f1db2
raw
history blame
8.68 kB
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, Brain, Cpu, Loader2 } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
// Import markdown content
import linearRegressionMd from '../docs/linear_regression.md?raw';
import cnnMd from '../docs/cnn.md?raw';
const AlgorithmDetail: React.FC = () => {
const { algorithmId } = useParams<{ algorithmId: string }>();
const navigate = useNavigate();
const [markdownContent, setMarkdownContent] = useState<string>('');
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
loadMarkdownContent();
}, [algorithmId]);
const loadMarkdownContent = async () => {
try {
setLoading(true);
setError(null);
let content = '';
switch (algorithmId) {
case 'linear_regression':
content = linearRegressionMd;
break;
case 'cnn':
content = cnnMd;
break;
default:
setError('Algorithm documentation not found');
setLoading(false);
return;
}
setMarkdownContent(content);
} catch (err) {
setError('Failed to load algorithm documentation');
} finally {
setLoading(false);
}
};
const getAlgorithmInfo = () => {
switch (algorithmId) {
case 'linear_regression':
return {
name: 'Linear Regression',
category: 'Classical ML',
icon: <Brain className="h-8 w-8 text-blue-600" />,
categoryColor: 'bg-blue-100 text-blue-800'
};
case 'cnn':
return {
name: 'Convolutional Neural Network',
category: 'Deep Learning',
icon: <Cpu className="h-8 w-8 text-purple-600" />,
categoryColor: 'bg-purple-100 text-purple-800'
};
default:
return {
name: 'Unknown Algorithm',
category: 'Unknown',
icon: <Brain className="h-8 w-8 text-gray-600" />,
categoryColor: 'bg-gray-100 text-gray-800'
};
}
};
const algorithmInfo = getAlgorithmInfo();
if (loading) {
return (
<div className="max-w-4xl mx-auto">
<button
onClick={() => navigate(-1)}
className="mb-6 flex items-center text-blue-600 hover:text-blue-800 transition-colors"
>
<ArrowLeft className="h-4 w-4 mr-2" />
Back
</button>
<div className="flex justify-center items-center h-64">
<Loader2 className="h-8 w-8 animate-spin text-blue-600" />
<span className="ml-2 text-gray-600">Loading documentation...</span>
</div>
</div>
);
}
if (error) {
return (
<div className="max-w-4xl mx-auto">
<button
onClick={() => navigate(-1)}
className="mb-6 flex items-center text-blue-600 hover:text-blue-800 transition-colors"
>
<ArrowLeft className="h-4 w-4 mr-2" />
Back
</button>
<div className="bg-white rounded-lg shadow-md p-8 text-center">
<h1 className="text-2xl font-bold text-gray-900 mb-4">Documentation Not Available</h1>
<p className="text-gray-600 mb-4">{error}</p>
<button
onClick={loadMarkdownContent}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
>
Try Again
</button>
</div>
</div>
);
}
return (
<div className="max-w-4xl mx-auto">
<button
onClick={() => navigate(-1)}
className="mb-6 flex items-center text-blue-600 hover:text-blue-800 transition-colors"
>
<ArrowLeft className="h-4 w-4 mr-2" />
Back
</button>
{/* Algorithm Header */}
<div className="bg-white rounded-lg shadow-md p-6 mb-6">
<div className="flex items-center justify-between">
<div className="flex items-center">
{algorithmInfo.icon}
<div className="ml-4">
<h1 className="text-2xl font-bold text-gray-900">{algorithmInfo.name}</h1>
</div>
</div>
<span className={`px-3 py-1 rounded-full text-sm font-semibold ${algorithmInfo.categoryColor}`}>
{algorithmInfo.category}
</span>
</div>
</div>
{/* Markdown Content */}
<div className="bg-white rounded-lg shadow-md p-8">
<div className="prose prose-lg max-w-none">
<ReactMarkdown
components={{
h1: ({ children }) => (
<h1 className="text-3xl font-bold text-gray-900 mb-6 border-b-2 border-gray-200 pb-2">
{children}
</h1>
),
h2: ({ children }) => (
<h2 className="text-2xl font-semibold text-gray-900 mt-8 mb-4 border-b border-gray-200 pb-2">
{children}
</h2>
),
h3: ({ children }) => (
<h3 className="text-xl font-semibold text-gray-900 mt-6 mb-3">
{children}
</h3>
),
h4: ({ children }) => (
<h4 className="text-lg font-semibold text-gray-900 mt-4 mb-2">
{children}
</h4>
),
p: ({ children }) => (
<p className="text-gray-700 leading-relaxed mb-4">
{children}
</p>
),
ul: ({ children }) => (
<ul className="list-disc list-outside text-gray-700 mb-4 space-y-2 ml-6">
{children}
</ul>
),
ol: ({ children }) => (
<ol className="list-decimal list-outside text-gray-700 mb-4 space-y-2 ml-6">
{children}
</ol>
),
li: ({ children }) => (
<li className="pl-2">
{children}
</li>
),
code: ({ children, className }) => {
const isBlock = className?.includes('language-');
if (isBlock) {
return (
<pre className="bg-gray-50 border border-gray-200 rounded-lg p-4 mb-4 overflow-x-auto">
<code className="text-sm font-mono text-gray-800">
{children}
</code>
</pre>
);
}
return (
<code className="bg-gray-100 px-2 py-1 rounded text-sm font-mono text-gray-800">
{children}
</code>
);
},
blockquote: ({ children }) => (
<blockquote className="border-l-4 border-blue-500 pl-4 italic text-gray-600 mb-4">
{children}
</blockquote>
),
strong: ({ children }) => (
<strong className="font-semibold text-gray-900">
{children}
</strong>
),
em: ({ children }) => (
<em className="italic text-gray-700">
{children}
</em>
),
table: ({ children }) => (
<div className="overflow-x-auto mb-4">
<table className="min-w-full divide-y divide-gray-200">
{children}
</table>
</div>
),
thead: ({ children }) => (
<thead className="bg-gray-50">
{children}
</thead>
),
tbody: ({ children }) => (
<tbody className="bg-white divide-y divide-gray-200">
{children}
</tbody>
),
tr: ({ children }) => (
<tr>
{children}
</tr>
),
th: ({ children }) => (
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{children}
</th>
),
td: ({ children }) => (
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{children}
</td>
)
}}
>
{markdownContent}
</ReactMarkdown>
</div>
</div>
</div>
);
};
export default AlgorithmDetail;