document.addEventListener("DOMContentLoaded", () => { const el = document.getElementById("hv-schema"); if (!el) return; wp.apiFetch({ path: "/hv/v1/schema" }).then((raw) => { const events = parseICS(raw.ics).slice(0, raw.antal); el.innerHTML = events .map( (ev) => `
${ev.kurs}
${ev.moment}
${ev.datum}
${ev.tid}
${ev.lokal}
`, ) .join(""); }); }); function parseICS(data) { const lines = data.split(/\r?\n/); let ev = [], cur = null; for (const l of lines) { if (l.startsWith("BEGIN:VEVENT")) cur = {}; if (l.startsWith("SUMMARY:")) { const raw = l.replace("SUMMARY:", "").trim(); // // ======== KURS ========= // let kurs = ""; let kursMatch = raw.match(/Kurs\.grp:\s*([^:]+?)(?:\s+Sign:|$)/); if (kursMatch) { kurs = kursMatch[1].trim(); } // ✅ Ta bort dubletter: "A A" → "A" kurs = kurs.replace(/^(.*)\s+\1$/, "$1").trim(); cur.kurs = kurs; // // ======== MOMENT ========= // let moment = ""; let momentMatch = raw.match(/Moment:\s*(.+?)(?:\s+Aktivitetstyp:|$)/); if (momentMatch) { moment = momentMatch[1].trim(); } else { // fallback const parts = raw.split(" - "); if (parts[1]) { moment = parts[1].trim(); } } // Rensa "Moment:" om det ligger kvar moment = moment.replace(/^Moment:\s*/i, "").trim(); cur.moment = moment; } // // ======== DATUM & TID ========= // if (l.startsWith("DTSTART:")) { const dt = l.replace("DTSTART:", ""); cur.datum = dt.substring(0, 4) + "-" + dt.substring(4, 6) + "-" + dt.substring(6, 8); cur.tid = dt.substring(9, 11) + ":" + dt.substring(11, 13); } // // ======== LOKAL ========= // if (l.startsWith("LOCATION:")) cur.lokal = l.replace("LOCATION:", "").trim(); if (l.startsWith("END:VEVENT")) ev.push(cur); } return ev; } function parseICS(data) { const lines = data.split(/\r?\n/); let ev = [], cur = null; for (const l of lines) { if (l.startsWith("BEGIN:VEVENT")) cur = {}; if (l.startsWith("SUMMARY:")) { const raw = l.replace("SUMMARY:", "").trim(); // // ======== KURS ========= // let kurs = ""; let kursMatch = raw.match(/Kurs\.grp:\s*([^:]+?)(?:\s+Sign:|$)/); if (kursMatch) kurs = kursMatch[1].trim(); kurs = kurs.replace(/^(.*)\s+\1$/, "$1").trim(); // ta bort dubletter cur.kurs = kurs; // // ======== MOMENT ========= // let moment = ""; let momentMatch = raw.match(/Moment:\s*(.+?)(?:\s+Aktivitetstyp:|$)/); if (momentMatch) { moment = momentMatch[1].trim(); } else { const parts = raw.split(" - "); if (parts[1]) moment = parts[1].trim(); } moment = moment.replace(/^Moment:\s*/i, "").trim(); cur.moment = moment; } // // ======== DATUM & TID (MED SVERIGE-TID) ======== // if (l.startsWith("DTSTART:")) { const dt = l.replace("DTSTART:", ""); // Plocka ut delar ur ICS-datumet const year = Number(dt.substring(0, 4)); const month = Number(dt.substring(4, 6)); const day = Number(dt.substring(6, 8)); const hour = Number(dt.substring(9, 11)); const min = Number(dt.substring(11, 13)); // Skapa en UTC-tid från ICS const dateUTC = new Date(Date.UTC(year, month - 1, day, hour, min)); // Konvertera till svensk tid const dateLocal = new Date( dateUTC.toLocaleString("sv-SE", { timeZone: "Europe/Stockholm" }), ); // Formatera svensk datumtext, t.ex. "2 april 2026" const formattedDate = new Intl.DateTimeFormat("sv-SE", { day: "numeric", month: "long", year: "numeric", }).format(dateLocal); // Formatera tiden, t.ex. "13:15" const hh = String(dateLocal.getHours()).padStart(2, "0"); const mi = String(dateLocal.getMinutes()).padStart(2, "0"); cur.datum = formattedDate; cur.tid = `${hh}:${mi}`; } // // ======== LOKAL ========= // if (l.startsWith("LOCATION:")) cur.lokal = l.replace("LOCATION:", "").trim(); if (l.startsWith("END:VEVENT")) ev.push(cur); } return ev; }