Skip to content

refactor(console/dashboard): replace Card with HeroUI Pro Widget + polish#6

Merged
dingyi merged 7 commits into
mainfrom
feature/widget-dashboard-cards
Apr 27, 2026
Merged

refactor(console/dashboard): replace Card with HeroUI Pro Widget + polish#6
dingyi merged 7 commits into
mainfrom
feature/widget-dashboard-cards

Conversation

@dingyi

@dingyi dingyi commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

把之前 dashboard widget 重构链上 6 个 commit 合并到 main:

```
b7eabc6 fix(api-info-panel): center empty state vertically inside the panel
f8b73ea style(charts-panel): drop chart tab label font from text-sm to text-xs
3721de7 style(uptime-panel): shrink the refresh action to read as inline glyph
c41b67c style(console/dashboard): use primary 充值 CTA and bare-icon header buttons
e6d9072 refactor(console/dashboard): polish Widget header, empty state, and grid
f54cb30 refactor(console/dashboard): replace Card with HeroUI Pro Widget
```

第一个 commit 跟 PR #3 同名但内容是独立的更早版本;后面 5 个是 PR #3 之后的 dashboard polish follow-up,覆盖:

  • API Info / Announcements / Charts / FAQ / Stats / Uptime panels
  • DashboardHeader(充值 CTA 改为 primary、header 按钮改为 bare-icon)
  • helpers/dashboard.jsx

改动文件

  • `web/src/components/dashboard/AnnouncementsPanel.jsx`
  • `web/src/components/dashboard/ApiInfoPanel.jsx`
  • `web/src/components/dashboard/ChartsPanel.jsx`
  • `web/src/components/dashboard/DashboardHeader.jsx`
  • `web/src/components/dashboard/FaqPanel.jsx`
  • `web/src/components/dashboard/StatsCards.jsx`
  • `web/src/components/dashboard/UptimePanel.jsx`
  • `web/src/components/dashboard/index.jsx`
  • `web/src/helpers/dashboard.jsx`
  • `TODO.md`

合并冲突

0 个。原本担心跟 PR #5 的 dashboard 改动冲突,但 git auto-merge 全部成功。

验证

  • ✅ `bun run build`: 20.62s
  • ✅ `go build .`: 通过

This PR was generated automatically by Cursor

Made with Cursor

dingyi and others added 7 commits April 26, 2026 23:15
Migrate every panel on /console (StatsCards, ChartsPanel, ApiInfoPanel,
AnnouncementsPanel, FaqPanel, UptimePanel) from `@heroui/react` Card to
the new `Widget` primitive in `@heroui-pro/react` so each surface gets
the gray outer shell + elevated white content area + subtle inner
shadow defined by widget.css.

Notable adjustments while wiring this up:

- StatsCards: Widget.Content padding tightened from p-4 to p-3 and the
  KPI value font dropped from text-lg to text-base, with min-w-0 on the
  label cluster and shrink-0 on the trailing button/sparkline so the
  rendered "充值" button no longer clips against "$200.00" inside the
  narrower Widget content area.
- ChartsPanel + AnnouncementsPanel: override Widget.Header from the
  default fixed h-8 to h-auto min-h-12 flex-col … lg:flex-row so the
  inline Tabs strip / legend has room to wrap on narrow viewports.
- AnnouncementsPanel + UptimePanel: adopt Widget.Legend / Widget.LegendItem
  for status legends; the announcement panel maps the existing
  grey/blue/green/orange/red swatch keys to concrete CSS colors via a
  small LEGEND_COLOR_MAP because Widget.LegendItem requires a CSS color
  string.
- All title clusters use a whitespace-nowrap flex wrapper around the
  lucide icon and Widget.Title so CJK title characters do not stack
  vertically when the grid column is narrow.

widget.css is already pulled in via `@import '@heroui-pro/react/css';`
in web/src/index.css, so no extra CSS plumbing is required.

Verified: `bun run build` passes; `bunx prettier --check` and
`bunx eslint` pass for all touched files; manual screenshot QA
confirms the dashboard panels render with the new Widget surface.

Made-with: Cursor
Address visual polish feedback on the Widget rebuild:

- Title size: createSectionTitle in helpers/dashboard.jsx now wraps the
  text in a `text-sm font-semibold text-foreground` span (matching the
  widget__title CSS) so the four StatsCards titles (账户数据 / 使用统计 /
  资源消耗 / 性能指标) match the Widget.Title used by every other panel.
  Also adds whitespace-nowrap + shrink-0 on the icon to prevent CJK
  characters from stacking.

- Header height: every simple Widget.Header now uses `h-12` so the
  header strip matches the AnnouncementsPanel header height (which the
  user pointed out as the correct one). The complex headers
  (ChartsPanel, AnnouncementsPanel) keep their `h-auto min-h-12 …
  flex-col` rule for content that can wrap to a second row.

