import React from 'react';
import { NavLink } from 'react-router-dom';
import {
Home,
Database,
Server,
Play,
Settings,
Key,
FileText,
Table2,
X,
} from 'lucide-react';
interface NavItem {
path: string;
label: string;
icon: React.ReactNode;
}
const navItems: NavItem[] = [
{ path: '/', label: 'Dashboard', icon: <Home className="w-5 h-5" /> },
{ path: '/connections', label: 'Connections', icon: <Server className="w-5 h-5" /> },
{ path: '/databases', label: 'Databases', icon: <Database className="w-5 h-5" /> },
{ path: '/browse', label: 'Browse Data', icon: <Table2 className="w-5 h-5" /> },
{ path: '/query', label: 'Query Tester', icon: <Play className="w-5 h-5" /> },
{ path: '/api-keys', label: 'API Keys', icon: <Key className="w-5 h-5" /> },
{ path: '/logs', label: 'Request Logs', icon: <FileText className="w-5 h-5" /> },
{ path: '/settings', label: 'Settings', icon: <Settings className="w-5 h-5" /> },
];
interface SidebarProps {
isOpen: boolean;
onClose: () => void;
}
export const Sidebar: React.FC<SidebarProps> = ({ isOpen, onClose }) => {
return (
<>
{/* Mobile overlay */}
{isOpen && (
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40 lg:hidden"
onClick={onClose}
aria-hidden="true"
/>
)}
{/* Sidebar */}
<aside
className={`
fixed lg:sticky top-0 left-0 z-50 lg:z-auto
w-64 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-700
h-screen lg:h-auto lg:min-h-screen
transform transition-transform duration-300 ease-in-out
${isOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}
`}
>
{/* Mobile close button */}
<div className="lg:hidden flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">Menu</h2>
<button
onClick={onClose}
className="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-300"
aria-label="Close menu"
>
<X className="w-5 h-5" />
</button>
</div>
<nav className="p-4 space-y-1 overflow-y-auto" style={{ maxHeight: 'calc(100vh - 73px)' }}>
{navItems.map((item) => (
<NavLink
key={item.path}
to={item.path}
end={item.path === '/'}
onClick={() => {
// Close mobile menu after navigation
if (window.innerWidth < 1024) {
onClose();
}
}}
className={({ isActive }) =>
`flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors ${
isActive
? 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400 font-medium'
: 'text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800'
}`
}
>
{item.icon}
<span>{item.label}</span>
</NavLink>
))}
</nav>
</aside>
</>
);
};