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;