BMS/UI_UX_PLAN.md
2026-03-19 11:32:17 +00:00

16 KiB
Raw Permalink Blame History

DemoBMS — UI/UX Improvement Plan

Generated from full page-by-page review (16 pages + shared layout). Work through phases in order — each phase builds on the previous.


Phase 1 — Foundation Fixes

Goal: Fix broken/incomplete global chrome and shared infrastructure before touching individual pages. Effort: ~12 days | Risk: Low

1.1 Topbar title map — complete it

  • Add missing entries for: generator, leak, fire, network, energy, maintenance
  • Replace pathname-based map with a route config object shared with sidebar

1.2 Topbar — replace placeholder avatar with Clerk UserButton

  • Swap the blue circle for <UserButton /> from @clerk/nextjs
  • Removes the hardcoded placeholder and provides sign-out, profile link for free

1.3 Topbar — remove or disable the site selector

  • The dropdown is hardcoded with 3 fake sites and does nothing
  • Either wire it to real site context, or remove it entirely until it's real
  • A non-functional control erodes trust

1.4 Topbar — consolidate the alarm badge

  • Remove the alarm count badge from the sidebar nav item
  • Keep it only on the topbar bell icon (single canonical location)

1.5 Sidebar — add section groupings with dividers

  • Split 15 nav items into labelled groups:
    • OVERVIEW — Dashboard, Floor Map
    • INFRASTRUCTURE — Power, Generator, Cooling, Environmental
    • SAFETY — Leak Detection, Fire & Safety, Network
    • OPERATIONS — Assets, Alarms, Capacity
    • MANAGEMENT — Reports, Energy & CO₂, Maintenance, Settings
  • Render section headers as small ALL-CAPS muted labels with a horizontal rule above
  • Collapsed sidebar: show only icons, hide section headers

1.6 Sidebar — move collapse toggle to bottom

  • Currently the toggle is an absolutely-positioned button that's easy to miss
  • Move it to the bottom of the sidebar as a regular icon button above Settings
  • Add a tooltip: "Collapse menu" / "Expand menu"

1.7 Centralise threshold constants

  • Create /lib/thresholds.ts exporting a single const object:
    export const THRESHOLDS = {
      temp: { warn: 26, critical: 28 },
      humidity: { warn: 65, critical: 80 },
      power: { warn: 0.75, critical: 0.85 },   // fraction of capacity
      filter: { warn: 80, critical: 120 },     // Pa
      compressor: { warn: 0.80, critical: 0.95 },
      battery: { warn: 30, critical: 20 },
      fuel: { warn: 30, critical: 15 },
    }
    
  • Replace all hardcoded threshold values across every page with imports from this file

1.8 Global spacing standardisation

  • Audit and enforce: all page wrappers use space-y-6, all cards use p-6, all card headers use pb-3
  • Create a <PageShell title=""> wrapper component used by every page to ensure consistent top padding and title rendering

1.9 Empty state and error boundary

  • Create a reusable <ErrorCard message=""> component shown when a fetch fails
  • Create a reusable <EmptyCard message=""> for no-data states
  • Wrap every data-dependent card in a try/catch that renders <ErrorCard> instead of crashing
  • Add a top-level React error boundary in the dashboard layout

Phase 2 — Alarms Page

Goal: Make the alarm page genuinely usable under operational pressure. Effort: ~1 day | Risk: Low

2.1 Sticky filter bar

  • Make the filter row (state tabs + severity dropdown) sticky top-0 z-10 so it stays visible while scrolling through long alarm lists

2.2 Bulk action at top

  • Move the "Bulk Resolve" button into the filter/action row at the top, not below the table
  • Add a "Select All" checkbox in the table header

2.3 Swap Critical stat card for Avg Age

  • Replace the "Critical" count card with "Avg Age" — the mean time alarms have been open
  • Display as "Xh Ym" format
  • Colour red if avg age > 1h, amber if > 15 min, green if < 15 min

