Kiosk: header info inline with title (save vertical space), show all zones

- Weather/AC/TRV summary now sits between the title and Select button on one
  row instead of a separate line below, truncating with an ellipsis if it
  doesn't fit rather than wrapping
- Grid now shows every active zone, not just ones with a live device already
  assigned -- KioskZoneBlock already renders 'No live devices' for one that
  has none

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-08-27 12:59:21 +00:00
parent 903877fec2
commit 29340beb7a
2 changed files with 19 additions and 16 deletions

View file

@ -449,16 +449,18 @@ table.data tr:last-child td { border-bottom: none; }
border: 1px solid var(--card-border); border-radius: 8px; padding: 10px 12px; font-size: 16px; border: 1px solid var(--card-border); border-radius: 8px; padding: 10px 12px; font-size: 16px;
} }
/* One row, not two — the info line sits inline between the title and the
Select button rather than on its own line, to save vertical space. */
.kiosk-header { .kiosk-header {
display: flex; flex-direction: column; gap: 6px; display: flex; align-items: center; gap: 16px;
padding: 14px 18px; background: var(--navy); color: var(--text); flex-shrink: 0; padding: 14px 18px; background: var(--navy); color: var(--text); flex-shrink: 0;
} }
.kiosk-header-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .kiosk-header-title { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 16px; color: var(--gold); flex-shrink: 0; }
.kiosk-header-title { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 16px; color: var(--gold); }
/* Same weather-compensation summary as the Dashboard's banner (plus TRV /* Same weather-compensation summary as the Dashboard's banner (plus TRV
default, which the kiosk has no Settings page to show separately) — see default, which the kiosk has no Settings page to show separately) — see
buildInfoLine() in Kiosk.tsx. */ buildInfoLine() in Kiosk.tsx. Takes the remaining space between the title
.kiosk-header-info { font-size: 12px; color: var(--text-muted); } and the Select button, truncating with an ellipsis if it doesn't fit. */
.kiosk-header-info { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; font-size: 12px; color: var(--text-muted); }
.kiosk-error { margin: 12px 16px 0; } .kiosk-error { margin: 12px 16px 0; }

View file

@ -87,7 +87,10 @@ export default function Kiosk() {
const load = useCallback(() => { const load = useCallback(() => {
kioskFetchStatus() kioskFetchStatus()
.then(s => { .then(s => {
setZones(s.zones.filter(z => liveDevicesOf(z).length > 0)) // Every active zone shows, not just ones with a live device assigned yet
// (per user request, 2026-08-26) — KioskZoneBlock already renders "No
// live devices" for one that has none.
setZones(s.zones)
setWeatherPeakC(s.weather_peak_c) setWeatherPeakC(s.weather_peak_c)
setActiveAcTemplate(s.active_ac_template) setActiveAcTemplate(s.active_ac_template)
setLoadError('') setLoadError('')
@ -191,15 +194,13 @@ export default function Kiosk() {
return ( return (
<div className="kiosk-shell"> <div className="kiosk-shell">
<header className="kiosk-header"> <header className="kiosk-header">
<div className="kiosk-header-row"> <span className="kiosk-header-title">
<span className="kiosk-header-title"> <Thermometer size={18} strokeWidth={1.75} /> HVAC Kiosk
<Thermometer size={18} strokeWidth={1.75} /> HVAC Kiosk </span>
</span> {infoParts.length > 0 && <span className="kiosk-header-info">{infoParts.join(' · ')}</span>}
<button className={`btn btn-sm${selectionMode ? ' btn-primary' : ''}`} onClick={toggleSelectionMode}> <button className={`btn btn-sm${selectionMode ? ' btn-primary' : ''}`} onClick={toggleSelectionMode}>
<CheckSquare size={14} strokeWidth={1.75} /> {selectionMode ? 'Cancel select' : 'Select'} <CheckSquare size={14} strokeWidth={1.75} /> {selectionMode ? 'Cancel select' : 'Select'}
</button> </button>
</div>
{infoParts.length > 0 && <div className="kiosk-header-info">{infoParts.join(' · ')}</div>}
</header> </header>
{loadError && <div className="error-banner kiosk-error">{loadError}</div>} {loadError && <div className="error-banner kiosk-error">{loadError}</div>}
@ -217,7 +218,7 @@ export default function Kiosk() {
/> />
))} ))}
{zones.length === 0 && !loadError && ( {zones.length === 0 && !loadError && (
<p className="muted">No live-controllable devices assigned to a zone yet.</p> <p className="muted">No zones configured yet.</p>
)} )}
</div> </div>
</div> </div>