attachments.js
campaigns.js
gmail-accounts.js
index.js
login.js
logs.js
phones.js
recipients.js
saved-templates.js
send-test.js
settings.js
subjects.js
suppression.js
templates.js
---SAVED-TEMPLATES---
window.pageBoot = async (me) => {
  let all = [];
  let q = "", src = "";

  async function load() {
    let d;
    try { d = await GET("/templates/list"); }
    catch (e) { $("#gal").innerHTML = `<div class="notice err" style="grid-column:1/-1"><span class="n-ico">✕</span><div>${esc(e.message)}</div></div>`; return; }
    all = d.templates || [];
    render();
  }

  function matches(t) {
    if (src && (t.source || "") !== src) return false;
    if (q && !((t.name || "") + " " + (t.subject_hint || "")).toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  }

  function thumb(t) {
    // fetch the rendered body lazily? /templates/{id} returns full row; too heavy for all cards.
    // Use a neutral placeholder frame with size info instead of iframe spam.
    return `<div class="tframe" style="display:grid;place-items:center;color:var(--muted);font-size:12px">
      <div style="text-align:center">${fmtBytes(t.size_html)}<br><span style="font-size:11px">HTML body</span></div></div>`;
  }

  function render() {
    const rows = all.filter(matches);
    $("#countLbl").textContent = `${rows.length} of ${all.length} template(s)`;
    if (!rows.length) {
      $("#gal").innerHTML = `<div class="empty-state" style="grid-column:1/-1"><div class="e-ico">❑</div>
        <p>${all.length ? "No templates match the filters." : "No saved templates yet. Create or upload templates on the HTML Templates page."}</p></div>`;
      return;
    }
    $("#gal").innerHTML = rows.map(t => `
      <div class="tcard" data-id="${t.id}">
        <div class="tc-hd">
          <div class="flex-between">
            <h3>${esc(t.name)}</h3>
            <span class="src-badge">${esc(t.source || "—")}</span>
          </div>
---RECIPIENTS CLEARALL---
static/js/pages/recipients.js:21:            <button class="btn xs warn" data-clear="${l.id}">Clear</button>
static/js/pages/recipients.js:180:    const id = +(b.dataset.view || b.dataset.import || b.dataset.clear || b.dataset.del);
static/js/pages/recipients.js:183:    if (b.dataset.clear) confirmedAction("Remove ALL recipients from this list? The list itself is kept.", async () => {
static/js/pages/recipients.js:184:      await POST(`/recipients/lists/${id}/clear`); toast("List cleared", "ok"); await loadLists(); if (state.cur) await loadRecs();
