Spaces:
Sleeping
Sleeping
| 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; |