import { useEffect, useState } from 'react' import { X, Thermometer, History } from 'lucide-react' import type { ZoneStatus, ActivityEntry, HvacDefaults } from '../types' import { ROOM_STATE_LABELS, DEFAULT_HVAC_TEMPLATE, MHI_MODES, MHI_FAN_SPEEDS, can } from '../types' import { useAuth } from './AuthGate' import { updateZone, overrideZone, fetchActivity, fetchConfig } from '../api' import MhiControlPanel from './MhiControlPanel' // The 12 fields a room can individually override — each is `null` on the zone when // inheriting the matching field from the global hvac_defaults template (Settings page), // or an explicit value when overridden. Mirrors the OVERRIDABLE_FIELDS list in // backend/src/routes/zones.js. type OverridableField = | 'occupied_temp' | 'vacant_temp' | 'heating_offset_min' | 'cooling_offset_min' | 'ac_occupied_power' | 'ac_occupied_mode' | 'ac_occupied_setpoint' | 'ac_occupied_fan_speed' | 'ac_vacant_power' | 'ac_vacant_mode' | 'ac_vacant_setpoint' | 'ac_vacant_fan_speed' function defaultFor(field: OverridableField, d: HvacDefaults): string | number { switch (field) { case 'occupied_temp': return d.trv_occupied_temp case 'vacant_temp': return d.trv_vacant_temp case 'heating_offset_min': return d.arrival_prep_offset_min case 'cooling_offset_min': return d.departure_prep_offset_min case 'ac_occupied_power': return d.ac_occupied.power case 'ac_occupied_mode': return d.ac_occupied.mode case 'ac_occupied_setpoint': return d.ac_occupied.setpoint case 'ac_occupied_fan_speed': return d.ac_occupied.fan_speed case 'ac_vacant_power': return d.ac_vacant.power case 'ac_vacant_mode': return d.ac_vacant.mode case 'ac_vacant_setpoint': return d.ac_vacant.setpoint case 'ac_vacant_fan_speed': return d.ac_vacant.fan_speed } } // Checkbox + either the override input (children) or the inherited default value, // depending on whether this field is currently overridden. function OverrideCell({ checked, defaultLabel, onToggle, children }: { checked: boolean defaultLabel: string onToggle: (checked: boolean) => void children: React.ReactNode }) { return (
No devices mapped to this zone yet — assign some on the Devices page.
} {zone.devices.map(d => (Disables auto mode for this zone until re-enabled below.
> )} {canEdit && ( <>Every value below inherits the global default (Settings → Default Templates) unless overridden here.
| Occupied | Vacant | |
|---|---|---|
| On/Off |
|
|
| Mode |
|
|
| Setpoint (°C) |
|
|
| Fan speed |
|
|