[object Object]

← back to Dw Pitch Followup

pitch: letter panel shows product thumbnails + DW product-page links

9aa4cdcd650a9629cfeb0c7944150f6ed469b447 · 2026-07-14 11:21:53 -0700 · Steve

renderLetterGallery draws a small strip under the letter — 40px thumbnail + link to the DW product page for each referenced sampled item (image/url from dw_unified). Shown on panel open. 476/600 list1 clients have images.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 9aa4cdcd650a9629cfeb0c7944150f6ed469b447
Author: Steve <steve@designerwallcoverings.com>
Date:   Tue Jul 14 11:21:53 2026 -0700

    pitch: letter panel shows product thumbnails + DW product-page links
    
    renderLetterGallery draws a small strip under the letter — 40px thumbnail + link to the DW product page for each referenced sampled item (image/url from dw_unified). Shown on panel open. 476/600 list1 clients have images.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 public/index.html | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/public/index.html b/public/index.html
index 1a45db8..0e9aab8 100644
--- a/public/index.html
+++ b/public/index.html
@@ -33,6 +33,15 @@
   .btn.done:hover{color:var(--green);border-color:var(--green)}
   a.fmlink{color:var(--gold);text-decoration:none;border-bottom:1px dotted color-mix(in srgb,var(--gold) 55%,transparent)}
   a.fmlink:hover{filter:brightness(1.12);border-bottom-style:solid}
+  .pgallery{margin-top:10px;display:flex;flex-direction:column;gap:6px}
+  .pgallery:empty{display:none}
+  .pgallery .pg-h{font-size:11px;color:var(--mut);text-transform:uppercase;letter-spacing:.04em}
+  .pgallery .pg-item{display:flex;align-items:center;gap:9px}
+  .pgallery img{width:40px;height:40px;object-fit:cover;border-radius:6px;border:1px solid var(--line);flex:0 0 auto}
+  .pgallery .pg-ph{width:40px;height:40px;border-radius:6px;background:#2a251e;flex:0 0 auto}
+  .pgallery a{color:var(--gold);text-decoration:none;font-size:13px}
+  .pgallery a:hover{text-decoration:underline}
+  .pgallery .pg-name{font-size:13px;color:var(--ink)}
   .reorder-note{color:var(--red);font-weight:600;margin:6px 0}
   .spacer{flex:1}
   .selcount{color:var(--gold);font-size:13px}
@@ -154,6 +163,7 @@
     <div class="subj" id="pSubj"></div>
     <div class="ctxnote" id="pNote"></div>
     <textarea id="pBody" spellcheck="false" placeholder="Click “Generate letter” to compose a follow-up grounded in this client’s history…"></textarea>
+    <div id="pGallery" class="pgallery"></div>
     <div style="margin-top:6px"><span class="sendstat" id="pSendStat"></span><span class="meta" id="pVariant"></span></div>
   </div>
 </aside>
@@ -402,9 +412,24 @@ function openPanelFor(card,{generate=false}={}){
   const reorder=needsReorder(r); const pGen=document.getElementById('pGen'); pGen.disabled=reorder;
   if(reorder){ document.getElementById('pSubj').innerHTML='<span class="reorder-note">Reorder Samples?? — nothing has shipped yet, so there’s nothing to follow up on.</span>'; }
   openPanel();
+  renderLetterGallery(r);
   if(list!=='list3') loadLastCorr(r);
   if(generate && !reorder) composeLetter({});
 }
+// Small product strip under the letter: thumbnail + link to the DW product page for each
+// product the letter references (the client's sampled items carry image + url from dw_unified).
+function renderLetterGallery(r){
+  const el=document.getElementById('pGallery'); if(!el)return;
+  const items=(Array.isArray(r.samples_sent)?r.samples_sent:[]).filter(s=>s&&(s.image||s.url));
+  if(!items.length){el.innerHTML='';return;}
+  el.innerHTML=`<div class="pg-h">Products referenced — thumbnail + DW product page</div>`+
+    items.slice(0,12).map(s=>{
+      const nm=esc(lbl(s.label||s.sku||'sample'));
+      const img=s.image?`<img src="${esc(s.image)}" alt="" loading="lazy">`:`<span class="pg-ph"></span>`;
+      const name=s.url?`<a href="${esc(s.url)}" target="_blank" rel="noopener noreferrer">${nm} ↗</a>`:`<span class="pg-name">${nm}</span>`;
+      return `<div class="pg-item">${img}${name}</div>`;
+    }).join('');
+}
 
 async function loadLastCorr(r){
   const wrap=document.querySelector('#pCtx [data-lastcorr]'); const span=document.querySelector('#pCtx [data-lc]');

← c6994a4 pitch: list2 letter follows up on the specific QUOTE (number  ·  back to Dw Pitch Followup  ·  5x: 2 clean sweeps (7/7 six-way + 51 controls, 0 defects) af 71574cf →