From 6bc1836e6665a1d0bd6c9f1d0c796e2ff64a4c15 Mon Sep 17 00:00:00 2001 From: BilalG1 Date: Sun, 19 Apr 2026 22:58:07 -0700 Subject: [PATCH] fix(dashboard): resolve UI issues across email-* pages (#1345) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Six UI issues found across the email-* dashboard pages, ranked by impact, fixed here: 1. **email-sent layout** — the email log table and domain reputation card were forced side-by-side at all widths. A fixed-width sidebar plus a flex-1 table meant that on tablet the table got crushed, and on mobile the row overflowed horizontally. Fix: stack vertically below `lg`, and let the reputation card span full width on narrow viewports. 2. **Domain status enum leaks to the UI** — `Status: {domain.status}` rendered raw values like `pending_dns` / `pending_verification`. Added a `MANAGED_DOMAIN_STATUS_LABELS` map and route through it before rendering. 3. **email-themes dialog grid cramped on mobile** — the Change Theme dialog hardcoded `grid-cols-2`, so at 375px each theme card had ~150px and the preview images were illegible. Changed to `grid-cols-1 sm:grid-cols-2`. 4. **Template name row overflow** — long template names pushed the Edit Template button off the right edge of the card because the flex row had no `min-w-0` / `truncate`. Fixed both, and made the action column `shrink-0`. 5. **Boosted-capacity label was color-only** — during an active boost the label used a red strikethrough for the base value and a blue number for the boosted value with no non-color cue. Added an explicit `→` arrow between the two numbers, `title` tooltips on each, and a visible \"(boosted)\" marker after `/h max`. 6. **Draft progress bar overflowed at mobile width** — the 4-step progress bar used fixed 80px connectors, giving a minimum width of ~400px that clipped off both ends at 375px. Changed connectors to `w-8 sm:w-20` (32px on mobile, 80px otherwise) so all four steps and their labels fit below 640px. ## Before / after Each GIF below loops \"before\" (1s) → \"after\" (1s) with a red pill in the top-right indicating which frame is which. Full-size stills (before + after + extra viewports) are listed under **All screenshots** at the bottom. ### 1. email-sent — two-column layout collapses on narrow viewports Mobile (375px): ![email-sent mobile](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-01-email-sent-mobile.gif) Tablet (900px): ![email-sent tablet](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-01-email-sent-tablet.gif) ### 2. email-settings — managed-domain status label ![domain status](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-02-domain-status.gif) ### 3. email-themes — Change Theme dialog on mobile ![themes mobile](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-03-themes-mobile.gif) ### 4. email-templates — long name overflow ![templates overflow](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-04-templates-overflow.gif) ### 5. email-sent — boosted capacity label ![capacity label](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-05-capacity-label.gif) ### 7. email-drafts — draft progress bar on mobile ![draft progress bar](https://gist.githubusercontent.com/BilalG1/edb04740a19c3f2d048da6e602209d45/raw/gif-07-draft-progress-mobile.gif) ## Test plan - [x] \`pnpm --filter @stackframe/dashboard lint\` — clean - [x] \`pnpm --filter @stackframe/dashboard typecheck\` — clean - [x] Manual verification in a browser at 375px / 900px / 1440px, light + dark mode, for each fixed page - [ ] Reviewer sanity check of the remaining email-* pages (email-outbox, email-viewer) for similar responsive regressions ## Notes - The initial review flagged a \"white-on-white capacity boost timer\" — on closer look the label sits on a deliberately dark `bg-zinc-900/0.82` overlay inside the boost card, so it reads fine in light and dark mode. Not fixing; that part of the review was a false positive. - The initial review also flagged a missing empty state on email-templates. Because Stack seeds built-in templates, the empty branch is unreachable in practice — skipping that fix to avoid dead code. ## All screenshots Gist with all the individual before/after PNGs and the GIFs themselves: https://gist.github.com/BilalG1/edb04740a19c3f2d048da6e602209d45 ## Summary by CodeRabbit ## Release Notes * **New Features** * Added human-readable status labels for managed domains in domain settings * **Improvements** * Enhanced responsive layouts across dashboard pages for improved mobile experience * Improved email capacity display with visual indicators and tooltips for boost status * Refined template and theme selection layouts with better text handling and spacing --- .../[draftId]/draft-progress-bar.tsx | 4 ++-- .../email-sent/domain-reputation-card.tsx | 20 ++++++++++++++----- .../[projectId]/email-sent/page-client.tsx | 2 +- .../email-settings/domain-settings.tsx | 10 +++++++++- .../email-templates/page-client.tsx | 10 +++++----- .../[projectId]/email-themes/page-client.tsx | 2 +- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-drafts/[draftId]/draft-progress-bar.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-drafts/[draftId]/draft-progress-bar.tsx index 4dddf3ba0..f9b4d1656 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-drafts/[draftId]/draft-progress-bar.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-drafts/[draftId]/draft-progress-bar.tsx @@ -55,7 +55,7 @@ export function DraftProgressBar({ steps, currentStep, onStepClick, disableNavig {!isLast && ( -
+
{step.label} - {!isLast &&
} + {!isLast &&
}
); })} diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/domain-reputation-card.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/domain-reputation-card.tsx index 08fd771a5..d43c6fa3d 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/domain-reputation-card.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/domain-reputation-card.tsx @@ -247,10 +247,20 @@ export function DomainReputationCard() { const capacityLabel = isBoostActive ? ( {hourlyUsed} of{" "} - {Math.round(baseHourlyCapacity)} - {" "} - {Math.round(hourlyCapacity)} - /h max + + {Math.round(baseHourlyCapacity)} + + {" \u2192 "} + + {Math.round(hourlyCapacity)} + + /h max (boosted) ) : ( `${hourlyUsed} of ${Math.round(hourlyCapacity)}/h max` @@ -260,7 +270,7 @@ export function DomainReputationCard() {
diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/page-client.tsx index 153092b8e..9852d6bf3 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/page-client.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-sent/page-client.tsx @@ -134,7 +134,7 @@ export default function PageClient() { title="Sent" description="View email logs and domain reputation" > -
+
{/* Left side: Email Log with toggle inside card */}
= { standard: "Custom SMTP", }; +const MANAGED_DOMAIN_STATUS_LABELS: Record = { + pending_dns: "Pending DNS records", + pending_verification: "Pending verification", + verified: "Verified", + applied: "Applied", + failed: "Failed", +}; + const VISIBLE_FIELDS: Record = { shared: [], managed: [], @@ -317,7 +325,7 @@ function ManagedEmailSetupDialog(props: { trigger: React.ReactNode }) { {domain.senderLocalPart}@{domain.subdomain} - Status: {domain.status} + Status: {(MANAGED_DOMAIN_STATUS_LABELS as Record)[domain.status] ?? domain.status} -
-
-
+
+
+
- + {template.displayName}
-
+