← back to Wallco Ai
PDP theme switcher: admin-only — hide .switcher bar from shoppers, gate dropdown+stepper on localStorage.dwAdmin
aa2d6d6b7cc0c99e064d896d428aacc081a6302c · 2026-06-01 20:55:02 -0700 · Steve Abrams
Files touched
M public/theme-variants/theme-variant-nav.js
Diff
commit aa2d6d6b7cc0c99e064d896d428aacc081a6302c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jun 1 20:55:02 2026 -0700
PDP theme switcher: admin-only — hide .switcher bar from shoppers, gate dropdown+stepper on localStorage.dwAdmin
---
public/theme-variants/theme-variant-nav.js | 59 +++++++++++++++++-------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/public/theme-variants/theme-variant-nav.js b/public/theme-variants/theme-variant-nav.js
index be201ae..ca5acc4 100644
--- a/public/theme-variants/theme-variant-nav.js
+++ b/public/theme-variants/theme-variant-nav.js
@@ -1,17 +1,18 @@
-/* theme-variant-nav.js — PDP theme switchers for the 17 variants.
+/* theme-variant-nav.js — ADMIN-ONLY PDP theme switchers for the 17 variants.
*
* Drop-in (ABSOLUTE path — variants are served at /design/:id/:slug):
* <script src="/theme-variants/theme-variant-nav.js" defer></script>
*
- * Two switchers:
- * (1) PUBLIC theme dropdown — turns each variant's static .switcher bar
- * ("Theme: X ← Classic") into a working <select> of Classic + all 17
- * variants. Runs for everyone (the bar is already public). Also fixes the
- * broken "← Classic" link (its inline href points at the bare /design/:id
- * which serves the LIVE theme, so when a variant is the live default it
- * loops back to itself — we route Classic through ?classic=1).
- * (2) ADMIN ‹ prev / next › stepper pill (upper-right) — shows ONLY when
- * localStorage.dwAdmin === '1' (set via ?admin=1). Alt+←/→ also step.
+ * ADMIN GATE: everything below shows ONLY when localStorage.dwAdmin === '1'
+ * (set via ?admin=1, cleared via ?admin=0). For shoppers we HIDE the static
+ * .switcher bar entirely so the internal theme machinery is never exposed.
+ *
+ * For admins, two switchers:
+ * (1) theme dropdown — turns each variant's .switcher bar ("Theme: X ← Classic")
+ * into a working <select> of Classic + all 17 variants. Classic routes via
+ * ?classic=1 (server forces the monolith) so it works even when a variant
+ * is the live default; variants route via /design/:id/<slug>.
+ * (2) ‹ prev / next › stepper pill (upper-right). Alt+←/→ also step.
* Marks the LIVE theme (from /api/pdp-theme). Self-styled · idempotent · 0 deps.
*/
(function () {
@@ -19,8 +20,27 @@
if (window.__themeVariantNavLoaded) return;
window.__themeVariantNavLoaded = true;
- // NOTE: the admin gate is DOWN below — it wraps ONLY the ‹ › stepper pill.
- // The public dropdown runs for everyone.
+ // ── ADMIN GATE ─────────────────────────────────────────────────────────
+ // Resolve admin first. Shoppers get the .switcher bar hidden and nothing else.
+ var isAdmin = false;
+ try {
+ var q = new URLSearchParams(location.search);
+ if (q.get('admin') === '1') localStorage.setItem('dwAdmin', '1');
+ if (q.get('admin') === '0') localStorage.removeItem('dwAdmin');
+ isAdmin = localStorage.getItem('dwAdmin') === '1';
+ } catch (e) { isAdmin = false; }
+
+ if (!isAdmin) {
+ // Hide the internal theme-switcher bar from shoppers (it's static HTML in
+ // every variant). Injected as early as the deferred script runs.
+ try {
+ var hide = document.createElement('style');
+ hide.id = 'tvn-hide-switcher';
+ hide.textContent = '.switcher{display:none !important}';
+ (document.head || document.documentElement).appendChild(hide);
+ } catch (e) {}
+ return;
+ }
// ordered route slugs (match server /design/:id/:slug + smoke test) → display name
var THEMES = [
@@ -75,11 +95,7 @@
var LIVE_IDX = -1;
- // ───────────────────────────────────────────────────────────────────────
- // (1) PUBLIC theme dropdown (everyone). Classic routes through ?classic=1
- // (server forces the monolith) so it works even when a variant is the live
- // default; variants route through /design/:id/<slug> (always that variant).
- // ───────────────────────────────────────────────────────────────────────
+ // ───────────────────────── (1) theme dropdown (admin) ─────────────────────
function classicUrl() {
if (mode !== 'route') return '/'; // file-mode dev: no monolith
var p = new URLSearchParams(location.search);
@@ -141,14 +157,7 @@
if (document.body) tvnInit();
else document.addEventListener('DOMContentLoaded', tvnInit);
- // ───────────── (2) ADMIN ‹ prev / next › stepper pill (admin-only) ─────────────
- try {
- var q = new URLSearchParams(location.search);
- if (q.get('admin') === '1') localStorage.setItem('dwAdmin', '1');
- if (q.get('admin') === '0') localStorage.removeItem('dwAdmin');
- if (localStorage.getItem('dwAdmin') !== '1') return;
- } catch (e) { return; }
-
+ // ───────────────── (2) ‹ prev / next › stepper pill (admin) ────────────────
// ---- styles ----
var css = document.createElement('style');
css.textContent = [
← f78404f follow-up #1 (two-master, /dtd Option B): disjoint id ranges
·
back to Wallco Ai
·
la-toile: fix prompt — gate off conflicting tone-on-tone pal dcdb679 →