367 lines
16 KiB
Markdown
367 lines
16 KiB
Markdown
# 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 `<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:
|
||
```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 `<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 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 `<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:** ~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 `<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) | 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.
|