webseite/layouts/_partials/head.html
Jannik Menzel 1d81060d7c
All checks were successful
publish / publish (push) Successful in 24s
Event Calendar adjustments for repeating events
2025-06-16 13:39:42 +02:00

121 lines
5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<meta name="description"
content="Offizielle Website des iFSR Informationen, Veranstaltungen und Ressourcen für Studierende der Informatik an der TU Dresden.">
<link rel="icon" href="{{ "favicon.ico" | relURL }}" type="image/x-icon">
<!-- SVG Preload -->
<link rel="preload" href="/images/logo.svg" as="image" type="image/svg+xml">
<link rel="preload" href="/icons/dark.svg" as="image" type="image/svg+xml">
<link rel="preload" href="/icons/light.svg" as="image" type="image/svg+xml">
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<!-- Bootstrap JS -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"
></script>
<!-- Darkmode JS -->
<script>
(function () {
try {
const stored = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const isDark = stored ? stored === "dark" : systemPrefersDark;
if (isDark) {
document.documentElement.classList.add("dark");
}
} catch (e) {
// ignore errors
}
})();
</script>
<!-- Exo 2 Font -->
<link href="https://fonts.googleapis.com/css2?family=Exo+2:wght@400;500;600&display=swap" rel="stylesheet"/>
<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title site.Title }}{{ end }}</title>
<!-- Event Calendar -->
{{ if eq .RelPermalink "/events/" }}
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5/main.min.css' rel='stylesheet'/>
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5/main.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5/locales/de.js'></script>
<script src='https://cdn.jsdelivr.net/npm/ical.js@1.4.0/build/ical.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', async function () {
const calendarEl = document.getElementById('calendar');
const calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
dayMaxEventRows: true,
height: 'auto',
locale: 'de',
firstDay: 1
});
calendar.render();
try {
const response = await fetch('https://nc.ifsr.de/remote.php/dav/public-calendars/W5Sk7zLD28n6ze44/?export');
const icsData = await response.text();
const jcalData = ICAL.parse(icsData);
const comp = new ICAL.Component(jcalData, null);
const events = comp.getAllSubcomponents('vevent');
console.log("ICS enthält", events.length, "Events");
const fcEvents = [];
events.forEach(event => {
try {
const icalEvent = new ICAL.Event(event);
if (icalEvent.isRecurring()) {
const expand = new ICAL.RecurExpansion({
component: event,
dtstart: icalEvent.startDate
});
for (let i = 0; i < 30; i++) {
if (!expand.next()) break;
const next = expand.last;
fcEvents.push({
title: icalEvent.summary || "Ohne Titel",
start: next.toJSDate(),
allDay: icalEvent.startDate.isDate
});
}
} else {
const start = icalEvent.startDate?.toJSDate();
const end = icalEvent.endDate?.toJSDate();
if (!start) return;
fcEvents.push({
title: icalEvent.summary || "Ohne Titel",
start: start,
end: end,
allDay: icalEvent.startDate.isDate
});
}
} catch (e) {
console.warn("Fehler beim Parsen eines Events:", e);
}
});
console.log("Nach dem Mapping:", fcEvents.length, "Events");
calendar.addEventSource(fcEvents);
} catch (error) {
console.error('Fehler beim Laden oder Parsen der ICS-Datei:', error);
}
});
</script>
{{ end }}
{{ partialCached "head/css.html" . }}
{{ partialCached "head/js.html" . }}