← back to Wallco Ai
/me/saved: add admin view-mode toggle pill (admin/live) — info@designerwallcoverings.com already gets dw_auth on trade-login allowlist (line 3667), but the toggle UI was only on /designs. Now flipped from /me/saved too.
a2a7d70d39dec1b748d6020b894edbd09b854e1f · 2026-05-28 12:39:51 -0700 · Steve Abrams
Files touched
Diff
commit a2a7d70d39dec1b748d6020b894edbd09b854e1f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu May 28 12:39:51 2026 -0700
/me/saved: add admin view-mode toggle pill (admin/live) — info@designerwallcoverings.com already gets dw_auth on trade-login allowlist (line 3667), but the toggle UI was only on /designs. Now flipped from /me/saved too.
---
server.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/server.js b/server.js
index 7cd7b15..f62eb99 100644
--- a/server.js
+++ b/server.js
@@ -3816,6 +3816,11 @@ app.get('/me/saved', (req, res) => {
if (!u) {
return res.redirect('/trade/login?return=' + encodeURIComponent('/me/saved'));
}
+ // Admin-only floating view-mode pill (Steve 2026-05-28: "allow info acct to
+ // toggle admin/live on /me/saved"). info@designerwallcoverings.com gets a
+ // dw_auth admin JWT minted on trade-login (line ~3667 allowlist); without
+ // this toggle, /me/saved had no way to flip back to live for QA.
+ const _isAdminAuth = isAdmin(req);
// Pull save rows joined to live DESIGNS array (DESIGNS is the in-memory
// snapshot we already render everywhere). Designs that no longer exist in
// the catalog are silently filtered out.
@@ -3944,6 +3949,57 @@ ${htmlHeader('/me/saved')}
</div>`}
</section>
</main>
+${_isAdminAuth ? `
+<!-- Admin view-mode pill — same mechanism as /designs (cookie 'view_mode'),
+ ported here so info@ + steve@ can flip from /me/saved without bouncing
+ to /designs first. Cookie propagates to all routes. -->
+<style>
+ .view-toggle{position:fixed;right:14px;bottom:14px;z-index:9999;display:flex;gap:6px;align-items:center;padding:6px 10px;border-radius:999px;background:rgba(20,18,16,0.88);color:#f2eadb;font:11px/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase;box-shadow:0 4px 14px rgba(0,0,0,.35);backdrop-filter:blur(6px);user-select:none}
+ .view-toggle button{appearance:none;border:1px solid rgba(242,234,219,0.18);background:transparent;color:inherit;padding:5px 10px;border-radius:999px;font:inherit;cursor:pointer;transition:all .12s ease}
+ .view-toggle button.is-active{background:#f2eadb;color:#141210;border-color:#f2eadb}
+ .view-toggle button:hover:not(.is-active){background:rgba(242,234,219,0.12)}
+ .view-toggle-label{opacity:.55;margin-right:4px}
+</style>
+<div class="view-toggle" id="viewToggle" role="group" aria-label="View mode (admin only)">
+ <span class="view-toggle-label">View:</span>
+ <button type="button" data-mode="admin" id="vmAdmin">Admin</button>
+ <button type="button" data-mode="live" id="vmLive">Live</button>
+</div>
+<script>
+(function(){
+ function setCookie(name, val, days){
+ var d = new Date(); d.setTime(d.getTime() + (days*86400000));
+ document.cookie = name + '=' + val + ';path=/;expires=' + d.toUTCString() + ';samesite=lax';
+ }
+ function readCookie(name){
+ var m = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]+)'));
+ return m ? decodeURIComponent(m[1]) : '';
+ }
+ function getMode(){
+ var url = new URL(window.location.href);
+ if (url.searchParams.get('view') === 'live') return 'live';
+ return readCookie('view_mode') === 'live' ? 'live' : 'admin';
+ }
+ function setActive(mode){
+ var a = document.getElementById('vmAdmin');
+ var l = document.getElementById('vmLive');
+ if (!a || !l) return;
+ a.classList.toggle('is-active', mode === 'admin');
+ l.classList.toggle('is-active', mode === 'live');
+ }
+ function applyMode(mode){
+ if (mode === getMode()) return;
+ setCookie('view_mode', mode, 365);
+ var url = new URL(window.location.href);
+ url.searchParams.delete('view');
+ window.location.replace(url.toString());
+ }
+ setActive(getMode());
+ var a = document.getElementById('vmAdmin'); if (a) a.addEventListener('click', function(){ applyMode('admin'); });
+ var l = document.getElementById('vmLive'); if (l) l.addEventListener('click', function(){ applyMode('live'); });
+})();
+</script>
+` : ''}
${FOOTER}
<script>
(function(){
← 09c554e hero: room slides use background-size:cover (full-width) ins
·
back to Wallco Ai
·
cactus-curator: hover any chip to swap flat tile → room mock 5f263d7 →