[object Object]

← back to Interiordesignershowroom

auto-save: 2026-08-03T10:53:14 (2 files) — lib/rooms.js server.js

c8362bbda12604e7a47302c145e9661c976c2705 · 2026-08-03 10:53:24 -0700 · Steve Abrams

Files touched

Diff

commit c8362bbda12604e7a47302c145e9661c976c2705
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 10:53:24 2026 -0700

    auto-save: 2026-08-03T10:53:14 (2 files) — lib/rooms.js server.js
---
 lib/rooms.js | 15 ++++++++++++---
 server.js    |  9 +++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/lib/rooms.js b/lib/rooms.js
index e8b5064..7330f99 100644
--- a/lib/rooms.js
+++ b/lib/rooms.js
@@ -65,12 +65,21 @@ async function getRoom(slug) {
   const r = rows[0];
   let products = [];
   if (r.product_ids && r.product_ids.length) {
-    const pr = await db.query(`SELECT ${COLS.PRODUCT} FROM products WHERE id = ANY($1)`, [r.product_ids]);
+    const pr = await db.query(`SELECT ${COLS.PRODUCT} FROM products WHERE id = ANY($1) AND NOT suppressed`, [r.product_ids]);
     // preserve the saved order
     products = r.product_ids.map(id => pr.rows.find(p => p.id === id)).filter(Boolean);
   }
   let paint = null;
-  if (r.wall_paint_id) paint = (await db.query(`SELECT ${COLS.PRODUCT} FROM products WHERE id=$1`, [r.wall_paint_id])).rows[0] || null;
+  if (r.wall_paint_id) paint = (await db.query(`SELECT ${COLS.PRODUCT} FROM products WHERE id=$1 AND NOT suppressed`, [r.wall_paint_id])).rows[0] || null;
+  // drop any scene hotspot whose product has since been suppressed, so a hidden item
+  // (e.g. Honiture) can't stay tappable on the scene while it's gone from the grid.
+  if (r.hotspots && r.hotspots.length) {
+    const hotIds = r.hotspots.map((h) => h.id).filter(Boolean);
+    if (hotIds.length) {
+      const sup = await db.query('SELECT id FROM products WHERE id = ANY($1) AND suppressed', [hotIds]);
+      if (sup.rows.length) { const gone = new Set(sup.rows.map((x) => x.id)); r.hotspots = r.hotspots.filter((h) => !gone.has(h.id)); }
+    }
+  }
   return { room: r, products, paint };
 }
 
@@ -80,7 +89,7 @@ async function listRooms({ limit = 60 } = {}) {
   for (const r of rows) {
     r.thumbs = [];
     if (r.product_ids && r.product_ids.length) {
-      const t = await db.query('SELECT image_url FROM products WHERE id = ANY($1) AND image_url IS NOT NULL LIMIT 4', [r.product_ids.slice(0, 4)]);
+      const t = await db.query('SELECT image_url FROM products WHERE id = ANY($1) AND image_url IS NOT NULL AND NOT suppressed LIMIT 4', [r.product_ids.slice(0, 4)]);
       r.thumbs = t.rows.map(x => x.image_url);
     }
   }
diff --git a/server.js b/server.js
index b22768c..3a23149 100644
--- a/server.js
+++ b/server.js
@@ -119,7 +119,10 @@ async function renderCatalog(res, { f, basePath, title, description, canonical,
       </div>
     </section><script src="/js/grid.js"></script>`;
   const jsonld = [productListJsonld(products, canonical), breadcrumbJsonld(crumbs)].filter(Boolean);
-  res.send(layout({ title, description, canonical, jsonld, body, activeNav }));
+  // Social share image: the top product's photo so a shared facet/room link shows real
+  // furniture, not the generic logo card. Falls back to og.png in layout() when empty.
+  const image = products.length ? products[0].image_url : null;
+  res.send(layout({ title, description, canonical, jsonld, body, activeNav, image }));
 }
 
 // SEO for /shop under filters. Only a whitelist of "clean" facet shapes — a single
@@ -634,7 +637,9 @@ app.get('/room/:slug', async (req, res, next) => {
       title: room.title,
       description: room.note || `A shoppable ${styleLabel || 'room'} — ${products.length} designer pieces.`,
       canonical: `${SITE.url}/room/${room.slug}`,
-      jsonld: [itemList, breadcrumbJsonld(crumbs)].filter(Boolean), image: room.scene_image, body, activeNav: '/looks'
+      jsonld: [itemList, breadcrumbJsonld(crumbs)].filter(Boolean),
+      // Scene-less saved rooms fall back to their first product's photo, not the logo.
+      image: room.scene_image || (products[0] && products[0].image_url), body, activeNav: '/looks'
     }));
   } catch (e) { next(e); }
 });

← 181743c deploy: schema-migration step + /shop smoke test (stop code-  ·  back to Interiordesignershowroom  ·  chore: v0.4.0 (session close — date+time-added on store card 7c3f401 →