let timersData = []; let detailOpenFor = null; function formatDiff(target) { const targetDate = target instanceof Date ? target : new Date(target); const now = new Date(); const diff = targetDate - now; if (diff <= 0) return "Abgelaufen"; const days = Math.floor(diff / (1000 * 60 * 60 * 24)); const hours = Math.floor((diff / (1000 * 60 * 60)) % 24); const minutes = Math.floor((diff / (1000 * 60)) % 60); const seconds = Math.floor((diff / 1000) % 60); return `${days}d ${hours}h ${minutes}m ${seconds}s`; } fetch("/api/countdowns") .then(res => res.json()) .then(data => { timersData = data.timers || []; const mainTargetDate = new Date(data.main.target); const mainLabel = data.main.label || ""; const mainLabelEl = document.getElementById("main-label"); const mainCountdownEl = document.getElementById("main-countdown"); function updateMainTimer() { const now = new Date(); const diff = mainTargetDate - now; if (diff <= 0) { mainLabelEl.textContent = mainLabel; mainCountdownEl.textContent = "Abgelaufen"; return; } mainLabelEl.textContent = mainLabel; mainCountdownEl.textContent = formatDiff(mainTargetDate); } function updateSmallTimers() { timersData.forEach(t => { const el = document.getElementById(t.id); if (!el) return; const now = new Date(); const nextEntry = t.targets .map(e => ({ ...e, date: new Date(e.time) })) .find(e => e.date > now); if (nextEntry) { el.textContent = `${nextEntry.label}\n${formatDiff(nextEntry.date)}`; } else { el.textContent = `${t.label}\nAbgelaufen`; } }); } function updateDetailsPanel() { if (!detailOpenFor) return; const timer = timersData.find(t => t.id === detailOpenFor); if (!timer) return; timer.targets.forEach((target, idx) => { const el = document.getElementById(`detail-${timer.id}-${idx}`); if (!el) return; el.textContent = formatDiff(target.time); }); } function renderDetails(timer) { const detailEl = document.getElementById("timer-details"); if (!detailEl) return; detailOpenFor = timer.id; const entries = timer.targets.map((target, idx) => { const entryId = `detail-${timer.id}-${idx}`; return `
${target.label}
`; }).join(""); detailEl.innerHTML = `

${timer.label}

${timer.targets.length} Termine
${entries} `; detailEl.classList.remove("hidden"); const closeBtn = document.getElementById("timer-details-close"); if (closeBtn) { closeBtn.addEventListener("click", () => { detailOpenFor = null; detailEl.classList.add("hidden"); }); } updateDetailsPanel(); } setInterval(() => { updateMainTimer(); updateSmallTimers(); updateDetailsPanel(); }, 1000); updateMainTimer(); updateSmallTimers(); document.querySelectorAll(".small-circle").forEach(circle => { circle.addEventListener("click", () => { const timerId = circle.getAttribute("data-timer"); const timer = timersData.find(t => t.id === timerId); if (timer) renderDetails(timer); }); }); }); document.getElementById("fullscreen-btn").addEventListener("click", () => { if (!document.fullscreenElement) { document.documentElement.requestFullscreen(); } else { document.exitFullscreen(); } }); const cantinaAudio = document.getElementById("cantina-audio"); const circleContainer = document.querySelector(".circle-container"); function playCantina() { if (!cantinaAudio) return; cantinaAudio.currentTime = 0; cantinaAudio.play().catch(err => console.warn("Cantina playback blocked:", err)); } if (circleContainer) { circleContainer.addEventListener("click", playCantina); } function scheduleNextFullHour() { const now = new Date(); const next = new Date(now); next.setMinutes(0, 0, 0); if (next <= now) { next.setHours(next.getHours() + 1); } const delay = next - now; setTimeout(() => { playCantina(); scheduleNextFullHour(); }, delay); } scheduleNextFullHour(); const overlay = document.getElementById("twitter-overlay"); function showOverlay() { overlay.style.display = "flex"; const gongVideo = document.getElementById("gong-video-fullscreen"); if (gongVideo) { gongVideo.currentTime = 0; gongVideo.play().catch(err => console.warn("Autoplay-Fehler:", err)); } setTimeout(() => { overlay.style.display = "none"; }, 60000); } (() => { const now = new Date(); const target = new Date(); target.setHours(23, 40, 0, 0); if (now > target && now - target < 60000) { showOverlay(); } else if (now <= target) { const delay = target - now; setTimeout(showOverlay, delay); } })();