import React, { useState } from 'react';
import { NavLink } from 'react-router-dom';
import {
Server,
Upload,
FileText,
ScrollText,
Settings,
Menu,
X,
Moon,
Sun
} from 'lucide-react';
interface LayoutProps {
children: React.ReactNode;
}
const Layout: React.FC<LayoutProps> = ({ children }) => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [darkMode, setDarkMode] = useState(false);
const toggleDarkMode = () => {
setDarkMode(!darkMode);
document.documentElement.classList.toggle('dark');
};
const navigation = [
{ name: 'Dashboard', href: '/', icon: Server },
{ name: 'Upload', href: '/upload', icon: Upload },
{ name: 'Context', href: '/context', icon: FileText },
{ name: 'Logs', href: '/logs', icon: ScrollText },
{ name: 'Tools', href: '/tools', icon: Settings },
];
return (
<div className="min-h-screen bg-background">
{/* Mobile sidebar */}
<div className={`fixed inset-0 z-50 lg:hidden ${sidebarOpen ? 'block' : 'hidden'}`}>
<div className="fixed inset-0 bg-black/50" onClick={() => setSidebarOpen(false)} />
<div className="fixed left-0 top-0 h-full w-64 bg-card border-r border-border">
<div className="flex h-16 items-center justify-between px-4">
<div className="flex items-center space-x-2">
<Server className="h-8 w-8 text-primary" />
<span className="text-xl font-bold text-foreground">MCP Server</span>
</div>
<button
onClick={() => setSidebarOpen(false)}
className="rounded-md p-2 text-muted-foreground hover:text-foreground"
>
<X className="h-5 w-5" />
</button>
</div>
<nav className="mt-8 px-4 space-y-2">
{navigation.map((item) => (
<NavLink
key={item.name}
to={item.href}
className={({ isActive }) =>
`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive
? 'bg-primary text-primary-foreground'
: 'text-muted-foreground hover:text-foreground hover:bg-accent'
}`
}
onClick={() => setSidebarOpen(false)}
>
<item.icon className="mr-3 h-5 w-5" />
{item.name}
</NavLink>
))}
</nav>
</div>
</div>
{/* Desktop sidebar */}
<div className="hidden lg:fixed lg:inset-y-0 lg:left-0 lg:z-50 lg:w-64 lg:block">
<div className="flex h-full flex-col bg-card border-r border-border">
<div className="flex h-16 items-center px-4">
<div className="flex items-center space-x-2">
<Server className="h-8 w-8 text-primary" />
<span className="text-xl font-bold text-foreground">MCP Server</span>
</div>
</div>
<nav className="flex-1 px-4 py-6 space-y-2">
{navigation.map((item) => (
<NavLink
key={item.name}
to={item.href}
className={({ isActive }) =>
`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive
? 'bg-primary text-primary-foreground'
: 'text-muted-foreground hover:text-foreground hover:bg-accent'
}`
}
>
<item.icon className="mr-3 h-5 w-5" />
{item.name}
</NavLink>
))}
</nav>
</div>
</div>
{/* Main content */}
<div className="lg:pl-64">
<div className="sticky top-0 z-40 flex h-16 items-center gap-x-4 border-b border-border bg-card px-4 shadow-sm">
<button
type="button"
className="lg:hidden -m-2.5 p-2.5 text-muted-foreground hover:text-foreground"
onClick={() => setSidebarOpen(true)}
>
<Menu className="h-6 w-6" />
</button>
<div className="flex-1" />
<button
onClick={toggleDarkMode}
className="rounded-md p-2 text-muted-foreground hover:text-foreground"
>
{darkMode ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
</button>
</div>
<main className="py-8">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
{children}
</div>
</main>
</div>
</div>
);
};
export default Layout;