/* ===== Shared components: icons, sidebar, topbar, thinking panel ===== */
const Icon = ({ name, className = 'icon' }) => {
const paths = {
home: <>>,
memory: <>>,
radar: <>>,
strategy:<>>,
creator: <>>,
brief: <>>,
content: <>>,
monitor: <>>,
review: <>>,
report: <>>,
search: <>>,
settings:<>>,
edit: <>>,
save: <>>,
bell: <>>,
plus: <>>,
arrow: <>>,
check: <>>,
x: <>>,
upload: <>>,
refresh: <>>,
moon: <>>,
sun: <>>,
doc: <>>,
spark: <>>,
chevron: <>>,
drag: <>>,
play: <>>,
warn: <>>,
lightning:<>>,
external:<>>,
filter: <>>,
};
return (
);
};
const Sidebar = ({ current, onNav, collapsed = false, onToggleCollapsed, workspace, workspaceBrands = WORKSPACE_BRANDS, onWorkspaceChange }) => {
const [workspaceOpen, setWorkspaceOpen] = React.useState(false);
const brand = workspaceBrands.find(item => item.id === workspace?.brandId) || workspaceBrands[0];
const updateBrand = (brandId) => {
const nextBrand = workspaceBrands.find(item => item.id === brandId) || workspaceBrands[0];
onWorkspaceChange?.({ brandId: nextBrand.id });
};
return (
);
};
const Topbar = ({ crumb, campaign, onToggleThinking, thinkingOpen, theme = 'light', themeMode = 'system', onToggleTheme }) => (
{crumb}
{/报表中心|社媒资产/.test(crumb || '') ? '社媒资产同步 · Live' : /仪表盘/.test(crumb || '') ? 'Workspace 同步 · Live' : 'Campaign 中枢 · Active'}
);
const ThinkingPanel = ({ page }) => {
const CustomRail = page === 'longform' ? window.LongformThinkingRail : null;
if (CustomRail) return ;
const lines = THINKING[page] || [];
const [visible, setVisible] = React.useState(0);
const [tick, setTick] = React.useState(0);
React.useEffect(() => {
setVisible(0);
const int = setInterval(() => {
setVisible(v => {
if (v >= lines.length) { clearInterval(int); return v; }
return v + 1;
});
}, 220);
return () => clearInterval(int);
}, [page]);
React.useEffect(() => {
const int = setInterval(() => setTick(t => t + 1), 1000);
return () => clearInterval(int);
}, []);
const bodyRef = React.useRef(null);
React.useEffect(() => {
if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
}, [visible]);
return (
);
};
Object.assign(window, { Icon, Sidebar, Topbar, ThinkingPanel });