Statische Landing Page mit Lead-Formular, Impressum und Datenschutzerklärung, ausgeliefert von einem abhängigkeitsfreien Node-Server mit lokaler Lead-Erfassung. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
128 lines
3.7 KiB
JavaScript
128 lines
3.7 KiB
JavaScript
/* ToolCTRL — Landing Page Interaktion */
|
|
(function () {
|
|
"use strict";
|
|
|
|
/* ---- Jahr im Footer ---- */
|
|
var yearEl = document.getElementById("year");
|
|
if (yearEl) yearEl.textContent = String(new Date().getFullYear());
|
|
|
|
/* ---- Mobile-Navigation ---- */
|
|
var toggle = document.querySelector(".nav-toggle");
|
|
var mobileNav = document.querySelector(".mobile-nav");
|
|
if (toggle && mobileNav) {
|
|
toggle.addEventListener("click", function () {
|
|
var open = mobileNav.hasAttribute("hidden");
|
|
if (open) {
|
|
mobileNav.removeAttribute("hidden");
|
|
toggle.setAttribute("aria-expanded", "true");
|
|
} else {
|
|
mobileNav.setAttribute("hidden", "");
|
|
toggle.setAttribute("aria-expanded", "false");
|
|
}
|
|
});
|
|
mobileNav.querySelectorAll("a").forEach(function (a) {
|
|
a.addEventListener("click", function () {
|
|
mobileNav.setAttribute("hidden", "");
|
|
toggle.setAttribute("aria-expanded", "false");
|
|
});
|
|
});
|
|
}
|
|
|
|
/* ---- Lead-Formular ---- */
|
|
var form = document.getElementById("lead-form");
|
|
var status = document.getElementById("form-status");
|
|
if (!form) return;
|
|
|
|
function setStatus(msg, kind) {
|
|
if (!status) return;
|
|
status.textContent = msg;
|
|
status.className = "form-status " + (kind || "");
|
|
status.hidden = false;
|
|
}
|
|
|
|
function fieldRow(input) {
|
|
return input.closest(".form-row");
|
|
}
|
|
|
|
function validate() {
|
|
var ok = true;
|
|
["f-name", "f-email", "f-nachricht"].forEach(function (id) {
|
|
var el = document.getElementById(id);
|
|
var row = fieldRow(el);
|
|
var valid = el.value.trim() !== "";
|
|
if (id === "f-email" && valid) {
|
|
valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(el.value.trim());
|
|
}
|
|
if (row) row.classList.toggle("invalid", !valid);
|
|
if (!valid) ok = false;
|
|
});
|
|
return ok;
|
|
}
|
|
|
|
form.addEventListener("submit", function (e) {
|
|
e.preventDefault();
|
|
|
|
if (!validate()) {
|
|
setStatus("Bitte füllen Sie die markierten Pflichtfelder aus.", "err");
|
|
return;
|
|
}
|
|
|
|
var btn = form.querySelector("button[type=submit]");
|
|
var payload = {
|
|
name: form.name.value.trim(),
|
|
firma: form.firma.value.trim(),
|
|
email: form.email.value.trim(),
|
|
telefon: form.telefon.value.trim(),
|
|
nachricht: form.nachricht.value.trim(),
|
|
website: form.website.value.trim(), // Honeypot
|
|
quelle: "Messe — Landing Page"
|
|
};
|
|
|
|
if (btn) { btn.disabled = true; btn.textContent = "Wird gesendet …"; }
|
|
setStatus("Anfrage wird übermittelt …", "");
|
|
|
|
fetch("/api/lead", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(payload)
|
|
})
|
|
.then(function (res) {
|
|
return res.json().then(function (data) {
|
|
return { ok: res.ok, data: data };
|
|
});
|
|
})
|
|
.then(function (r) {
|
|
if (r.ok) {
|
|
form.reset();
|
|
setStatus(
|
|
"Vielen Dank — Ihre Anfrage ist bei uns eingegangen. Wir melden uns zeitnah.",
|
|
"ok"
|
|
);
|
|
} else {
|
|
setStatus(
|
|
(r.data && r.data.error) ||
|
|
"Es ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.",
|
|
"err"
|
|
);
|
|
}
|
|
})
|
|
.catch(function () {
|
|
setStatus(
|
|
"Verbindung fehlgeschlagen. Bitte schreiben Sie uns direkt an admin@tool-ctrl.de.",
|
|
"err"
|
|
);
|
|
})
|
|
.finally(function () {
|
|
if (btn) { btn.disabled = false; btn.textContent = "Anfrage senden"; }
|
|
});
|
|
});
|
|
|
|
/* Markierung beim Tippen entfernen */
|
|
form.querySelectorAll("input, textarea").forEach(function (el) {
|
|
el.addEventListener("input", function () {
|
|
var row = fieldRow(el);
|
|
if (row) row.classList.remove("invalid");
|
|
});
|
|
});
|
|
})();
|