"use strict"; const $ = (sel) => document.querySelector(sel); function pad(n) { return String(n).padStart(2, "0"); } function setStatus(ok) { const el = $("#status"); if (!el) return; el.classList.toggle("ok", ok === true); el.classList.toggle("err", ok === false); } // --- Välistemperatuur (Suuremõisa) --- async function loadLatest() { setStatus(null); try { const res = await fetch("/api/latest"); if (!res.ok) throw new Error(await res.text()); const data = await res.json(); renderCards(data); setStatus(true); } catch (e) { console.error(e); setStatus(false); } } function renderCards(data) { const host = $("#cards"); if (!host) return; const out = data.outside || {}; const temp = out.temperature == null ? "–" : out.temperature; const updated = out.hour ? `
Uuendatud ${out.hour}
` : ""; host.innerHTML = `
🌤️ Välistemperatuur
${temp} °C
Suuremõisa
${updated}
`; } // --- Teema --- function setTheme(theme) { document.documentElement.setAttribute("data-theme", theme); localStorage.setItem("minukodu-theme", theme); const toggle = $("#theme-toggle"); if (toggle) toggle.textContent = theme === "dark" ? "☀️" : "🌙"; const meta = $("#meta-theme"); if (meta) meta.setAttribute("content", theme === "dark" ? "#0e1116" : "#1f6feb"); } // --- Vahelehed (tabid): Andurid | Transport --- const transport = { active: false, days: 1 }; function switchView(view) { const isTransport = view === "transport"; document.querySelectorAll("#tabs .tab").forEach((b) => { b.classList.toggle("active", b.dataset.view === view); }); const vAnd = document.getElementById("view-andurid"); const vTr = document.getElementById("view-transport"); if (vAnd) vAnd.hidden = isTransport; if (vTr) vTr.hidden = !isTransport; transport.active = isTransport; if (location.hash !== "#" + view) history.replaceState(null, "", "#" + view); if (isTransport) loadTransport(); } function initTabs() { document.querySelectorAll("#tabs .tab").forEach((btn) => { btn.addEventListener("click", () => switchView(btn.dataset.view)); }); const days = document.getElementById("praam-days"); if (days) { days.querySelectorAll("button").forEach((b) => { b.addEventListener("click", () => { days.querySelectorAll("button").forEach((x) => x.classList.remove("active")); b.classList.add("active"); transport.days = Number(b.dataset.days) || 1; loadPraam(); }); }); } setInterval(() => { if (transport.active) loadTransport(); }, 60000); switchView(location.hash === "#transport" ? "transport" : "andurid"); } function loadTransport() { loadBus(); loadPraam(); } function fmtDayLabel(iso, today) { if (!iso || iso === today) return ""; const d = new Date(iso + "T00:00:00"); const t = new Date((today || iso) + "T00:00:00"); const diff = Math.round((d - t) / 864e5); if (diff === 1) return "homme"; return d.toLocaleDateString("et-EE", { weekday: "short", day: "numeric", month: "short" }); } function setTransportUpdated(updated) { const el = document.getElementById("transport-updated"); if (el && updated) el.textContent = `Uuendatud ${updated}`; } async function loadBus() { const hint = document.getElementById("bus-hint"); try { const res = await fetch("/api/buss?limit=12"); if (!res.ok) throw new Error("HTTP " + res.status); renderBus(await res.json()); } catch (e) { console.error(e); if (hint) { hint.hidden = false; hint.textContent = "Bussiaegade laadimine ebaõnnestus."; } } } function renderBus(data) { const list = document.getElementById("bus-list"); const hint = document.getElementById("bus-hint"); if (!list) return; const rows = data.departures || []; if (!rows.length) { list.innerHTML = ""; if (hint) { hint.hidden = false; hint.textContent = "Täna enam busse ei välju."; } return; } if (hint) hint.hidden = true; list.innerHTML = rows.map((d) => { const day = fmtDayLabel(d.date, data.today); const dayBadge = day ? `${day}` : ""; let rt = ""; if (d.realtime && d.delay_min != null && d.delay_min !== 0) { rt = d.delay_min > 0 ? `+${d.delay_min} min` : `${d.delay_min} min`; } return `
${d.time} ${d.route || ""} → ${d.headsign || "?"} ${rt}${dayBadge}
`; }).join(""); } async function loadPraam() { const hint = document.getElementById("praam-hint"); try { const res = await fetch(`/api/praam?days=${transport.days}`); if (!res.ok) throw new Error("HTTP " + res.status); renderPraam(await res.json()); } catch (e) { console.error(e); if (hint) { hint.hidden = false; hint.textContent = "Praamiaegade laadimine ebaõnnestus."; } } } function renderPraam(data) { const list = document.getElementById("praam-list"); const hint = document.getElementById("praam-hint"); const warn = document.getElementById("praam-warning"); const rows = data.departures || []; if (warn) { if (Array.isArray(data.warnings) && data.warnings.length) { warn.hidden = false; warn.innerHTML = "⚠️ Ilmahoiatuse kontekst (Väinameri)" + data.warnings.map((w) => `
• ${w.area}: ${w.valid || w.text}
`).join("") + `
Praamiliiklus võib häiruda — kontrolli ` + `praamid.ee.
`; } else { warn.hidden = true; } } if (!rows.length) { list.innerHTML = ""; if (hint) { hint.hidden = false; hint.textContent = "Väljumisi ei leitud."; } return; } if (hint) hint.hidden = true; setTransportUpdated(data.updated); const groups = {}; for (const d of rows) (groups[d.direction] = groups[d.direction] || []).push(d); list.innerHTML = ["HR", "RH"].filter((k) => groups[k]).map((k) => { const items = groups[k].map((d) => { const day = fmtDayLabel(d.date, data.today); const dayBadge = day ? `${day}` : ""; const st = d.disrupted ? `${d.status_et}` : `${d.status_et}`; return `
${d.time} ${d.ship || ""} ${st}${dayBadge}
`; }).join(""); return `
${groups[k][0].direction_name}
${items}
`; }).join(""); } function init() { const saved = localStorage.getItem("minukodu-theme"); const prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; setTheme(saved || (prefersDark ? "dark" : "light")); const toggle = $("#theme-toggle"); if (toggle) { toggle.addEventListener("click", () => { setTheme(document.documentElement.getAttribute("data-theme") === "dark" ? "light" : "dark"); }); } initTabs(); loadLatest(); setInterval(loadLatest, 60000); } document.addEventListener("DOMContentLoaded", init);