Logo der Deutsch-Niederländische Handelskammer

Steuerplicht in NL Check

Steuerpflichtig in den Niederlanden? Unser Tool für Ihr Steuerrecht. Mit wenigen Clicks überprüfen ob Sie Abgaben abführen müssen.

Umfrage Dienstleistungsportal.jpg
document.addEventListener("DOMContentLoaded", function () { // === KONFIGURATION === const JSON_URL = "/assets/baumdiagramm.json"; // Pfad zu deiner Excel->JSON const MOUNT_ID = "qa-tool"; // === STYLES (zentriert, max 800px) === const css = ` .qa-wrap{width:100%;max-width:800px;margin:0 auto;padding:16px;box-sizing:border-box;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif} .qa-card{border:0;border-radius:16px;box-shadow:0 4px 12px rgba(0,0,0,0.06);padding:16px;background:#fff} .qa-title{font-size:20px;font-weight:600;margin:0 0 6px} .qa-sub{font-size:13px;color:#666;margin:0 0 14px} .qa-breadcrumb{font-size:13px;color:#666;margin:0 0 10px} .qa-breadcrumb a{color:inherit;text-decoration:underline;text-underline-offset:2px;cursor:pointer} .qa-list{display:grid;gap:8px;margin:0;padding:0;list-style:none} .qa-btn{display:flex;justify-content:space-between;align-items:center;width:100%;text-align:left;padding:12px 14px;border-radius:12px;border:1px solid #e5e7eb;background:#fff;cursor:pointer} .qa-btn:hover{background:#f8fafc} .qa-answer h3{margin:10px 0 8px;font-size:16px} .qa-answer p{margin:0 0 8px;line-height:1.5} .qa-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px} .qa-secondary,.qa-ghost{border-radius:10px;padding:10px 12px;font-size:14px;cursor:pointer} .qa-secondary{background:#f1f5f9;border:1px solid #e2e8f0} .qa-ghost{background:transparent;border:1px solid transparent} .qa-search{display:flex;gap:8px;margin:0 0 12px} .qa-input{flex:1;padding:10px 12px;border-radius:10px;border:1px solid #e5e7eb} .qa-copy{font-size:12px;color:#666;margin-top:6px} `; const style = document.createElement("style"); style.textContent = css; document.head.appendChild(style); // === Hilfsfunktionen === function buildTreeFromSheets(json) { const sheets = json && json.sheets ? json.sheets : {}; const firstName = Object.keys(sheets)[0]; const rows = (firstName && Array.isArray(sheets[firstName])) ? sheets[firstName] : []; const matrix = rows.map(obj => { const vals = Object.values(obj || {}); return vals.map(v => v == null ? "" : String(v).trim()).filter(s => s !== ""); }).filter(arr => arr.length > 0); return buildTreeFromPaths(matrix); } function buildTreeFromPaths(rows) { const root = { id: "root", label: "Start", children: [] }; const indexByPath = new Map(); indexByPath.set("root", root); const keyOf = (arr) => arr.join(" > "); rows.forEach((labels, rIdx) => { let parent = root; let pathParts = ["root"]; for (let i = 0; i < labels.length; i++) { const lab = labels[i]; const isLast = i === labels.length - 1; const key = keyOf([...pathParts, lab]); let node = indexByPath.get(key); if (!node) { node = { id: key + "#" + rIdx + "_" + i, label: lab }; (parent.children || (parent.children = [])).push(node); indexByPath.set(key, node); } if (isLast) { const looksLikeAnswer = /[.!?]/.test(lab) || lab.split(" ").length > 8; if (looksLikeAnswer) node.answer = lab; } parent = node; pathParts.push(lab); } }); return root; } function isLeaf(n){ return !!n.answer && !n.children; } function childrenOf(n){ return Array.isArray(n.children) ? n.children : []; } // === DOM aufbauen === const mount = document.getElementById(MOUNT_ID); if (!mount) return; const wrap = document.createElement("div"); wrap.className = "qa-wrap"; mount.appendChild(wrap); const card = document.createElement("div"); card.className = "qa-card"; wrap.appendChild(card); const title = document.createElement("h2"); title.className = "qa-title"; title.textContent = "Fragen & Antworten"; card.appendChild(title); const sub = document.createElement("p"); sub.className = "qa-sub"; sub.textContent = "Wählen Sie Schritt für Schritt aus oder nutzen Sie die Suche."; card.appendChild(sub); // Suche const searchForm = document.createElement("form"); searchForm.className = "qa-search"; const input = document.createElement("input"); input.className = "qa-input"; input.placeholder = "Suchen…"; const searchBtn = document.createElement("button"); searchBtn.type = "submit"; searchBtn.className = "qa-secondary"; searchBtn.textContent = "Suchen"; searchForm.appendChild(input); searchForm.appendChild(searchBtn); card.appendChild(searchForm); const breadcrumb = document.createElement("div"); breadcrumb.className = "qa-breadcrumb"; card.appendChild(breadcrumb); const list = document.createElement("ul"); list.className = "qa-list"; card.appendChild(list); const answerBox = document.createElement("div"); answerBox.className = "qa-answer"; card.appendChild(answerBox); const actions = document.createElement("div"); actions.className = "qa-actions"; card.appendChild(actions); const backBtn = document.createElement("button"); backBtn.className = "qa-secondary"; backBtn.textContent = "Zurück"; backBtn.disabled = true; const restartBtn = document.createElement("button"); restartBtn.className = "qa-ghost"; restartBtn.textContent = "Neu starten"; actions.appendChild(backBtn); actions.appendChild(restartBtn); // Kontakt-iframe programmatisch erzeugen (nicht über innerHTML – hilft gegen Sanitizer) function addContactIframe(target) { const outer = document.createElement("div"); outer.style.width = "100%"; outer.style.display = "flex"; outer.style.justifyContent = "center"; outer.style.alignItems = "center"; outer.style.margin = "0 auto"; const iframe = document.createElement("iframe"); iframe.src = "https://analytics-eu.clickdimensions.com/wwwdnhkorg-aj4kw/pages/c9n27oy3eeubugbqvoa6bw.html?PageId=ec76d30b37e6eb11815200505686ba6f"; iframe.allowTransparency = true; iframe.width = "100%"; iframe.height = "1100px"; iframe.frameBorder = "0"; iframe.style.border = "0"; iframe.style.maxWidth = "800px"; outer.appendChild(iframe); target.appendChild(outer); } // State let tree = null, path = []; function renderBreadcrumb() { breadcrumb.innerHTML = ""; const span = document.createElement("span"); span.textContent = "Pfad: "; breadcrumb.appendChild(span); path.forEach((n, i) => { if (i > 0) breadcrumb.appendChild(document.createTextNode(" / ")); const a = document.createElement("a"); a.textContent = n.label || "Start"; a.onclick = () => { path = path.slice(0, i + 1); render(); }; breadcrumb.appendChild(a); }); } function setContactAuto(n) { const label = (n && n.label ? String(n.label) : "").toLowerCase(); if (label.includes("registrierungspflicht")) addContactIframe(answerBox); } function renderNode(n) { list.innerHTML = ""; answerBox.innerHTML = ""; if (!isLeaf(n)) { childrenOf(n).forEach(c => { const li = document.createElement("li"); const btn = document.createElement("button"); btn.className = "qa-btn"; btn.textContent = c.label; btn.onclick = () => { path.push(c); render(); }; li.appendChild(btn); list.appendChild(li); }); setContactAuto(n); } else { const h3 = document.createElement("h3"); h3.textContent = "Antwort"; const p = document.createElement("p"); p.textContent = n.answer || ""; answerBox.appendChild(h3); answerBox.appendChild(p); const copyNote = document.createElement("div"); copyNote.className = "qa-copy"; const copyBtn = document.createElement("button"); copyBtn.className = "qa-secondary"; copyBtn.textContent = "Antwort kopieren"; copyBtn.onclick = () => { navigator.clipboard.writeText(n.answer || ""); copyNote.textContent = "Antwort kopiert."; }; actions.insertBefore(copyBtn, actions.firstChild); setTimeout(() => { try { actions.removeChild(copyBtn); } catch(e){} }, 0); // einmalig answerBox.appendChild(copyNote); setContactAuto(n); } } function render(){ backBtn.disabled = path.length <= 1; renderBreadcrumb(); renderNode(path[path.length - 1]); } backBtn.onclick = () => { if (path.length > 1) { path.pop(); render(); } }; restartBtn.onclick = () => { path = [tree]; render(); }; searchForm.onsubmit = (e) => { e.preventDefault(); const t = (input.value || "").trim().toLowerCase(); if (!t) return; const results = []; (function dfs(n, p){ const inLabel = (n.label || "").toLowerCase().includes(t); const inAns = (n.answer || "").toLowerCase().includes(t); if (inLabel || inAns) results.push([...p, n]); (n.children || []).forEach(c => dfs(c, [...p, n])); })(tree, []); if (results.length) { path = results[0]; render(); } else { alert("Kein Treffer."); } }; // Daten laden & starten fetch(JSON_URL, { cache: "no-store" }) .then(r => r.json()) .then(json => { tree = buildTreeFromSheets(json); path = [tree]; render(); }) .catch(err => { console.error("Fehler beim Laden der JSON:", err); card.innerHTML = "

Die Inhalte konnten nicht geladen werden. Prüfe bitte den JSON-Pfad.

"; }); });