let rennplanData = {}; let resultsData = {}; let messageData = {}; document.addEventListener("DOMContentLoaded", () => { initAppUI(); initTabs(); initAppPromotion(); loadData(); setInterval(loadData, CONFIG.REFRESH_INTERVAL); }); function initAppUI() { const fullTitle = `${CONFIG.EVENT_NAME} – Rennplan & Ergebnisse`; document.title = fullTitle; const titleEl = document.getElementById("app-title"); if (titleEl) { titleEl.textContent = fullTitle; } } function initTabs() { const rennplanBtn = document.getElementById("tab-rennplan"); const resultsBtn = document.getElementById("tab-ergebnisse"); const rennplanView = document.getElementById("rennplan-view"); const resultsView = document.getElementById("ergebnisse-view"); rennplanBtn.addEventListener("click", () => { rennplanView.classList.remove("hidden"); resultsView.classList.add("hidden"); setTabActive(rennplanBtn, resultsBtn); }); resultsBtn.addEventListener("click", () => { resultsView.classList.remove("hidden"); rennplanView.classList.add("hidden"); setTabActive(resultsBtn, rennplanBtn); }); } function setTabActive(active, inactive) { active.className = "flex-1 py-4 text-indigo-600 border-b-4 border-indigo-600 font-medium"; inactive.className = "flex-1 py-4 text-slate-500 font-medium"; } async function loadData() { try { const scrollY = window.scrollY; const [rennplanRes, resultsRes, messageRes] = await Promise.all([ fetch(CONFIG.RENNPLAN_URL), fetch(CONFIG.RESULTS_URL), fetch(CONFIG.MESSAGE_URL) ]); rennplanData = await rennplanRes.json(); resultsData = await resultsRes.json(); messageData = await messageRes.json(); renderMessage(); renderRennplan(); renderResults(); requestAnimationFrame(() => { window.scrollTo(0, scrollY); }); } catch (err) { console.error("API Fehler:", err); } } function renderMessage() { const box = document.getElementById("message-box"); if (!messageData?.message) { box.classList.add("hidden"); return; } let style = ""; switch (messageData.type) { case "danger": style = "bg-red-50 border-red-400 text-red-900"; break; case "warning": style = "bg-amber-50 border-amber-400 text-amber-900"; break; default: style = "bg-blue-50 border-blue-400 text-blue-900"; } box.className = `border-l-4 p-4 rounded-xl shadow-sm ${style}`; box.innerHTML = `
${messageData.message}
`; box.classList.remove("hidden"); } function renderRennplan() { const container = document.getElementById("rennplan-content"); container.innerHTML = ""; const rennplan = rennplanData.rennplan || {}; const sortedLaeufe = Object.keys(rennplan) .sort((a, b) => { return parseInt(b.replace("lauf", "")) - parseInt(a.replace("lauf", "")); }); sortedLaeufe.forEach(laufKey => { const laufNum = laufKey.replace("lauf", ""); const races = Object.entries(rennplan[laufKey]) .sort((a, b) => Number(a[0]) - Number(b[0])); container.innerHTML += `
${laufNum}

Lauf ${laufNum}

${races.map(([_, race]) => `
${race.name}
${race.art}
${race.zeit}
Bahn 1 · ${race.bahn1} Bahn 2 · ${race.bahn2} Bahn 3 · ${race.bahn3}
`).join("")}
`; }); } function renderResults() { const container = document.getElementById("results-content"); container.innerHTML = ""; const races = Object.entries(resultsData.ergebnisse || {}) .sort((a, b) => Number(b[0]) - Number(a[0])); races.forEach(([_, race]) => { const lane = (key, data, winner) => { const isWinner = race.winner === key; return `
${data.boot}
${isWinner ? ` Sieger ` : ""}
${data.zeit}
${formatLaneLabel(key)}
`; }; container.innerHTML += `
${race.title}
${race.art}
Lauf ${race.lauf}
${formatDateTime(race.start)}
${lane("bahn1", race.bahn1)} ${lane("bahn2", race.bahn2)} ${lane("bahn3", race.bahn3)}
`; }); } function formatLaneLabel(key) { const map = { bahn1: "Bahn 1", bahn2: "Bahn 2", bahn3: "Bahn 3" }; return map[key] || key; } function formatDateTime(dateString) { const match = dateString.match( /^(\d{4})-(\d{2})-(\d{2})-(\d{2}):(\d{2}):(\d{2})$/ ); if (!match) return dateString; const [, y, m, d, h, i, s] = match; const date = new Date(y, m - 1, d, h, i, s); return date.toLocaleString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit" }); } function initAppPromotion() { if (CONFIG.IOS_APP_ID) { const meta = document.createElement("meta"); meta.name = "apple-itunes-app"; meta.content = `app-id=${CONFIG.IOS_APP_ID}`; document.head.appendChild(meta); } renderAndroidPromo(); } function isAndroidDevice() { return /android/i.test(navigator.userAgent || ""); } function renderAndroidPromo() { const promo = document.getElementById("app-promo"); if (!promo) return; const isAndroid = isAndroidDevice(); console.log("Android detected:", isAndroid); if (!isAndroid || !CONFIG.ANDROID_PACKAGE_NAME) { promo.classList.add("hidden"); return; } const playStoreUrl = `https://play.google.com/store/apps/details?id=${CONFIG.ANDROID_PACKAGE_NAME}`; promo.innerHTML = `
Jetzt die Android App herunterladen
Öffnen
`; promo.classList.remove("hidden"); }