Compare commits

..

No commits in common. "1c71ea60a89ee6f471aa1029b43b5a66e63e810c" and "492b47a927d6ebbe83baca9c31a7dac9a70cfff2" have entirely different histories.

2 changed files with 18 additions and 94 deletions

View File

@ -656,7 +656,7 @@ footer {
border: 1px solid #ddd; border: 1px solid #ddd;
border-top: 0; border-top: 0;
border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px;
overflow: visible; overflow: hidden;
} }
.calendar-weekday-header { .calendar-weekday-header {
@ -712,11 +712,6 @@ footer {
border-bottom: none; border-bottom: none;
} }
.calendar-day-hidden {
visibility: hidden;
pointer-events: none;
}
@media (min-width: 992px) { @media (min-width: 992px) {
.calendar-grid { .calendar-grid {
grid-template-columns: repeat(7, minmax(0, 1fr)); grid-template-columns: repeat(7, minmax(0, 1fr));
@ -732,12 +727,7 @@ footer {
border: 1px solid #ddd; border: 1px solid #ddd;
border-bottom: 0; border-bottom: 0;
border-radius: 8px 8px 0 0; border-radius: 8px 8px 0 0;
overflow: visible; overflow: hidden;
position: sticky;
top: 70px;
z-index: 900;
background: var(--card-background, #fff);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
} }
.calendar-day { .calendar-day {

View File

@ -24,7 +24,15 @@
</div> </div>
</div> </div>
<div class="calendar-weekday-header"></div> <div class="calendar-weekday-header">
<div>Mo</div>
<div>Di</div>
<div>Mi</div>
<div>Do</div>
<div>Fr</div>
<div>Sa</div>
<div>So</div>
</div>
<div id="calendar-days" class="calendar-grid"> <div id="calendar-days" class="calendar-grid">
<!-- Populated via inline script below --> <!-- Populated via inline script below -->
@ -53,15 +61,6 @@
<input type="time" class="form-control" id="calendarTime"> <input type="time" class="form-control" id="calendarTime">
</div> </div>
</div> </div>
{% if admin_enabled %}
<div class="row g-3 mt-1" id="calendarRecurrenceRow">
<div class="col-md-6">
<label for="calendarRepeatCount" class="form-label">Wöchentliche Wiederholung</label>
<input type="number" class="form-control" id="calendarRepeatCount" min="1" max="52" step="1" value="1">
<div class="form-text">Legt einzelne wöchentliche Termine an (für Nachbearbeitung).</div>
</div>
</div>
{% endif %}
<div class="mt-3"> <div class="mt-3">
<label for="calendarTitle" class="form-label">Titel</label> <label for="calendarTitle" class="form-label">Titel</label>
<input type="text" class="form-control" id="calendarTitle" required> <input type="text" class="form-control" id="calendarTitle" required>
@ -149,40 +148,18 @@
return holidays.get(toLocalISO(date)) || ''; return holidays.get(toLocalISO(date)) || '';
} }
function isDesktopView() {
return window.matchMedia && window.matchMedia('(min-width: 992px)').matches;
}
function getCalendarRange() { function getCalendarRange() {
const weeks = window._calendarIsAdmin ? 12 : 4; const weeks = window._calendarIsAdmin ? 12 : 4;
const start = new Date(); const start = new Date();
start.setHours(0, 0, 0, 0); start.setHours(0, 0, 0, 0);
// shift back to Monday (0 = Sunday)
if (isDesktopView()) { const diffToMonday = (start.getDay() + 6) % 7;
// shift back to Monday (0 = Sunday) start.setDate(start.getDate() - diffToMonday);
const diffToMonday = (start.getDay() + 6) % 7;
start.setDate(start.getDate() - diffToMonday);
}
const end = new Date(start); const end = new Date(start);
end.setDate(end.getDate() + (weeks * 7) - 1); end.setDate(end.getDate() + (weeks * 7) - 1);
return { start, end }; return { start, end };
} }
function renderWeekdayHeader(startDate) {
const header = document.querySelector('.calendar-weekday-header');
if (!header) return;
header.innerHTML = '';
const formatDayShort = new Intl.DateTimeFormat('de-DE', { weekday: 'short' });
for (let i = 0; i < 7; i++) {
const d = new Date(startDate);
d.setDate(startDate.getDate() + i);
const div = document.createElement('div');
div.textContent = formatDayShort.format(d);
header.appendChild(div);
}
}
(function renderInitialCalendarRange() { (function renderInitialCalendarRange() {
const daysContainer = document.getElementById('calendar-days'); const daysContainer = document.getElementById('calendar-days');
if (!daysContainer || daysContainer.childElementCount > 0) return; if (!daysContainer || daysContainer.childElementCount > 0) return;
@ -195,8 +172,6 @@
const formatDayName = new Intl.DateTimeFormat('de-DE', { weekday: 'long' }); const formatDayName = new Intl.DateTimeFormat('de-DE', { weekday: 'long' });
const formatDate = new Intl.DateTimeFormat('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }); const formatDate = new Intl.DateTimeFormat('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
const { start, end } = getCalendarRange(); const { start, end } = getCalendarRange();
const todayIso = toLocalISO(new Date());
renderWeekdayHeader(start);
const dayCount = Math.round((end - start) / (1000 * 60 * 60 * 24)) + 1; const dayCount = Math.round((end - start) / (1000 * 60 * 60 * 24)) + 1;
for (let i = 0; i < dayCount; i++) { for (let i = 0; i < dayCount; i++) {
@ -219,9 +194,6 @@
if (holidayName) { if (holidayName) {
dayBlock.classList.add('calendar-day-holiday'); dayBlock.classList.add('calendar-day-holiday');
} }
if (isDesktopView() && isoDate < todayIso) {
dayBlock.classList.add('calendar-day-hidden');
}
dayBlock.innerHTML = ` dayBlock.innerHTML = `
<div class="calendar-day-header"> <div class="calendar-day-header">
@ -463,22 +435,6 @@
return response.json(); return response.json();
} }
async function createRecurringEntries(entry, repeatCount) {
const count = Math.max(1, Math.min(52, repeatCount || 1));
const baseDate = entry.date;
if (!baseDate) return [];
const base = new Date(baseDate);
const savedEntries = [];
for (let i = 0; i < count; i++) {
const next = new Date(base);
next.setDate(base.getDate() + i * 7);
const entryForWeek = { ...entry, date: toLocalISO(next) };
const saved = await saveCalendarEntry(entryForWeek);
savedEntries.push(saved);
}
return savedEntries;
}
async function deleteCalendarEntry(id) { async function deleteCalendarEntry(id) {
const response = await fetch(`/api/calendar/${id}`, { method: 'DELETE' }); const response = await fetch(`/api/calendar/${id}`, { method: 'DELETE' });
if (!response.ok) { if (!response.ok) {
@ -534,22 +490,12 @@
const form = document.getElementById('calendarForm'); const form = document.getElementById('calendarForm');
const daysContainer = document.getElementById('calendar-days'); const daysContainer = document.getElementById('calendar-days');
const locationFilter = document.getElementById('calendar-location-filter'); const locationFilter = document.getElementById('calendar-location-filter');
const repeatCountInput = document.getElementById('calendarRepeatCount');
const recurrenceRow = document.getElementById('calendarRecurrenceRow');
const calendarModal = modalEl && window.bootstrap ? new bootstrap.Modal(modalEl) : null; const calendarModal = modalEl && window.bootstrap ? new bootstrap.Modal(modalEl) : null;
if (calendarModal) { if (calendarModal) {
window.calendarModal = calendarModal; window.calendarModal = calendarModal;
} }
let calendarHasLoaded = false; let calendarHasLoaded = false;
const setRecurrenceMode = (isEditing) => {
if (!recurrenceRow) return;
recurrenceRow.style.display = isEditing ? 'none' : '';
if (!isEditing && repeatCountInput) {
repeatCountInput.value = '1';
}
};
if (addBtn && calendarModal) { if (addBtn && calendarModal) {
addBtn.addEventListener('click', () => { addBtn.addEventListener('click', () => {
if (form) form.reset(); if (form) form.reset();
@ -561,7 +507,6 @@
const idInput = document.getElementById('calendarEntryId'); const idInput = document.getElementById('calendarEntryId');
if (idInput) idInput.value = ''; if (idInput) idInput.value = '';
setRecurrenceMode(false);
calendarModal.show(); calendarModal.show();
}); });
} }
@ -578,24 +523,14 @@
location: document.getElementById('calendarLocation')?.value, location: document.getElementById('calendarLocation')?.value,
details: document.getElementById('calendarDetails')?.value details: document.getElementById('calendarDetails')?.value
}; };
const isEditing = Boolean(entry.id);
const repeatCount = (!isEditing && window._calendarIsAdmin && repeatCountInput)
? Math.max(1, Math.min(52, parseInt(repeatCountInput.value, 10) || 1))
: 1;
try { try {
if (isEditing) { if (entry.id) {
removeCalendarEntryFromUI(entry.id); removeCalendarEntryFromUI(entry.id);
const saved = await saveCalendarEntry(entry);
addLocationOption(saved.location);
addCalendarEntry(saved);
} else {
const savedEntries = await createRecurringEntries(entry, repeatCount);
savedEntries.forEach(saved => {
addLocationOption(saved.location);
addCalendarEntry(saved);
});
} }
const saved = await saveCalendarEntry(entry);
addLocationOption(saved.location);
addCalendarEntry(saved);
calendarModal.hide(); calendarModal.hide();
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@ -668,7 +603,6 @@
document.getElementById('calendarTitle').value = entry.title || ''; document.getElementById('calendarTitle').value = entry.title || '';
document.getElementById('calendarLocation').value = entry.location || ''; document.getElementById('calendarLocation').value = entry.location || '';
document.getElementById('calendarDetails').value = entry.details || ''; document.getElementById('calendarDetails').value = entry.details || '';
setRecurrenceMode(true);
if (calendarModal) calendarModal.show(); if (calendarModal) calendarModal.show();
return; return;
} }