20260617 增加RPKI Explorer前端

This commit is contained in:
2026-06-17 17:29:20 +08:00
parent 6ef2c98890
commit 56f0d10dc6
28 changed files with 7362 additions and 0 deletions

View 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>
);
}