diff --git a/frontend/src/pages/DocumentationPage.jsx b/frontend/src/pages/DocumentationPage.jsx index 93e8966..9e36f22 100644 --- a/frontend/src/pages/DocumentationPage.jsx +++ b/frontend/src/pages/DocumentationPage.jsx @@ -1,11 +1,66 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { Book, Code, Play, Settings, ChevronRight, ChevronDown, ExternalLink, Copy, Check } from 'lucide-react'; import { useTheme } from '../contexts/ThemeContext'; +import { useLocation, useNavigate } from 'react-router-dom'; const DocumentationPage = () => { const { isDark, classes, getThemedGradient } = useTheme(); const [expandedSections, setExpandedSections] = useState({}); const [copiedCode, setCopiedCode] = useState(''); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const [activeSection, setActiveSection] = useState(''); + const location = useLocation(); + const navigate = useNavigate(); + const sectionsRef = useRef({}); + + // Handle scroll spy for active section + useEffect(() => { + const handleScroll = () => { + const scrollPosition = window.scrollY + 100; // Offset for better UX + + Object.entries(sectionsRef.current).forEach(([id, element]) => { + if (element) { + const { offsetTop, offsetHeight } = element; + if ( + scrollPosition >= offsetTop && + scrollPosition < offsetTop + offsetHeight + ) { + setActiveSection(id); + if (!location.hash.includes(id)) { + navigate(`/documentation#${id}`, { replace: true }); + } + } + } + }); + }; + + window.addEventListener('scroll', handleScroll); + return () => window.removeEventListener('scroll', handleScroll); + }, [navigate, location.hash]); + + // Handle initial hash navigation and browser back/forward + useEffect(() => { + const hash = location.hash.slice(1); + if (hash && sectionsRef.current[hash]) { + scrollToSection(hash, false); + setActiveSection(hash); + } + }, [location.hash]); + + const scrollToSection = (sectionId, updateHash = true) => { + const element = sectionsRef.current[sectionId]; + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + if (updateHash) { + navigate(`/documentation#${sectionId}`, { replace: true }); + } + // Expand the section if it's collapsed + setExpandedSections(prev => ({ + ...prev, + [sectionId]: true + })); + } + }; const toggleSection = (sectionId) => { setExpandedSections(prev => ({ @@ -70,6 +125,12 @@ const DocumentationPage = () => { }` }; + // Close mobile menu when section is clicked + const handleSectionClick = (sectionId) => { + scrollToSection(sectionId); + setMobileMenuOpen(false); + }; + return (
@@ -93,8 +154,8 @@ const DocumentationPage = () => {
- {/* Table of Contents */} -
{ }`}> Table of Contents -
{/* Main Content */}
- - {/* Getting Started */} -
-

- + {/* Getting Started Section */} +
sectionsRef.current['getting-started'] = el} + className={`p-8 rounded-2xl backdrop-blur-xl ${ + isDark ? 'bg-gray-800/20 border-gray-700/50' : 'bg-white/20 border-white/50' + } border`} + > +

Getting Started

-
-
-

- How to Use -

-
    -
  1. Choose an algorithm category from the navigation menu
  2. -
  3. Select a specific algorithm from the dropdown
  4. -
  5. Configure input data (array for sorting, graph for graph algorithms)
  6. -
  7. Click the play button to start visualization
  8. -
  9. Use controls to pause, step through, or adjust speed
  10. -
-
- -
-

- Controls -

-
- {[ - { icon: Play, name: 'Play/Pause', desc: 'Start or pause algorithm execution' }, - { icon: Settings, name: 'Speed Control', desc: 'Adjust visualization speed' }, - { icon: Code, name: 'Step Mode', desc: 'Execute one step at a time' }, - { icon: Book, name: 'Reset', desc: 'Reset to initial state' } - ].map((control, index) => ( -
-
- - - {control.name} - -
-

- {control.desc} -

-
- ))} -
-
+
+ {/* Add your getting started content here */}
- {/* Algorithms */} -
-

- - Supported Algorithms + {/* Algorithms Section */} +
sectionsRef.current['algorithms'] = el} + className={`p-8 rounded-2xl backdrop-blur-xl ${ + isDark ? 'bg-gray-800/20 border-gray-700/50' : 'bg-white/20 border-white/50' + } border`} + > +

+ Algorithms

- - {Object.entries(algorithms).map(([category, algos]) => ( -
- - - {expandedSections[category] && ( -
- {algos.map((algo, index) => ( -
-
-

- {algo.name} -

- - {algo.complexity} - -
-

- {algo.description} -

-
- ))} -
- )} -
- ))} + {/* Add your algorithms content here */}
- {/* Code Examples */} -
-

- - Code Examples + {/* API Reference Section */} +
sectionsRef.current['api-reference'] = el} + className={`p-8 rounded-2xl backdrop-blur-xl ${ + isDark ? 'bg-gray-800/20 border-gray-700/50' : 'bg-white/20 border-white/50' + } border`} + > +

+ API Reference

- - {Object.entries(codeExamples).map(([key, code]) => ( -
-
-

- {key === 'bubbleSort' ? 'Bubble Sort' : 'Breadth-First Search'} -

- -
-
-
-                      {code}
-                    
-
-
- ))} + {/* Add your API reference content here */}
- {/* API Reference */} -
-

- - API Reference + {/* Examples Section */} +
sectionsRef.current['examples'] = el} + className={`p-8 rounded-2xl backdrop-blur-xl ${ + isDark ? 'bg-gray-800/20 border-gray-700/50' : 'bg-white/20 border-white/50' + } border`} + > +

+ Examples

-
-
-

- Sorting Algorithms -

- - POST /api/sorting/{algorithms} - -

- Execute sorting algorithm with provided array data -

-
- -
-

- Graph Algorithms -

- - POST /api/graph/{algorithms} - -

- Execute graph algorithm with nodes and edges data -

-
-
+ {/* Add your examples content here */}