added description to event-calendar

This commit is contained in:
Jannik Menzel 2025-06-23 11:36:04 +02:00
parent 66afba730e
commit e65d2f4c88

View file

@ -1,121 +1,126 @@
{{ if or (eq .RelPermalink "/events/") (eq .RelPermalink "/en/events/") }} {{ if or (eq .RelPermalink "/events/") (eq .RelPermalink "/en/events/") }}
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5/main.min.css' rel='stylesheet'/> <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/main.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5/locales/de.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 src='https://cdn.jsdelivr.net/npm/ical.js@1.4.0/build/ical.min.js'></script>
<script> <script>
/* global bootstrap */ /* global bootstrap */
document.addEventListener('DOMContentLoaded', async function () { document.addEventListener('DOMContentLoaded', async function () {
const calendarEl = document.getElementById('calendar'); const calendarEl = document.getElementById('calendar');
const calendar = new FullCalendar.Calendar(calendarEl, { const calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth', initialView: 'dayGridMonth',
dayMaxEventRows: true, dayMaxEventRows: true,
height: 'auto', height: 'auto',
locale: 'de', locale: 'de',
firstDay: 1, firstDay: 1,
eventClick: function(info) { eventClick: function (info) {
const event = info.event; const event = info.event;
const title = event.title; const title = event.title;
const location = event.extendedProps.location || 'Nicht angegeben'; const location = event.extendedProps.location || 'Nicht angegeben';
const start = event.start; const start = event.start;
const end = event.end; const end = event.end;
let dateStr = ''; let dateStr = '';
if (start && end) { if (start && end) {
dateStr = start.toLocaleString() + ' ' + end.toLocaleString(); dateStr = start.toLocaleString() + ' ' + end.toLocaleString();
} else if (start) { } else if (start) {
dateStr = start.toLocaleString(); dateStr = start.toLocaleString();
} }
document.getElementById('modalEventTitle').textContent = title; document.getElementById('modalEventTitle').textContent = title;
document.getElementById('modalEventDate').textContent = dateStr; document.getElementById('modalEventDate').textContent = dateStr;
document.getElementById('modalEventLocation').textContent = location; document.getElementById('modalEventLocation').textContent = location;
document.getElementById('modalEventDescription').textContent = event.extendedProps.description || 'Keine Beschreibung verfügbar';
const modal = new bootstrap.Modal(document.getElementById('eventModal')); const modal = new bootstrap.Modal(document.getElementById('eventModal'));
modal.show(); modal.show();
}, },
}); });
calendar.render(); calendar.render();
try { try {
const response = await fetch('https://nc.ifsr.de/remote.php/dav/public-calendars/W5Sk7zLD28n6ze44/?export'); const response = await fetch('https://nc.ifsr.de/remote.php/dav/public-calendars/W5Sk7zLD28n6ze44/?export');
const icsData = await response.text(); const icsData = await response.text();
const jcalData = ICAL.parse(icsData); const jcalData = ICAL.parse(icsData);
const comp = new ICAL.Component(jcalData, null); const comp = new ICAL.Component(jcalData, null);
const events = comp.getAllSubcomponents('vevent'); const events = comp.getAllSubcomponents('vevent');
console.log("ICS enthält", events.length, "Events"); console.log("ICS enthält", events.length, "Events");
const fcEvents = []; const fcEvents = [];
events.forEach(event => { events.forEach(event => {
try { try {
const icalEvent = new ICAL.Event(event); const icalEvent = new ICAL.Event(event);
if (icalEvent.isRecurring()) { if (icalEvent.isRecurring()) {
const expand = new ICAL.RecurExpansion({ const expand = new ICAL.RecurExpansion({
component: event, component: event,
dtstart: icalEvent.startDate dtstart: icalEvent.startDate
}); });
for (let i = 0; i < 30; i++) { for (let i = 0; i < 30; i++) {
if (!expand.next()) break; if (!expand.next()) break;
const next = expand.last; const next = expand.last;
fcEvents.push({ fcEvents.push({
title: icalEvent.summary || "Ohne Titel", title: icalEvent.summary || "Ohne Titel",
start: next.toJSDate(), start: next.toJSDate(),
allDay: icalEvent.startDate.isDate, allDay: icalEvent.startDate.isDate,
location: icalEvent.location, 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);
}
}); });
}
} else {
const start = icalEvent.startDate?.toJSDate();
const end = icalEvent.endDate?.toJSDate();
if (!start) return;
fcEvents.push({ console.log("Nach dem Mapping:", fcEvents.length, "Events");
title: icalEvent.summary || "Ohne Titel",
start: start, calendar.addEventSource(fcEvents);
end: end,
allDay: icalEvent.startDate.isDate, } catch (error) {
location: icalEvent.location, console.error('Fehler beim Laden oder Parsen der ICS-Datei:', error);
});
} }
} catch (e) {
console.warn("Fehler beim Parsen eines Events:", e);
}
}); });
</script>
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 }} {{ end }}
<!-- Event Details Modal --> <!-- Event Details Modal -->
<div class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel" aria-hidden="true"> <div class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h2 class="modal-title" id="eventModalLabel">Event Details</h2> <h2 class="modal-title" id="eventModalLabel">Event Details</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<h4 id="modalEventTitle"></h4> <h4 id="modalEventTitle"></h4>
<p><strong>Datum:</strong> <span id="modalEventDate"></span></p> <p><strong>Datum:</strong> <span id="modalEventDate"></span></p>
<p><strong>Ort:</strong> <span id="modalEventLocation"></span></p> <p><strong>Ort:</strong> <span id="modalEventLocation"></span></p>
</div> <p><strong>Beschreibung:</strong></p>
<div class="modal-footer"> <div id="modalEventDescription" style="overflow-wrap: anywhere; word-break: break-word;"></div>
<button type="button" class="btn btn-secondary btn-lg" data-bs-dismiss="modal">Schließen</button> </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>
</div>
</div> </div>