webui: highlight temperature cards on alerts

This commit is contained in:
2026-06-12 01:14:52 -06:00
parent 21ca2db2ca
commit c210c563fd
@@ -391,6 +391,17 @@ button[onclick^="scan"]{
} }
} }
.temp-alert {
border-color: #f97066 !important;
background: linear-gradient(180deg, rgba(122,39,26,0.95), rgba(67,24,24,0.95)) !important;
box-shadow: 0 0 0 1px rgba(249,112,102,0.35), 0 0 18px rgba(249,112,102,0.25) !important;
}
.temp-alert .muted,
.temp-alert .inputHelp {
color: #ffd7d3 !important;
}
</style> </style>
</head> </head>
<body> <body>
@@ -1015,6 +1026,7 @@ function render(data){
$("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||""); $("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||"");
$("uptime").textContent=formatUptime(s.uptime_seconds||0); $("uptime").textContent=formatUptime(s.uptime_seconds||0);
renderConfigControls(data); renderConfigControls(data);
applyTempAlertStyles(data);
populateSetupFields(data); populateSetupFields(data);
} }
@@ -1143,6 +1155,65 @@ async function factoryReset(){
alert("Factory reset requested. Reconnect to the controller AP if needed."); alert("Factory reset requested. Reconnect to the controller AP if needed.");
} }
function tempHighAlertActive(t){
const temp = Number(t.temperature_f);
const threshold = Number(t.high_alert_f);
return !!(
t.high_alert ||
(
t.high_alert_enabled &&
Number.isFinite(temp) &&
Number.isFinite(threshold) &&
temp > threshold
)
);
}
function tempDisplayGroup(t){
const group = String(t.group || "").trim().toLowerCase();
if (t.weather || group === "outside" || group === "weather") return "outside";
if (group) return group;
return String(t.name || "").trim().toLowerCase();
}
function applyTempAlertStyles(data){
const temps = data && Array.isArray(data.temps) ? data.temps : [];
const active = temps.filter(tempHighAlertActive);
document.querySelectorAll(".temp-alert").forEach(el => el.classList.remove("temp-alert"));
if (!active.length) return;
const alertKeys = new Set();
active.forEach(t => {
const name = String(t.name || "").trim().toLowerCase();
const group = tempDisplayGroup(t);
if (name) alertKeys.add(name);
if (group) alertKeys.add(group);
if (group === "fridge") alertKeys.add("fridge");
if (group === "cabin") alertKeys.add("cabin");
if (group === "outside") alertKeys.add("outside");
});
const candidates = document.querySelectorAll(
".card, .tile, .tempCard, .tempTile, .tempConfigCard, .reading, .sensor, .stat"
);
candidates.forEach(el => {
const text = (el.textContent || "").toLowerCase();
if (!text.includes("°") && !text.includes("temp") && !text.includes("fridge") && !text.includes("cabin")) {
return;
}
for (const key of alertKeys) {
if (key && text.includes(key)) {
el.classList.add("temp-alert");
return;
}
}
});
}
function renderConfigControls(data){ function renderConfigControls(data){
const cfg=data.config||{}; const cfg=data.config||{};
const relays=cfg.relays||[]; const relays=cfg.relays||[];