[object Object]

← back to Marketing Command Center

make quick post asset picking simpler

3a9133d94830f209de27769a4fc90c09702bc625 · 2026-08-28 09:08:35 -0700 · Steve

Files touched

Diff

commit 3a9133d94830f209de27769a4fc90c09702bc625
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Aug 28 09:08:35 2026 -0700

    make quick post asset picking simpler
---
 public/panels/quickpost.html |  2 ++
 public/panels/quickpost.js   | 15 ++++++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/public/panels/quickpost.html b/public/panels/quickpost.html
index e6f0455..d7edb98 100644
--- a/public/panels/quickpost.html
+++ b/public/panels/quickpost.html
@@ -9,6 +9,7 @@
   <main class="kp-card">
     <section class="kp-pane on" data-step="1">
       <div class="kp-number">1</div><div class="kp-copy"><h3>Pick a picture or video</h3><p>Tap one you like. Every DW post needs a picture or video.</p></div>
+      <div class="kp-asset-tools"><div class="kp-filter" role="group" aria-label="Picture choices"><button type="button" class="on" data-filter="all">✨ All ideas</button><button type="button" data-filter="catalog">🏷️ DW picks</button><button type="button" data-filter="upload">📤 My uploads</button></div><input id="kp-asset-search" type="search" placeholder="🔎 Find a color or room" aria-label="Find a picture"></div>
       <div id="kp-assets" class="kp-assets" aria-live="polite"><div class="kp-wait">Loading your pictures…</div></div>
       <details class="kp-more"><summary>Paste a picture link instead</summary><input id="kp-media" type="url" placeholder="https://…/picture.jpg" autocomplete="off"></details>
     </section>
