2026-07-09-mailhub-ui-redesign-design.md 10 KB

MailHub UI Visual Redesign Design

Goal

全面升级 MailHub 管理台与登录/注册页的视觉系统,使其从「默认 Ant Design 后台模板」提升为辨识度高的 Modern SaaS 控制台,同时不改动后端 API、权限模型、业务状态机与核心信息架构

Confirmed Product Decisions

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

Non-Goals

  • New features, new routes, or new API endpoints
  • Replacing Ant Design / React / Vite stack
  • Full custom component library rebuild
  • Dark mode theme
  • Changing domain DNS workflow semantics, token lifecycle, or admin permissions
  • Rewriting analytics models or i18n message semantics (minor chrome strings only)

Architecture

Continue the current React admin app (src/frontend/, src/layouts/, src/pages/, src/components/) built by Vite into public/. Visual upgrades land as:

  1. Design tokens — CSS custom properties + Ant Design ConfigProvider theme tokens
  2. Shell redesignAdminLayout and auth shell (AuthApp)
  3. Shared presentation components — PageHeader, MetricCard, SectionCard, StatusPill, EmptyState, CodeBlock
  4. Page restyles — recompose existing page markup around the new patterns without changing data loading or handlers

Business logic remains in existing model modules (*-model.js), api.ts, and page containers.

Admin and auth are separate Vite entry points (src/frontend/main.tsxApp.tsx, src/frontend/auth/main.tsxAuthApp). Each mounts its own ConfigProvider. Extract a shared theme/token module (e.g. src/frontend/theme.ts + CSS variables in styles.css) and apply it in both entry trees so brand stays consistent without implying a single React tree.

theme.ts + styles.css (shared tokens)
  ├── Auth entry: ConfigProvider → I18nProvider → AuthApp
  └── Admin entry: ConfigProvider → I18nProvider → App
        └── AdminLayout (sider + header + content)
              └── pages (Dashboard, Domains, …)
                    └── shared presentation components

Visual System (Tokens)

Color

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

Shape, Type, Space

  • Radius: controls 10px, cards 14px, pills 999px
  • Shadow: light elevation — thin border + soft ambient (0 1px 2px + 0 8px 24px slate-tinted)
  • Spacing rhythm: 8-based (8 / 16 / 24 / 32); content padding 24–32px
  • Type scale: page title 22–24px, metric value 28–32px, body 14px
  • Font stack: Inter preferred, with system-ui / -apple-system / Segoe UI fallbacks
  • Inter loading: prefer system stack only or self-hosted font files if Inter is added later; avoid third-party CDN font loads for self-hosted deploy reliability. Default implementation may use system-ui stack without shipping Inter files.

Ant Design Theme Mapping

Map tokens into ConfigProvider at least for:

  • colorPrimary, colorSuccess, colorWarning, colorError
  • colorBgLayout, colorBgContainer, colorBorderSecondary, colorText, colorTextSecondary
  • borderRadius, borderRadiusLG
  • Component overrides for Card, Table (comfortable cell padding), Button, Menu (sider), Tag or custom StatusPill preference

Default Ant blue #1677ff must not remain as brand primary.

Shell Design

AdminLayout

  • Sticky dark sider width 248px, background ink #0F172A
  • Brand block: gradient MH mark + title MailHub + subtitle Email Delivery
  • Navigation groups (labels only; routes unchanged):
    • Overview — Dashboard, Domains, DNS API
    • Delivery — SMTP, API Tokens, Sending Logs, Webhooks
    • System — Admin (admin role only), Settings
  • Active item: primary-soft indigo wash + light text (custom sider styles; avoid stock dark-menu look)
  • Header: white surface, border bottom, page title / breadcrumb, language select, refresh, primary CTA Add domain, user dropdown
  • Content: canvas background, comfortable padding
  • Responsive: below lg, collapse sider to drawer-style behavior (existing Ant Layout breakpoint pattern)
  • Optional light account summary at sider bottom is allowed; primary account actions stay in header dropdown

