"use client"; import { Crown, BadgeCheck, ShieldCheck, Shield, Users, type LucideIcon } from "lucide-react"; import { roleMeta, type RoleIconKey } from "@/lib/roles"; import { BOARD_COLOR_COUNT } from "@/components/BoardIcon"; // 角色图标集中映射(图标库不含 ShieldStar,超管使用 BadgeCheck 表达"全权限认证") const ICONS: Record = { crown: Crown, "shield-star": BadgeCheck, shield: ShieldCheck, "shield-board": Shield, user: Users, }; /** 已知板块信息:名称 + 配色下标(0..15) */ type BoardRef = { name: string; colorIdx: number | null }; /** * 角色徽章:图标 + 文案。 * - 普通角色:配色走角色元数据中的 CSS token * - board_admin 提供板块名时逐板块渲染「{板块名} · 板块管理员」,配色对齐板块色 * (av-N,深浅色自适应);truncate 窄列场景折叠为单枚「{首板块}等 N 个板块 · 板块管理员」 * - board_admin 未提供板块名时退回「板块管理员 · N 个板块」 */ export default function RoleBadge({ role, boardIds, boardNames, boardColors, size = 12, className = "", title, truncate = false, }: { role?: string | null; boardIds?: number[] | null; /** id -> 名称映射;提供时板块管理员按板块逐枚展示 */ boardNames?: Map | Record; /** id -> 配色下标(boardColor 计算);提供时徽章配色对齐板块色 */ boardColors?: Map | Record; size?: number; className?: string; title?: string; /** 窄列场景:限制最大宽度并省略过长文案;多板块折叠为单枚 */ truncate?: boolean; }) { const meta = roleMeta(role); const Icon = ICONS[meta.icon]; // 单枚渲染:有板块配色下标时用 av-N 类(自带深浅色两套值),否则角色配色 token const renderBadge = (label: string, boardColorIdx: number | null, key?: number) => ( {truncate ? {label} : label} ); if (role === "board_admin" && boardNames) { const boards = (boardIds ?? []) .map((id): BoardRef | null => { const name = boardNames instanceof Map ? boardNames.get(id) : boardNames[id]; if (!name) return null; const c = boardColors ? boardColors instanceof Map ? boardColors.get(id) : boardColors[id] : undefined; return { name, colorIdx: typeof c === "number" ? c % BOARD_COLOR_COUNT : null }; }) .filter((b): b is BoardRef => b !== null); if (boards.length > 0) { if (truncate) { // 窄列:折叠为单枚,避免多枚徽章撑破布局 const first = boards[0]; const label = boards.length === 1 ? `${first.name} · ${meta.label}` : `${first.name} 等 ${boards.length} 个板块 · ${meta.label}`; return renderBadge(label, first.colorIdx); } return <>{boards.map((b, i) => renderBadge(`${b.name} · ${meta.label}`, b.colorIdx, i))}; } // 板块名缺失(板块被删等):回落通用渲染 } let label = meta.label; if (role === "board_admin" && boardIds && boardIds.length > 0) { label = `${meta.label} · ${boardIds.length} 个板块`; } return renderBadge(label, null); }