@tfdesign/b-end 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/AI_READ_FIRST.md +131 -0
  2. package/LICENSE +21 -0
  3. package/README.md +353 -0
  4. package/package.json +67 -0
  5. package/scripts/check-tfds-contract.mjs +334 -0
  6. package/scripts/check-tfds-integration.mjs +263 -0
  7. package/scripts/postinstall-cursor-skill.mjs +382 -0
  8. package/scripts/setup.mjs +520 -0
  9. package/skills/tfds/CHECKLIST.md +205 -0
  10. package/skills/tfds/COMMON_FAILURES.md +238 -0
  11. package/skills/tfds/DESIGN_PRINCIPLES.md +477 -0
  12. package/skills/tfds/GLOBAL_DESIGN_RULES.md +636 -0
  13. package/skills/tfds/LAYOUT_RECIPES.md +140 -0
  14. package/skills/tfds/LAYOUT_RULES.md +1355 -0
  15. package/skills/tfds/PAGE_ARCHETYPES.md +201 -0
  16. package/skills/tfds/SKILL.md +188 -0
  17. package/skills/tfds/components.index.json +7305 -0
  18. package/skills/tfds/components.summary.json +1809 -0
  19. package/src/_b_end_runtime/components/AiSuggestionShared.jsx +166 -0
  20. package/src/_b_end_runtime/components/Avatar.jsx +325 -0
  21. package/src/_b_end_runtime/components/Avatar.tokens.js +76 -0
  22. package/src/_b_end_runtime/components/AvatarGridPreview.jsx +56 -0
  23. package/src/_b_end_runtime/components/AvatarGroup.jsx +80 -0
  24. package/src/_b_end_runtime/components/AvatarGroup.tokens.js +28 -0
  25. package/src/_b_end_runtime/components/Button.jsx +144 -0
  26. package/src/_b_end_runtime/components/Button.tokens.js +90 -0
  27. package/src/_b_end_runtime/components/Card.jsx +460 -0
  28. package/src/_b_end_runtime/components/Card.tokens.js +124 -0
  29. package/src/_b_end_runtime/components/CardPreview.jsx +51 -0
  30. package/src/_b_end_runtime/components/ChatBubble.jsx +384 -0
  31. package/src/_b_end_runtime/components/ChatBubble.tokens.js +60 -0
  32. package/src/_b_end_runtime/components/ChatBubblePreview.jsx +129 -0
  33. package/src/_b_end_runtime/components/ChatInput.jsx +1399 -0
  34. package/src/_b_end_runtime/components/ChatInput.tokens.js +75 -0
  35. package/src/_b_end_runtime/components/ChatMessage.jsx +2215 -0
  36. package/src/_b_end_runtime/components/ChatMessage.tokens.js +257 -0
  37. package/src/_b_end_runtime/components/ChatMessagePreview.jsx +388 -0
  38. package/src/_b_end_runtime/components/Checkbox.jsx +317 -0
  39. package/src/_b_end_runtime/components/Checkbox.tokens.js +59 -0
  40. package/src/_b_end_runtime/components/ConversationList.jsx +1264 -0
  41. package/src/_b_end_runtime/components/ConversationList.tokens.js +135 -0
  42. package/src/_b_end_runtime/components/ConversationListPreview.jsx +108 -0
  43. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.jsx +324 -0
  44. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.tokens.js +69 -0
  45. package/src/_b_end_runtime/components/DatePicker.jsx +739 -0
  46. package/src/_b_end_runtime/components/DatePicker.tokens.js +99 -0
  47. package/src/_b_end_runtime/components/Empty.jsx +141 -0
  48. package/src/_b_end_runtime/components/Empty.tokens.js +40 -0
  49. package/src/_b_end_runtime/components/Form.jsx +609 -0
  50. package/src/_b_end_runtime/components/Form.tokens.js +77 -0
  51. package/src/_b_end_runtime/components/FormFieldStack.jsx +123 -0
  52. package/src/_b_end_runtime/components/FormFieldStack.tokens.js +12 -0
  53. package/src/_b_end_runtime/components/FormTitle.jsx +119 -0
  54. package/src/_b_end_runtime/components/FormTitle.tokens.js +87 -0
  55. package/src/_b_end_runtime/components/FullScreenPage.jsx +97 -0
  56. package/src/_b_end_runtime/components/FullScreenPage.tokens.js +19 -0
  57. package/src/_b_end_runtime/components/Icon.jsx +172 -0
  58. package/src/_b_end_runtime/components/Icon.tokens.js +26 -0
  59. package/src/_b_end_runtime/components/IconGridPreview.jsx +277 -0
  60. package/src/_b_end_runtime/components/InfoDisplayPanel.jsx +620 -0
  61. package/src/_b_end_runtime/components/InfoDisplayPanel.tokens.js +71 -0
  62. package/src/_b_end_runtime/components/InfoDisplayPanelPreview.jsx +133 -0
  63. package/src/_b_end_runtime/components/Input.jsx +258 -0
  64. package/src/_b_end_runtime/components/Input.tokens.js +68 -0
  65. package/src/_b_end_runtime/components/InputNumber.jsx +242 -0
  66. package/src/_b_end_runtime/components/InputNumber.tokens.js +55 -0
  67. package/src/_b_end_runtime/components/Modal.jsx +155 -0
  68. package/src/_b_end_runtime/components/Modal.tokens.js +73 -0
  69. package/src/_b_end_runtime/components/NavBar.jsx +842 -0
  70. package/src/_b_end_runtime/components/NavBar.tokens.js +97 -0
  71. package/src/_b_end_runtime/components/NavBarPreview.jsx +11 -0
  72. package/src/_b_end_runtime/components/Radio.jsx +227 -0
  73. package/src/_b_end_runtime/components/Radio.tokens.js +59 -0
  74. package/src/_b_end_runtime/components/Select.jsx +766 -0
  75. package/src/_b_end_runtime/components/Select.tokens.js +99 -0
  76. package/src/_b_end_runtime/components/Sheet.jsx +132 -0
  77. package/src/_b_end_runtime/components/Sheet.tokens.js +61 -0
  78. package/src/_b_end_runtime/components/Slider.jsx +346 -0
  79. package/src/_b_end_runtime/components/Slider.tokens.js +47 -0
  80. package/src/_b_end_runtime/components/Switch.jsx +124 -0
  81. package/src/_b_end_runtime/components/Switch.tokens.js +38 -0
  82. package/src/_b_end_runtime/components/Table.jsx +1338 -0
  83. package/src/_b_end_runtime/components/Table.tokens.js +147 -0
  84. package/src/_b_end_runtime/components/TablePreview.jsx +599 -0
  85. package/src/_b_end_runtime/components/Tabs.jsx +149 -0
  86. package/src/_b_end_runtime/components/Tabs.tokens.js +102 -0
  87. package/src/_b_end_runtime/components/Tag.jsx +199 -0
  88. package/src/_b_end_runtime/components/Tag.tokens.js +171 -0
  89. package/src/_b_end_runtime/components/TagBar.jsx +1134 -0
  90. package/src/_b_end_runtime/components/TagBar.tokens.js +75 -0
  91. package/src/_b_end_runtime/components/TagGridPreview.jsx +23 -0
  92. package/src/_b_end_runtime/components/TagInput.jsx +382 -0
  93. package/src/_b_end_runtime/components/TagInput.tokens.js +52 -0
  94. package/src/_b_end_runtime/components/TextArea.jsx +363 -0
  95. package/src/_b_end_runtime/components/TextArea.tokens.js +65 -0
  96. package/src/_b_end_runtime/components/TimePicker.jsx +444 -0
  97. package/src/_b_end_runtime/components/TimePicker.tokens.js +77 -0
  98. package/src/_b_end_runtime/components/Toast.jsx +120 -0
  99. package/src/_b_end_runtime/components/Toast.tokens.js +146 -0
  100. package/src/_b_end_runtime/components/Tooltip.jsx +282 -0
  101. package/src/_b_end_runtime/components/Tooltip.tokens.js +48 -0
  102. package/src/_b_end_runtime/components/TooltipPreview.jsx +50 -0
  103. package/src/_b_end_runtime/components/Upload.jsx +455 -0
  104. package/src/_b_end_runtime/components/Upload.tokens.js +47 -0
  105. package/src/_b_end_runtime/components/avatar-assets/avatar-default.png +0 -0
  106. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-1.png +0 -0
  107. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-2.png +0 -0
  108. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-3.png +0 -0
  109. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-4.png +0 -0
  110. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-5.png +0 -0
  111. package/src/_b_end_runtime/components/empty-assets/administrator-1.svg +40 -0
  112. package/src/_b_end_runtime/components/empty-assets/administrator-2.svg +33 -0
  113. package/src/_b_end_runtime/components/empty-assets/construction.svg +33 -0
  114. package/src/_b_end_runtime/components/empty-assets/failure.svg +49 -0
  115. package/src/_b_end_runtime/components/empty-assets/idle.svg +34 -0
  116. package/src/_b_end_runtime/components/empty-assets/no-access.svg +36 -0
  117. package/src/_b_end_runtime/components/empty-assets/no-content.svg +77 -0
  118. package/src/_b_end_runtime/components/empty-assets/no-result.svg +61 -0
  119. package/src/_b_end_runtime/components/empty-assets/not-found.svg +46 -0
  120. package/src/_b_end_runtime/components/empty-assets/success.svg +38 -0
  121. package/src/_b_end_runtime/components/file-type-assets/batch-report.png +0 -0
  122. package/src/_b_end_runtime/components/file-type-assets/catcat.svg +21 -0
  123. package/src/_b_end_runtime/components/file-type-assets/code.png +0 -0
  124. package/src/_b_end_runtime/components/file-type-assets/conversation.png +0 -0
  125. package/src/_b_end_runtime/components/file-type-assets/document.png +0 -0
  126. package/src/_b_end_runtime/components/file-type-assets/feishu-card.png +0 -0
  127. package/src/_b_end_runtime/components/file-type-assets/feishu-sheet.png +0 -0
  128. package/src/_b_end_runtime/components/file-type-assets/feishu.png +0 -0
  129. package/src/_b_end_runtime/components/file-type-assets/image.png +0 -0
  130. package/src/_b_end_runtime/components/file-type-assets/index.js +105 -0
  131. package/src/_b_end_runtime/components/file-type-assets/knowledge.png +0 -0
  132. package/src/_b_end_runtime/components/file-type-assets/pdf.png +0 -0
  133. package/src/_b_end_runtime/components/file-type-assets/pe.png +0 -0
  134. package/src/_b_end_runtime/components/file-type-assets/strategy.png +0 -0
  135. package/src/_b_end_runtime/components/file-type-assets/table.png +0 -0
  136. package/src/_b_end_runtime/components/file-type-assets/webpage.png +0 -0
  137. package/src/_b_end_runtime/components/file-type-assets/xmind.png +0 -0
  138. package/src/_b_end_runtime/components/icons/icon-data.js +12496 -0
  139. package/src/_b_end_runtime/components/nav-bar-assets/bytehi-logo-mark.svg +21 -0
  140. package/src/_b_end_runtime/components/table-assets/avatar.png +0 -0
  141. package/src/_b_end_runtime/components/table-assets/button.png +0 -0
  142. package/src/_b_end_runtime/components/table-assets/icon-chevron-down.png +0 -0
  143. package/src/_b_end_runtime/components/table-cell-assets/avatar.png +0 -0
  144. package/src/_b_end_runtime/components/table-cell-assets/button.png +0 -0
  145. package/src/_b_end_runtime/components/table-cell-assets/checkbox.png +0 -0
  146. package/src/_b_end_runtime/components/table-cell-assets/icon-chevron-right.png +0 -0
  147. package/src/_b_end_runtime/components/table-cell-assets/icon.png +0 -0
  148. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-handle.png +0 -0
  149. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-tree-triangle-right.png +0 -0
  150. package/src/_b_end_runtime/components/table-cell-assets/switch.png +0 -0
  151. package/src/_b_end_runtime/components/tagShared.js +3 -0
  152. package/src/_b_end_runtime/components/team-avatar-assets/chengcheng-murphy.png +0 -0
  153. package/src/_b_end_runtime/components/team-avatar-assets/duan-ran.png +0 -0
  154. package/src/_b_end_runtime/components/team-avatar-assets/guo-zhezhi.png +0 -0
  155. package/src/_b_end_runtime/components/team-avatar-assets/li-siru.png +0 -0
  156. package/src/_b_end_runtime/components/team-avatar-assets/liu-delin.png +0 -0
  157. package/src/_b_end_runtime/components.js +3499 -0
  158. package/src/_b_end_runtime/index.js +9 -0
  159. package/src/_b_end_runtime/page-patterns/BasePageFramePattern.jsx +395 -0
  160. package/src/_b_end_runtime/page-patterns/ChatConversationPattern.jsx +989 -0
  161. package/src/_b_end_runtime/page-patterns/ChatHomePagePattern.jsx +281 -0
  162. package/src/_b_end_runtime/page-patterns/CopilotPagePattern.jsx +380 -0
  163. package/src/_b_end_runtime/page-patterns/CustomerServiceWorkspaceFramePattern.jsx +392 -0
  164. package/src/_b_end_runtime/page-patterns/IMConversationPattern.jsx +590 -0
  165. package/src/_b_end_runtime/page-patterns/McpManagementPage.jsx +237 -0
  166. package/src/_b_end_runtime/page-patterns/StrategyListPage.jsx +189 -0
  167. package/src/_b_end_runtime/page-patterns/TabTopBarListPage.jsx +594 -0
  168. package/src/_b_end_runtime/page-patterns/VariableManagementPage.jsx +87 -0
  169. package/src/_b_end_runtime/page-patterns/pageListShared.jsx +177 -0
  170. package/src/_b_end_runtime/patterns.js +428 -0
  171. package/src/_b_end_runtime/preview-registry.jsx +4719 -0
  172. package/src/_b_end_runtime/teamMembers.js +56 -0
  173. package/src/_b_end_runtime/tokens.js +500 -0
  174. package/src/index.d.ts +1073 -0
  175. package/src/index.js +52 -0
  176. package/theme.css +350 -0
