# 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:** ~1–2 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 `` 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: ```ts 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 `` wrapper component used by every page to ensure consistent top padding and title rendering ### 1.9 Empty state and error boundary - Create a reusable `` component shown when a fetch fails - Create a reusable `` for no-data states - Wrap every data-dependent card in a try/catch that renders `` 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 1–25 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 60–120s, 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:** Low–Medium ### 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" ### 6.3 VESDA and Leak panels — link to dedicated pages - 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:** Low–Medium ### 7.1 Overlay controls — proper segmented control - Replace the 4 overlay buttons with a shadcn `` 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 `` 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:** ~1–2 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 `` 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) | 1–2 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 | 1–2 days | | **Total** | | | **~11–13 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 2–9 are independent of each other and can be parallelised once Phase 1 is complete.