20260617 增加RPKI Explorer前端
This commit is contained in:
66
ui/rpki-explorer/src/components/layout/Shell.tsx
Normal file
66
ui/rpki-explorer/src/components/layout/Shell.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import { BarChart3, ChevronDown, CircleHelp, Search, Sun } from "lucide-react";
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
export interface NavigationItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: LucideIcon;
|
||||
}
|
||||
|
||||
interface ShellProps extends PropsWithChildren {
|
||||
activeView: string;
|
||||
navigationItems: NavigationItem[];
|
||||
onNavigate: (id: string) => void;
|
||||
}
|
||||
|
||||
export function Shell({ activeView, navigationItems, onNavigate, children }: ShellProps) {
|
||||
return (
|
||||
<div className="app-shell">
|
||||
<aside className="sidebar" aria-label="Primary navigation">
|
||||
<div className="brand">
|
||||
<div className="brand-mark">R</div>
|
||||
<div>
|
||||
<h1 className="brand-title">RPKI Explorer</h1>
|
||||
<div className="brand-subtitle">Validation Intelligence</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav className="nav-list">
|
||||
{navigationItems.map((item) => (
|
||||
<button
|
||||
aria-current={activeView === item.id ? "page" : undefined}
|
||||
className={`nav-item ${activeView === item.id ? "active" : ""}`}
|
||||
key={item.id}
|
||||
onClick={() => onNavigate(item.id)}
|
||||
type="button"
|
||||
>
|
||||
<item.icon aria-hidden="true" size={18} />
|
||||
<span>{item.label}</span>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
<main className="main-panel">
|
||||
<header className="topbar">
|
||||
<div className="run-selector" aria-label="Current run">
|
||||
<span>Run</span>
|
||||
<strong>latest run</strong>
|
||||
<ChevronDown aria-hidden="true" size={16} />
|
||||
</div>
|
||||
<div className="topbar-actions">
|
||||
<label className="search-box">
|
||||
<Search aria-hidden="true" size={18} />
|
||||
<span className="sr-only">Search URI or hash</span>
|
||||
<input placeholder="Search URI / hash / ASN / prefix…" />
|
||||
</label>
|
||||
<div className="ready-pill"><span /> Ready</div>
|
||||
<button aria-label="Help" className="icon-button" type="button"><CircleHelp size={19} /></button>
|
||||
<button aria-label="Theme" className="icon-button" type="button"><Sun size={19} /></button>
|
||||
<button aria-label="Analytics" className="icon-button" type="button"><BarChart3 size={19} /></button>
|
||||
</div>
|
||||
</header>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user