Spaces:
Running
Running
File size: 4,547 Bytes
1e2158c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | import React, { useEffect } from 'react';
import { NavLink, useLocation } from 'react-router-dom';
import {
LayoutDashboard,
Database,
MessageSquare,
BarChart3,
FileText,
Settings,
LogOut,
X,
Boxes,
Brain,
TrendingUp,
TrendingDown,
Rocket,
BookOpen,
Activity,
Workflow,
} from 'lucide-react';
import { motion } from 'framer-motion';
import Logo from '@/components/Logo';
import { useAuth } from '@/contexts/AuthContext';
const navItems = [
{ path: '/data-hub', icon: Database, label: 'Data Hub' },
{ path: '/dashboard', icon: LayoutDashboard, label: 'Dashboard' },
{ path: '/anomalies', icon: TrendingDown, label: 'Anomaly Monitor' },
{ path: '/lineage', icon: Boxes, label: 'Data Lineage' },
{ path: '/simulator', icon: TrendingUp, label: 'Scenario Simulator' },
{ path: '/reports', icon: FileText, label: 'Reports' },
{ path: '/data-stories', icon: BookOpen, label: 'Data Stories', badge: 'V5' },
{ path: '/ml-predictions', icon: Brain, label: 'ML Predictions' },
{ path: '/model-monitoring', icon: Activity, label: 'Model Monitoring', badge: 'V5' },
{ path: '/pipelines', icon: Workflow, label: 'Pipeline Builder', badge: 'V5' },
{ path: '/chat', icon: MessageSquare, label: 'AI Analyst' },
{ path: '/collaborate', icon: MessageSquare, label: 'Collaborate' },
{ path: '/settings', icon: Settings, label: 'Settings' },
{ path: '/developer', icon: Boxes, label: 'Developer' },
];
interface SidebarProps {
isMobileMenuOpen?: boolean;
onClose?: () => void;
}
const Sidebar: React.FC<SidebarProps> = ({ isMobileMenuOpen = false, onClose }) => {
const { signOut, user } = useAuth();
const location = useLocation();
// Close menu on route change
useEffect(() => {
if (onClose) onClose();
}, [location.pathname]);
const handleLogout = async () => {
if (confirm('Are you sure you want to sign out?')) {
await signOut();
}
};
return (
<motion.aside
initial={false}
animate={{ x: 0 }}
transition={{ duration: 0.3, ease: 'easeInOut' }}
className={`
w-64 bg-dark-surface border-r border-dark-border flex-col
fixed lg:relative inset-y-0 left-0 z-50
${isMobileMenuOpen ? 'flex' : 'hidden'} lg:flex
`}
>
{/* Mobile close button */}
<div className="lg:hidden absolute top-4 right-4">
<button
onClick={onClose}
className="p-2 rounded-lg hover:bg-dark-card transition-colors"
>
<X className="w-5 h-5 text-gray-400" />
</button>
</div>
{/* Logo */}
<div className="p-4 border-b border-dark-border">
<Logo size="md" showText={true} />
</div>
{/* Navigation */}
<nav className="flex-1 p-4 space-y-2 overflow-y-auto">
{navItems.map((item) => (
<NavLink
key={item.path}
to={item.path}
className={({ isActive }) =>
`sidebar-item flex items-center space-x-3 px-4 py-3 rounded-xl transition-all duration-200 ${isActive ? 'active bg-primary-500/10' : 'hover:bg-dark-card'}`
}
>
{({ isActive }) => (
<>
<item.icon className={`w-5 h-5 flex-shrink-0 ${isActive ? 'text-primary-400' : ''}`} />
<span className="font-medium">{item.label}</span>
{(item as any).badge && (
<span className="ml-auto text-[10px] font-bold px-1.5 py-0.5 rounded-full bg-gradient-to-r from-violet-500 to-fuchsia-500 text-white">
{(item as any).badge}
</span>
)}
</>
)}
</NavLink>
))}
</nav>
{/* User Info & Logout */}
<div className="p-4 border-t border-dark-border space-y-3">
{/* User Email */}
{user && (
<div className="px-3 py-2 bg-dark-card rounded-lg">
<p className="text-xs text-gray-400">Signed in as</p>
<p className="text-sm text-white truncate" title={user.email || ''}>{user.email}</p>
</div>
)}
{/* Logout Button */}
<button
onClick={handleLogout}
className="w-full flex items-center space-x-3 px-4 py-3 rounded-xl text-gray-400 hover:text-red-400 hover:bg-red-500/10 transition-all duration-200"
>
<LogOut className="w-5 h-5 flex-shrink-0" />
<span className="font-medium">Sign Out</span>
</button>
</div>
</motion.aside>
);
};
export default Sidebar;
|