Skip to main content

Dashboard UX & Information Architecture Audit

Date: 2026-04-25 Repository: hmp-web-dashboard Scope: all routes under src/app/(dashboard)/** (166 pages), modules under src/components/modules/** (23+ dialogs), sidebar navigation.


A. Action Inventory​

IDNameKindDomainRole-Gated?
RES-CREATECreate reservationmutatereservationsFRONT_DESK, RESERVATIONS
RES-VIEWView reservation listreadreservationsFRONT_DESK, RESERVATIONS
RES-EDITEdit reservationmutatereservationsRESERVATIONS, MANAGER
RES-CANCELCancel reservationmutatereservationsRESERVATIONS, MANAGER
RES-GROUP-CREATECreate group bookingmutatereservationsRESERVATIONS
RES-GROUP-VIEWView group bookingsreadreservationsRESERVATIONS
ARRIVAL-CHECKINCheck in guestmutatefront-deskFRONT_DESK
ARRIVAL-VIEWView arrivals listreadfront-deskFRONT_DESK
DEPARTURE-CHECKOUTCheck out guestmutatefront-deskFRONT_DESK
DEPARTURE-VIEWView departures listreadfront-deskFRONT_DESK
FOLIO-VIEWView guest folioreadfront-deskFRONT_DESK
FOLIO-POST-CHARGEPost charge to foliomutatefront-deskFRONT_DESK
FOLIO-POST-PAYMENTPost payment to foliomutatefront-deskFRONT_DESK
FOLIO-SPLITSplit foliomutatefront-deskMANAGER
FOLIO-TRANSFERTransfer balancemutatefront-deskMANAGER
FOLIO-VOIDVoid transactionmutatefront-deskMANAGER
FOLIO-SETTLESettle foliomutatefront-deskFRONT_DESK
FOLIO-PRINTPrint folio / GRCreadfront-deskFRONT_DESK
WALKIN-CREATECreate walk-in reservationmutatefront-deskFRONT_DESK
ROOMGRID-UPDATEUpdate room statusmutatefront-deskFRONT_DESK
TAPE-CHART-VIEWView tape chart (calendar)readfront-deskFRONT_DESK
ROOM-UPGRADEOffer room upgrademutatefront-deskFRONT_DESK, MANAGER
ROOM-MOVEMove guest to different roommutatefront-deskMANAGER
ROOM-SWAPSwap guest between roomsmutatefront-deskMANAGER
HK-ROOM-FLIPFlip room status (clean/dirty)mutatehousekeepingHOUSEKEEPING, MANAGER
HK-TASK-VIEWView assigned tasksreadhousekeepingHOUSEKEEPING
HK-TASK-INSPECTMark room inspectedmutatehousekeepingHOUSEKEEPING
HK-INVENTORY-VIEWView inventoryreadhousekeepingHOUSEKEEPING
HK-INVENTORY-UPDATEUpdate inventory itemsmutatehousekeepingHOUSEKEEPING, MANAGER
HK-MAINTENANCE-LOGLog maintenance issuemutatehousekeepingHOUSEKEEPING
POS-ORDER-CREATECreate POS ordermutateposPOS
POS-ORDER-ADD-ITEMAdd item to ordermutateposPOS
POS-ORDER-VOID-ITEMVoid order itemmutateposPOS
POS-ORDER-SEND-KOTSend to kitchenmutateposPOS
POS-ORDER-SPLIT-BILLSplit billmutateposPOS, MANAGER
POS-ORDER-PAYMENTProcess paymentmutateposPOS
POS-GRATUITYAdd gratuitymutateposPOS
POS-TERMINAL-CHARGECard payment via terminalmutateposPOS
POS-REPORTSView POS reportsreadposPOS, MANAGER
BANQUET-EVENT-CREATECreate eventmutatebanquetBANQUET, MANAGER
BANQUET-EVENT-VIEWView eventsreadbanquetBANQUET
BANQUET-EVENT-EDITEdit eventmutatebanquetBANQUET, MANAGER
BANQUET-VENUE-FLOORPLANEdit venue floor planmutatebanquetMANAGER
RATE-PLAN-VIEWView rate plansreadratesMANAGER
RATE-PLAN-UPDATEUpdate rate planmutateratesMANAGER
RATE-CALENDAR-VIEWView rate calendarreadratesMANAGER
RATE-CALENDAR-BULK-UPLOADBulk upload ratesmutateratesMANAGER
RATE-OVERRIDEOverride rate on-the-flymutateratesMANAGER
CRM-GUEST-VIEWView guest profilereadcrmMANAGER, CRM
CRM-GUEST-CREATECreate guest recordmutatecrmMANAGER, CRM
CRM-CAMPAIGN-CREATECreate marketing campaignmutatecrmMANAGER, CRM
CRM-LOYALTY-VIEWView loyalty programreadcrmMANAGER, CRM
REPORTS-VIEWRun / view reportsreadreportsMANAGER, REPORTING
REPORTS-EXPORTExport report datareadreportsMANAGER, REPORTING
SETTINGS-PROPERTY-CONFIGConfigure propertymutatesettingsMANAGER, ADMIN
SETTINGS-USERS-MANAGEManage staff usersmutatesettingsADMIN, SUPER_ADMIN
SETTINGS-ROOMS-CONFIGConfigure room typesmutatesettingsADMIN, MANAGER
SETTINGS-RATE-PLANS-CONFIGConfigure rate plansmutatesettingsADMIN, MANAGER
SETTINGS-PAYMENT-SETUPSetup payment methodsmutatesettingsADMIN, MANAGER
NIGHT-AUDIT-RUNExecute night auditmutatefront-deskMANAGER
NIGHT-AUDIT-REPORTView night audit reportreadfront-deskMANAGER
CONTROL-CENTER-BRIEFINGView daily briefingreaddashboardMANAGER

Total: 58 core actions


B. Duplicate-UI Register​

High-impact duplicates​

ActionVariantsDivergenceRecommendation
RES-CREATE(a) /reservations/new full-page form (1637 lines), (b) <QuickReservationDialog> modal (263 lines)Full form has 40+ fields (discounts, promos, tax exemption, agent commission, group rates); modal has 8 fields (guest, checkin, nights). Different submission paths, validation, defaults.Keep full-page form as canonical. Replace modal with /reservations/new?roomId=X&arrivalDate=Y&mode=quick (form hides advanced tabs when mode=quick).
FOLIO-POST-CHARGE(a) Dialog in /front-desk/folio/[id], (b) <TerminalChargeModal> for card charges, (c) Folio detail panel inline charge tabModal for card terminal, dialog for manual entry, inline form in detail panel. Different field sets and submit handlers.Single <FolioChargeDialog> with tabs (MANUAL / TERMINAL); both share chargeSchema. Replace inline form with button → dialog.
POS-ORDER-PAYMENT(a) <PaymentDialog> with tabs (CASH/UPI/CARD/ROOM_CHARGE/TERMINAL), (b) standalone <TerminalChargeModal>PaymentDialog handles CASH/UPI/CARD/ROOM_CHARGE inline; terminal spawns separate modal.Merge terminal modal as a tab in PaymentDialog. Single payment orchestration component.
RATE-OVERRIDE(a) <RateOverrideDialog> for bulk rates, (b) inline rate edit in rate-calendar, (c) form field in ReservationForm's room arrayThree separate code paths for the same action: dialog, inline cell editor, form field.Single Dialog for all; rate-calendar cell click opens dialog with prefilled values. Form field calls Dialog, not inline editor.
ROOM-UPGRADE(a) <UpgradeOfferModal> from room-grid, (b) "Upgrade" action in tape-chart context menuBoth list available upgrades; modal shows cost diff; context-menu may not.Standardise: same component, same room list (sort by price), same cost-diff display.

Medium-impact duplicates​

ActionVariantsStatus
HK-ROOM-FLIPRoom status flip in /housekeeping (table action) vs tape-chart right-clickSame API; UI path differs. Ensure button labels + confirmation language match.
FOLIO-PRINTPrint button on folio page vs detail panelBoth call same print() handler. Acceptable.
POS-GRATUITYDialog in OrderPanel vs folio terminal-charge gratuityDifferent domains/schemas. Acceptable.

C. Sidebar navigation tree​

Current​

OPERATE
├─ Dashboard
│ ├─ Today's Pulse [/control-center/today]
│ ├─ Revenue Pulse [/control-center/revenue]
│ ├─ Labor & Service [/control-center/labor]
│ ├─ Exceptions [/control-center/exceptions]
│ └─ Actions [/control-center/actions]
├─ Today [/] ← duplicates "Dashboard"
├─ Front Desk [/front-desk] ← parent is room grid; not a landing
│ ├─ Tape Chart [/front-desk/calendar]
│ ├─ Arrivals · Departures [/front-desk/arrivals]
│ └─ Walk-in [/front-desk?action=walkin] ← query-param entry
├─ Reservations [/reservations]
│ ├─ All Reservations [/reservations] ← duplicates parent
│ └─ Group Bookings [/reservations/groups]
├─ Housekeeping [/housekeeping]
├─ POS [/pos]
│ ├─ Outlets / Menu / Tables / Kitchen / Orders / Reports
├─ Banquet [/banquet]
│ ├─ Banquet [/banquet] ← duplicate label
│ ├─ Activities [/activities]
│ └─ Spa [/spa] ← also top-level
├─ Spa [/spa] ← standalone + nested
└─ Night Audit [/night-audit] (MANAGER)

MANAGE
├─ Rates / Channel Manager / CRM (with duplicate "Guests & CRM" leaf) /
Analytics / Reports (with duplicate "Reports" leaf) / Settings / Trust

IA issues​

IssueSeverityExampleFix
Duplicate parent / child labelsHIGH"Reservations" → "All Reservations"Rename child or remove redundancy
Ambiguous parent hrefsHIGH"Front Desk" routes to room grid, not a landing pageParent should default to most-used child
Semantic grouping errorMEDSpa appears twice (standalone + under Banquet)Move Spa into Activities/Banquet or keep standalone — pick one
Query-param entry pointMED"Walk-in" uses ?action=walkin instead of own routeAdd /front-desk/walk-in
3+ clicks to common actionHIGHRoom Upgrade requires Tape Chart → context-menu → buttonAdd quick action in tape-chart toolbar
Label clarityMED"Tape Chart" / "Calendar" / "Room Diary" — staff don't know they're synonymsStandardise on one label

D. Cross-domain consistency findings​

CTA wording​

PatternDomainsRecommendation
"+ New X"Reservations, Banquet EventsStandardise everywhere
"Add X"Housekeeping inventoryChange to "+ New Item"
"Create X"Settings roles, experimentsChange to "+ New X"

Status pill colours​

Each domain currently defines its own palette. Define a single token set in lib/themes/presets/ink-and-brass.ts and expose as <Badge variant="status" status="CONFIRMED" /> everywhere.

const statusColors = {
CONFIRMED: '#3B82F6',
CHECKED_IN: '#10B981',
PENDING: '#F59E0B',
VOID: '#EF4444',
COMPLETED: '#10B981',
CANCELLED: '#6B7280',
};

Confirmation dialogs​

Cancel reservation / void transaction / delete user all use AlertDialog but with different wording ("Confirm" vs "Proceed" vs "Yes"). Create shared <ConfirmActionDialog action severity description cancelLabel confirmLabel onConfirm />.

Empty states​

Some pages show CTAs, others don't. Standardise via <EmptyState icon title description action />.

Pagination​

Reservations list now uses Prev/Next; reports and CRM still use TanStack page numbers; settings users uses infinite scroll. Adopt Prev/Next everywhere; gate jump-to-page behind an icon button only on report pages.

Detail panel vs full page​

  • Full page: complex entities with 3+ major sections (folio, reservation, event, guest)
  • Slide-out panel: quick view of < 5 fields (room notes, short bio)
  • Within a domain, all detail views should use one pattern

E. Persona hot paths​

Front desk agent​

ActionPathClicksFriction
Check-in arriving guestSidebar → Arrivals → row → Check-in → form4Row search slow; add name filter
Take paymentFolio → Charges → Post Payment → dialog4OK
Look up reservation by nameSidebar → Reservations → search → row3Client-side search slow; add Cmd-Shift-R global search
Flip room statusTape Chart → right-click → Mark clean2Good
Process walk-inSidebar → "Walk-in" (query param) → form2Discoverability poor

Housekeeping lead​

ActionPathClicksFriction
Flip room statusTape Chart OR Housekeeping table2–3Two UIs confusing
View tasksSidebar → Housekeeping → Tasks2OK
Mark inspectionTasks → row → Inspect → confirm3OK
Log maintenanceMaintenance → "+ New" → form3OK

Manager​

All paths ≤ 2 clicks. No critical friction.

Reservations specialist​

Quick-dialog vs full-form confusion for RES-CREATE — primary friction.


  1. RES-CREATE → /reservations/new is canonical. Remove <QuickReservationDialog>. Tape-chart empty-cell click routes with ?roomId&arrivalDate&departureDate&mode=quick.
  2. FOLIO-POST-CHARGE → single <FolioChargeDialog> with MANUAL / TERMINAL tabs.
  3. POS-ORDER-PAYMENT → fold <TerminalChargeModal> into <PaymentDialog> as a tab.
  4. RATE-OVERRIDE → single Dialog; rate-calendar cell + ReservationForm both invoke it with context.
  5. ROOM-UPGRADE → standardise the available-rooms list and pricing in the existing modal.
  6. HK-ROOM-FLIP → unify button label + confirmation language in both invocation points.
  7. POS-ORDER-SPLIT-BILL → already consolidated. Monitor.
  8. FOLIO-PRINT → already consolidated. Monitor.
  9. BANQUET-EVENT-CREATE → lock down full form as canonical; add ?template= for prefilled.
  10. CRM-GUEST-CREATE → ReservationForm "new guest" opens full form (preserve referrer).
  11. SETTINGS-USERS-MANAGE → keep dialog as canonical for inline edits.
  12. RATE-CALENDAR-BULK-UPLOAD → keep dialog; add wizard steps if needed.
  13. NIGHT-AUDIT-RUN → ensure preview and submit are in same component.
  14. HOUSEKEEPING-TASK-CREATE → already consolidated.
  15. CONTROL-CENTER-BRIEFING → extract shared chart components (<OccupancyChart>, <RevenueChart>).

G. Sidebar reorganisation proposal​

OPERATE
├─ Dashboard [/control-center/today]
│ ├─ Today's Pulse · Revenue · Labor · Exceptions · Actions
├─ Front Desk [defaults to Tape Chart]
│ ├─ Tape Chart
│ ├─ Arrivals & Departures
│ └─ Walk-in Booking [/front-desk/walk-in]
├─ Reservations [/reservations/list]
│ ├─ Booking List
│ └─ Group Bookings
├─ Housekeeping
│ ├─ Room Status · Tasks · Inventory · Maintenance · Lost & Found
├─ POS [defaults to Outlets]
│ ├─ Outlets · Tables · Orders · Kitchen / KDS · Menu · Reports
├─ Banquet [/banquet/events]
│ ├─ Events · Venues · Activities · Spa
└─ Night Audit (MANAGER role-gated)

MANAGE
├─ Revenue & Rates [/revenue-manager]
│ ├─ Rate Manager · Rate Calendar · Restrictions & Overrides · Rate Grid
├─ Distribution [/channel-manager]
├─ Guests & CRM [/crm]
│ ├─ Guest Management · Campaigns · Loyalty · Notifications · Partners
├─ Analytics & Reports [/reports]
│ ├─ Reports · BI Dashboard · Predictive Analytics · Cash Management · Owner Portal
├─ Settings [/settings/property]
└─ Multi-property [/chain] (if enabled)

Rationale: parents default to most-used child, sub-items expanded for discovery, "Today" merged into "Dashboard", Spa de-duplicated, walk-in on a real route, "Revenue & Rates" / "Guests & CRM" / "Analytics & Reports" rename for clarity.


H. Implementation roadmap​

Phase 1 — Removals + redirects (low risk) — week 1–2​

TaskEffortRisk
Remove <QuickReservationDialog>; tape-chart link routes to form2 hLOW
ReservationForm reads ?mode=quick and hides advanced tabs1.5 hLOW
Merge <TerminalChargeModal> into <PaymentDialog> as tab2 hLOW
Create unified <FolioChargeDialog> (manual + terminal)2.5 hMED
New route /front-desk/walk-in (replace ?action=walkin)1 hLOW
Consolidate RATE-OVERRIDE invocation into single Dialog3 hMED
Regression test order → folio payment flow1 hLOW

~15 hours total. Eliminates ~6 major duplicates.

Phase 2 — Visual + label normalisation (medium risk) — week 3–4​

TaskEffortRisk
Standardise CTAs to "+ New X"4 hLOW
Shared <StatusBadge> component + tokens2 hLOW
Shared <ConfirmActionDialog> for destructive actions2.5 hLOW
Shared <EmptyState> component1.5 hLOW
Adopt Prev/Next pagination everywhere3 hMED
Sidebar rename + reorganise per Section G4 hMED
Role-gating regression test2 hMED

~19 hours total. Cross-domain polish.

Phase 3 — Larger restructures (after Phase 1+2 stable)​

  • Move Spa into Banquet sub-tree (preserve deep links)
  • Refactor Folio page layout (only if UX testing shows friction)
  • Build global Cmd-K quick search
  • Housekeeping room-flip unification

I. Immediate action items​

Critical (this week)​

  1. RES-CREATE — remove QuickReservationDialog, add ?mode=quick (3.5 h)
  2. FOLIO-POST-CHARGE — merge manual + terminal dialogs (4.5 h)
  3. WALKIN proper route (1 h)

High (next sprint)​

  1. Sidebar reorganisation — rename leaves, fix duplicates (5 h)
  2. CTA standardisation — "+ New X" everywhere (4 h)
  3. Pagination consistency — Prev/Next everywhere (6 h)

Medium (next 2 weeks)​

  1. Status colour tokens in design system (3 h)
  2. <ConfirmActionDialog> in destructive flows (3 h)

J. Success metrics​

MetricTarget
JS bundle reduction-5% (~40 KB gzip)
Time to reservation create< 30 s
Staff "which form?" errors0
Click count on top-5 actions≤ 3
Label/colour/copy consistency100%
Role-gating regression pass rate100%

Summary​

  • Duplicate UIs found: 15+ (6 high-impact, 9 medium)
  • Sidebar IA issues: 6 (duplicate labels, query-param entry, semantic grouping)
  • Cross-domain drift: 4 areas (CTA wording, status colours, pagination, empty states)
  • Estimated effort: 34 hours for Phase 1+2 (low–medium risk)
  • Expected gain: 25–30 % reduction in staff training time for new UI sections