Files
jiang13-bbs/frontend/components/sidebar/SidebarRenderer.tsx
freefire 7b327bc8cc feat: 站点访问统计与可配置侧边栏组件
- 新增访问统计:visitstats 服务与查询、visit_capture 中间件、爬虫/来源识别、管理端 analytics 页面
- 新增侧边栏:sidebar 服务与 handler、管理端 sidebar 配置页、前端侧边栏组件
- 新增 widget 嵌入代码生成(widgetCode)与 widgetApi
- 遥测逻辑迁移至 handler 层,删除 service/telemetry
- env 示例补充 Docker 部署可信代理 IP 说明
2026-09-24 18:53:45 +08:00

41 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Fragment } from "react";
import type { SidebarBlockRef, SidebarWidgetPublic } from "@/lib/sidebarMeta";
import { renderSidebarBlock, type SidebarBlockProps } from "./registry";
// 页面从本文件导入该类型(registry 中定义)
export type { SidebarBlockProps };
import CustomWidgetBlock from "./CustomWidgetBlock";
// 按管理端配置渲染一列侧栏块:
// - 内置块经注册表解析,未知 key / 数据缺失静默跳过;
// - 自定义工具引用已删除或停用(公开载荷不含)时静默跳过;
// - className 缺省时输出 Fragment,布局容器(gap/space-y、sticky、限高)由页面自行决定。
export default function SidebarRenderer({
blocks,
widgets,
props,
className,
}: {
blocks: SidebarBlockRef[];
widgets: SidebarWidgetPublic[];
props: SidebarBlockProps;
className?: string;
}) {
const items = blocks
.map((ref, i) => {
if (ref.widget) {
const widget = widgets.find((x) => x.id === ref.widget);
if (!widget) return null;
return <CustomWidgetBlock key={`w-${widget.id}-${i}`} widget={widget} viewer={props.user} />;
}
if (!ref.key) return null;
const node = renderSidebarBlock(ref.key, props);
if (node === null) return null;
return <Fragment key={`k-${ref.key}-${i}`}>{node}</Fragment>;
})
.filter((x) => x !== null);
if (items.length === 0) return null;
return className ? <div className={className}>{items}</div> : <>{items}</>;
}