2.4 Column priority on small screens

  • On mobile/tablet, keep: Severity | Message | Escalation timer | Actions
  • Drop: Sensor ID, State (already conveyed by row colour)
  • Escalation timer must always be visible — it is the most operationally critical column

2.5 Pagination

  • Add simple page controls: Previous / Page X of Y / Next
  • Default page size: 25 rows
  • Show total count above the table: "Showing 125 of 142 alarms"

2.6 Embed sparkline in stat cards

  • Remove the standalone 24-hour sparkline chart
  • Embed a micro line chart (24 data points, 40px tall) inside each stat card below the number
  • Net result: less vertical space used, same information

Phase 3 — Dashboard Page

Goal: Reduce clutter, improve at-a-glance legibility. Effort: ~1 day | Risk: Low

3.1 Uniform KPI card grid

  • Standardise all 6 KPI cards to the same height and same layout template
  • Use a 3×2 grid (3 cols on lg, 2 on md, 1 on sm) consistently

3.2 Replace mini floor map

  • The mini floor map widget is too small to be useful
  • Replace with a "Room Quick Status" card:
    • Two rows: Hall A / Hall B
    • Each row: health badge (OK / Warning / Critical), avg temp, total power, CRAC state
    • Link to /floor-map for full view

3.3 Data freshness pill in topbar

  • Move the "last updated" indicator from the dashboard page into the topbar (right side, before the bell)
  • Make it global — show the last successful API poll timestamp for any page
  • Colour: green if < 60s, amber if 60120s, red if > 120s (stale)

3.4 Alarm feed / Room status layout

  • Change the bottom row from 2-col + 1-col to 50/50
  • Alarm Feed: left panel
  • Room Quick Status: right panel (replaces mini floor map)

Phase 4 — Power Page

Goal: Tame the long scroll, improve information hierarchy. Effort: ~1.5 days | Risk: LowMedium

4.1 Page-internal anchor navigation

  • Add a sticky sub-nav bar below the topbar with anchor links: Site Overview | UPS | Generator | Transfer Switch | Phase Analysis
  • Each section gets an id="" and smooth-scroll on click

4.2 Power path diagram

  • Add a simple horizontal flow diagram at the top of the page: Grid → [ATS: feed A/B] → [UPS: battery/online] → Rack Distribution
  • Use coloured nodes (green = live, amber = degraded, red = fault)
  • No library needed — a flex row of icon + connector line components

4.3 Always-visible Phase Summary card

  • Show a collapsed "Phase Balance" summary card at all times (Phase A / B / C current kW in a 3-col grid)
  • Expand to full Phase Imbalance Table on click or if violations exist

4.4 Per-rack bar chart — full width

  • The per-rack chart needs more horizontal room to show 10 bars legibly
  • Move it to full width above the history chart (stack them, not side by side)

Phase 5 — Cooling Page

Goal: Reduce card density, surface critical maintenance items earlier. Effort: ~1 day | Risk: Low

5.1 Standardise fleet summary bar

  • Replace the horizontal KPI tile flex row with proper KPI cards matching dashboard style

5.2 Promote filter replacement alert

  • If any CRAC unit is within 14 days of filter replacement threshold, show a dismissible alert banner at the top of the page
  • Move the Predictive Filter Replacement card to the top of the page (above CRAC cards)

5.3 CRAC card — progressive disclosure

  • The current CRAC card has 6 stacked sections
  • Keep: thermal hero (supply/return/ΔT), capacity bar, fan speed
  • Collapse into a "Details" accordion: compressor pressures + electrical readings
  • The thermal hero section should be 30% larger — it is the most important readout

5.4 Thermal hero — increase visual weight

  • Increase supply/return temp font to text-3xl
  • ΔT value in a coloured pill (green/amber/red based on threshold)
  • Add a small up/down arrow showing trend (last 5 min)

Phase 6 — Environmental Page

Goal: Unify interactive state across sections, reduce redundancy. Effort: ~1 day | Risk: Low

