← back to Claude Webdev Accelerator

templates/public/index.html

56 lines

<!doctype html><html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1"><title>Storefront starter</title>
<style>
  :root{--cols:4}
  *{box-sizing:border-box} body{margin:0;font:15px/1.4 -apple-system,Segoe UI,Roboto,sans-serif;color:#1a1a1a;background:#fafafa}
  header{display:flex;gap:14px;align-items:center;flex-wrap:wrap;padding:14px 20px;border-bottom:1px solid #e6e6e6;position:sticky;top:0;background:#fff;z-index:5}
  h1{font-size:17px;margin:0;font-weight:700} .spacer{flex:1}
  label{font-size:12px;color:#666;display:flex;gap:6px;align-items:center}
  select,input[type=range]{font:inherit} .count{font-size:12px;color:#999}
  .grid{display:grid;grid-template-columns:repeat(var(--cols),1fr);gap:14px;padding:20px}
  .card{background:#fff;border:1px solid #e6e6e6;border-radius:8px;overflow:hidden}
  .card img{width:100%;aspect-ratio:1/1;object-fit:cover;display:block;background:#f0f0f0}
  .meta{padding:8px 10px} .t{font-size:13px;font-weight:600;margin:0 0 2px} .s{font-size:11px;color:#888}
  .p{font-size:13px;margin-top:4px} .empty{padding:40px;color:#999;text-align:center}
</style></head><body>
<header>
  <h1>Storefront starter</h1>
  <label>Sort
    <select id="sort">
      <option value="newest">Newest</option>
      <option value="title">Title A→Z</option>
      <option value="sku">SKU A→Z</option>
      <option value="price-asc">Price ↑</option>
      <option value="price-desc">Price ↓</option>
      <option value="light">Light → Dark</option>
      <option value="dark">Dark → Light</option>
    </select>
  </label>
  <label>Density <input id="density" type="range" min="2" max="8" value="4"></label>
  <span class="spacer"></span><span class="count" id="count"></span>
</header>
<div class="grid" id="grid"><div class="empty">Loading…</div></div>
<script>
// House rule: sort + density both persist in localStorage so the choice survives reloads.
const $=s=>document.querySelector(s), esc=s=>(s||'').replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));
const sortSel=$('#sort'), dens=$('#density');
sortSel.value=localStorage.getItem('sort')||'newest'; dens.value=localStorage.getItem('cols')||'4';
function applyCols(){document.documentElement.style.setProperty('--cols',dens.value);localStorage.setItem('cols',dens.value);}
applyCols();
async function load(){
  const r=await fetch('/api/products?sort='+encodeURIComponent(sortSel.value)); const d=await r.json();
  $('#count').textContent=d.count+' items';
  $('#grid').innerHTML = d.products.length ? d.products.map(p=>`
    <div class="card">
      <img src="${esc(p.image||'')}" alt="${esc(p.title||'')}" loading="lazy">
      <div class="meta"><p class="t">${esc(p.title||'Untitled')}</p>
        <div class="s">${esc(p.sku||p.handle||'')}</div>
        ${p.price?`<div class="p">$${Number(p.price).toFixed(2)}</div>`:''}
      </div>
    </div>`).join('') : '<div class="empty">No products yet — fill data/products.json.</div>';
}
sortSel.onchange=()=>{localStorage.setItem('sort',sortSel.value);load();};
dens.oninput=applyCols;
load();
</script></body></html>