gongxiangp2/components/work-review/WorkReviewHeader.tsx
chenpei f8db4232ce feat: 第一阶段框架——登录落点切换为品牌中心看板首页
- 看板首页 / :Zen Minimal × Future Organic 融合(用户裁定),编号索引+柔光光晕+GSAP克制动效,白皮书气质
- 素材库首页整体迁移至 /materials(含colocated测试),全站返回素材库链接同步清扫
- 组织架构页上移为顶层 /organization(保留云采石场契约注释),旧路径 /admin/org 服务端跳转;API 迁移 /api/organization(逻辑零改动)
- 后台删除组织架构跳转按钮(白屏问题源头消失);middleware 增 /materials 登录门、/organization 管理员门
- 品牌统一:浅色顶栏用 loginLogoUrl(深色图案版),标题「由壹点·品牌中心」;字体自托管 @fontsource
- 可访问性收尾(评审fix项):全文对比度过WCAG、焦点环、加载骨架防闪灰、移动端状态可见、::selection
- PRODUCT.md/DESIGN.md 记录方向契约;测试基线 1815 通过/6 既有失败(无劣化)
2026-08-15 11:01:27 +08:00

91 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import Image from 'next/image'
import Link from 'next/link'
export function WorkReviewHeader({
name,
avatar,
secondaryAction,
primaryAction,
wide = false,
}: {
name: string
avatar?: string | null
secondaryAction?: {
label: string
onClick: () => void
icon: 'add' | 'back'
}
primaryAction?: {
label: string
onClick: () => void
icon: 'add' | 'back'
}
wide?: boolean
}) {
const initials = name.trim().slice(0, 2) || '我'
return (
<header className="sticky top-0 z-30 bg-[#1f2937] text-white shadow-sm">
<div className={`mx-auto flex min-h-[64px] w-full flex-wrap items-center justify-between gap-x-4 gap-y-2 px-4 py-3 sm:flex-nowrap sm:px-6 ${wide ? 'max-w-[1600px]' : 'max-w-[1280px]'}`}>
<div className="flex min-w-0 items-center gap-3">
<div className="flex h-9 w-9 shrink-0 items-center justify-center overflow-hidden rounded-full border border-white/15 bg-white/15 text-[12px] font-bold">
{avatar ? (
<Image
src={avatar}
alt={name}
width={36}
height={36}
unoptimized
className="h-full w-full object-cover"
/>
) : initials}
</div>
<div className="min-w-0">
<div className="truncate text-[16px] font-bold">作品过稿看板</div>
<div className="truncate text-[11px] font-medium text-white/65">{name}</div>
</div>
</div>
<div className={`flex shrink-0 items-center gap-2 ${secondaryAction ? 'w-full sm:w-auto' : ''}`}>
{secondaryAction && (
<button
type="button"
onClick={secondaryAction.onClick}
className="inline-flex min-h-10 flex-1 items-center justify-center rounded bg-[#0050cb] px-3 text-[12px] font-bold text-white transition-colors hover:bg-[#003fa3] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-[#1f2937] sm:min-h-9 sm:flex-none sm:px-4 sm:text-[13px]"
>
<span className="mr-1 text-[17px] font-light leading-none" aria-hidden="true">
{secondaryAction.icon === 'add' ? '+' : '←'}
</span>
{secondaryAction.label}
</button>
)}
{primaryAction && (
<button
type="button"
onClick={primaryAction.onClick}
className={`inline-flex items-center justify-center rounded px-3 text-[12px] font-bold text-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-[#1f2937] sm:min-h-9 sm:px-4 sm:text-[13px] ${
secondaryAction
? 'min-h-10 flex-1 border border-white/25 bg-white/10 hover:bg-white/15 sm:flex-none'
: 'min-h-9 bg-[#0050cb] hover:bg-[#003fa3]'
}`}
>
<span className="mr-1 text-[17px] font-light leading-none" aria-hidden="true">
{primaryAction.icon === 'add' ? '+' : '←'}
</span>
{primaryAction.label}
</button>
)}
<Link
href="/materials"
className="inline-flex min-h-10 items-center justify-center rounded px-2 text-[12px] font-semibold text-white/80 transition-colors hover:bg-white/10 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white sm:min-h-9 sm:px-3 sm:text-[13px]"
>
返回素材库
</Link>
</div>
</div>
</header>
)
}