diff --git a/components/department-dashboard/TeamFunctionsDashboard.test.tsx b/components/department-dashboard/TeamFunctionsDashboard.test.tsx
index 5a6ef84..6ae2af7 100644
--- a/components/department-dashboard/TeamFunctionsDashboard.test.tsx
+++ b/components/department-dashboard/TeamFunctionsDashboard.test.tsx
@@ -1,4 +1,4 @@
-import { render, screen } from '@testing-library/react'
+import { fireEvent, render, screen } from '@testing-library/react'
import TeamFunctionsDashboard from './TeamFunctionsDashboard'
jest.mock('next-auth/react', () => ({
@@ -7,24 +7,39 @@ jest.mock('next-auth/react', () => ({
}))
describe('TeamFunctionsDashboard', () => {
- it('shows the four teams and their function branches from the approved map', () => {
+ it('shows department navigation and the selected team introduction', () => {
render()
expect(screen.getByRole('heading', { level: 1, name: '团队职能' })).toBeInTheDocument()
expect(screen.getByRole('heading', { level: 2, name: '品牌中心职责地图' })).toBeInTheDocument()
+ expect(screen.getByRole('complementary', { name: '团队职能二级部门导航' })).toBeInTheDocument()
for (const team of ['品牌创意A部', '品牌创意B部', '空间设计部', '综合支持部']) {
- expect(screen.getByRole('heading', { level: 2, name: team })).toBeInTheDocument()
+ expect(screen.getByRole('button', { name: new RegExp(team) })).toBeInTheDocument()
}
- for (const label of ['服务品牌', '前置能力', '定位', '岗位', '职责']) {
- expect(screen.getAllByText(label).length).toBeGreaterThan(0)
- }
+ expect(screen.getByRole('region', { name: '品牌创意A部部门介绍' })).toBeInTheDocument()
+ expect(screen.getByText('负责朴美、索菲亚、顾家品牌的视觉创意与内容前置策划,统筹品牌调性、商品卖点及页面与短视频创意。')).toBeInTheDocument()
- for (const item of ['朴美', '索菲亚', '顾家', '欧意朗', '卓禾', '亿家达', '空间设计师', 'AIGC设计师', '批量生产']) {
- expect(screen.getByText(item)).toBeInTheDocument()
+ for (const item of ['朴美', '索菲亚', '顾家', '品牌视觉策划设计', 'AI+平面+策划', '编导/短视频策划', '品牌调性', '商品卖点', '页面/短视频创意', '经验与复盘']) {
+ expect(screen.getByRole('region', { name: '品牌创意A部部门介绍' }).querySelector(`[data-team-item="${item}"]`)).not.toBeNull()
}
expect(screen.getByRole('link', { name: '返回部门看板' })).toHaveAttribute('href', '/')
})
+
+ it('switches the department introduction from the secondary navigation', () => {
+ render()
+
+ fireEvent.click(screen.getByRole('button', { name: /空间设计部/ }))
+
+ expect(screen.getByRole('region', { name: '空间设计部部门介绍' })).toBeInTheDocument()
+ expect(screen.getByText('负责空间、置景、灯光、机位与拍摄一体化,为内容生产提供场景和拍摄执行能力。')).toBeInTheDocument()
+ expect(screen.queryByRole('region', { name: '品牌创意A部部门介绍' })).not.toBeInTheDocument()
+ expect(screen.getByText('美术指导')).toBeInTheDocument()
+
+ fireEvent.click(screen.getByRole('button', { name: /品牌创意B部/ }))
+ expect(screen.getByRole('region', { name: '品牌创意B部部门介绍' })).toBeInTheDocument()
+ expect(screen.getByText('欧意朗')).toBeInTheDocument()
+ })
})
diff --git a/components/department-dashboard/TeamFunctionsDashboard.tsx b/components/department-dashboard/TeamFunctionsDashboard.tsx
index 6462a08..70b9f1e 100644
--- a/components/department-dashboard/TeamFunctionsDashboard.tsx
+++ b/components/department-dashboard/TeamFunctionsDashboard.tsx
@@ -1,5 +1,8 @@
+'use client'
+
import Link from 'next/link'
import { ArrowLeft, Blocks, BriefcaseBusiness, Check, Layers3, UsersRound } from 'lucide-react'
+import { useState } from 'react'
import DepartmentShell from './DepartmentShell'
type FunctionBranch = {
@@ -10,6 +13,7 @@ type FunctionBranch = {
type TeamFunction = {
name: string
lead: string
+ description: string
tone: 'coral' | 'navy' | 'blue' | 'teal'
branches: FunctionBranch[]
}
@@ -18,6 +22,7 @@ const TEAM_FUNCTIONS: TeamFunction[] = [
{
name: '品牌创意A部',
lead: '伯言',
+ description: '负责朴美、索菲亚、顾家品牌的视觉创意与内容前置策划,统筹品牌调性、商品卖点及页面与短视频创意。',
tone: 'coral',
branches: [
{ label: '服务品牌', items: ['朴美', '索菲亚', '顾家'] },
@@ -28,6 +33,7 @@ const TEAM_FUNCTIONS: TeamFunction[] = [
{
name: '品牌创意B部',
lead: '清云',
+ description: '负责欧意朗、卓禾、亿家达品牌的视觉创意与内容前置策划,推动品牌辅导、页面及短视频创意落地。',
tone: 'navy',
branches: [
{ label: '服务品牌', items: ['欧意朗', '卓禾', '亿家达'] },
@@ -38,6 +44,7 @@ const TEAM_FUNCTIONS: TeamFunction[] = [
{
name: '空间设计部',
lead: '希文',
+ description: '负责空间、置景、灯光、机位与拍摄一体化,为内容生产提供场景和拍摄执行能力。',
tone: 'blue',
branches: [
{ label: '定位', items: ['空间、置景、灯光、机位、拍摄一体化'] },
@@ -48,6 +55,7 @@ const TEAM_FUNCTIONS: TeamFunction[] = [
{
name: '综合支持部',
lead: '无邪',
+ description: '承接3D、AI、平面、修图、视频后期等生产支持,沉淀资产标准并推进批量生产。',
tone: 'teal',
branches: [
{ label: '岗位', items: ['3D设计师', '平面设计师', 'AIGC设计师', '视频后期', '修图'] },
@@ -104,6 +112,7 @@ function Branch({ branch, tone }: { branch: FunctionBranch; tone: TeamFunction['
{branch.items.map((item) => (
@@ -116,41 +125,11 @@ function Branch({ branch, tone }: { branch: FunctionBranch; tone: TeamFunction['
)
}
-function TeamFunctionPanel({ team }: { team: TeamFunction }) {
- const colors = toneStyles[team.tone]
-
- return (
-
-
-
-
-
-
-
-
- {team.name}
-
-
负责人:{team.lead}
-
-
-
- 职能地图
-
-
-
-
-
- {team.branches.map((branch) => )}
-
-
-
- )
-}
-
export default function TeamFunctionsDashboard() {
+ const [selectedTeamName, setSelectedTeamName] = useState(TEAM_FUNCTIONS[0].name)
+ const selectedTeam = TEAM_FUNCTIONS.find((team) => team.name === selectedTeamName) || TEAM_FUNCTIONS[0]
+ const colors = toneStyles[selectedTeam.tone]
+
return (
@@ -164,21 +143,62 @@ export default function TeamFunctionsDashboard() {
-