// Online-Terminbuchung – Buchungsseite (html/terminbuchung.html). // Liest den gewählten Termin aus der URL (berater, datum, zeit), füllt die // Zusammenfassung, verwaltet die Anamnese-Tags und prüft das Formular. // Die Bestätigung wird nur auf der Seite angezeigt; es wird keine E-Mail versendet. // ----- Scroll-Reveal ----- (function () { const elements = document.querySelectorAll(".terminbuchung-seite .reveal"); if (!elements.length) return; const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (reduceMotion || !("IntersectionObserver" in window)) { elements.forEach(function (el) { el.classList.add("visible"); }); return; } const observer = new IntersectionObserver( function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.classList.add("visible"); observer.unobserve(entry.target); } }); }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" } ); elements.forEach(function (el) { observer.observe(el); }); })(); // ----- Anamnese-Tags (Allergien & Unverträglichkeiten) ----- (function () { const input = document.getElementById("tag-input"); const addButton = document.getElementById("tag-add"); const liste = document.getElementById("tag-list"); if (!input || !addButton || !liste) return; const tags = []; const MAX_TAGS = 20; function tagHinzufuegen() { let wert = input.value.trim().replace(/^#+/, "").trim(); if (!wert) return; if (tags.length >= MAX_TAGS) { input.value = ""; return; } // Doppelte Einträge (groß/kleinschreibungsgleich) werden nicht aufgenommen. const existiert = tags.some(function (t) { return t.toLowerCase() === wert.toLowerCase(); }); if (!existiert) { tags.push(wert); } input.value = ""; zeichnen(); } function tagEntfernen(index) { tags.splice(index, 1); zeichnen(); } function zeichnen() { liste.innerHTML = ""; tags.forEach(function (wert, index) { const li = document.createElement("li"); li.className = "tb-tag"; const text = document.createElement("span"); text.textContent = wert; const entfernen = document.createElement("button"); entfernen.type = "button"; entfernen.setAttribute("aria-label", "Tag entfernen: " + wert); entfernen.innerHTML = "×"; entfernen.addEventListener("click", function () { tagEntfernen(index); }); li.appendChild(text); li.appendChild(entfernen); liste.appendChild(li); }); } addButton.addEventListener("click", tagHinzufuegen); input.addEventListener("keydown", function (event) { if (event.key === "Enter") { event.preventDefault(); tagHinzufuegen(); } }); // Für das E-Mail-Body: aktuelle Tag-Liste als Text. window.TerminbuchungTags = { holen: function () { return tags.slice(); }, leeren: function () { tags.length = 0; zeichnen(); } }; })(); // ----- Formularprüfung und Absenden ----- (function () { const form = document.getElementById("terminbuchung-formular"); if (!form) return; const bestaetigungDialog = document.getElementById("anfrage-bestaetigung"); const fields = { art: form.querySelector("[name='art']"), format: form.querySelector("[name='format']"), gespraech: form.querySelector("[name='gespraech']"), beschreibung: form.querySelector("[name='beschreibung']"), name: form.querySelector("[name='name']"), email: form.querySelector("[name='email']"), phone: form.querySelector("[name='phone']") }; const statusEl = document.getElementById("form-status"); const formularBereich = document.getElementById("formular"); const pruefBereich = document.getElementById("anfrage-pruefen"); const pruefDetails = document.getElementById("anfrage-pruefen-details"); const bearbeitenButton = document.getElementById("anfrage-bearbeiten"); const sendenButton = document.getElementById("anfrage-senden"); function wrap(el) { return el.closest(".field"); } function setFieldState(el, state) { const box = wrap(el); if (!box) return; box.classList.remove("has-error", "is-ok"); el.classList.remove("invalid", "valid"); if (state === "error") { box.classList.add("has-error"); el.classList.add("invalid"); } else if (state === "ok") { box.classList.add("is-ok"); el.classList.add("valid"); } } function validateName() { const ok = fields.name.value.trim().length > 0; setFieldState(fields.name, ok ? null : "error"); return ok; } function validateEmail() { const value = fields.email.value.trim(); const ok = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(value); setFieldState(fields.email, ok ? null : "error"); return ok; } function validateSelect(key) { const ok = fields[key].value !== ""; setFieldState(fields[key], ok ? null : "error"); return ok; } function allValid() { return ( terminIstGueltig() && fields.art.value !== "" && fields.format.value !== "" && fields.gespraech.value !== "" && fields.name.value.trim().length > 0 && /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(fields.email.value.trim()) ); } function updateSubmitState() { const submit = form.querySelector("[type='submit']"); if (submit) { submit.disabled = !allValid(); } } form.addEventListener("input", updateSubmitState); form.addEventListener("change", updateSubmitState); ["name", "email"].forEach(function (key) { fields[key].addEventListener("blur", function () { if (fields[key].value.trim() !== "" || form.dataset.touched === "true") { ({ name: validateName, email: validateEmail })[key](); } }); }); ["art", "format", "gespraech"].forEach(function (key) { fields[key].addEventListener("change", function () { validateSelect(key); }); }); // Nur ein eingetragener, noch zukünftiger Termin darf angefragt werden. const params = new URLSearchParams(window.location.search); const beraterId = params.get("berater"); const datum = params.get("datum"); const zeit = params.get("zeit"); let termin = null; function terminIstGueltig() { return termin !== null && termin.zeitpunkt > Date.now(); } function terminFehlerAnzeigen(text) { termin = null; const zusammenfassung = document.getElementById("termin-zusammenfassung"); zusammenfassung.classList.add("tb-summary--fehlend"); zusammenfassung.innerHTML = `
Wähle auf der Startseite einen Berater, einen verfügbaren Tag und eine Uhrzeit.