const POLL_MS = 5 * 60 * 1000; // "2026-10-13T17:30:00" -> "17:30" function hhmm(iso) { return iso.slice(11, 16); } // map kijkwijzer codes to /static/.png function kijkwijzerIcons(codes) { return (codes || []).map(c => `${c}` ).join(""); } function renderFilms(films) { const rows = (films || []).map(f => { const isBoutique = f.screen === "6"; const ratio = f.seats_sold / f.seats_total; const start = new Date(f.start); // "2026-10-13T18:00:00" parses as local time const minsUntil = (start - new Date()) / 60000; const badge = ratio >= 1 ? '
Uitverkocht
' : "
"; return `
${hhmm(f.start)}
${hhmm(f.end)}
${kijkwijzerIcons(f.kijkwijzer)}
${f.title}
${isBoutique ? `Zaal 6 - Boutique Cinema` : `Zaal ${f.screen}`} ${f.en_subs ? "EN subs" : ""}
${badge}
`; }).join(""); document.getElementById("films").innerHTML = rows + ``; } function renderPrices(prices) { const row = p => `
${p.label}${p.price}
`; document.getElementById("prijzen").innerHTML = prices.prijzen.map(row).join(""); document.getElementById("kortingsprijzen").innerHTML = prices.kortingsprijzen.map(row).join(""); } function renderClock() { const d = new Date(); const hh = String(d.getHours()).padStart(2, "0"); const mm = String(d.getMinutes()).padStart(2, "0"); document.getElementById("date").innerHTML = `${hh}:${mm}`; } async function refresh() { try { const [filmsRes, pricesRes] = await Promise.all([ fetch("/api/screenings"), fetch("/api/screenings/prices"), ]); renderFilms(await filmsRes.json()); renderPrices(await pricesRes.json()); } catch (err) { console.error("refresh failed, keeping current display:", err); } } renderClock(); setInterval(renderClock, 1_000); // every second: updates minutes + blinks the colon refresh(); // initial paint setInterval(refresh, POLL_MS); // poll every 5 minutes setInterval(renderClock, 30_000); // keep the clock accurate