89 lines
2.5 KiB
JavaScript
89 lines
2.5 KiB
JavaScript
"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();
|
|
}
|
|
})();
|