document.addEventListener("DOMContentLoaded", () => { const dataElement = document.getElementById("consumption-data"); let data = { scenarios: [], consumption: {}, unit_options: [] }; if (dataElement) { try { const parsed = JSON.parse(dataElement.textContent || "{}"); if (parsed && typeof parsed === "object") { data = { scenarios: Array.isArray(parsed.scenarios) ? parsed.scenarios : [], consumption: parsed.consumption && typeof parsed.consumption === "object" ? parsed.consumption : {}, unit_options: Array.isArray(parsed.unit_options) ? parsed.unit_options : [], }; } } catch (error) { console.error("Unable to parse consumption data", error); } } const consumptionByScenario = data.consumption; const filterSelect = document.getElementById("consumption-scenario-filter"); const tableWrapper = document.getElementById("consumption-table-wrapper"); const tableBody = document.getElementById("consumption-table-body"); const emptyState = document.getElementById("consumption-empty"); const form = document.getElementById("consumption-form"); const feedbackEl = document.getElementById("consumption-feedback"); const unitSelect = document.getElementById("consumption-form-unit"); const unitSymbolInput = document.getElementById( "consumption-form-unit-symbol" ); const showFeedback = (message, type = "success") => { if (!feedbackEl) { return; } feedbackEl.textContent = message; feedbackEl.classList.remove("hidden", "success", "error"); feedbackEl.classList.add(type); }; const hideFeedback = () => { if (!feedbackEl) { return; } feedbackEl.classList.add("hidden"); feedbackEl.textContent = ""; }; const formatAmount = (value) => Number(value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, }); const formatMeasurement = (amount, symbol, name) => { if (symbol) { return `${formatAmount(amount)} ${symbol}`; } if (name) { return `${formatAmount(amount)} ${name}`; } return formatAmount(amount); }; const renderConsumptionRows = (scenarioId) => { if (!tableBody || !tableWrapper || !emptyState) { return; } const key = String(scenarioId); const records = consumptionByScenario[key] || []; tableBody.innerHTML = ""; if (!records.length) { emptyState.textContent = "No consumption records for this scenario yet."; emptyState.classList.remove("hidden"); tableWrapper.classList.add("hidden"); return; } emptyState.classList.add("hidden"); tableWrapper.classList.remove("hidden"); records.forEach((record) => { const row = document.createElement("tr"); row.innerHTML = ` ${formatMeasurement( record.amount, record.unit_symbol, record.unit_name )} ${record.description || "—"} `; tableBody.appendChild(row); }); }; if (filterSelect) { filterSelect.addEventListener("change", (event) => { const value = event.target.value; if (!value) { if (emptyState && tableWrapper && tableBody) { emptyState.textContent = "Choose a scenario to review its consumption records."; emptyState.classList.remove("hidden"); tableWrapper.classList.add("hidden"); tableBody.innerHTML = ""; } return; } renderConsumptionRows(value); }); } const submitConsumption = async (event) => { event.preventDefault(); hideFeedback(); if (!form) { return; } const formData = new FormData(form); const scenarioId = formData.get("scenario_id"); const unitName = formData.get("unit_name"); const unitSymbol = formData.get("unit_symbol"); const payload = { scenario_id: scenarioId ? Number(scenarioId) : null, amount: Number(formData.get("amount")), description: formData.get("description") || null, unit_name: unitName ? String(unitName) : null, unit_symbol: unitSymbol ? String(unitSymbol) : null, }; try { const response = await fetch("/api/consumption/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (!response.ok) { const errorDetail = await response.json().catch(() => ({})); throw new Error( errorDetail.detail || "Unable to add consumption record." ); } const result = await response.json(); const mapKey = String(result.scenario_id); if (!Array.isArray(consumptionByScenario[mapKey])) { consumptionByScenario[mapKey] = []; } consumptionByScenario[mapKey].push(result); form.reset(); syncUnitSelection(); showFeedback("Consumption record saved.", "success"); if (filterSelect && filterSelect.value === String(result.scenario_id)) { renderConsumptionRows(filterSelect.value); } } catch (error) { showFeedback(error.message || "An unexpected error occurred.", "error"); } }; if (form) { form.addEventListener("submit", submitConsumption); } const syncUnitSelection = () => { if (!unitSelect || !unitSymbolInput) { return; } if (!unitSelect.value && unitSelect.options.length > 0) { const firstOption = Array.from(unitSelect.options).find( (option) => option.value ); if (firstOption) { firstOption.selected = true; } } const selectedOption = unitSelect.options[unitSelect.selectedIndex]; unitSymbolInput.value = selectedOption ? selectedOption.getAttribute("data-symbol") || "" : ""; }; if (unitSelect) { unitSelect.addEventListener("change", syncUnitSelection); syncUnitSelection(); } if (filterSelect && filterSelect.value) { renderConsumptionRows(filterSelect.value); } });