← back to Dw Collections Viewer
snapshot before dep reinstall + pm2 restart
aa7d92875c60e5ecb3c40ec92eb05d7d95f26c4f · 2026-06-10 09:22:32 -0700 · SteveStudio2
Files touched
Diff
commit aa7d92875c60e5ecb3c40ec92eb05d7d95f26c4f
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed Jun 10 09:22:32 2026 -0700
snapshot before dep reinstall + pm2 restart
---
public/products.html | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/public/products.html b/public/products.html
index b5a1dd0..d1d9b3a 100644
--- a/public/products.html
+++ b/public/products.html
@@ -21,7 +21,7 @@ button:disabled{opacity:.4;cursor:not-allowed}
.pill.live{color:var(--green);border-color:var(--green)}
.pill.warn{color:var(--gold);border-color:var(--gold)}
main{padding:18px 28px}
-.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px}
+.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--pcol,180px),1fr));gap:14px}
.card{background:var(--bg2);border:1px solid var(--rule);cursor:pointer;transition:all .15s;position:relative;display:flex;flex-direction:column}
.card:hover{border-color:var(--gold)}
.card.selected{border-color:var(--gold);box-shadow:0 0 0 2px var(--gold) inset}
@@ -67,6 +67,15 @@ main{padding:18px 28px}
<select id="vendor-filter"><option value="">all vendors</option></select>
<select id="type-filter"><option value="">all types</option></select>
<select id="coll-filter"><option value="">all collections</option></select>
+ <select id="sort-by" title="Sort products">
+ <option value="newest">Newest</option>
+ <option value="title">Title A→Z</option>
+ <option value="sku">SKU/Handle A→Z</option>
+ <option value="vendor">Vendor A→Z</option>
+ <option value="price-asc">Price ↑</option>
+ <option value="price-desc">Price ↓</option>
+ </select>
+ <input id="density" type="range" min="120" max="320" step="10" value="180" title="Card density" style="flex:0 0 120px" />
<button id="select-all">Select all visible</button>
<button id="clear-sel">Clear</button>
<button id="reload">↻ Reload</button>
@@ -115,6 +124,25 @@ main{padding:18px 28px}
let PRODUCTS = [], FILTERED = [], SELECTED = new Set(), COLLECTIONS = [], COLL_FILTER_IDS = null;
const $ = id => document.getElementById(id);
+// Sort + density state — persisted in localStorage so the choice survives reloads.
+let PRODUCTS_SORT = localStorage.getItem('dwcv_prod_sort') || 'newest';
+let PRODUCTS_SIZE = parseInt(localStorage.getItem('dwcv_prod_size') || '180', 10);
+
+function sortProducts(list) {
+ const arr = list.slice();
+ const num = v => { const n = parseFloat(v); return isNaN(n) ? 0 : n; };
+ const txt = v => String(v == null ? '' : v).toLowerCase();
+ switch (PRODUCTS_SORT) {
+ case 'title': arr.sort((a, b) => txt(a.title).localeCompare(txt(b.title))); break;
+ case 'sku': arr.sort((a, b) => txt(a.sku || a.handle).localeCompare(txt(b.sku || b.handle))); break;
+ case 'vendor': arr.sort((a, b) => txt(a.vendor).localeCompare(txt(b.vendor))); break;
+ case 'price-asc': arr.sort((a, b) => num(a.price) - num(b.price)); break;
+ case 'price-desc': arr.sort((a, b) => num(b.price) - num(a.price)); break;
+ case 'newest': default: break; // server's natural order
+ }
+ return arr;
+}
+
function esc(s) { return String(s == null ? '' : s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); }
async function load() {
← 61f62d9 Add rel=noopener noreferrer to Open site external link
·
back to Dw Collections Viewer
·
similar-pattern search: per-tile ≈ button → /api/similar pro 1d1ab8c →