Files
ftb-project-management/docs/superpowers/specs/2026-06-16-profile-ui-redesign.md
Script Generator d1b4d81a75 feat: 个人中心 UI 改版(Banner + 大头像 + 卡片化)
从孤立白卡改为 GitHub/Notion 风格个人页:
- 顶部 h-40 渐变 Banner(主色到 hover 色),左下 80px 圆头像 + ring 描边
- Banner 内显示姓名/角色·部门/手机·邮箱,右上白底透明退出按钮
- max-w-3xl 卡片居中:标题 + 副标题(如「修改后立即生效」)+ 字段单栏堆叠
- 保存按钮加 spinner(提交中)+ 已保存绿色文字带 Check icon 3 秒淡出
- refreshUser 后 Banner 立即同步新名字/邮箱
- 不考虑移动端

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-16 20:26:22 +08:00

155 lines
6.8 KiB
Markdown
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.

# 个人中心 UI 改版设计
## Context
当前 `/profile` 页面commit `7c49868`)的视觉太单调——内容用 `max-w-xl` 限宽,单张白卡片孤立漂浮在空白页上,没有头部装饰,整体像一个被推平的弹窗。改为 GitHub/Notion 风格的"个人页":渐变 Banner + 大头像 + Tab 切换的卡片。
## 决策摘要
| 项 | 决策 |
|---|---|
| 整体风格 | 顶部渐变 Banner + 头像 + 下方 Tab 卡片(方案 A |
| Banner 高度 | h-40160px |
| Banner 背景 | `bg-gradient-to-br from-[var(--accent)] to-[var(--accent-hover)]` |
| 头像 | 80px 圆形,主色背景 + 白字首字母,`ring-4 ring-white/20` |
| 退出按钮位置 | Banner 右上角 absolute白底红描边红字 |
| Tab 风格 | 沿用版本详情页风格active 主色下划线) |
| 字段布局 | 单栏堆叠(用户决定,避免两栏挤迫) |
| 卡片宽度 | `max-w-3xl mx-auto` 居中 |
| 保存反馈 | 提交中 spinner + 已保存绿色文字 3 秒淡出 |
| 移动端 | 不考虑(项目仅面向桌面端) |
## 1. Banner 视觉规格
**结构**
```
┌─────────────────────────────────────────────────────┐
│ [渐变背景 h-40] │
│ [退出登录] │
│ │
│ [80px 圆头像] 张三 │
│ "张" 产品经理 · 产品部 / 前端组 │
│ 📞 138... · ✉ zhang@... │
└─────────────────────────────────────────────────────┘
```
**实现要点**
- 容器 `relative h-40 px-8 py-6 rounded-b-3xl bg-gradient-to-br from-[var(--accent)] to-[var(--accent-hover)] text-white`
- 内部 flex 布局:左侧头像 + 文字组,右上 absolute 退出按钮
- 头像:`h-20 w-20 rounded-full bg-white/15 ring-4 ring-white/20 flex items-center justify-center text-3xl font-semibold`,内容是 `user.name?.[0]`
- 主名 `text-2xl font-semibold`
- 副名 `text-sm text-white/80`,格式:"角色名 · 部门层级"
- 联系方式 `text-xs text-white/60`Phone/Mail icon + 文本
- 退出按钮:`absolute top-5 right-5 h-8 px-3 rounded-lg bg-white/10 border border-white/20 hover:bg-white/20 text-white`(白色透明)
## 2. Tab 内容布局
**结构**
```
[Banner]
┌─ 个人信息 ─┐ ┌─ 修改密码 ─┐
════════════
┌──────────────────────────────────────────┐
│ 基本信息 │
│ 修改后立即生效 │
│ ───────────────────────────────────── │
│ │
│ 姓名 * │
│ [_____________________________________] │
│ │
│ 手机号 * │
│ [_____________________________________] │
│ │
│ 邮箱 * │
│ [_____________________________________] │
│ │
│ 部门 │
│ [产品部 / 前端组] │
│ │
│ 角色 │
│ [产品经理] │
│ │
│ [取消] [保存] │
└──────────────────────────────────────────┘
```
**实现要点**
- Banner 与 Tab 之间留 `mt-6` 间距
- Tab 容器 `max-w-3xl mx-auto px-5`,无外边框,仅 Tab 按钮带下划线
- 卡片 `max-w-3xl mx-auto rounded-2xl border border-[var(--line)] bg-[var(--bg-card)] p-6`
- 卡片头:标题 `text-base font-semibold` + 副标题 `text-xs text-[var(--ink-muted)] mt-1`
- 标题区下细分割线 `border-t border-[var(--line)] pt-5 mt-4`
- 字段单栏堆叠 `space-y-4`
- 必填星号 `text-red-500`
- 部门、角色字段 `disabled bg-zinc-50`
**密码 Tab**
- 卡片标题"修改密码"+ 副标题"密码修改后下次登录生效"
- 三个字段单栏堆叠(与第 1 节澄清一致)
- 眼睛 icon 切换可见性保留
## 3. 保存反馈微调
**保存按钮三态**
```
普通: [取消] [保存]
提交中: [取消] [● 保存中...] ← spinner 禁用
成功: 已保存 ✓ [取消] [保存] ← 绿色文字 3 秒淡出
```
- 提交瞬间设 `submitting=true`,按钮 disabled + 左侧 Loader2 icon spinning
- 成功后 `submitting=false` + `savedAt=Date.now()`3 秒后 `setTimeout` 清掉 savedAt
- 已保存提示:`text-emerald-600` + Check icon
**取消按钮**
- 个人信息 Tab`handleReset` 重读 `useMemberStore.members.find(m => m.id === user.id)` 的字段
- 密码 Tab清空三个输入 + 清空 errors
**Banner 与表单同步**
- 字段改了未保存Banner 仍显老值(不联动)
- 保存成功 → `refreshUser()` → Banner 立即更新
## 数据流
```
useAuthStore.user
└─ 触发渲染
├─ Banneruser.name / role.name / dept name 链 / phone / email
└─ 表单字段(从 useMemberStore.members.find 取最新值)
提交流程:
form submit → updateMember() → refreshUser() → Banner 自动重渲
```
## 实施清单
修改:
- `apps/web/app/profile/page.tsx` — 整页重写Banner + Tab + 卡片布局 + 保存 spinner + 已保存淡出
不变:
- `apps/web/components/layout/Sidebar.tsx`(已正确)
- `apps/web/stores/useAuthStore.ts`(已加 refreshUser
- `apps/web/components/FieldError.tsx`(复用)
## 验证
1. `pnpm type-check` 0 错误
2. `pnpm build` 14+1 个页面成功
3. 进入 `/profile`
- 顶部渐变 Banner左下圆头像 + 姓名/角色/部门/联系方式
- 右上角白底红字退出按钮
- Banner 下 Tab 切换条 + 卡片
4. 改姓名后保存:
- 按钮 spinner 一闪
- 显示绿色"已保存 ✓"3 秒后淡出
- Banner 上的姓名立即更新refreshUser 生效)
5. 修改密码spinner + "密码已修改,下次登录生效" 3 秒淡出
6. 取消按钮:恢复初始值