← back to Wallco Ai
wallco.ai · /designs "In a room ·N" filter chip — surface room-preview designs
354cb1741953321daff788ae776163e32e910f62 · 2026-05-12 00:07:14 -0700 · SteveStudio2
The hover-preview ships only on the top-5 saturated designs today. The
catalog renders 228 total, so a visitor on page 1 might never see one.
Adds a "Preview" filter row right under Motif chips with a single "In a room"
pill. Clicking it appends ?room=1 to the URL and narrows to only designs
that have a residential mockup. The pill shows live count (·5 today, will
grow as more rooms are generated).
Reversible: 1 new query param `room`, 1 new chip row, no schema changes.
Smoke: ?room=1 returns 5 cards (vs 228 default); all 5 carry the has-room
class so the hover overlay fires on the first card the visitor sees.
Files touched
Diff
commit 354cb1741953321daff788ae776163e32e910f62
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Tue May 12 00:07:14 2026 -0700
wallco.ai · /designs "In a room ·N" filter chip — surface room-preview designs
The hover-preview ships only on the top-5 saturated designs today. The
catalog renders 228 total, so a visitor on page 1 might never see one.
Adds a "Preview" filter row right under Motif chips with a single "In a room"
pill. Clicking it appends ?room=1 to the URL and narrows to only designs
that have a residential mockup. The pill shows live count (·5 today, will
grow as more rooms are generated).
Reversible: 1 new query param `room`, 1 new chip row, no schema changes.
Smoke: ?room=1 returns 5 cards (vs 228 default); all 5 carry the has-room
class so the hover overlay fires on the first card the visitor sees.
---
server.js | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/server.js b/server.js
index 35a1d72..6d93810 100644
--- a/server.js
+++ b/server.js
@@ -824,6 +824,7 @@ app.get('/designs', (req, res) => {
const motifQ = (req.query.motif || '').toLowerCase().trim();
const hueQ = (req.query.hue || '').toLowerCase().trim();
+ const roomQ = (req.query.room || '').toLowerCase().trim(); // '1' or 'all' = only designs with room previews
function hueBucketOf(hex) {
if (!hex || !/^#[0-9a-fA-F]{6}$/.test(hex)) return null;
const r = parseInt(hex.slice(1,3),16)/255, g = parseInt(hex.slice(3,5),16)/255, b = parseInt(hex.slice(5,7),16)/255;
@@ -851,6 +852,7 @@ app.get('/designs', (req, res) => {
if (cat) filtered = filtered.filter(d => d.category === cat);
if (motifQ) filtered = filtered.filter(d => (d.motifs || []).includes(motifQ));
if (hueQ) filtered = filtered.filter(d => hueBucketOf(d.dominant_hex) === hueQ);
+ if (roomQ) filtered = filtered.filter(d => (d.room_mockups || []).length > 0);
if (q) filtered = filtered.filter(d =>
d.title.toLowerCase().includes(q) ||
d.category.toLowerCase().includes(q) ||
@@ -1008,7 +1010,26 @@ ${htmlHeader('/designs')}
${topMotifs.map(([m,n]) => `<a href="/designs?${cat?'cat='+encodeURIComponent(cat)+'&':''}motif=${encodeURIComponent(m)}" class="motif-chip${motifQ===m?' is-on':''}" style="font:11px var(--sans);padding:5px 12px;border:1px solid ${motifQ===m?'var(--accent)':'var(--line)'};background:${motifQ===m?'var(--accent)':'transparent'};color:${motifQ===m?'var(--bg)':'var(--ink-soft)'};border-radius:999px;text-decoration:none">${m} <span style="opacity:.55">·${n}</span></a>`).join('')}
</div>
- <p class="result-count">${total} design${total===1?'':'s'}${cat?' in '+cat:''}${motifQ?' with '+motifQ:''}${q?' matching "'+q+'"':''}</p>
+ <!-- Room-preview filter chip (toggles ?room=1 — shows only designs that have a residential mockup) -->
+ ${(() => {
+ const roomCnt = DESIGNS.filter(d => (d.room_mockups || []).length > 0).length;
+ const on = !!roomQ;
+ const href = `/designs${[
+ cat ? `cat=${encodeURIComponent(cat)}` : '',
+ motifQ? `motif=${encodeURIComponent(motifQ)}`: '',
+ hueQ ? `hue=${encodeURIComponent(hueQ)}` : '',
+ !on ? 'room=1' : ''
+ ].filter(Boolean).join('&').replace(/^/, on ? '' : '?')}`;
+ return `<div class="motif-chips" style="display:flex;flex-wrap:wrap;gap:6px;margin:0 0 6px;align-items:center">
+ <span style="font:11px var(--sans);text-transform:uppercase;letter-spacing:.08em;color:var(--ink-faint);margin-right:6px">Preview</span>
+ <a href="${href}" class="motif-chip${on?' is-on':''}" title="Show only designs with a room mockup preview"
+ style="font:11px var(--sans);padding:5px 12px;border:1px solid ${on?'var(--accent)':'var(--line)'};background:${on?'var(--accent)':'transparent'};color:${on?'var(--bg)':'var(--ink-soft)'};border-radius:999px;text-decoration:none">
+ In a room <span style="opacity:.55">·${roomCnt}</span>
+ </a>
+ </div>`;
+ })()}
+
+ <p class="result-count">${total} design${total===1?'':'s'}${cat?' in '+cat:''}${motifQ?' with '+motifQ:''}${roomQ?' with room preview':''}${q?' matching "'+q+'"':''}</p>
<div id="surprise-result" style="display:none;margin-bottom:18px;padding:16px;border:1px solid var(--gold);border-radius:8px;background:var(--card-bg)"></div>
<script>
← a7922f0 hot-or-not: standalone server on port 9794 — own pm2 process
·
back to Wallco Ai
·
wallco.ai · refinement signal: ctx-passing through /swipe + c6eb465 →