@@ -36,6 +37,7 @@
 .kidpost{--navy:#172235;--paper:#fffdf7;--sun:#f6c84c;--green:#287a55;--coral:#df684f;max-width:1120px;margin:0 auto;color:var(--navy);font-family:"Avenir Next",Avenir,"Trebuchet MS",sans-serif}.kp-hero{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;padding:24px 28px;background:var(--navy);color:#fff;border-radius:24px 24px 0 0;box-shadow:0 18px 45px rgba(23,34,53,.14)}.kp-kicker{font-size:12px;font-weight:800;letter-spacing:.16em;color:var(--sun)}.kp-hero h2{font:700 clamp(28px,4vw,48px)/1.02 "Cormorant Garamond",Georgia,serif;margin:7px 0}.kp-hero p{margin:0;color:#dce4ef;font-size:16px}.kp-score{background:var(--sun);color:var(--navy);border-radius:18px;padding:12px 17px;text-align:center;min-width:94px}.kp-score b{display:block;font-size:20px}.kp-score span{font-size:11px;font-weight:700}
 .kp-steps{display:grid;grid-template-columns:repeat(5,1fr);background:#edf0f3;padding:12px;gap:8px}.kp-step{border:0;background:transparent;padding:9px 4px;border-radius:14px;color:#6c7480;cursor:pointer}.kp-step span{display:grid;place-items:center;width:34px;height:34px;margin:0 auto 5px;border:2px solid #aab1ba;border-radius:50%;font-weight:800}.kp-step b{font-size:12px}.kp-step.on{background:#fff;color:var(--navy);box-shadow:0 4px 14px rgba(23,34,53,.09)}.kp-step.on span,.kp-step.done span{border-color:var(--green);background:var(--green);color:#fff}.kp-card{background:var(--paper);border:1px solid #e0ddd2;border-top:0;border-radius:0 0 24px 24px;box-shadow:0 18px 45px rgba(23,34,53,.14);overflow:hidden}.kp-pane{padding:30px;min-height:390px}.kp-number{float:left;display:grid;place-items:center;width:48px;height:48px;border-radius:16px;background:var(--sun);font-size:24px;font-weight:900;margin-right:14px}.kp-copy{min-height:58px}.kp-copy h3{font:700 28px/1.1 "Cormorant Garamond",Georgia,serif;margin:0 0 5px}.kp-copy p{margin:0;color:#667080;font-size:15px}
 .kp-assets{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:12px;margin-top:22px;max-height:360px;overflow:auto;padding:4px}.kp-asset{position:relative;aspect-ratio:1;border:3px solid transparent;border-radius:16px;overflow:hidden;background:#ece8de;cursor:pointer;padding:0}.kp-asset img{width:100%;height:100%;object-fit:cover}.kp-asset.on{border-color:var(--green);box-shadow:0 0 0 3px #c8ead9}.kp-asset.on:after{content:'✓';position:absolute;right:7px;top:7px;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--green);color:#fff;font-weight:900}.kp-more{margin-top:18px;color:#5c6570}.kp-more summary{cursor:pointer;font-weight:700}.kp-more input,.kp-prompt input,#kp-caption,#kp-account{width:100%;box-sizing:border-box;margin-top:9px;border:2px solid #d7d9dc;border-radius:13px;padding:12px 14px;font:inherit;background:#fff}.kp-more input:focus,.kp-prompt input:focus,#kp-caption:focus,#kp-account:focus{outline:3px solid #f8dfa0;border-color:#c99927}
+.kp-asset-tools{display:flex;gap:10px;align-items:center;margin-top:20px;flex-wrap:wrap}.kp-filter{display:flex;gap:6px;flex-wrap:wrap}.kp-filter button{border:1px solid #dadddf;background:#fff;border-radius:999px;padding:8px 11px;font:700 12px inherit;cursor:pointer}.kp-filter button.on{background:var(--navy);border-color:var(--navy);color:#fff}.kp-asset-tools input{flex:1;min-width:180px;border:2px solid #d7d9dc;border-radius:999px;padding:9px 13px;font:inherit}
 .kp-choices,.kp-channels{display:grid;grid-template-columns:repeat(auto-fill,minmax(205px,1fr));gap:12px;margin-top:22px}.kp-choice,.kp-channel{min-height:86px;text-align:left;border:2px solid #dadddf;background:#fff;border-radius:16px;padding:14px;cursor:pointer;color:var(--navy);font:inherit}.kp-choice b,.kp-channel b{display:block;font-size:15px;margin-bottom:4px}.kp-choice small,.kp-channel small{display:block;color:#6b7480;line-height:1.35}.kp-choice.on,.kp-channel.on{border-color:var(--green);background:#ecf8f1;box-shadow:0 0 0 2px #c8ead9}.kp-channel.off{opacity:.48;cursor:not-allowed}.kp-label{display:block;margin-top:20px;font-weight:800;font-size:14px}.kp-prompt{display:flex;gap:10px}.kp-prompt input{margin:9px 0 0}.kp-prompt button,#kp-all,#kp-none{border:0;border-radius:12px;padding:12px 16px;font-weight:800;cursor:pointer;white-space:nowrap}.kp-prompt button{margin-top:9px;background:var(--sun);color:var(--navy)}
 .kp-suggestions{display:grid;gap:9px;margin-top:14px}.kp-suggestion{border:2px solid #dadddf;background:#fff;border-radius:14px;padding:12px 14px;text-align:left;cursor:pointer;font:inherit;line-height:1.45}.kp-suggestion:hover{border-color:#c99927;background:#fffaec}.kp-suggestion:before{content:'Use this';display:block;color:var(--green);font-size:11px;font-weight:900;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px}#kp-caption{min-height:130px;resize:vertical}.kp-count{text-align:right;color:#707987;font-size:12px;margin-top:4px}.kp-allrow{display:flex;gap:9px;margin-top:20px}#kp-all{background:var(--navy);color:#fff}#kp-none{background:#e9ecef;color:var(--navy)}
 .kp-review{display:grid;grid-template-columns:190px 1fr;gap:20px;margin-top:22px;border:2px solid #dadddf;border-radius:18px;padding:16px;background:#fff}.kp-preview{aspect-ratio:1;border-radius:13px;overflow:hidden;background:#ece8de}.kp-preview img,.kp-preview video{width:100%;height:100%;object-fit:cover}.kp-summary h4{margin:2px 0 5px;font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:#75808c}.kp-summary p{white-space:pre-wrap;line-height:1.5;margin:0 0 14px}.kp-tags{display:flex;gap:7px;flex-wrap:wrap}.kp-tag{background:#edf1f4;border-radius:999px;padding:6px 10px;font-size:12px;font-weight:700}.kp-confirm{display:flex;gap:12px;align-items:flex-start;background:#fff5d5;border:2px solid #efd06f;border-radius:15px;padding:14px;margin-top:17px;font-weight:700;line-height:1.4}.kp-confirm input{width:22px;height:22px;flex:none}.kp-publish,.kp-draft{width:100%;border:0;border-radius:14px;padding:15px;margin-top:12px;font:800 17px/1 inherit;cursor:pointer}.kp-publish{background:var(--green);color:#fff}.kp-publish:disabled{background:#aeb6b1;cursor:not-allowed}.kp-draft{background:#e9ecef;color:var(--navy)}.kp-result{margin-top:12px;font-weight:700;line-height:1.45}.kp-result.ok{color:var(--green)}.kp-result.bad{color:#a33c2f}.kp-nav{display:flex;justify-content:space-between;border-top:1px solid #e3e1d9;padding:16px 30px;background:#fff}.kp-nav button{border:0;border-radius:12px;padding:12px 18px;font-weight:800;cursor:pointer}.kp-nav button:disabled{opacity:.35}.kp-nav #kp-next{background:var(--coral);color:#fff}.kp-wait{grid-column:1/-1;padding:28px;text-align:center;color:#68717c}.kp-error{background:#fff0eb;color:#923f32;border-radius:12px;padding:12px;margin-top:12px}
diff --git a/public/panels/quickpost.js b/public/panels/quickpost.js
index f001293..8c4418a 100644
--- a/public/panels/quickpost.js
+++ b/public/panels/quickpost.js
@@ -9,6 +9,7 @@ window.MCC_PANELS.quickpost = {
     const esc = s => String(s == null ? '' : s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
     const icons = {facebook:'📘',instagram:'📸',bluesky:'🦋',linkedin:'💼',tiktok:'🎵',youtube:'▶️',threads:'🧵'};
     const state = { step:1, mediaUrl:'', song:null, channels:[], targets:[], status:{} };
+    let allAssets = [];
     const names = ['','Picture','Music','Words','Where','Check'];
 
     function note(step, msg) {
@@ -40,11 +41,19 @@ window.MCC_PANELS.quickpost = {
     async function loadAssets() {
       try {
         const d = await fetch(O + '/api/assets/list', {credentials:'same-origin'}).then(r => r.json());
-        const assets = (d.assets || []).filter(a => a.src).slice(0, 48);
-        $('#kp-assets').innerHTML = assets.length ? assets.map((a,i) => `<button class="kp-asset" type="button" data-url="${esc(new URL(a.src, O).href)}" aria-label="Choose ${esc(a.name || 'picture '+(i+1))}"><img loading="lazy" src="${esc(a.src)}" alt="${esc(a.name || 'Wallpaper picture')}"></button>`).join('') : '<div class="kp-wait">No saved pictures yet. Paste a picture link below.</div>';
-        $$('.kp-asset').forEach(b => b.onclick = () => { $$('.kp-asset').forEach(x => x.classList.remove('on')); b.classList.add('on'); state.mediaUrl = b.dataset.url; $('#kp-media').value = state.mediaUrl; });
+        allAssets = (d.assets || []).filter(a => a.src);
+        renderAssets();
       } catch (_) { $('#kp-assets').innerHTML = '<div class="kp-error">Pictures could not load. Paste a picture link below.</div>'; }
     }
+    function renderAssets() {
+      const filter = root.querySelector('.kp-filter button.on')?.dataset.filter || 'all';
+      const q = ($('#kp-asset-search')?.value || '').trim().toLowerCase();
+      const assets = allAssets.filter(a => (filter === 'all' || String(a.kind || '').toLowerCase() === filter) && (!q || `${a.name || ''} ${(a.tags || []).join(' ')} ${JSON.stringify(a.aiTags || {})}`.toLowerCase().includes(q))).slice(0, 120);
+      $('#kp-assets').innerHTML = assets.length ? assets.map((a,i) => `<button class="kp-asset" type="button" data-url="${esc(new URL(a.src, O).href)}" aria-label="Choose ${esc(a.name || 'picture '+(i+1))}"><img loading="lazy" src="${esc(a.src)}" alt="${esc(a.name || 'Wallpaper picture')}"></button>`).join('') : '<div class="kp-wait">No matching pictures yet. Try another word or paste a link below.</div>';
+      $$('.kp-asset').forEach(b => b.onclick = () => { $$('.kp-asset').forEach(x => x.classList.remove('on')); b.classList.add('on'); state.mediaUrl = b.dataset.url; $('#kp-media').value = state.mediaUrl; });
+    }
+    $$('.kp-filter button').forEach(b => b.onclick = () => { $$('.kp-filter button').forEach(x => x.classList.remove('on')); b.classList.add('on'); renderAssets(); });
+    $('#kp-asset-search').addEventListener('input', renderAssets);
     $('#kp-media').addEventListener('input', e => { state.mediaUrl = e.target.value.trim(); $$('.kp-asset').forEach(x => x.classList.toggle('on', x.dataset.url === state.mediaUrl)); });
 
     async function loadMusic() {

← a34711a snapshot before MCC click-through debug  ·  back to Marketing Command Center  ·  simplify MCC navigation and expand quick post assets 8cbe82e →