// Main app shell — router, scroll restore, tweaks integration, mounts pages. function DSCApp() { const [route, setRoute] = useState("home"); const [params, setParams] = useState({}); // Hash-based router useEffect(() => { function readHash() { const seededRoute = window.__BYTESGLUE_SHOWCASE_ROUTE || ""; const fallbackHash = seededRoute && seededRoute !== "home" ? `#/${seededRoute}` : "#/"; const h = (window.location.hash || fallbackHash).replace(/^#\/?/, ""); const segs = h.split("/").filter(Boolean); if (segs.length === 0) { setRoute("home"); setParams({}); return; } const [head, ...rest] = segs; if (head === "treatments") { if (rest[0]) { setRoute("treatment-detail"); setParams({ slug: rest[0] }); } else { setRoute("treatments"); setParams({}); } } else if (head === "dentists") { if (rest[0]) { setRoute("dentist-bio"); setParams({ slug: rest[0] }); } else { setRoute("dentists"); setParams({}); } } else if (head === "book" || head === "contact") { setRoute("contact"); setParams({}); } else { setRoute("home"); setParams({}); } } readHash(); window.addEventListener("hashchange", readHash); return () => window.removeEventListener("hashchange", readHash); }, []); // navigate helper updates hash and scroll-resets to top function navigate(to, extra = {}) { let hash = "#/"; if (to === "home") hash = "#/"; else if (to === "treatments") { hash = extra.slug ? `#/treatments/${extra.slug}` : "#/treatments"; } else if (to === "dentists") { hash = extra.slug ? `#/dentists/${extra.slug}` : "#/dentists"; } else if (to === "book" || to === "contact") { hash = "#/book"; } if (window.location.hash !== hash) { window.location.hash = hash; } // store prefill (for booking) if (extra && (extra.treatment || extra.branch || extra.dentist)) { window.__dscPrefill = extra; } else if (!extra.slug) { // not a treatment/dentist navigation — clear prefill stash unless going to book if (to !== "book" && to !== "contact") window.__dscPrefill = null; } setTimeout(() => window.scrollTo({ top: 0, behavior: "instant" in window ? "auto" : "auto" }), 0); } // Top-level page render const navRoute = ( route === "home" ? "home" : route === "treatments" || route === "treatment-detail" ? "treatments" : route === "dentists" || route === "dentist-bio" ? "dentists" : route === "contact" ? "contact" : "" ); let page = null; if (route === "home") page = ; else if (route === "treatments") page = ; else if (route === "treatment-detail") page = ; else if (route === "dentists") page = ; else if (route === "dentist-bio") page = ; else if (route === "contact") page = ; return ( <>
{page}
); } /* ---------- Tweaks integration ---------- */ const DSC_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "palette": "sky", "type": "default", "accent": "champagne", "density": "default" }/*EDITMODE-END*/; function DSCTweaks() { const [t, setTweak] = window.useTweaks(DSC_TWEAK_DEFAULTS); useEffect(() => { const root = document.documentElement; if (t.palette && t.palette !== "sky") root.setAttribute("data-palette", t.palette); else root.removeAttribute("data-palette"); if (t.type && t.type !== "default") root.setAttribute("data-type", t.type); else root.removeAttribute("data-type"); if (t.accent && t.accent !== "champagne") root.setAttribute("data-accent", t.accent); else root.removeAttribute("data-accent"); if (t.density && t.density !== "default") root.setAttribute("data-density", t.density); else root.removeAttribute("data-density"); }, [t.palette, t.type, t.accent, t.density]); return ( setTweak("palette", v)} options={[ { value: "sky", label: "Sky" }, { value: "monochrome", label: "Mono" }, { value: "warm", label: "Warm" }, { value: "deep", label: "Deep" }, ]} /> setTweak("type", v)} options={[ { value: "default", label: "Instrument" }, { value: "sans", label: "Tenor" }, { value: "alt-serif", label: "Cormorant" }, ]} /> setTweak("accent", v)} options={[ { value: "champagne", label: "Champagne" }, { value: "muted", label: "Muted" }, { value: "none", label: "None" }, ]} /> setTweak("density", v)} options={[ { value: "default", label: "Airy" }, { value: "compact", label: "Compact" }, ]} /> ); } window.DSCApp = DSCApp; window.DSCTweaks = DSCTweaks; /* ---------- Mount ---------- */ const root = ReactDOM.createRoot(document.getElementById("dsc-root")); root.render(<>);