全面升级 MailHub 管理台与登录/注册页的视觉系统,使其从「默认 Ant Design 后台模板」提升为辨识度高的 Modern SaaS 控制台,同时不改动后端 API、权限模型、业务状态机与核心信息架构。
| Decision | Choice |
|---|---|
| Scope | Full visual system redesign (theme + layout shell + component patterns + key pages) |
| Auth pages | Included; same visual language as admin console |
| Visual style | Modern SaaS — light canvas, indigo primary, airy product feel (Resend / Railway-like) |
| Shell | Dark left sidebar (full text labels) + light top bar + content canvas |
| Density | Comfortable — larger type, generous whitespace, breathable cards |
| Implementation approach | Design system + shell upgrade on existing React + Ant Design v5 |
| Dark mode | Out of scope for this redesign |
Continue the current React admin app (src/frontend/, src/layouts/, src/pages/, src/components/) built by Vite into public/. Visual upgrades land as:
ConfigProvider theme tokensAdminLayout and auth shell (AuthApp)Business logic remains in existing model modules (*-model.js), api.ts, and page containers.
ConfigProvider(theme tokens)
└── I18nProvider
├── AuthApp (login/register/forgot/reset) ← shared tokens
└── App
└── AdminLayout (sider + header + content)
└── pages (Dashboard, Domains, …)
└── shared presentation components
| Role | Value | Usage |
|---|---|---|
| Primary | #4F46E5 |
Primary buttons, links, active nav accent |
| Primary hover | #4338CA |
Hover / pressed primary |
| Primary soft | #EEF2FF |
Soft fills, selected chips |
| Ink / Sider | #0F172A |
Sidebar background, primary text |
| Text secondary | #64748B |
Labels, helper text |
| Text muted | #94A3B8 |
Meta / placeholders |
| Canvas | #F4F6FB |
App background |
| Surface | #FFFFFF |
Cards, header, auth form card |
| Border | #E2E8F0 |
Dividers, card borders |
| Success | #16A34A (+ soft green bg) |
Healthy / accepted |
| Warning | #D97706 (+ soft amber bg) |
Pending / DNS issues |
| Danger | #DC2626 (+ soft red bg) |
Failed / destructive |
10px, cards 14px, pills 999px0 1px 2px + 0 8px 24px slate-tinted)8 / 16 / 24 / 32); content padding 24–32px22–24px, metric value 28–32px, body 14pxMap tokens into ConfigProvider at least for:
colorPrimary, colorSuccess, colorWarning, colorErrorcolorBgLayout, colorBgContainer, colorBorderSecondary, colorText, colorTextSecondaryborderRadius, borderRadiusLGCard, Table (comfortable cell padding), Button, Menu (sider), Tag or custom StatusPill preferenceDefault Ant blue #1677ff must not remain as brand primary.
#0F172AMailHub + subtitle Email Deliverylg, collapse sider to drawer-style behavior (existing Ant Layout breakpoint pattern)| Component | Responsibility |
|---|---|
PageHeader |
Title, optional subtitle/description, right-side actions (one primary action per region) |
MetricCard |
Label, large value, optional trend pill / soft icon tile |
SectionCard |
Standard content card (14px radius, light shadow, consistent header/body padding) |
StatusPill |
Semantic soft status chip (success / warning / error / info / neutral) |
EmptyState |
Icon, message, optional primary CTA for empty lists/charts |
CodeBlock |
Mono, wrap-safe long values (DNS/token samples) with copy affordance |
Prefer placing these under src/components/common/ (or equivalent) and reusing across pages. Existing StatusTag may be adapted into or replaced by StatusPill for visual consistency.
DomainHealthCard to a hero block: domain title, status pill, key stats, DNS progress, primary action stack (apply DNS / check / test / edit)src/frontend/App.tsx — theme provider tokenssrc/frontend/styles.css — CSS variables + shell/page stylessrc/frontend/auth/AuthApp.tsx (+ auth-related styles)src/layouts/AdminLayout.tsxsrc/components/common/* (new or updated shared UI)src/components/domain/* (visual structure only)src/pages/** (composition / classNames / shared components; handlers stay)src/server.js, src/db.js, mailer/submission/DNS provider logicnpm test suite must remain green (models, i18n, server APIs unchanged)npm run build (and UI smoke of login + dashboard + domain detail)npm test and npm run build passNone blocking. Optional later (explicitly out of this spec): dark mode, illustration pack, custom icon set beyond @ant-design/icons.