6.1 Shared room tab state

  • All sections on the page (heatmap, dew point, trend chart) should react to a single room tab selector at the top of the page, not per-section tabs
  • Add one prominent "Hall A / Hall B" tab switcher at the page level

6.2 Dual-axis chart — clarify axes

  • Add unit labels on the Y-axis: left axis "Temperature (°C)", right axis "Humidity (%)"
  • Change the humidity line to a dashed style (already done) but also add a subtle fill under it to visually distinguish it from the temperature line
  • Add a brief legend note: "Shaded areas = ASHRAE A1 safe zone"
  • Label both panels clearly as "Summary — see Leak Detection / Fire & Safety for detail"
  • Add a "View full page →" link in each panel header
  • This avoids duplicating full detail here

Phase 7 — Floor Map Page

Goal: Improve overlay controls and map legibility. Effort: ~1 day | Risk: LowMedium

7.1 Overlay controls — proper segmented control

  • Replace the 4 overlay buttons with a shadcn <Tabs> style segmented control
  • Active tab: filled background, not just a subtle border change

7.2 Hot/cold aisle labels — improve visibility

  • Increase aisle divider label font size and weight
  • Add icon: 🔴 Hot Aisle / 🔵 Cold Aisle (or Lucide Flame / Snowflake)
  • Increase divider bar height slightly

7.3 Rack tile — secondary metric on hover only

  • In Temperature overlay: show °C as main value; power bar appears on hover tooltip only
  • In Power overlay: show % as main value; temp appears in tooltip
  • Reduces visual clutter in the tile grid

7.4 CRAC strip — move above rack grid

  • The CRAC strip is currently below the rack grid and easy to miss
  • Move it above the grid with a stronger visual separator (border + label "Cooling Unit")

7.5 Leak sensor panel — add zone labels

  • Add a brief location description to each sensor: "Hall A — under floor, near CRAC" etc.
  • Use consistent zone label chips rather than free text

Phase 8 — Assets Page

Goal: Make each tab genuinely useful and distinct from other pages. Effort: ~1 day | Risk: Low

8.1 Rack Grid tab → Rack Summary Table

  • Replace the visual rack grid (duplicates Floor Map) with a sortable table:
    • Columns: Rack ID | Room | Temp (°C) | Power (kW) | Power % | Alarms | Status
    • Sortable by any column
    • Row click opens RackDetailSheet

8.2 Device List — sort headers

  • Add click-to-sort on every column header with a sort direction indicator (chevron icon)
  • Default sort: Type then Name

8.3 Device type legend

  • Add a compact colour legend row above the device table explaining the dot colours
  • One row of: ● Server ● Switch ● PDU ● Storage ● Firewall ● KVM

8.4 CRAC / UPS cards → inventory rows

  • Replace the large card components with compact inventory table rows:
    • ID | Type | Status | Room | Rack | Last Maintenance
  • Link to full detail on click (CracDetailSheet / UpsCard modal)

Phase 9 — Remaining Pages

Goal: Individual page improvements that don't interact with other phases. Effort: ~1.5 days | Risk: Low

9.1 Generator page — add fuel runtime estimate

  • Add "Est. runtime at current load: X hours" as the hero stat in each generator card
  • Show a small fuel consumption trend chart (last 24h) if data is available
  • Clearly differentiate this page from the generator section in Power page by adding: last start log, maintenance schedule table

9.2 Capacity page — radial gauge values

  • Ensure a large centered text value (e.g. "74%") is always visible inside the gauge arc
  • Add "Headroom: X kW" as a sub-label below the gauge

9.3 Capacity page — runway in months

  • Display runway as "~2.3 months" alongside weeks
  • Add a 90-day forecast line on the per-rack chart (dotted line extrapolating current growth)

9.4 Fire & Safety page — fire state improvements

  • Fire-level cards: increase border to 4px, add a very faint red background overlay (bg-red-950/30)
  • Replace small status dots with a proper status row: icon + label + state text (e.g. ✓ Detector 1 — Online)
  • Show raw obscuration value (%/m) on the bar, not just the bar fill