@@ -0,0 +1,281 @@
1
+ import { useState } from 'react';
2
+ import NavBar from '../components/NavBar';
3
+ import Tabs from '../components/Tabs';
4
+ import ChatInput from '../components/ChatInput';
5
+ import Card from '../components/Card';
6
+ import Input from '../components/Input';
7
+ import Icon from '../components/Icon';
8
+
9
+ /**
10
+ * ChatHomePagePattern — Chat 类产品首页模板
11
+ *
12
+ * 右侧内容区从上到下:
13
+ * 1. Hero 区:大标题 + 副标题 + 居中 ChatInput + 快捷建议 chip
14
+ * 2. 筛选行(左 Search + 右胶囊 Tab),左右 40px 边距
15
+ * 3. 自适应卡片网格(auto-fill minmax(260px,1fr)),左右 40px 边距
16
+ */
17
+
18
+ /* ── 筛选 Tab ── */
19
+ const FILTER_TABS = [
20
+ { label: '全部', id: 'all' },
21
+ { label: '基础分析', id: '基础分析' },
22
+ { label: '链路分析', id: '链路分析' },
23
+ { label: '数据完善', id: '数据完善' },
24
+ ];
25
+
26
+ /* ── 示例卡片数据(20 张,category 对应 Tab id)── */
27
+ const MOCK_CARDS = [
28
+ {
29
+ category: '基础分析',
30
+ title: '智能服务近7天趋势分析',
31
+ description: '针对指定业务场景下智能服务核心指标、运行路径、渠道等进行趋势分析,并输出总结报告',
32
+ tags: ['基础分析', '官方'],
33
+ stats: [{ iconName: 'users-01-stroked', value: '1,289' }, { iconName: 'message-chat-square-stroked', value: '1,289' }, { iconName: 'hearts-stroked', value: '276' }],
34
+ },
35
+ {
36
+ category: '基础分析',
37
+ title: '渠道来源分布报告',
38
+ description: '统计各渠道用户来源占比与活跃度,输出结构化渠道分布分析报告',
39
+ tags: ['基础分析'],
40
+ stats: [{ iconName: 'users-01-stroked', value: '987' }, { iconName: 'message-chat-square-stroked', value: '3,410' }, { iconName: 'hearts-stroked', value: '198' }],
41
+ },
42
+ {
43
+ category: '基础分析',
44
+ title: '用户满意度周报',
45
+ description: '汇聚 NPS 评分与用户反馈关键词,自动生成满意度周报并标注波动原因',
46
+ tags: ['基础分析', '官方'],
47
+ stats: [{ iconName: 'users-01-stroked', value: '2,341' }, { iconName: 'message-chat-square-stroked', value: '7,890' }, { iconName: 'hearts-stroked', value: '512' }],
48
+ },
49
+ {
50
+ category: '基础分析',
51
+ title: '高频问题分类汇总',
52
+ description: '对用户提问进行语义聚类,输出 Top 问题类别及占比,辅助运营决策',
53
+ tags: ['基础分析'],
54
+ stats: [{ iconName: 'users-01-stroked', value: '1,654' }, { iconName: 'message-chat-square-stroked', value: '5,230' }, { iconName: 'hearts-stroked', value: '341' }],
55
+ },
56
+ {
57
+ category: '基础分析',
58
+ title: '会话量环比分析',
59
+ description: '对比本周期与上周期会话量变化,自动识别波峰波谷并给出可能归因',
60
+ tags: ['基础分析'],
61
+ stats: [{ iconName: 'users-01-stroked', value: '876' }, { iconName: 'message-chat-square-stroked', value: '2,100' }, { iconName: 'hearts-stroked', value: '143' }],
62
+ },
63
+ {
64
+ category: '基础分析',
65
+ title: '机器人接待率分析',
66
+ description: '统计机器人独立解决率与转人工率,分析接待效率并提出优化建议',
67
+ tags: ['基础分析', '官方'],
68
+ stats: [{ iconName: 'users-01-stroked', value: '3,102' }, { iconName: 'message-chat-square-stroked', value: '9,870' }, { iconName: 'hearts-stroked', value: '678' }],
69
+ },
70
+ {
71
+ category: '链路分析',
72
+ title: '服务全链路复盘',
73
+ description: '复盘指定会话的封闭答案错误链路,着重分析价值量服务结果,并输出复盘报告',
74
+ tags: ['链路分析', '官方'],
75
+ stats: [{ iconName: 'users-01-stroked', value: '1,289' }, { iconName: 'message-chat-square-stroked', value: '1,289' }, { iconName: 'hearts-stroked', value: '276' }],
76
+ },
77
+ {
78
+ category: '链路分析',
79
+ title: '产品深度对比分析报告',
80
+ description: '针对指定产品进行全面的理解和战略策略,产生一份深入的对比分析报告',
81
+ tags: ['链路分析'],
82
+ stats: [{ iconName: 'users-01-stroked', value: '1,289' }, { iconName: 'message-chat-square-stroked', value: '1,289' }, { iconName: 'hearts-stroked', value: '275' }],
83
+ },
84
+ {
85
+ category: '链路分析',
86
+ title: '转人工节点溯源',
87
+ description: '识别用户从机器人流转至人工的触发节点,分析转接原因分布并给出优化路径',
88
+ tags: ['链路分析'],
89
+ stats: [{ iconName: 'users-01-stroked', value: '743' }, { iconName: 'message-chat-square-stroked', value: '2,567' }, { iconName: 'hearts-stroked', value: '189' }],
90
+ },
91
+ {
92
+ category: '链路分析',
93
+ title: '对话意图识别偏差分析',
94
+ description: '检测意图识别命中率偏低的节点,输出误判 TopN 并关联用户原话样本',
95
+ tags: ['链路分析', '官方'],
96
+ stats: [{ iconName: 'users-01-stroked', value: '1,102' }, { iconName: 'message-chat-square-stroked', value: '4,320' }, { iconName: 'hearts-stroked', value: '267' }],
97
+ },
98
+ {
99
+ category: '链路分析',
100
+ title: '流失节点热力图',
101
+ description: '可视化用户在对话链路中的退出热点,标记高流失步骤并输出改进建议',
102
+ tags: ['链路分析'],
103
+ stats: [{ iconName: 'users-01-stroked', value: '892' }, { iconName: 'message-chat-square-stroked', value: '3,140' }, { iconName: 'hearts-stroked', value: '221' }],
104
+ },
105
+ {
106
+ category: '链路分析',
107
+ title: '多轮对话路径聚合',
108
+ description: '聚合相似多轮对话路径,识别主干流程与长尾异常路径,辅助流程优化',
109
+ tags: ['链路分析'],
110
+ stats: [{ iconName: 'users-01-stroked', value: '654' }, { iconName: 'message-chat-square-stroked', value: '1,980' }, { iconName: 'hearts-stroked', value: '134' }],
111
+ },
112
+ {
113
+ category: '链路分析',
114
+ title: '跨渠道链路对比',
115
+ description: '横向对比 Web、App、小程序等渠道的用户对话路径差异,输出渠道策略建议',
116
+ tags: ['链路分析'],
117
+ stats: [{ iconName: 'users-01-stroked', value: '1,432' }, { iconName: 'message-chat-square-stroked', value: '5,670' }, { iconName: 'hearts-stroked', value: '389' }],
118
+ },
119
+ {
120
+ category: '数据完善',
121
+ title: '未命中问题标注助手',
122
+ description: '对未命中知识库的用户提问进行批量标注与分类,输出待补充知识点清单',
123
+ tags: ['数据完善', '官方'],
124
+ stats: [{ iconName: 'users-01-stroked', value: '2,150' }, { iconName: 'message-chat-square-stroked', value: '8,760' }, { iconName: 'hearts-stroked', value: '567' }],
125
+ },
126
+ {
127
+ category: '数据完善',
128
+ title: '知识库覆盖率评估',
129
+ description: '统计业务问题被知识库覆盖的比例,识别空白领域并生成补全优先级建议',
130
+ tags: ['数据完善'],
131
+ stats: [{ iconName: 'users-01-stroked', value: '1,876' }, { iconName: 'message-chat-square-stroked', value: '6,340' }, { iconName: 'hearts-stroked', value: '432' }],
132
+ },
133
+ {
134
+ category: '数据完善',
135
+ title: '相似问法聚合归并',
136
+ description: '识别表达不同但语义相近的用户问法,推荐合并为标准问并扩展同义词库',
137
+ tags: ['数据完善', '官方'],
138
+ stats: [{ iconName: 'users-01-stroked', value: '1,234' }, { iconName: 'message-chat-square-stroked', value: '4,890' }, { iconName: 'hearts-stroked', value: '312' }],
139
+ },
140
+ {
141
+ category: '数据完善',
142
+ title: '答案质量评分报告',
143
+ description: '对知识库现有答案进行可读性、准确性和完整性评分,输出低分条目改写建议',
144
+ tags: ['数据完善'],
145
+ stats: [{ iconName: 'users-01-stroked', value: '987' }, { iconName: 'message-chat-square-stroked', value: '3,210' }, { iconName: 'hearts-stroked', value: '198' }],
146
+ },
147
+ {
148
+ category: '数据完善',
149
+ title: '过期内容检测清理',
150
+ description: '扫描知识库中含有过期日期、已下线产品的条目,生成待更新清单并辅助批量修订',
151
+ tags: ['数据完善'],
152
+ stats: [{ iconName: 'users-01-stroked', value: '654' }, { iconName: 'message-chat-square-stroked', value: '2,340' }, { iconName: 'hearts-stroked', value: '145' }],
153
+ },
154
+ {
155
+ category: '数据完善',
156
+ title: '多语言内容对齐检查',
157
+ description: '对比中英文知识库条目的语义一致性,标记翻译偏差并输出修订优先级',
158
+ tags: ['数据完善'],
159
+ stats: [{ iconName: 'users-01-stroked', value: '432' }, { iconName: 'message-chat-square-stroked', value: '1,560' }, { iconName: 'hearts-stroked', value: '98' }],
160
+ },
161
+ {
162
+ category: '数据完善',
163
+ title: '冷热知识分布分析',
164
+ description: '按调用频次区分高频热点知识与长尾冷门知识,辅助知识库瘦身与重点维护',
165
+ tags: ['数据完善', '官方'],
166
+ stats: [{ iconName: 'users-01-stroked', value: '1,109' }, { iconName: 'message-chat-square-stroked', value: '4,120' }, { iconName: 'hearts-stroked', value: '278' }],
167
+ },
168
+ ];
169
+
170
+ export default function ChatHomePagePattern() {
171
+ const [selectedItemId, setSelectedItemId] = useState('ai');
172
+ const [searchValue, setSearchValue] = useState('');
173
+ const [activeTabIndex, setActiveTabIndex] = useState(0);
174
+
175
+ const activeCategory = FILTER_TABS[activeTabIndex]?.id ?? 'all';
176
+ const filteredCards = MOCK_CARDS.filter((card) => {
177
+ const matchCategory = activeCategory === 'all' || card.category === activeCategory;
178
+ const matchSearch = !searchValue || card.title.includes(searchValue) || card.description.includes(searchValue);
179
+ return matchCategory && matchSearch;
180
+ });
181
+
182
+ return (
183
+ <div
184
+ className="flex h-full min-h-0 min-w-0 w-full items-stretch overflow-hidden"
185
+ style={{
186
+ background: 'var(--color-blueGrey-200, #F2F4F7)',
187
+ borderRadius: 0,
188
+ }}
189
+ >
190
+ {/* 左侧 NavBar:单项,仅显示 AI */}
191
+ <div className="flex shrink-0">
192
+ <NavBar
193
+ platform="ola"
194
+ navItems={[{ id: 'ai', label: 'AI', iconName: 'bot-02-stroked' }]}
195
+ selectedItemId={selectedItemId}
196
+ onSelect={(nextKey) => setSelectedItemId(nextKey)}
197
+ />
198
+ </div>
199
+
200
+ {/* 右侧内容区 */}
201
+ <div className="flex flex-1 min-w-0 flex-col min-h-0 overflow-hidden">
202
+
203
+ {/* ① Hero 区 */}
204
+ <div
205
+ className="flex flex-col items-center shrink-0"
206
+ style={{ padding: '120px 40px 80px' }}
207
+ >
208
+ <h1
209
+ className="m-0 text-center text-3xl [font-weight:var(--font-semibold)] leading-9"
210
+ style={{
211
+ color: 'var(--foreground, #0F1C35)',
212
+ marginBottom: '6px',
213
+ }}
214
+ >
215
+ 今天想做什么?
216
+ </h1>
217
+
218
+ <p
219
+ className="m-0 text-sm text-center"
220
+ style={{
221
+ color: 'var(--foreground-muted, rgba(15,28,53,0.45))',
222
+ marginBottom: '24px',
223
+ }}
224
+ >
225
+ 直接描述你的需求,或从下方模板快速开始
226
+ </p>
227
+
228
+ <div className="w-full" style={{ maxWidth: '680px' }}>
229
+ <ChatInput variant="default" placeholder="描述你想完成的任务…" />
230
+ </div>
231
+ </div>
232
+
233
+ {/* ② 筛选行:左侧胶囊 Tab + 右侧搜索,左右 40px */}
234
+ <div
235
+ className="flex min-w-0 shrink-0 flex-wrap items-center justify-between gap-4"
236
+ style={{ padding: '16px 40px' }}
237
+ >
238
+ <Tabs
239
+ variant="pill"
240
+ size="sm"
241
+ items={FILTER_TABS}
242
+ defaultIndex={0}
243
+ onChange={(index) => setActiveTabIndex(index)}
244
+ />
245
+ <Input
246
+ placeholder="搜索标题、描述"
247
+ prefix={<Icon name="search-md-stroked" size="sm" />}
248
+ allowClear
249
+ value={searchValue}
250
+ onChange={(e) => setSearchValue(e.target.value)}
251
+ className="max-w-full"
252
+ style={{ flex: '0 1 240px', width: '240px', minWidth: '200px', '--size-input-width': '100%' }}
253
+ />
254
+ </div>
255
+
256
+ {/* ③ 卡片网格(自适应列,可滚动,左右 40px) */}
257
+ <div
258
+ className="flex-1 min-h-0 overflow-y-auto"
259
+ style={{ padding: '0 40px 32px' }}
260
+ >
261
+ <div
262
+ className="grid gap-4"
263
+ style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(min(320px, 100%), 1fr))' }}
264
+ >
265
+ {filteredCards.map((card, index) => (
266
+ <Card
267
+ key={`${activeCategory}-${index}`}
268
+ title={card.title}
269
+ description={card.description}
270
+ tags={card.tags}
271
+ stats={card.stats}
272
+ color="white"
273
+ />
274
+ ))}
275
+ </div>
276
+ </div>
277
+
278
+ </div>
279
+ </div>
280
+ );
281
+ }
@@ -0,0 +1,380 @@
1
+ import { useState } from 'react';
2
+ import Button from '../components/Button';
3
+ import Tabs from '../components/Tabs';
4
+ import ChatInput from '../components/ChatInput';
5
+ import Switch from '../components/Switch';
6
+ import Icon from '../components/Icon';
7
+ import catcatSvg from '../components/file-type-assets/catcat.svg';
8
+
9
+ /**
10
+ * CopilotPagePattern — B端 Copilot + 内容区 双栏模板
11
+ *
12
+ * 基于 Figma 设计稿 243-9115(无 Copilot)/ 243-9162(有 Copilot)还原。
13
+ *
14
+ * 布局:
15
+ * 顶导栏(shrink-0):左侧返回+标题+AI触发按钮 | 居中胶囊Tab | 右侧操作组
16
+ * 内容区(flex-1):
17
+ * [AI按钮展开] Copilot侧边栏(w-280,新会话列表+ChatInput)
18
+ * 主内容白卡(flex-1,内部有二级Tab+操作栏)
19
+ *
20
+ * 交互:点击顶导栏右侧"OLA AI"胶囊 ↔ 切换 Copilot 展开/收起
21
+ */
22
+
23
+ /* ── 顶导栏中间的一级页面 Tab ── */
24
+ const PAGE_TABS = [
25
+ { label: '服务策略', icon: <Icon name="share-07-stroked" /> },
26
+ { label: '批测&归因', icon: <Icon name="file-07-stroked" /> },
27
+ { label: '运行数据', icon: <Icon name="pie-chart-01-stroked" /> },
28
+ ];
29
+
30
+ /* ── Copilot 快捷建议 ── */
31
+ const COPILOT_SUGGESTIONS = [
32
+ '分析智能会话与人工会话差异',
33
+ '分析总结智能会话的问题和机会点',
34
+ '分析一个 case',
35
+ '基于批测报告分析优化方向和问题',
36
+ ];
37
+
38
+ export default function CopilotPagePattern() {
39
+ const [copilotOpen, setCopilotOpen] = useState(false);
40
+
41
+ return (
42
+ <div
43
+ className="flex h-full min-h-0 min-w-0 w-full flex-col overflow-hidden"
44
+ style={{
45
+ background: 'var(--color-blueGrey-200, #F2F4F7)',
46
+ borderRadius: 'inherit',
47
+ border: '1px solid var(--color-border-default, #E4E7EC)',
48
+ minHeight: '100%',
49
+ }}
50
+ >
51
+ {/* ── 顶导栏 ── */}
52
+ <TopBar copilotOpen={copilotOpen} onToggleCopilot={() => setCopilotOpen(v => !v)} />
53
+
54
+ {/* ── 内容区 ── */}
55
+ <div className="flex flex-1 min-h-0 min-w-0 flex-wrap gap-4 overflow-hidden px-4 pb-4">
56
+ {copilotOpen && <CopilotPanel onClose={() => setCopilotOpen(false)} />}
57
+ <ContentCard />
58
+ </div>
59
+ </div>
60
+ );
61
+ }
62
+
63
+ /* ────────────────────────────────────────────
64
+ 顶导栏
65
+ 左:返回 + 标题 + OLA AI 触发按钮
66
+ 中:居中胶囊 Tab(绝对定位使其真正居中)
67
+ 右:版本 + 更多 + 次操作 + 主操作
68
+ ──────────────────────────────────────────── */
69
+ function TopBar({ copilotOpen, onToggleCopilot }) {
70
+ return (
71
+ <div className="shrink-0 px-4 py-4">
72
+ <div className="relative flex min-h-[36px] items-center">
73
+ <div className="flex min-w-0 flex-1 items-center gap-3 pr-4">
74
+ <TopBarLead copilotOpen={copilotOpen} onToggleCopilot={onToggleCopilot} />
75
+ </div>
76
+
77
+ <div className="pointer-events-none absolute inset-x-0 flex justify-center">
78
+ <div className="pointer-events-auto flex min-w-0 items-center">
79
+ <TopBarTabs />
80
+ </div>
81
+ </div>
82
+
83
+ <div className="ml-auto flex shrink-0 items-center gap-4 pl-4">
84
+ <TopBarActions />
85
+ </div>
86
+ </div>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ function TopBarLead({ copilotOpen, onToggleCopilot }) {
92
+ return (
93
+ <>
94
+ <Button variant="outline-black" iconOnly icon={<Icon name="arrow-left-stroked" />} aria-label="返回" />
95
+
96
+ <span
97
+ className="font-semibold text-base leading-[22px] whitespace-nowrap"
98
+ style={{ color: 'var(--foreground, #0F1C35)' }}
99
+ >
100
+ 主策略:抖音社区-社交-私信
101
+ </span>
102
+
103
+ {!copilotOpen && (
104
+ <div
105
+ onClick={onToggleCopilot}
106
+ className="shrink-0 cursor-pointer"
107
+ style={{
108
+ padding: '1.5px',
109
+ borderRadius: '999px',
110
+ background: 'linear-gradient(-45deg, rgba(255, 153, 248, 0.4) 0%, rgba(181, 131, 255, 0.4) 25%, rgba(114, 156, 255, 0.4) 48%, rgba(117, 218, 231, 0.4) 83%, rgba(115, 230, 204, 0.4) 100%)',
111
+ }}
112
+ >
113
+ <div
114
+ className="inline-flex items-center gap-2"
115
+ style={{
116
+ height: '34px',
117
+ padding: '0 14px',
118
+ borderRadius: '999px',
119
+ background: 'var(--gradient-ai-fill-1)',
120
+ fontSize: '14px',
121
+ fontWeight: 600,
122
+ color: 'var(--foreground, #0F1C35)',
123
+ fontFamily: 'inherit',
124
+ userSelect: 'none',
125
+ }}
126
+ >
127
+ <img src={catcatSvg} alt="OLA AI" style={{ width: '20px', height: '20px', display: 'block' }} />
128
+ <span>OLA AI</span>
129
+ </div>
130
+ </div>
131
+ )}
132
+ </>
133
+ );
134
+ }
135
+
136
+ function TopBarTabs() {
137
+ return <Tabs variant="pill" size="md" items={PAGE_TABS} defaultIndex={0} />;
138
+ }
139
+
140
+ function TopBarActions() {
141
+ return (
142
+ <>
143
+ <div
144
+ className="inline-flex items-center gap-1 shrink-0"
145
+ style={{
146
+ height: '36px',
147
+ padding: '0 16px',
148
+ borderRadius: '999px',
149
+ background: 'var(--color-brand-50, #f0fdfa)',
150
+ border: '1px solid var(--color-brand-500, #5eead4)',
151
+ fontSize: '14px',
152
+ fontWeight: 600,
153
+ color: 'var(--color-brand-950, #065f46)',
154
+ }}
155
+ >
156
+ <span>V8 线上</span>
157
+ <Icon name="chevron-selector-vertical-stroked" size={16} />
158
+ </div>
159
+
160
+ <div className="flex items-center gap-2">
161
+ <Button variant="ghost-black" iconOnly icon={<Icon name="dots-horizontal-stroked" />} aria-label="更多" />
162
+ <Button variant="outline-black">次操作</Button>
163
+ <Button variant="primary" icon={<Icon name="plus-stroked" />}>主操作</Button>
164
+ </div>
165
+ </>
166
+ );
167
+ }
168
+
169
+ /* ────────────────────────────────────────────
170
+ Copilot 侧边栏
171
+ 上:标题栏(新会话 + 图标按钮组)
172
+ 中:AI 欢迎态(头像 + 标题 + 欢迎语 + 快捷建议 chips)
173
+ 下:ChatInput
174
+ ──────────────────────────────────────────── */
175
+ function CopilotPanel({ onClose }) {
176
+ return (
177
+ <div
178
+ className="flex h-full min-h-0 min-w-0 flex-col overflow-hidden"
179
+ style={{
180
+ width: 'min(450px, 100%)',
181
+ }}
182
+ >
183
+ {/* 标题栏 */}
184
+ <div className="flex items-center shrink-0" style={{ height: '48px', paddingRight: '4px' }}>
185
+ <div className="flex items-center flex-1 min-w-0 gap-1">
186
+ <span
187
+ className="text-sm leading-5 pl-1"
188
+ style={{ color: 'var(--foreground-muted, rgba(15,28,53,0.6))' }}
189
+ >
190
+ 新会话
191
+ </span>
192
+ </div>
193
+ <div className="flex items-center gap-0.5 shrink-0">
194
+ <Button variant="ghost-black" iconOnly icon={<Icon name="message-plus-square-stroked" />} aria-label="新建会话" />
195
+ <Button variant="ghost-black" iconOnly icon={<Icon name="clock-stroked" />} aria-label="历史记录" />
196
+ <Button variant="ghost-black" iconOnly icon={<Icon name="layout-left-stroked" />} aria-label="收起面板" onClick={onClose} />
197
+ </div>
198
+ </div>
199
+
200
+ {/* 对话流:欢迎态 */}
201
+ <div className="flex flex-1 min-h-0 flex-col items-center justify-center gap-6" style={{ padding: '0 80px' }}>
202
+ {/* AI 头像 + 标题 */}
203
+ <div className="flex flex-col items-center gap-3">
204
+ {/* 头像:渐变描边圆 + 蓝色投影 + CATCAT */}
205
+ <div style={{ position: 'relative', width: '66px', height: '66px', flexShrink: 0 }}>
206
+ {/* 渐变描边圆(外层渐变 0.5px + 内层白底) */}
207
+ <div style={{
208
+ position: 'absolute',
209
+ inset: '0',
210
+ borderRadius: '50%',
211
+ padding: '0.5px',
212
+ background: 'linear-gradient(135deg, rgba(63,226,213,0.6) 0%, rgba(64,147,224,0.6) 35%, rgba(122,97,250,0.6) 65%, rgba(214,130,235,0.6) 100%)',
213
+ }}>
214
+ <div style={{
215
+ width: '100%',
216
+ height: '100%',
217
+ borderRadius: '50%',
218
+ background: [
219
+ 'linear-gradient(42deg, #FFF 11.61%, rgba(255,255,255,0.00) 37.84%)',
220
+ 'linear-gradient(74deg, rgba(63,226,213,0.15) 12.18%, rgba(64,147,224,0.15) 39.9%, rgba(122,97,250,0.15) 63.86%, rgba(214,130,235,0.15) 86.38%)',
221
+ '#FFF',
222
+ ].join(', '),
223
+ boxShadow: '0px 8px 15px rgba(180,218,244,0.50)',
224
+ }} />
225
+ </div>
226
+ {/* CATCAT 图标 */}
227
+ <img
228
+ src={catcatSvg}
229
+ alt="OLA AI"
230
+ style={{
231
+ position: 'absolute',
232
+ width: '32px',
233
+ height: '32px',
234
+ top: '50%',
235
+ left: '50%',
236
+ transform: 'translate(-50%, -50%)',
237
+ zIndex: 1,
238
+ }}
239
+ />
240
+ </div>
241
+ <span
242
+ className="font-semibold whitespace-nowrap"
243
+ style={{ fontSize: '18px', lineHeight: '24px', letterSpacing: '-0.03em', color: 'var(--foreground, #0F1C35)' }}
244
+ >
245
+ OLA AI
246
+ </span>
247
+ </div>
248
+
249
+ {/* 欢迎语 */}
250
+ <p
251
+ className="text-sm text-center leading-5 m-0"
252
+ style={{ color: 'var(--foreground-muted, rgba(15,28,53,0.6))', width: '100%' }}
253
+ >
254
+ 您好!我是您的智能小助手 ✨ ~ 我能帮您归因分析、生成策略、Prompt、知识、工具等方案~
255
+ </p>
256
+
257
+ {/* 快捷建议 chips */}
258
+ <div className="flex flex-col gap-2 w-full">
259
+ {COPILOT_SUGGESTIONS.map((text) => (
260
+ <button
261
+ key={text}
262
+ type="button"
263
+ className="flex items-center justify-between w-full cursor-pointer border-0 text-left"
264
+ style={{
265
+ padding: '10px 12px',
266
+ borderRadius: '8px',
267
+ background: 'rgba(255,255,255,0.6)',
268
+ boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.9)',
269
+ fontSize: '12px',
270
+ lineHeight: '16px',
271
+ color: 'var(--foreground, #0F1C35)',
272
+ fontFamily: 'inherit',
273
+ transition: 'background 150ms ease',
274
+ }}
275
+ onMouseEnter={e => { e.currentTarget.style.background = 'rgba(255,255,255,0.85)'; }}
276
+ onMouseLeave={e => { e.currentTarget.style.background = 'rgba(255,255,255,0.6)'; }}
277
+ >
278
+ <span>{text}</span>
279
+ <Icon name="arrow-narrow-right-stroked" size={12} />
280
+ </button>
281
+ ))}
282
+ </div>
283
+ </div>
284
+
285
+ {/* ChatInput:父级 CopilotPanel 不裁剪,让 -bottom-2 氛围背景与炫彩投影能向外溢出 */}
286
+ <div className="shrink-0 pt-2">
287
+ <ChatInput variant="default" placeholder="需要我为你做什么" />
288
+ </div>
289
+ </div>
290
+ );
291
+ }
292
+
293
+ /* ────────────────────────────────────────────
294
+ 主内容白卡
295
+ 上:二级 Tab 栏(策略画布 | 流程数据开关 + 操作按钮)
296
+ 下:内容区(空白,业务方在此填充)
297
+ ──────────────────────────────────────────── */
298
+ function ContentCard() {
299
+ return (
300
+ <div
301
+ className="flex flex-1 min-w-0 flex-col overflow-hidden"
302
+ style={{
303
+ background: 'var(--color-white, #FFFFFF)',
304
+ borderRadius: '12px',
305
+ }}
306
+ >
307
+ {/* 二级 Tab 栏 */}
308
+ <div
309
+ className="flex items-center shrink-0 gap-2 px-2"
310
+ style={{
311
+ background: 'var(--color-blueGrey-50, #F9FAFB)',
312
+ borderBottom: '1px solid var(--color-border-default, #E4E7EC)',
313
+ minHeight: '48px',
314
+ }}
315
+ >
316
+ {/* 左侧:当前 Tab(策略画布) */}
317
+ <div className="flex flex-1 min-w-0 items-end">
318
+ <div
319
+ className="flex items-center gap-2 px-3 shrink-0"
320
+ style={{
321
+ height: '48px',
322
+ borderRadius: '8px 8px 0 0',
323
+ border: '1px solid rgba(255,255,255,0.03)',
324
+ }}
325
+ >
326
+ <div
327
+ className="flex items-center justify-center shrink-0"
328
+ style={{
329
+ width: '24px',
330
+ height: '24px',
331
+ borderRadius: '8px',
332
+ background: 'var(--color-blueGrey-900, #0F1C35)',
333
+ }}
334
+ >
335
+ <Icon name="if-stroked" size={12} color="#ffffff" />
336
+ </div>
337
+ <span
338
+ className="text-sm font-semibold leading-5 whitespace-nowrap"
339
+ style={{ color: 'var(--foreground, #0F1C35)' }}
340
+ >
341
+ 策略画布
342
+ </span>
343
+ </div>
344
+ </div>
345
+
346
+ {/* 右侧:流程数据开关 + 操作按钮 */}
347
+ <div className="flex items-center gap-2 shrink-0">
348
+ {/* 流程数据 Switch */}
349
+ <div className="flex items-center gap-2 px-2 shrink-0">
350
+ <span
351
+ className="text-sm font-semibold leading-5 whitespace-nowrap"
352
+ style={{ color: 'var(--foreground-muted, rgba(15,28,53,0.6))' }}
353
+ >
354
+ 流程数据
355
+ </span>
356
+ <Switch
357
+ variant="brand"
358
+ defaultChecked={false}
359
+ onChange={() => {}}
360
+ />
361
+ </div>
362
+
363
+ <Button variant="ghost-black">流程单测</Button>
364
+ <Button variant="ghost-black">批量测试</Button>
365
+ <Button variant="ghost-black" iconOnly icon={<Icon name="git-branch-02-stroked" />} aria-label="对比" />
366
+ </div>
367
+ </div>
368
+
369
+ {/* 内容区(业务填充) */}
370
+ <div className="flex flex-1 min-h-0 items-center justify-center">
371
+ <span
372
+ className="text-sm"
373
+ style={{ color: 'var(--foreground-muted, rgba(15,28,53,0.3))' }}
374
+ >
375
+ 👉 业务内容区域
376
+ </span>
377
+ </div>
378
+ </div>
379
+ );
380
+ }