gongxiangp2/components/department-dashboard/AutomationWorkflowsDashboard.tsx

102 lines
3.9 KiB
TypeScript

'use client'
import {
ClipboardCheck,
FileCheck2,
type LucideIcon,
} from 'lucide-react'
import { useRouter, useSearchParams } from 'next/navigation'
import { useEffect, useState } from 'react'
import DepartmentShell from './DepartmentShell'
type AutomationWorkflowKey = 'performance-survey' | 'work-review'
type AutomationWorkflow = {
key: AutomationWorkflowKey
title: string
description: string
href: string
icon: LucideIcon
}
const AUTOMATION_WORKFLOWS: AutomationWorkflow[] = [
{
key: 'performance-survey',
title: '绩效考核调研',
description: '考核问卷、填报与结果管理',
href: '/performance-survey',
icon: ClipboardCheck,
},
{
key: 'work-review',
title: '作品过稿看板',
description: '作品提交、评审与退修流转',
href: '/work-review',
icon: FileCheck2,
},
]
function normalizeWorkflow(value: string | null): AutomationWorkflowKey {
return value === 'work-review' ? 'work-review' : 'performance-survey'
}
export default function AutomationWorkflowsDashboard() {
const router = useRouter()
const searchParams = useSearchParams()
const requestedWorkflow = normalizeWorkflow(searchParams.get('workflow'))
const [activeWorkflowKey, setActiveWorkflowKey] = useState<AutomationWorkflowKey>(requestedWorkflow)
const activeWorkflow = AUTOMATION_WORKFLOWS.find((workflow) => workflow.key === activeWorkflowKey) || AUTOMATION_WORKFLOWS[0]
useEffect(() => {
setActiveWorkflowKey(requestedWorkflow)
}, [requestedWorkflow])
const selectWorkflow = (workflow: AutomationWorkflow) => {
if (workflow.key === activeWorkflowKey) return
setActiveWorkflowKey(workflow.key)
router.replace(`/workspaces/assets/automation-workflows?workflow=${workflow.key}`, { scroll: false })
}
return (
<DepartmentShell>
<main className="flex h-[calc(100dvh-72px)] min-h-[560px] flex-col overflow-hidden bg-white lg:grid lg:grid-cols-[232px_minmax(0,1fr)]">
<aside className="shrink-0 border-b border-[#e2e8f0] bg-[#f8fafc] px-4 py-4 lg:min-h-0 lg:overflow-y-auto lg:border-b-0 lg:border-r lg:px-4 lg:py-6">
<nav aria-label="自动化工作流二级导航" className="grid grid-cols-2 gap-2 lg:grid-cols-1 lg:gap-1">
{AUTOMATION_WORKFLOWS.map((workflow) => {
const Icon = workflow.icon
const active = workflow.key === activeWorkflowKey
return (
<button
key={workflow.key}
type="button"
aria-current={active ? 'page' : undefined}
onClick={() => selectWorkflow(workflow)}
className={`group flex min-h-[58px] min-w-0 items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#5a9ce6] ${active ? 'bg-[#e6f4ff] text-[#0050cb]' : 'text-[#4f6077] hover:bg-[#eef2f6] hover:text-[#101828]'}`}
>
<Icon className={`h-4 w-4 shrink-0 ${active ? 'text-[#1677ff]' : 'text-[#087052]'}`} aria-hidden="true" />
<span className="min-w-0">
<span className="block truncate text-sm font-bold">{workflow.title}</span>
<span className={`mt-0.5 hidden truncate text-xs lg:block ${active ? 'text-[#315f91]' : 'text-[#667085]'}`}>
{workflow.description}
</span>
</span>
</button>
)
})}
</nav>
</aside>
<section aria-label={`${activeWorkflow.title}操作区`} className="relative min-h-0 min-w-0 flex-1 bg-[#f2f4f7]">
<iframe
key={activeWorkflow.key}
src={activeWorkflow.href}
title={`${activeWorkflow.title}操作界面`}
className="h-full w-full border-0 bg-white"
/>
</section>
</main>
</DepartmentShell>
)
}