Punit1's picture
Initial commit
939c0c0
Raw History Blame Contribute Delete
6.72 kB
import { useState } from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import {
MessageSquare, FileText, BarChart3, Settings,
LogOut, ChevronLeft, ChevronRight, Plus, Shield,
Bot, Database, Search, Code2,
} from 'lucide-react';
import { useAuthStore } from '@/store/authStore';
import { clsx } from 'clsx';
import toast from 'react-hot-toast';
const navItems = [
{ to: '/chat', icon: MessageSquare, label: 'Chat', badge: null },
{ to: '/documents', icon: FileText, label: 'Documents', badge: 'Phase 2' },
{ to: '/analytics', icon: BarChart3, label: 'Analytics', badge: 'Phase 5' },
{ to: '/sql', icon: Database, label: 'SQL Agent', badge: 'Phase 4' },
{ to: '/code', icon: Code2, label: 'Code Agent', badge: 'Phase 5' },
{ to: '/search', icon: Search, label: 'Web Search', badge: 'Phase 5' },
];
const agentColors: Record<string, string> = {
'πŸ”΅': 'text-blue-400',
'🟒': 'text-green-400',
'🟑': 'text-amber-400',
'🟣': 'text-purple-400',
};
export default function Sidebar() {
const [collapsed, setCollapsed] = useState(false);
const { user, logout } = useAuthStore();
const navigate = useNavigate();
const handleLogout = async () => {
await logout();
toast.success('Logged out successfully');
navigate('/login');
};
return (
<aside
className={clsx(
'flex flex-col h-full border-r border-dark-700 bg-dark-900 transition-all duration-300 ease-in-out relative',
collapsed ? 'w-16' : 'w-64'
)}
>
{/* ── Logo ─────────────────────────────────────────────── */}
<div className="flex items-center gap-3 px-4 py-5 border-b border-dark-700">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary-500 to-accent-purple flex items-center justify-center flex-shrink-0">
<Bot size={16} className="text-white" />
</div>
{!collapsed && (
<div className="min-w-0">
<p className="text-sm font-bold text-white truncate">Enterprise Copilot</p>
<p className="text-xs text-dark-400 truncate">AI Platform v1.0</p>
</div>
)}
</div>
{/* ── New Chat Button ───────────────────────────────────── */}
<div className="px-3 py-3">
<button
onClick={() => navigate('/chat')}
className={clsx(
'flex items-center gap-2 w-full rounded-lg px-3 py-2.5',
'bg-primary-600 hover:bg-primary-500 text-white text-sm font-medium',
'transition-all duration-150 active:scale-95',
collapsed && 'justify-center'
)}
>
<Plus size={16} />
{!collapsed && <span>New Chat</span>}
</button>
</div>
{/* ── Navigation ───────────────────────────────────────── */}
<nav className="flex-1 px-3 space-y-0.5 overflow-y-auto">
{navItems.map(({ to, icon: Icon, label, badge }) => (
<NavLink
key={to}
to={to}
className={({ isActive }) =>
clsx(
'sidebar-item flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm transition-all duration-150',
isActive
? 'active text-white bg-primary-500/10'
: 'text-dark-300 hover:text-white',
collapsed && 'justify-center'
)
}
>
<Icon size={18} className="flex-shrink-0" />
{!collapsed && (
<span className="flex-1 truncate">{label}</span>
)}
{!collapsed && badge && (
<span className="text-xs px-1.5 py-0.5 rounded bg-dark-700 text-dark-400">
{badge}
</span>
)}
</NavLink>
))}
</nav>
{/* ── User Section ─────────────────────────────────────── */}
<div className="border-t border-dark-700 px-3 py-3 space-y-1">
{user?.role === 'admin' && (
<NavLink
to="/admin"
className={({ isActive }) =>
clsx(
'sidebar-item flex items-center gap-3 rounded-lg px-3 py-2 text-sm',
isActive ? 'active text-white' : 'text-dark-300 hover:text-white',
collapsed && 'justify-center'
)
}
>
<Shield size={16} className="flex-shrink-0" />
{!collapsed && <span>Admin</span>}
</NavLink>
)}
<NavLink
to="/settings"
className="sidebar-item flex items-center gap-3 rounded-lg px-3 py-2 text-sm text-dark-300 hover:text-white"
>
<Settings size={16} className="flex-shrink-0" />
{!collapsed && <span>Settings</span>}
</NavLink>
{/* User info */}
{!collapsed && user && (
<div className="flex items-center gap-2 px-3 py-2 mt-1">
<div className="w-7 h-7 rounded-full bg-gradient-to-br from-primary-400 to-accent-purple flex items-center justify-center text-xs font-bold text-white flex-shrink-0">
{user.full_name.charAt(0).toUpperCase()}
</div>
<div className="min-w-0 flex-1">
<p className="text-xs font-medium text-white truncate">{user.full_name}</p>
<p className="text-xs text-dark-400 capitalize">{user.role}</p>
</div>
</div>
)}
<button
onClick={handleLogout}
className={clsx(
'sidebar-item flex items-center gap-3 w-full rounded-lg px-3 py-2 text-sm text-dark-300 hover:text-red-400 transition-colors',
collapsed && 'justify-center'
)}
>
<LogOut size={16} className="flex-shrink-0" />
{!collapsed && <span>Sign Out</span>}
</button>
</div>
{/* ── Collapse Toggle ───────────────────────────────────── */}
<button
onClick={() => setCollapsed(!collapsed)}
className="absolute -right-3 top-20 w-6 h-6 rounded-full bg-dark-700 border border-dark-600 flex items-center justify-center hover:bg-dark-600 transition-colors z-10"
>
{collapsed ? <ChevronRight size={12} /> : <ChevronLeft size={12} />}
</button>
</aside>
);
}