- Empty state: every empty state now uses HeroUI Pro's `EmptyState`
  with `size='sm'` and `EmptyState.Media variant='icon'`, dropping the
  custom 96×96 illustration container override. FaqPanel previously
  used a bespoke div + HelpCircle 42px; it now uses EmptyState too, so
  the four panels (ApiInfoPanel / AnnouncementsPanel / FaqPanel /
  UptimePanel) share the same circular muted icon background and
  consistent typography.

- Responsive grid: StatsCards collapses to 4-col only at xl (≥1280px)
  via `grid-cols-1 sm:grid-cols-2 xl:grid-cols-4` so each KPI card has
  ~360px at common 1024–1280 widths instead of ~150px (which was
  forcing labels like "统计次数" to wrap CJK character per line).
  ChartsPanel + ApiInfoPanel switch to `lg:grid-cols-3 xl:grid-cols-4`
  with the chart panel spanning 2/3, giving the API info column a
  more usable ~256px width at lg. The bottom info panels grid switches
  to `lg:grid-cols-2 xl:grid-cols-4` so 系统公告 takes the full row at
  lg with FAQ + Uptime side-by-side beneath it.

- ChartsPanel tabs strip: keeps the title and the Tabs.List on
  separate rows through lg and only inlines them at xl. The tab list
  is wrapped in an overflow-x-auto container with whitespace-nowrap
  on each Tabs.Tab so the 4–6 chart tabs no longer collapse into
  vertical CJK character columns when the chart panel narrows.

- Cleanup: drop the now-unused ILLUSTRATION_SIZE prop from
  AnnouncementsPanel / ApiInfoPanel / FaqPanel / UptimePanel and from
  the dashboard index that wired it through.

Verified: bun run build passes, prettier --check + eslint pass on all
touched files, and manual screenshot QA confirms consistent header
heights, title sizes, empty state icons, and a clean 2-col KPI grid +
horizontally scrollable tabs at the typical 1024px viewport.

Made-with: Cursor
…tons

- StatsCards: switch the 当前余额 → 充值 button from `variant='secondary'`
  (default surface fill + accent-soft text, which read as a muted green
  pill) to `variant='primary'` so it now renders with the accent fill +
  accent-foreground text expected of a recharge CTA.

- DashboardHeader: switch the 搜索条件 + 刷新 icon-only buttons from
  `variant='tertiary'` (which paints the surrounding pill at rest) to
  `variant='ghost'` so the trigger reads as a bare icon and the
  background only fades in on hover/press. Drop the gap from `gap-2`
  to `gap-1` since the buttons no longer carry their own pill.

Made-with: Cursor
The refresh trigger inside 服务可用性's compact 48px Widget.Header was
still rendering at full Button `sm` icon-only dimensions (32×32 with a
16px svg, since `.button--sm` forces svg to size-4 regardless of the
lucide `size` prop). Override to `!h-6 !w-6 !min-w-0` plus
`[&_svg]:!size-3` so the affordance reads as a 24×24 hover pill with a
12px refresh glyph — proportionate to the small panel header without
dominating the title. HeroUI Button only ships `sm`/`md`/`lg`, so a
className escape hatch is the cleanest sub-`sm` path.

Made-with: Cursor
The Tabs.List inside 模型数据分析's Widget.Header carries 4–6 entries
(消耗分布 / 调用趋势 / 调用次数分布 / 调用次数排行 / 用户消耗排行 /
用户消耗趋势). At the default 14px tab font, only the first three fit
across the chart panel at lg, forcing the rest behind the horizontal
scroll. Drop each Tabs.Tab label to text-xs (12px) so 4–5 tabs are
visible at rest while the secondary chrome stays subordinate to the
14px Widget.Title.

Made-with: Cursor
ApiInfoPanel sits in a CSS grid row alongside the much-taller
ChartsPanel, so the row stretches the API info Widget to ~24rem.
Previously the empty state branch rendered straight inside
ScrollableContainer, which collapses to its content height — leaving
the empty state pinned to the top with all the empty space below it.

Split the two render paths:

- Data path keeps the ScrollableContainer for scroll-with-fade and now
  carries `flex-1` so the scroll region claims the stretched height.
- Empty path renders into a `flex flex-1 min-h-80 items-center
  justify-center` wrapper, which propagates the row height down via the
  `flex` Widget.Content + `flex-1` child chain and centers the
  EmptyState both axes regardless of grid stretch height.

Made-with: Cursor
Auto-merge — no conflicts. Brings the PR #5 (HeroUI rewrite) and PR #1/#3
console template work into the widget-dashboard-cards branch so the dashboard
widget polish work (6 commits: replace Card with HeroUI Pro Widget, polish
Widget header/empty state/grid, primary 充值 CTA + bare-icon header buttons,
shrink uptime panel refresh action, drop charts panel tab font, vertically
center api-info-panel empty state) can be merged on top of the latest UI
foundation.

Validation:
- bun run build: passes (20.62s)
- go build .: passes
@dingyi
dingyi merged commit dcbe5bf into main Apr 27, 2026
1 check passed
@dingyi
dingyi deleted the feature/widget-dashboard-cards branch April 27, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant