UNPKG

vulnzap-mcp

Version:

Multi-ecosystem vulnerability scanning service with MCP interface for LLMs

134 lines (130 loc) 5.87 kB
import React from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { useAuth } from '../../contexts/auth-context'; const sidebarNavItems = [ { title: 'Overview', href: '/dashboard', icon: ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5"> <rect width="7" height="9" x="3" y="3" rx="1" /> <rect width="7" height="5" x="14" y="3" rx="1" /> <rect width="7" height="9" x="14" y="12" rx="1" /> <rect width="7" height="5" x="3" y="16" rx="1" /> </svg> ), }, { title: 'Scans', href: '/dashboard/scans', icon: ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5"> <path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z" /> <line x1="16" x2="2" y1="8" y2="22" /> <line x1="17.5" x2="9" y1="15" y2="15" /> </svg> ), }, { title: 'Projects', href: '/dashboard/projects', icon: ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5"> <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" /> </svg> ), }, { title: 'API Keys', href: '/dashboard/api-keys', icon: ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5"> <path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" /> </svg> ), }, { title: 'Billing', href: '/dashboard/billing', icon: ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5"> <rect width="20" height="14" x="2" y="5" rx="2" /> <line x1="2" x2="22" y1="10" y2="10" /> </svg> ), }, { title: 'Settings', href: '/dashboard/settings', icon: ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-5 h-5"> <path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" /> <circle cx="12" cy="12" r="3" /> </svg> ), }, ]; export function DashboardLayout({ children }) { const { user } = useAuth(); const pathname = usePathname(); return ( <div className="grid min-h-screen grid-cols-1 md:grid-cols-[240px_1fr]"> {/* Sidebar */} <aside className="border-r border-border bg-card"> <div className="flex h-full max-h-screen flex-col gap-2"> <div className="flex h-14 items-center border-b border-border px-4"> <Link href="/" className="flex items-center gap-2 font-semibold"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-6 w-6"> <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" /> </svg> <span className="text-lg font-bold"> <span className="text-primary">Vuln</span> <span>Zap</span> </span> </Link> </div> <div className="flex-1 overflow-auto py-2"> <nav className="grid items-start px-2 text-sm font-medium"> {sidebarNavItems.map((item, index) => ( <Link key={index} href={item.href} className={`flex items-center gap-3 rounded-lg px-3 py-2 transition-all ${ pathname === item.href ? 'bg-primary text-primary-foreground' : 'hover:bg-accent' }`} > {item.icon} {item.title} </Link> ))} </nav> </div> <div className="mt-auto p-4"> <div className="flex items-center gap-2 rounded-lg border border-border p-4"> <div className="grid gap-1"> <p className="text-sm font-medium leading-none"> {user?.user_metadata?.full_name || user?.email || 'User'} </p> <p className="text-xs text-muted-foreground"> {user?.email || ''} </p> </div> </div> </div> </div> </aside> {/* Main content */} <main className="flex flex-col"> <header className="sticky top-0 z-10 flex h-14 items-center gap-4 border-b border-border bg-background px-4 lg:px-6"> <div className="flex-1"> <h1 className="text-lg font-semibold">Dashboard</h1> </div> </header> <div className="flex-1 p-4 lg:p-8">{children}</div> </main> </div> ); }