Assist_Design/docs/plans/2026-03-05-portal-ui-cleanup-design.md
barsa cab58d1c5b refactor: streamline component layouts and enhance navigation
- Updated the AppShell and Sidebar components for improved layout and spacing.
- Replaced font colors in the Logo component for better visibility.
- Adjusted the PageLayout component to utilize backLink props instead of breadcrumbs for navigation consistency.
- Removed unnecessary description props from multiple PageLayout instances across various views to simplify the codebase.
- Introduced SectionCard component in OrderDetail for better organization of billing information.
- Enhanced utility styles in CSS for improved typography and layout consistency.
2026-03-06 10:45:51 +09:00

6.3 KiB

Portal UI Cleanup Design

Problem

The portal account pages have accumulated visual inconsistencies: different card styles, spacing, button variants, badge implementations, and header structures across pages. The sidebar color feels disconnected from the landing page brand. Logo visibility is poor on the dark sidebar. Subscriptions navigation is over-complicated. Breadcrumbs conflict with page titles. Detail pages lack consistent structure.

Decisions

1. Sidebar & Brand Consistency

Sidebar background: Shift from oklch(0.18 0.03 250) to oklch(0.20 0.06 234.4) — same hue as primary blue, slightly more saturated, still dark. Creates brand harmony with landing page.

Sidebar border: Adjust to match new tone.

Logo: White variant for dark sidebar. SVG fallback colors change from #60A5FA/#1E40AF to #ffffff/rgba(255,255,255,0.6). Remove the bg-white/10 container — let logo sit directly.

Subscriptions nav: Change from expandable with child links to a direct link to /account/subscriptions (like Dashboard or Services). Remove computeNavigation dynamic children.

2. Unified List Page Pattern

All list pages (Subscriptions, Orders, Invoices, Support) follow one pattern:

PageLayout (bg-muted/40 header built-in, icon + title + action buttons, NO description)
  Metric cards row (grid-cols-2 lg:grid-cols-4 gap-3) — where applicable
  Content card (bg-card rounded-xl border border-border shadow-[var(--cp-shadow-1)])
    Search/filter bar (px-5 py-3.5 border-b border-border/40)
    Content area (p-5)
      Grid: grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-3
      or Table: DataTable

List header: Handled by PageLayout. Icon + title on left, action buttons right-aligned. No description text.

Card borders: border border-border everywhere — drop /60 opacity variants on outer cards.

List item hover: hover:border-border hover:shadow-[var(--cp-shadow-2)] hover:-translate-y-0.5 — consistent across all.

Status badges: Always use StatusPill atom — no inline badge classes.

Affected pages: SubscriptionsList, OrdersList, InvoicesList, SupportCasesView.

3. Unified Detail Page Pattern

PageLayout (bg-muted/40 header, backLink + title + status pill + right-aligned action buttons)
  Stats/summary row (bg-card rounded-xl border border-border shadow-[var(--cp-shadow-1)])
    Grid: grid-cols-2 md:grid-cols-4 gap-6, px-6 py-5
  Stacked section cards (space-y-6)

Back navigation: PageLayout backLink prop renders ← Back to {parent} link above the header. Detail pages only. No breadcrumbs.

Action buttons: Always in PageLayout actions prop, right-aligned. Use <Button> component variants (not inline-styled).

Affected pages: SubscriptionDetail, OrderDetail, InvoiceDetail, SupportCaseDetailView.

4. PageLayout Template Changes

PageLayout becomes the single source of truth for page header styling. Changes:

  • Header area: Always renders with bg-muted/40 border-b border-border/40 background. No more plain/transparent headers.
  • Remove description: Drop the description prop usage — title is enough, description was redundant with sidebar context.
  • New backLink prop: { label: string; href: string } — renders ← Back to {parent} above the header on detail pages. List pages don't pass this.
  • Remove breadcrumbs: Drop breadcrumb rendering entirely — replaced by backLink on detail pages, sidebar on list pages.
  • Header layout: flex items-center justify-between — icon + title on left, actions on right. Status pills sit next to the title.
  • Consistent spacing: Header padding px-6 py-4, content area spacing space-y-6.

This means every account page automatically gets the same header treatment by using PageLayout. No per-page header styling needed.

5. Section Card Pattern

Every content section in detail pages uses this structure:

bg-card rounded-xl border border-border shadow-[var(--cp-shadow-1)] overflow-hidden
  Header (bg-muted/40 px-6 py-4 border-b border-border/40)
    flex items-center justify-between
      Left: flex items-center gap-3
        Icon circle (h-9 w-9 rounded-lg bg-{tone}/10 text-{tone})
        Title: text-sm font-semibold text-foreground
        Subtitle: text-xs text-muted-foreground
      Right: action button(s) or link
  Content (px-6 py-5)

Each section gets a semantic tone for its icon circle:

  • Billing: primary
  • SIM Management: info
  • Order Items: success
  • Support: warning

6. Subscriptions-Specific Fixes

  • Active/inactive dimming: Active subscriptions render normally. Completed/Cancelled/Terminated get opacity-60 on the grid card + muted status indicator.
  • Cancel button: Move from inline-styled to <Button variant="destructive" size="sm"> via PageLayout actions.
  • Domain imports: Fix @customer-portal/domain/subscriptions module resolution (run pnpm domain:build).
  • Grid card borders: Standardize from border-border/60 to border-border.

7. Cross-Page Consistency

Typography:

  • Page titles: PageLayout handles it (text-xl sm:text-2xl md:text-3xl font-bold). Remove custom title sizes in views.
  • Section headings: text-sm font-semibold text-foreground inside section cards.
  • Stat values: font-heading for numbers.

Buttons — always use <Button> component:

  • Primary actions: variant="default" (Browse Services, New Case)
  • Secondary: variant="outline" (Back, Retry, View All)
  • Destructive: variant="destructive" (Cancel Service)
  • Links: variant="link" or ghost for in-section navigation

Status display:

  • Always <StatusPill> — no inline badge classes
  • size="sm" in list views, size="md" in detail headers

Borders:

  • Outer cards: border border-border
  • Internal dividers only: border-b border-border/40

Spacing:

  • Card padding: p-4 for list item cards, p-5 for container sections
  • Gap between items: gap-3
  • Section spacing: space-y-6

8. Navigation Changes

  • List pages: No back link — sidebar handles navigation.
  • Detail pages: ← Back to {parent} link above title.
  • Breadcrumbs: Removed — redundant with page title.
  • Sidebar subscriptions: Direct link, no expandable children.

Out of Scope

  • Landing page color token migration (separate effort)
  • New component creation beyond what's needed for the patterns above
  • Mobile-specific layout changes