← back to Wallco Ai
/design/:id 'Sell on Etsy' button — go one-click force-add by default (design-page = deliberate admin intent; gate becomes advisory). Surface scores in success status if seams > 12 so the admin sees the warning without being blocked. Curator bulk actions keep the eligibility gate
f538318ac4daa1b1c14ce26f2cda2bf9683d7f4c · 2026-05-28 10:59:45 -0700 · Steve Abrams
Files touched
Diff
commit f538318ac4daa1b1c14ce26f2cda2bf9683d7f4c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu May 28 10:59:45 2026 -0700
/design/:id 'Sell on Etsy' button — go one-click force-add by default (design-page = deliberate admin intent; gate becomes advisory). Surface scores in success status if seams > 12 so the admin sees the warning without being blocked. Curator bulk actions keep the eligibility gate
---
server.js | 67 +++++++++++++++++++--------------------------------------------
1 file changed, 20 insertions(+), 47 deletions(-)
diff --git a/server.js b/server.js
index 1fe23e1..e270c44 100644
--- a/server.js
+++ b/server.js
@@ -10804,63 +10804,36 @@ try {
else setStatus('smart-fix failed: ' + (j.error || j.reason || r.status), 'err');
});
onClick('atb-etsy', async function(b){
- if (!confirm('Queue #' + b.dataset.id + ' in wallco_etsy_bucket (runs a seam scan first — ~30-60s)? Does NOT create a live Etsy listing.')) return;
- // The eligibility scan takes ~30-60s. Give a heartbeat so the UI doesn't
- // look frozen. The disabled-overlay above already gates clicks.
- setStatus('🔍 Running seam scan… (~30-60s)');
+ // From the design page, the admin has DELIBERATELY picked this design to
+ // sell on Etsy. The seam gate is advisory here, not gating — digital
+ // downloads have a lower quality bar than wall printing and we shouldn't
+ // make the admin click twice for an action they already chose. We pass
+ // force:true on the first call; if the eligibility scan reveals issues,
+ // they get surfaced in the success status (transparency) but don't block.
+ // Curator bulk-actions on /admin/cactus-curator KEEP the gate-checking
+ // behavior — different surface, different intent.
+ if (!confirm('Add #' + b.dataset.id + ' to the Etsy bucket? Runs a seam check (~30-60s) but goes through either way. Does NOT create a live Etsy listing yet.')) return;
+ setStatus('🔍 Running seam scan + adding…');
var heartbeat = 0;
var pulse = setInterval(function(){ heartbeat++;
- setStatus('🔍 Running seam scan… ' + heartbeat + 's elapsed'); }, 1000);
+ setStatus('🔍 Running seam scan + adding… ' + heartbeat + 's'); }, 1000);
var _o = location.protocol + '//' + location.host;
- async function callBucket(force){
- return fetch(_o + '/api/etsy-bucket/add', { method:'POST', credentials:'include',
- headers:{'Content-Type':'application/json'},
- body: JSON.stringify({ id: parseInt(b.dataset.id, 10), force: !!force }) });
- }
try {
- var r = await callBucket(false);
+ var r = await fetch(_o + '/api/etsy-bucket/add', { method:'POST', credentials:'include',
+ headers:{'Content-Type':'application/json'},
+ body: JSON.stringify({ id: parseInt(b.dataset.id, 10), force: true }) });
var j = await r.json();
clearInterval(pulse);
if (!(r.ok && j.ok)) { setStatus('etsy queue failed: ' + (j.error || r.status), 'err'); return; }
var first = (j.results && j.results[0]) || {};
- if (first.ok && first.already_in) {
- setStatus('already in bucket (' + first.already_in + ')', 'ok'); return;
- }
- if (first.ok) {
- setStatus('✓ queued · ' + first.target_dpi + ' DPI · ' + first.upscale_px + 'px upscale', 'ok'); return;
- }
- // Eligibility gate held — show the reason + an amber "Sell anyway" override.
- // Digital downloads have a lower quality bar than wall printing, so an
- // imperfect-seam design can still be Etsy-ready when Steve says so.
+ if (first.already_in) { setStatus('already in bucket (' + first.already_in + ')', 'ok'); return; }
+ if (!first.ok) { setStatus('add failed: ' + (first.reason || 'unknown'), 'err'); return; }
var sc = first.scores || {};
- var detail = 'Gate held — ' + (first.reason || 'not eligible');
- if (sc.v_mid != null) detail += ' [v_mid=' + sc.v_mid + ' h_mid=' + sc.h_mid + ' edges=' + sc.edges_max + ']';
- setStatus(detail, 'err');
- // Inject a "Sell anyway" button next to the status line if not already there.
- if (!document.getElementById('atb-etsy-force')) {
- var btn = document.createElement('button');
- btn.id = 'atb-etsy-force';
- btn.type = 'button';
- btn.textContent = '🛒 Sell anyway →';
- btn.style.cssText = 'margin-left:8px;padding:4px 10px;border:1px solid #c98a00;border-radius:5px;background:#3b2e08;color:#f0b400;font:600 11px var(--sans);cursor:pointer;letter-spacing:.04em';
- btn.title = 'Force-add to the Etsy bucket regardless of seam-gate verdict. Digital downloads tolerate imperfect seams better than print.';
- btn.addEventListener('click', async function(){
- btn.disabled = true; setStatus('🔍 Force-adding…');
- try {
- var r2 = await callBucket(true);
- var j2 = await r2.json();
- var first2 = (j2.results && j2.results[0]) || {};
- if (r2.ok && j2.ok && first2.ok) {
- setStatus('✓ force-queued · ' + first2.target_dpi + ' DPI · ' + first2.upscale_px + 'px upscale', 'ok');
- btn.remove();
- } else {
- setStatus('force-add failed: ' + (first2.reason || j2.error || r2.status), 'err');
- btn.disabled = false;
- }
- } catch(e){ setStatus('force-add error: ' + e.message, 'err'); btn.disabled = false; }
- });
- stat.parentNode.insertBefore(btn, stat.nextSibling);
+ var note = '';
+ if (sc.overall_max != null && sc.overall_max > 12) {
+ note = ' · ⚠ seams (v=' + sc.v_mid + ' h=' + sc.h_mid + ' e=' + sc.edges_max + ')';
}
+ setStatus('✓ added · ' + first.target_dpi + ' DPI · ' + first.upscale_px + 'px upscale' + note, 'ok');
} catch(e){ clearInterval(pulse); setStatus('error: ' + e.message, 'err'); }
});
})();
← d9d340a /design/:id admin toolbar: 'Sell on Etsy' button — (1) absol
·
back to Wallco Ai
·
homepage hero: prefer photoreal room-mockup over flat tile w 46eb294 →