From 7d2db0bc0897e9991db8cbfa260787e38a25044c Mon Sep 17 00:00:00 2001 From: Ben de Roo Date: Wed, 24 Jun 2026 21:14:05 +0200 Subject: [PATCH] Add domme-converters/assets/js/router.js --- domme-converters/assets/js/router.js | 88 ++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 domme-converters/assets/js/router.js diff --git a/domme-converters/assets/js/router.js b/domme-converters/assets/js/router.js new file mode 100644 index 0000000..5a610d8 --- /dev/null +++ b/domme-converters/assets/js/router.js @@ -0,0 +1,88 @@ +"use strict"; + +/** + * Hash-router voor de single-page shell. Houdt semantische, leesbare paden aan + * (bijv. #/producten/hdmi-naar-tuinslang) en werkt zonder serverconfiguratie, + * ook bij direct openen van het bestand. + */ +(function () { + const CL = (window.CL = window.CL || {}); + const pages = CL.pages; + + const headerEl = document.getElementById("site-header"); + const appEl = document.getElementById("app"); + const footerEl = document.getElementById("site-footer"); + + // Statische routes -> view-functies. + const routes = { + "/": pages.home, + "/producten": pages.producten, + "/catalogus": pages.catalogus, + "/specificaties": pages.specificaties, + "/aanbiedingen": pages.aanbiedingen, + "/bedrijf": pages.bedrijf, + "/over-ons": pages.overOns, + "/contact": pages.contact, + "/vacatures": pages.vacatures, + "/voorwaarden": pages.voorwaarden, + "/privacy": pages.privacy, + "/disclaimer": pages.disclaimer, + }; + + function parsePath() { + const raw = location.hash.replace(/^#/, ""); + const path = raw.split("?")[0] || "/"; + return path === "" ? "/" : path; + } + + // Bepaalt welke view bij een pad hoort (incl. dynamische productroute). + function resolve(path) { + if (routes[path]) return routes[path](); + const productMatch = path.match(/^\/producten\/([^/]+)$/); + if (productMatch) return pages.productDetail(decodeURIComponent(productMatch[1])); + return pages.notFound(); + } + + // Het pad dat de header gebruikt voor de actieve-link-markering. + function navPathFor(path) { + if (/^\/producten\/[^/]+$/.test(path)) return "/producten"; + return path; + } + + function render() { + const path = parsePath(); + const view = resolve(path); + + headerEl.innerHTML = CL.components.header(navPathFor(path)); + appEl.innerHTML = view.html; + document.title = view.title; + + CL.ui.bindHeader(); + CL.ui.updateCartCount(); + if (typeof view.onMount === "function") view.onMount(); + + window.scrollTo({ top: 0, behavior: "auto" }); + } + + function boot() { + footerEl.innerHTML = CL.components.footer(); + CL.ui.init(); + + // Mandje-wijzigingen werken de teller en de lade overal bij. + CL.store.subscribe(() => { + CL.ui.updateCartCount(); + CL.ui.renderCart(); + }); + + window.addEventListener("hashchange", render); + if (!location.hash) location.replace("#/"); + render(); + CL.ui.renderCart(); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", boot); + } else { + boot(); + } +})();