// Dennis: Kontaktseite – Scroll-Reveal und Formular-Logik. // ----- Scroll-Reveal ----- (function () { const elements = document.querySelectorAll(".kontakt-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); }); })(); // ----- Kontaktformular ----- (function () { const form = document.getElementById("kontakt-formular"); if (!form) return; const MIN_MESSAGE = 10; const EMAIL_TARGET = "info@trihub.de"; const fields = { name: form.querySelector("[name='name']"), email: form.querySelector("[name='email']"), phone: form.querySelector("[name='phone']"), type: form.querySelector("[name='anfragetyp']"), subject: form.querySelector("[name='betreff']"), message: form.querySelector("[name='nachricht']") }; const statusEl = document.getElementById("form-status"); 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 validateType() { const ok = fields.type.value !== ""; setFieldState(fields.type, ok ? null : "error"); return ok; } function validateSubject() { const ok = fields.subject.value.trim().length > 0; setFieldState(fields.subject, ok ? null : "error"); return ok; } function validateMessage() { const len = fields.message.value.trim().length; if (len === 0) { setFieldState(fields.message, "error"); return false; } if (len >= MIN_MESSAGE) { setFieldState(fields.message, "ok"); return true; } // Zu kurz: erst bei Submit als Fehler markieren, live nur grün bei erfüllt. setFieldState(fields.message, null); return false; } function allValid() { return ( fields.name.value.trim().length > 0 && /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(fields.email.value.trim()) && fields.type.value !== "" && fields.subject.value.trim().length > 0 && fields.message.value.trim().length >= MIN_MESSAGE ); } function updateSubmitState() { const submit = form.querySelector("[type='submit']"); if (submit) { submit.disabled = !allValid(); } } // Live-Feedback: Nachricht wird bei 10+ Zeichen grün markiert. fields.message.addEventListener("input", function () { validateMessage(); updateSubmitState(); }); ["name", "email", "subject"].forEach(function (key) { fields[key].addEventListener("blur", function () { if (fields[key].value.trim() !== "" || form.dataset.touched === "true") { ({ name: validateName, email: validateEmail, subject: validateSubject })[key](); } }); }); fields.type.addEventListener("change", validateType); form.addEventListener("submit", function (event) { event.preventDefault(); form.dataset.touched = "true"; const okName = validateName(); const okEmail = validateEmail(); const okType = validateType(); const okSubject = validateSubject(); const okMessage = validateMessage(); if (!(okName && okEmail && okType && okSubject && okMessage)) { showStatus("error", "Bitte überprüfe die markierten Felder und versuche es erneut."); return; } const subject = fields.subject.value.trim(); const typeLabel = fields.type.options[fields.type.selectedIndex].text; const body = [ "Name: " + fields.name.value.trim(), "E-Mail: " + fields.email.value.trim(), "Telefon: " + (fields.phone.value.trim() || "–"), "Anfrage-Typ: " + typeLabel, "", fields.message.value.trim() ].join("\n"); // Statische Seite ohne Backend: E-Mail-Programm wird mit allen Angaben geöffnet. window.location.href = "mailto:" + EMAIL_TARGET + "?subject=" + encodeURIComponent("Ernährungsberatung – " + subject) + "&body=" + encodeURIComponent(body); showStatus( "ok", "Danke! Dein E-Mail-Programm wurde geöffnet. Sende die Nachricht ab – wir melden uns zeitnah bei dir." ); form.reset(); Object.values(fields).forEach(function (el) { setFieldState(el, null); }); updateSubmitState(); }); function showStatus(kind, text) { if (!statusEl) return; statusEl.textContent = kind === "ok" ? "✓ " + text : "✗ " + text; statusEl.className = "form-status is-visible " + (kind === "ok" ? "form-status--ok" : "form-status--error"); } updateSubmitState(); })();