Spaces:
Running
Running
BRIDGE Platform Agent
feat(platform): BRIDGE Modules hub with /modules/e and /modules/s routed workspaces
1955a0f Download src/modules/PlatformSidebar.tsx from sitcod3/BRIDGE_Modul-S_prod: direct link, hf CLI and curl.
- Browser
- Download file 6.53 kB
-
https://huggingface.co/spaces/sitcod3/BRIDGE_Modul-S_prod/resolve/main/src/modules/PlatformSidebar.tsx
- Command line
-
hf download hf://spaces/sitcod3/BRIDGE_Modul-S_prod/src/modules/PlatformSidebar.tsx
-
curl -L -o PlatformSidebar.tsx https://huggingface.co/spaces/sitcod3/BRIDGE_Modul-S_prod/resolve/main/src/modules/PlatformSidebar.tsx
6.53 kB
| import { Link, useLocation, useNavigate } from "react-router-dom"; | |
| import { LayoutDashboard } from "lucide-react"; | |
| import { cn } from "../utils/cn"; | |
| import { useTheme } from "../context/ThemeContext"; | |
| import AnimatedLogo from "./../components/AnimatedLogo"; | |
| import Logo from "./../components/Logo"; | |
| import { useLaunch } from "./LaunchContext"; | |
| import { MODULES, ModuleId, moduleHref } from "./registry"; | |
| /** | |
| * Platform sidebar — wires the BRIDGE MODULES direct-launch section plus the | |
| * active module's navigation registry. Launching a module plays its | |
| * random-reassembly animation (re-seeded every launch). | |
| */ | |
| export default function PlatformSidebar({ module, onClose }: { module: ModuleId; onClose?: () => void }) { | |
| const location = useLocation(); | |
| const navigate = useNavigate(); | |
| const { config } = useTheme(); | |
| const { startLaunch } = useLaunch(); | |
| const def = MODULES[module]; | |
| const launch = (target: ModuleId | "hub") => { | |
| onClose?.(); | |
| startLaunch(target); | |
| }; | |
| const isActiveModule = (id: ModuleId) => location.pathname.startsWith(MODULES[id].basePath); | |
| const isActivePath = (path: string) => { | |
| const full = moduleHref(module, path); | |
| return path === "" ? location.pathname === full : location.pathname.startsWith(full); | |
| }; | |
| return ( | |
| <div className="w-64 border-r border-white/5 bg-zinc-950/90 md:bg-zinc-950/60 backdrop-blur-2xl flex flex-col shrink-0 h-full relative z-20 shadow-[4px_0_24px_-4px_rgba(0,0,0,0.8)]"> | |
| <div className="h-16 flex items-center px-6 border-b border-white/5 shrink-0 gap-3"> | |
| <AnimatedLogo className="w-7 h-7" /> | |
| <Logo wordmark={def.wordmark} /> | |
| </div> | |
| <nav className="flex-1 overflow-y-auto py-4 px-3 space-y-1"> | |
| {/* BRIDGE MODULES — direct-launch section (Phase 5) */} | |
| <div className="mb-4"> | |
| <div className="px-3 pb-2 text-[9px] font-bold tracking-[0.22em] uppercase text-zinc-600 font-mono"> | |
| Bridge Modules | |
| </div> | |
| <div className="space-y-1.5"> | |
| {(["e", "s"] as ModuleId[]).map((id) => { | |
| const m = MODULES[id]; | |
| const active = isActiveModule(id); | |
| const Icon = m.icon; | |
| return ( | |
| <button | |
| key={id} | |
| type="button" | |
| onClick={() => launch(id)} | |
| aria-current={active ? "page" : undefined} | |
| className={cn( | |
| "w-full flex items-center gap-3 px-3 py-2.5 text-[13px] font-medium rounded-lg transition-all duration-300 relative group overflow-hidden border text-left", | |
| active | |
| ? "bg-white/5 border-white/10 shadow-[inset_0_1px_1px_rgba(255,255,255,0.05)]" | |
| : "text-zinc-400 hover:text-zinc-200 hover:bg-white/5 border-transparent" | |
| )} | |
| style={active ? { color: m.theme.accentText } : {}} | |
| > | |
| {active && ( | |
| <span | |
| className="absolute left-0 top-1/2 -translate-y-1/2 w-1 h-6 rounded-r-full" | |
| style={{ backgroundColor: m.theme.accent, boxShadow: `0 0 15px ${m.theme.accent}` }} | |
| /> | |
| )} | |
| <span | |
| className="w-5 h-5 rounded-md flex items-center justify-center shrink-0 border transition-transform duration-300 group-hover:scale-110" | |
| style={{ | |
| backgroundColor: `${m.theme.accent}14`, | |
| borderColor: `${m.theme.accent}44`, | |
| }} | |
| > | |
| <Icon className="w-3 h-3" style={{ color: m.theme.accent }} /> | |
| </span> | |
| <span className="flex-1">{m.label}</span> | |
| <span | |
| className="w-1.5 h-1.5 rounded-full shrink-0 transition-opacity" | |
| style={{ | |
| backgroundColor: m.theme.accent, | |
| boxShadow: `0 0 8px ${m.theme.accent}`, | |
| opacity: active ? 1 : 0.35, | |
| }} | |
| /> | |
| </button> | |
| ); | |
| })} | |
| </div> | |
| <button | |
| type="button" | |
| onClick={() => launch("hub")} | |
| className="mt-1.5 w-full flex items-center gap-3 px-3 py-2 text-[11px] font-medium rounded-lg text-zinc-500 hover:text-zinc-300 hover:bg-white/5 border border-transparent transition-all duration-300 text-left" | |
| > | |
| <LayoutDashboard className="w-3.5 h-3.5" /> | |
| Platform Hub | |
| </button> | |
| </div> | |
| {/* Active module navigation */} | |
| <div className="px-3 pb-2 pt-1 text-[9px] font-bold tracking-[0.22em] uppercase text-zinc-600 font-mono"> | |
| {def.label} | |
| </div> | |
| {def.nav.map((item) => { | |
| const isActive = isActivePath(item.path); | |
| const full = moduleHref(module, item.path); | |
| return ( | |
| <button | |
| key={item.name} | |
| type="button" | |
| onClick={() => { | |
| onClose?.(); | |
| if (location.pathname !== full) navigate(full); | |
| }} | |
| aria-current={isActive ? "page" : undefined} | |
| className={cn( | |
| "w-full flex items-center gap-3 px-3 py-2.5 text-[13px] font-medium rounded-lg transition-all duration-300 relative group overflow-hidden border text-left", | |
| isActive | |
| ? "bg-white/5 border-white/10 shadow-[inset_0_1px_1px_rgba(255,255,255,0.05)]" | |
| : "text-zinc-400 hover:text-zinc-200 hover:bg-white/5 border-transparent" | |
| )} | |
| style={isActive ? { color: config.accentText } : {}} | |
| > | |
| {isActive && ( | |
| <div | |
| className="absolute left-0 top-1/2 -translate-y-1/2 w-1 h-6 rounded-r-full" | |
| style={{ | |
| backgroundColor: config.accent, | |
| boxShadow: `0 0 15px ${config.accent}`, | |
| }} | |
| /> | |
| )} | |
| <item.icon | |
| className={cn("w-4 h-4 transition-transform duration-300 group-hover:scale-110", isActive ? "" : "text-zinc-500")} | |
| style={isActive ? { color: config.accent, filter: `drop-shadow(0 0 8px ${config.accent})` } : {}} | |
| /> | |
| {item.name} | |
| </button> | |
| ); | |
| })} | |
| </nav> | |
| </div> | |
| ); | |
| } | |