Auth (Login / Register / Forgot / Reset / Resend)

  • Same tokens as admin
  • Desktop split:
    • Left: ink brand panel — logo, headline, short value prop, 2–3 capability signals
    • Right: soft canvas/indigo wash + elevated white form card
  • Mobile: single column; brand panel compressed on top
  • Keep existing auth modes and API calls; restyle forms, alerts, segmented control, and spacing only

Shared Presentation Components

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.

Key Page Treatments

Dashboard

  • Keep security alert (default admin password) at top when applicable
  • Condense the metric strip to exactly four primary MetricCards:
    1. 今日发送 (today sent)
    2. 成功率 (success rate)
    3. 已验证域名 (verified domains)
    4. DNS 问题 (DNS issues count)
  • Place remaining current summary fields as secondary, not equal-weight cards:
    • Bounce rate / complaint rate — show as captions or mini stats under success-rate card, or in status distribution context
    • Last sent at — meta line under recent-sends SectionCard header or toolbar
    • SMTP status — compact readiness chip in PageHeader extra area or a small readiness row above charts
  • Chart row: trend + status distribution in SectionCards; recolor plots to token palette
  • Retain existing secondary panels (domain ranking, hourly heatmap, domain health list / recent failures if present) — restyle with SectionCard chrome; do not drop them from the layout inventory
  • Recent sends table inside SectionCard
  • No analytics model API changes

Domains list

  • PageHeader + toolbar (search, status filter, add domain)
  • Table inside SectionCard; domain name as emphasized link control
  • Status via StatusPill; comfortable row padding

Domain detail

  • Upgrade DomainHealthCard to a hero block: domain title, status pill, key stats, DNS progress, primary action stack (apply DNS / check / test / edit)
  • Tabs and two-column DNS records layout remain
  • DNS record cards use CodeBlock + StatusPill + consistent action buttons
  • No change to DNS apply/check/test flows

Other pages (SMTP, Tokens, Logs, DNS API, Settings, Admin, Webhooks placeholder)

  • Apply PageHeader + SectionCard + table/form spacing polish
  • Do not redesign information architecture or form field sets beyond visual hierarchy
  • Token create modal / secret-once warning keeps existing behavior with improved visual emphasis

Engineering Boundaries

In scope files (expected)

  • src/frontend/App.tsx — theme provider tokens
  • src/frontend/styles.css — CSS variables + shell/page styles
  • src/frontend/auth/AuthApp.tsx (+ auth-related styles)
  • src/layouts/AdminLayout.tsx
  • src/components/common/* (new or updated shared UI)
  • src/components/domain/* (visual structure only)
  • src/pages/** (composition / classNames / shared components; handlers stay)

Out of scope

  • src/server.js, src/db.js, mailer/submission/DNS provider logic
  • Model pure functions unless a pure presentation helper is needed
  • Docker / deploy scripts

i18n

  • Reuse existing keys for page meaning
  • May add short chrome keys (nav group labels, empty-state titles) in both locales already supported by the app

Testing & verification

  • Existing npm test suite must remain green (models, i18n, server APIs unchanged)
  • Add tests only if new pure helpers are introduced
  • Manual / build verification: npm run build (and UI smoke of login + dashboard + domain detail)

Delivery Order

  1. Design tokens (CSS vars + ConfigProvider)
  2. AdminLayout shell + nav groups
  3. Auth shell restyle
  4. Shared presentation components
  5. Dashboard
  6. Domains list + domain detail / health / DNS cards
  7. Remaining pages sweep
  8. Build + test gate

Success Criteria

  • Brand primary is indigo-based, not default Ant blue
  • Admin and auth feel like one product
  • Layout remains dark sidebar + comfortable density as approved
  • All existing navigation destinations and primary workflows remain reachable
  • No intentional API or auth behavior regressions
  • npm test and npm run build pass

Open Questions

None blocking. Optional later (explicitly out of this spec): dark mode, illustration pack, custom icon set beyond @ant-design/icons.