| typescript | |
| import React from 'react' | |
| import { Link, useLocation } from 'react-router-dom' | |
| import { | |
| LayoutDashboard, | |
| Server, | |
| BookOpen, | |
| Network, | |
| Settings, | |
| X | |
| } from 'lucide-react' | |
| interface SidebarProps { | |
| open: boolean | |
| onClose: () => void | |
| } | |
| const navigation = [ | |
| { name: 'Dashboard', href: '/', icon: LayoutDashboard }, | |
| { name: 'Asset Inventory', href: '/assets', icon: Server }, | |
| { name: 'Knowledge Base', href: '/knowledge', icon: BookOpen }, | |
| { name: 'Relationship Map', href: '/map', icon: Network }, | |
| { name: 'Settings', href: '/settings', icon: Settings }, | |
| ] | |
| const Sidebar: React.FC<SidebarProps> = ({ open, onClose }) => { | |
| const location = useLocation() | |
| return ( | |
| <> | |
| {/* Mobile overlay */} | |
| {open && ( | |
| <div | |
| className="fixed inset-0 z-40 bg-gray-600 bg-opacity-75 lg:hidden" | |
| onClick={onClose} | |
| /> | |
| )} | |
| {/* Sidebar */} | |
| <div className={` | |
| fixed inset-y-0 left-0 z-50 w-64 bg-white shadow-xl transform transition-transform duration-300 ease-in-out lg:translate-x-0 lg:static lg:inset-0 | |
| ${open ? 'translate-x-0' : '-translate-x-full'} | |
| `}> | |
| <div className="flex items-center justify-between h-16 px-4 border-b border-gray-200"> | |
| <div className="flex items-center"> | |
| <div className="flex-shrink-0"> | |
| <div className="h-8 w-8 bg-primary-600 rounded-button flex items-center justify-center"> | |
| <span className="text-white font-bold text-sm">MI</span> | |
| </div> | |
| <span className="ml-3 text-lg font-semibold text-gray-900">MapIT</span> | |
| </div> | |
| </div> | |
| <button | |
| onClick={onClose} | |
| className="lg:hidden p-2 rounded-button text-gray-400 hover:text-gray-500 hover:bg-gray-100" | |
| > | |
| <X className="h-5 w-5" /> | |
| </button> | |
| </div> | |
| <nav className="mt-8 px-4 space-y-2"> | |
| {navigation.map((item) => { | |
| const isActive = location.pathname === item.href | |
| return ( | |
| <Link | |
| key={item.name} | |
| to={item.href} | |
| className={` | |
| group flex items-center px-3 py-2 text-sm font-medium rounded-button transition-colors duration-200 | |
| ${isActive | |
| ? 'bg-primary-50 text-primary-700 border border-primary-200' | |
| : 'text-gray-600 hover:text-gray-900 hover:bg-gray-50' | |
| } | |
| `} | |
| onClick={() => window.innerWidth < 1024 && onClose()} | |
| > | |
| <item.icon className={` | |
| mr-3 h-5 w-5 flex-shrink-0 | |
| ${isActive ? 'text-primary-500' : 'text-gray-400 group-hover:text-gray-500'} | |
| `} /> | |
| {item.name} | |
| </Link> | |
| ) | |
| })} | |
| </nav> | |
| </div> | |
| </> | |
| ) | |
| } | |
| export default Sidebar | |
| </html> |