/* Browsernatives ES-Modul; wird ohne TypeScript-Compiler ausgeliefert. */ const demoSlots = [ { id: 'pw-2026-08-25-1000', project: 'perspektivwerk', date: '2026-08-25', start: '10:00', title: 'Erstgespräch', status: 'available' }, { id: 'pw-2026-08-25-1300', project: 'perspektivwerk', date: '2026-08-25', start: '13:00', title: 'Soz. Päd. Modul', status: 'booked' }, { id: 'pw-2026-08-25-1500', project: 'perspektivwerk', date: '2026-08-25', start: '15:00', title: 'Erstgespräch', status: 'available' }, { id: 'pw-2026-08-27-0900', project: 'perspektivwerk', date: '2026-08-27', start: '09:00', title: 'Psy Modul', status: 'available' }, { id: 'pw-2026-08-31-0800', project: 'perspektivwerk', date: '2026-08-31', start: '08:00', title: 'Praxis Modul', status: 'available' }, { id: 'ps-2026-08-25-1000', project: 'produktionsschule', date: '2026-08-25', start: '10:00', title: 'Kennenlerntermin', status: 'available' }, { id: 'ps-2026-08-25-1300', project: 'produktionsschule', date: '2026-08-25', start: '13:00', title: 'Kennenlerntermin', status: 'booked' }, { id: 'ps-2026-08-31-0800', project: 'produktionsschule', date: '2026-08-31', start: '08:00', title: 'Probearbeiten', status: 'available' } ]; export function getSlotsForDate(project, date) { return demoSlots.filter((slot) => slot.project === project && slot.date === date); } const dateFormatter = new Intl.DateTimeFormat('de-DE', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }); const monthFormatter = new Intl.DateTimeFormat('de-DE', { month: 'long', year: 'numeric' }); const weekdays = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']; function parseDate(value) { return new Date(`${value}T12:00:00`); } function formatDateKey(date) { return date.toISOString().slice(0, 10); } function createMonthDates(month) { const first = new Date(month.getFullYear(), month.getMonth(), 1); const padding = (first.getDay() + 6) % 7; const days = new Array(padding).fill(null); const lastDay = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate(); for (let day = 1; day <= lastDay; day += 1) { days.push(new Date(month.getFullYear(), month.getMonth(), day)); } return days; } function monthForProject(project) { const firstSlot = demoSlots.find((slot) => slot.project === project); return firstSlot ? new Date(parseDate(firstSlot.date).getFullYear(), parseDate(firstSlot.date).getMonth(), 1) : new Date(); } function renderComponent(container) { const configuredProject = container.dataset.project; const project = configuredProject === 'produktionsschule' ? 'produktionsschule' : 'perspektivwerk'; let currentMonth = monthForProject(project); let selectedDate = demoSlots.find((slot) => slot.project === project)?.date ?? ''; const render = () => { const slots = selectedDate ? getSlotsForDate(project, selectedDate) : []; const selectedLabel = selectedDate ? dateFormatter.format(parseDate(selectedDate)) : 'einen Tag'; container.innerHTML = `

Terminbuchung – Vorschau

${project === 'perspektivwerk' ? 'PerspektivWerk' : 'Produktionsschule'}

Wählen Sie einen Tag. Freie Termine sind mit „frei“ gekennzeichnet.

Termin verfügbar Termin belegt

${monthFormatter.format(currentMonth)}

${createMonthDates(currentMonth).map((date) => { if (!date) return ''; const key = formatDateKey(date); const daySlots = getSlotsForDate(project, key); const available = daySlots.some((slot) => slot.status === 'available'); const booked = daySlots.length > 0 && !available; const selected = key === selectedDate; const state = available ? 'available' : booked ? 'booked' : 'none'; const label = daySlots.length ? `${dateFormatter.format(date)}: ${available ? 'freie Termine verfügbar' : 'nur belegte Termine'}` : dateFormatter.format(date); return ``; }).join('')}

Termine am ${selectedLabel}

${slots.length ? `` : '

Für diesen Tag liegen in der Vorschau keine Termine vor.

'}

`; container.querySelector('[data-action="previous"]')?.addEventListener('click', () => { currentMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1); render(); }); container.querySelector('[data-action="next"]')?.addEventListener('click', () => { currentMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1); render(); }); container.querySelectorAll('[data-date]').forEach((button) => button.addEventListener('click', () => { selectedDate = button.dataset.date ?? ''; render(); })); container.querySelectorAll('[data-slot-id]').forEach((button) => button.addEventListener('click', () => { const status = container.querySelector('.sufw-booking__status'); if (status) status.textContent = 'Vorschau: Die eigentliche Buchungsmaske wird im nächsten Schritt ergänzt.'; })); }; render(); } export function initializeBookingComponents(root = document) { root.querySelectorAll('[data-sufw-booking]').forEach(renderComponent); } if (typeof document !== 'undefined') { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => initializeBookingComponents()); } else { initializeBookingComponents(); } }