/* global React, PR */ const { useState, useMemo, useRef, useEffect } = React; const { I, Avatar, StagePill } = PR; // ============ Sidebar ============ function Sidebar({ active, setActive, theme, setTheme, data, user, onLogout }) { const counts = useMemo(() => { const c = { all: 0, active: 0, decision: 0, scale: 0, archive: 0 }; data.hypotheses.forEach(h => { c.all++; if (h.decision === "kill") c.archive++; else if (h.decision === "scale") c.scale++; else c.active++; if (h.stage === "decision" && !h.decision) c.decision++; }); return c; }, [data]); const NavItem = ({ id, icon, label, count }) => (
setActive(id)}>
{icon} {label}
{count != null && {count}}
); const userAuthor = user ? { name: user.full_name || user.username, color: user.color || "#7C8BA1" } : null; return ( ); } // ============ Topbar ============ function Topbar({ crumbs, onNew }) { return (
{crumbs.map((c, i) => ( {i > 0 && /} {c} ))}
{I.search} Search hypotheses ⌘K
); } // ============ Filter chip with dropdown ============ function FilterChip({ label, value, options, onChange }) { const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return; const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, [open]); const selected = options.find(o => o.value === value); const isActive = !!value; return (
setOpen(o => !o)} > {label}: {selected ? selected.label : "any"} {isActive && ( { e.stopPropagation(); onChange(""); setOpen(false); }} style={{ marginLeft: 4, opacity: 0.65, cursor: "pointer" }} >× )} {open && (
{ onChange(""); setOpen(false); }} > Any
{options.map(o => (
{ onChange(o.value); setOpen(false); }} > {o.label}
))}
)}
); } // ============ Page header with view switch ============ function PageHead({ title, sub, view, setView, filters, setFilters, filterOptions, currentUserId }) { const set = (k, v) => setFilters(f => ({ ...f, [k]: v })); return ( <>

{title}

{sub}

{view !== undefined && (
)}
{filters && filterOptions && (
set("set", "all")}>All set("set", "active")}>Active {currentUserId && ( set("set", "mine")}>Mine )} set("stage", v)} /> set("genre", v)} /> set("author", v)} /> set("risk", v)} />
)} ); } window.PRShell = { Sidebar, Topbar, PageHead };