feat(frontend): P1 核心 UI 组件 — Context Bar + Work Mode + Insight Rail + 工作区 + 决策线程
- ContextBar: Scope/Lens/Time 三维切换器 + Action Filter - ContextBarProvider: 全局 Context + URL 参数双向同步 - WorkModeSwitcher: Overview/Compare/Focus/Queue 四种模式 - FocusMode: 全屏沉浸分析 + TOC/BML 入口 - QueueMode: 左右分栏 Split View - CompareMode: 2-5 企业并排对比 + 差异高亮 - InsightRail: 右侧可折叠 AI 面板 + 12 Agent 差异化卡片 - WorkspaceTabs: 多 Tab 管理(最多 8 个) - HighlightsPanel: 企业战情室顶部 KPI 摘要 - ThreadList + ThreadDetail: 决策线程列表/详情 + 状态机时间线
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/** Work Mode 切换器组件 — Overview/Compare/Focus/Queue 四种自适应模式。 */
|
||||
|
||||
"use client";
|
||||
|
||||
import { LayoutGrid, GitCompareArrows, Focus, Columns2 } from "lucide-react";
|
||||
import { useState, type ReactNode } from "react";
|
||||
|
||||
/** 工作模式类型。 */
|
||||
export type WorkMode = "overview" | "compare" | "focus" | "queue";
|
||||
|
||||
/** 工作模式配置。 */
|
||||
const MODE_CONFIG: Record<WorkMode, { label: string; icon: typeof LayoutGrid; description: string }> = {
|
||||
overview: {
|
||||
label: "总览",
|
||||
icon: LayoutGrid,
|
||||
description: "Portfolio 全局浏览",
|
||||
},
|
||||
compare: {
|
||||
label: "对比",
|
||||
icon: GitCompareArrows,
|
||||
description: "2-5 家企业并排对比",
|
||||
},
|
||||
focus: {
|
||||
label: "聚焦",
|
||||
icon: Focus,
|
||||
description: "单企业深度分析",
|
||||
},
|
||||
queue: {
|
||||
label: "队列",
|
||||
icon: Columns2,
|
||||
description: "左右分栏批量处理",
|
||||
},
|
||||
};
|
||||
|
||||
/** Work Mode 切换器 Props。 */
|
||||
interface WorkModeSwitcherProps {
|
||||
mode: WorkMode;
|
||||
onChange: (mode: WorkMode) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work Mode 切换器组件。
|
||||
*
|
||||
* 四种自适应工作模式:Overview / Compare / Focus / Queue。
|
||||
*/
|
||||
export function WorkModeSwitcher({ mode, onChange }: WorkModeSwitcherProps) {
|
||||
return (
|
||||
<div className="flex items-center gap-1 rounded-lg border bg-white p-1">
|
||||
{(Object.keys(MODE_CONFIG) as WorkMode[]).map((key) => {
|
||||
const config = MODE_CONFIG[key];
|
||||
const isActive = mode === key;
|
||||
return (
|
||||
<button
|
||||
key={key}
|
||||
type="button"
|
||||
onClick={() => onChange(key)}
|
||||
title={config.description}
|
||||
className={`flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${
|
||||
isActive
|
||||
? "bg-indigo-50 text-indigo-600"
|
||||
: "text-gray-600 hover:bg-gray-50"
|
||||
}`}
|
||||
aria-pressed={isActive}
|
||||
>
|
||||
<config.icon size={16} aria-hidden="true" />
|
||||
{config.label}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user