Really-amin's picture
Upload 577 files
b190b45 verified
raw
history blame
4.21 kB
import React, { useState, useEffect } from 'react';
import { useLocation, Link } from 'react-router-dom';
import {
LayoutDashboard,
TrendingUp,
BarChart3,
Bot,
Smile,
Activity,
DollarSign,
Newspaper,
Radio,
Monitor,
Settings,
HelpCircle,
ChevronLeft,
ChevronRight
} from 'lucide-react';
interface NavItem {
path: string;
label: string;
icon: React.ReactNode;
badge?: string;
section?: string;
}
const navItems: NavItem[] = [
// Main Section
{ path: '/', label: 'Dashboard', icon: <LayoutDashboard size={20} />, section: 'Main' },
{ path: '/market', label: 'Market', icon: <TrendingUp size={20} /> },
{ path: '/charts', label: 'Charts', icon: <BarChart3 size={20} /> },
// AI & Analysis Section
{ path: '/ai-models', label: 'AI Models', icon: <Bot size={20} />, section: 'AI & Analysis' },
{ path: '/sentiment', label: 'Sentiment', icon: <Smile size={20} /> },
{ path: '/ai-analyst', label: 'AI Analyst', icon: <Activity size={20} /> },
{ path: '/technical-analysis', label: 'Technical', icon: <BarChart3 size={20} /> },
// Trading Section
{ path: '/trading-assistant', label: 'Trading Assistant', icon: <DollarSign size={20} />, section: 'Trading' },
{ path: '/news', label: 'News', icon: <Newspaper size={20} /> },
// System Section
{ path: '/providers', label: 'Providers', icon: <Radio size={20} />, section: 'System' },
{ path: '/system-monitor', label: 'System Monitor', icon: <Monitor size={20} />, badge: 'LIVE' },
{ path: '/settings', label: 'Settings', icon: <Settings size={20} /> },
{ path: '/help', label: 'Help', icon: <HelpCircle size={20} /> },
];
export const Sidebar: React.FC = () => {
const [collapsed, setCollapsed] = useState(false);
const location = useLocation();
useEffect(() => {
const savedState = localStorage.getItem('sidebar-collapsed');
if (savedState === 'true') {
setCollapsed(true);
}
}, []);
const toggleCollapse = () => {
const newState = !collapsed;
setCollapsed(newState);
localStorage.setItem('sidebar-collapsed', String(newState));
};
const isActive = (path: string) => {
if (path === '/' && location.pathname === '/') return true;
if (path !== '/' && location.pathname.startsWith(path)) return true;
return false;
};
let currentSection = '';
return (
<aside className={`sidebar ${collapsed ? 'collapsed' : ''}`} role="navigation" aria-label="Main navigation">
{/* Sidebar Header */}
<div className="sidebar-header">
<div className="sidebar-logo">
<span>C</span>
</div>
<div className="sidebar-brand">Crypto Monitor</div>
</div>
{/* Sidebar Navigation */}
<nav className="sidebar-nav">
{navItems.map((item) => {
const showSection = item.section && item.section !== currentSection;
if (item.section) currentSection = item.section;
return (
<React.Fragment key={item.path}>
{showSection && (
<div className="nav-section-header">{item.section}</div>
)}
<Link
to={item.path}
className={`nav-item ${isActive(item.path) ? 'active' : ''}`}
>
<span className="nav-item-icon">{item.icon}</span>
<span className="nav-item-label">{item.label}</span>
{item.badge && (
<span className="nav-item-badge">{item.badge}</span>
)}
</Link>
</React.Fragment>
);
})}
</nav>
{/* Sidebar Footer */}
<div className="sidebar-footer">
<button
className="sidebar-toggle"
onClick={toggleCollapse}
aria-label="Toggle sidebar"
>
<span className="sidebar-toggle-icon">
{collapsed ? <ChevronRight size={20} /> : <ChevronLeft size={20} />}
</span>
<span className="nav-item-label">Collapse</span>
</button>
</div>
</aside>
);
};
export default Sidebar;