class ProgramCard extends HTMLElement { constructor() { super(); this.source = null; } connectedCallback() { this.innerHTML = `

Program

--Pump --

      
`; this.querySelector('#save').addEventListener('click', () => this.saveProgram()); this.querySelectorAll('input[name="programMode"]').forEach(input => input.addEventListener('change', () => this.saveProgram())); window.addEventListener('app:login', event => this.startEvents(event.detail.token)); if (window.App && window.App.token()) this.startEvents(window.App.token()); } disconnectedCallback() { this.stopEvents(); } startEvents(token) { this.stopEvents(); this.loadProgram(); if (!token || !window.EventSource) return; this.source = new EventSource('/api/temperature/events?token=' + encodeURIComponent(token)); this.source.addEventListener('temperature', event => { try { this.renderLiveTemperature(JSON.parse(event.data)); } catch (error) {} }); this.source.addEventListener('pump', event => { try { this.renderPump(JSON.parse(event.data)); } catch (error) {} }); } stopEvents() { if (this.source) this.source.close(); this.source = null; } selectedMode() { const input = this.querySelector('input[name="programMode"]:checked'); return input ? input.value : 'off'; } renderSettings(json) { const mode = json.mode || 'off'; const modeInput = this.querySelector('input[name="programMode"][value="' + mode + '"]'); if (modeInput) modeInput.checked = true; if (json.targetTemperatureC !== undefined) this.querySelector('#target').value = Number(json.targetTemperatureC).toFixed(2); } renderLiveTemperature(json) { this.querySelector('#temp').textContent = json.sensorConnected && json.temperatureC !== null ? Number(json.temperatureC).toFixed(2) + ' C' : 'Sensor --'; } renderPump(json) { const enabled = json.enabled !== undefined ? json.enabled : json.pumpEnabled; if (enabled === undefined) return; this.querySelector('#pump').textContent = enabled ? 'Pump on' : 'Pump off'; } render(json) { this.renderSettings(json); this.renderLiveTemperature(json); this.renderPump(json); } async loadProgram() { const text = await window.App.req('GET', '/api/program'); this.querySelector('#out').textContent = text; try { const json = JSON.parse(text); if (json.success) this.render(json); } catch (error) {} } async saveProgram() { const target = Number(this.querySelector('#target').value); const text = await window.App.req('POST', '/api/program', {mode: this.selectedMode(), targetTemperatureC: Number(target.toFixed(2))}); this.querySelector('#out').textContent = text; try { const json = JSON.parse(text); if (json.success) this.render(json); } catch (error) {} } } customElements.define('program-card', ProgramCard);