9.5 Leak Detection page — add history

  • Add "Last triggered: X days ago" to each sensor card
  • Add a 30-day trigger count badge: "0 events" / "3 events"
  • This keeps the page useful when all sensors are clear

9.6 Network page — improve port display

  • Change port headline from "72%" to "36 / 48 ports active" — then show % as sub-label
  • Group card metrics: top 3 bold (state, ports, bandwidth) + secondary row (CPU, memory, temp)

9.7 Reports page — promote export to top

  • Move the 3 export buttons to a prominent action bar at the top of the page
  • Add a page-level date range picker that controls all KPIs on the page simultaneously
  • Always show numeric % labels on CRAC/UPS uptime bars

9.8 Maintenance page — modal for create form

  • Move "Create window" form into a shadcn <Dialog> modal triggered by the header button
  • In the target selector, group options: Site / Hall A racks / Hall B racks / Cooling / Power
  • Add a 7-day horizontal timeline strip below the active windows list showing when each window falls

9.9 Settings page — skeleton structure

  • Replace "Coming soon" with a tabbed layout: Profile | Notifications | Thresholds | Site Config
  • Thresholds tab: shows the values from lib/thresholds.ts as editable fields (even if not persisted to backend yet)
  • This makes the page look intentional rather than unfinished

Phase 10 — Polish & Accessibility

Goal: Final consistency pass, mobile, keyboard navigation. Effort: ~12 days | Risk: Low

10.1 Mobile audit

  • Test every page at 375px and 768px width
  • Fix broken chart widths (use ResponsiveContainer everywhere, check it's set)
  • Ensure touch targets are ≥44px tall
  • Test sidebar sheet on mobile

10.2 Focus rings and keyboard nav

  • Add focus-visible:ring-2 focus-visible:ring-primary to all interactive elements that are missing it
  • Verify logical tab order on every page (left-to-right, top-to-bottom)
  • Add aria-label to icon-only buttons (alarm bell, collapse toggle, overlay buttons)

10.3 Chart skeleton height matching

  • Measure actual rendered chart heights for each chart type
  • Set skeleton h-[] to match exactly, preventing layout shift on load

10.4 Dark/light mode toggle

  • Add a theme toggle button in the topbar (Moon / Sun icon)
  • The ThemeProvider is already wired — just needs a toggle button and localStorage persistence

10.5 Loading state audit

  • Every card that fetches data must show a <Skeleton> during initial load
  • No card should show an empty white box or flash unstyled content

10.6 Toast notification consistency

  • Audit all toast.error() / toast.success() calls across pages
  • Ensure every user action (acknowledge alarm, bulk resolve, create maintenance window, export) has a corresponding success/error toast

Summary Table

Phase Focus Pages Touched Est. Effort
1 Foundation fixes (nav, thresholds, errors) All (shared) 12 days
2 Alarms page Alarms 1 day
3 Dashboard page Dashboard 1 day
4 Power page Power 1.5 days
5 Cooling page Cooling 1 day
6 Environmental page Environmental 1 day
7 Floor Map page Floor Map 1 day
8 Assets page Assets 1 day
9 Remaining pages Generator, Capacity, Fire, Leak, Network, Reports, Maintenance, Settings 1.5 days
10 Polish & accessibility All 12 days
Total ~1113 days

Dependency Order

Phase 1 (foundation)
  └─► Phase 2 (alarms)
  └─► Phase 3 (dashboard)
  └─► Phase 4 (power)
  └─► Phase 5 (cooling)
  └─► Phase 6 (environmental)
  └─► Phase 7 (floor map)
  └─► Phase 8 (assets)
  └─► Phase 9 (remaining pages)
        └─► Phase 10 (polish — last, after all pages stable)

Phases 29 are independent of each other and can be parallelised once Phase 1 is complete.