[object Object]

← 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,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }
 
 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 →