webseite/layouts/_partials/event-calendar.html
2025-06-23 11:36:04 +02:00

126 lines
5.7 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.

{{ if or (eq .RelPermalink "/events/") (eq .RelPermalink "/en/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>
/* global bootstrap */
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,
eventClick: function (info) {
const event = info.event;
const title = event.title;
const location = event.extendedProps.location || 'Nicht angegeben';
const start = event.start;
const end = event.end;
let dateStr = '';
if (start && end) {
dateStr = start.toLocaleString() + ' ' + end.toLocaleString();
} else if (start) {
dateStr = start.toLocaleString();
}
document.getElementById('modalEventTitle').textContent = title;
document.getElementById('modalEventDate').textContent = dateStr;
document.getElementById('modalEventLocation').textContent = location;
document.getElementById('modalEventDescription').textContent = event.extendedProps.description || 'Keine Beschreibung verfügbar';
const modal = new bootstrap.Modal(document.getElementById('eventModal'));
modal.show();
},
});
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,
location: icalEvent.location,
description: icalEvent.description,
});
}
} 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,
location: icalEvent.location,
description: icalEvent.description,
});
}
} 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 }}
<!-- Event Details Modal -->
<div class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="eventModalLabel">Event Details</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<h4 id="modalEventTitle"></h4>
<p><strong>Datum:</strong> <span id="modalEventDate"></span></p>
<p><strong>Ort:</strong> <span id="modalEventLocation"></span></p>
<p><strong>Beschreibung:</strong></p>
<div id="modalEventDescription" style="overflow-wrap: anywhere; word-break: break-word;"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-lg" data-bs-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>