AppIcon.tsx whitelists imported Lucide icons rather than doing a dynamic
lookup, so both apps' sidebar/dashboard icons were silently rendering
nothing -- same gotcha as the earlier 'Register Gauge icon for plant' fix.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
AppIcon.js was a stale, tracked, out-of-sync compiled duplicate of
AppIcon.tsx (missing Zap/Thermometer too) sitting next to the real
source. Since imports use bare 'from ./AppIcon' with no extension,
Vite's default resolve order picks .js before .tsx, so it may have
been silently shadowing the real source. Removed it so there's a
single source of truth, and added Gauge (plant's icon) there.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A 7-day window meant "next week"-type events could miss both the Mine
fetch and the All backfill entirely, since they queried the same range.
The Upcoming list is still capped by UPCOMING_LIMIT, so this doesn't
flood the dashboard — it just means events further out get a chance.
When the Mine tab has fewer than 3 relevant events in range, top it up with
the earliest not-mine events from All (Today + Upcoming combined), rendered
in italics so it's clear they aren't personally assigned.
Dashboard now shows today's and upcoming events (mine or all, toggle) for
users with calendar app access. Also gives the portal shell a 1-hour
inactivity default for devices that have never been configured, instead of
following child apps into an unlimited 30-day session — that's why the
dashboard could sit logged in for days without prompting. An explicit "Off"
choice in Admin Settings still overrides it (now written as mins=0 instead
of clearing the cookie, so it's distinguishable from "never configured").
Login.tsx only read the return path from router state, which a hard
cross-document navigation (a child app bouncing the whole shell here
on session expiry) can never carry — so re-authenticating always
landed on the Dashboard instead of back in whatever app you were
using. Login.tsx now also accepts a ?from= query param for that case.
Also wired up AuthGate's inactivity auto-logout timer, which was
defined (getInactivityMs) but never actually called — so the
per-device timeout configurable in Admin Settings had no effect.
Disabled for installed PWAs as intended.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
If a different user logs into a child app while the portal tab is open,
the portal cookie changes but the in-memory user state goes stale. Now
AuthGate re-fetches /api/auth/me on visibilitychange and focus events,
updating state only when the user identity actually changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Portal sidebar was rendering nothing for the history app entry because
History was missing from the Lucide icon map.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maintenance (Wrench) and Reports (BarChart2) icons were missing from
the hardcoded iconMap, causing those app tiles to show no icon.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When an app is open, the sidebar collapses to a 44px strip with a
chevron button. Clicking it opens the full sidebar as a fixed overlay
with a backdrop that closes on click. Also closes automatically when
the user interacts with / navigates within the iframe (window blur).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wire /admin/settings route and sidebar link; proxy /settings/api/ to the
new settings service at 10.10.10.116. Admin can configure integration
credentials and manage Newbook room ordering from the portal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sidebar now renders uncategorised apps flat and categorised apps in
collapsible accordion sections; active category stays expanded. Dashboard
groups tiles under category section headings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- index.css: light body (#f4f5f7), white cards, sidebar stays dark navy
- AppIcon.tsx: Lucide icon lookup component for app tiles and nav
- Sidebar.tsx: Lucide nav icons (LayoutGrid, Users, Activity, LogOut)
- Dashboard.tsx: white cards with shadows, coloured Lucide app icons
- AdminMonitor.tsx: light theme throughout, Lucide tab icons,
better status colours for light backgrounds
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Defaults to 'Number Four at Stow'. Replaces hardcoded 'Hotel Number Four'
and 'HNF Manage' in sidebar, login page, and browser title. Other hotels
set VITE_HOTEL_NAME in their /opt/portal/.env before rebuilding.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>