← back to Fleet Tv

public/widget/embed.html

190 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fleet TV — Embed Snippet</title>
<style>
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  :root {
    --bg: #07080a; --fg: #e8e6e0; --dim: #6a6862; --accent: #c9a14b;
    --pane: #11141a; --rule: rgba(255,255,255,0.08);
  }
  html, body { background: var(--bg); color: var(--fg); font-family: -apple-system, "Helvetica Neue", "Segoe UI", system-ui, sans-serif; min-height: 100vh; padding: 1.5rem; }
  h1 { font-size: 0.95rem; letter-spacing: 0.18em; text-transform: uppercase; font-weight: 500; margin-bottom: 0.4rem; }
  .crumb { color: var(--dim); font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase; margin-bottom: 2rem; }
  .crumb a { color: var(--dim); text-decoration: none; border-bottom: 1px solid transparent; }
  .crumb a:hover { color: var(--fg); border-color: var(--rule); }

  .layout { display: grid; grid-template-columns: 360px 1fr; gap: 2rem; max-width: 1100px; }

  .preview {
    background: var(--pane); border: 1px solid var(--rule); border-radius: 6px;
    overflow: hidden;
    aspect-ratio: 320/420;
  }
  .preview iframe { width: 100%; height: 100%; border: 0; display: block; }

  .right { display: grid; gap: 1.25rem; }

  .panel {
    background: var(--pane); border: 1px solid var(--rule); border-radius: 6px;
    overflow: hidden;
  }
  .panel header {
    padding: 0.85rem 1.25rem;
    border-bottom: 1px solid var(--rule);
    font-size: 0.78rem; letter-spacing: 0.22em; text-transform: uppercase; font-weight: 500;
  }
  .panel .body { padding: 1rem 1.25rem; }
  .panel .body p { color: var(--dim); font-size: 0.85rem; line-height: 1.5; margin-bottom: 0.5rem; }

  pre {
    background: #0a0c10;
    border: 1px solid var(--rule);
    border-radius: 4px;
    padding: 0.85rem 1rem;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.78rem;
    color: var(--fg);
    overflow-x: auto;
    white-space: pre;
    line-height: 1.5;
  }
  .copy-btn {
    margin-top: 0.5rem;
    background: transparent; color: var(--accent);
    border: 1px solid var(--accent); border-radius: 999px;
    padding: 0.35rem 0.85rem; cursor: pointer;
    font-family: inherit; font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase;
  }
  .copy-btn:hover { background: var(--accent); color: var(--bg); }
  .copy-btn.copied { background: var(--accent); color: var(--bg); }

  .controls {
    display: grid; gap: 0.75rem;
  }
  .controls label {
    display: grid; grid-template-columns: 110px 1fr; gap: 0.85rem; align-items: center;
    font-size: 0.78rem; letter-spacing: 0.04em;
  }
  .controls input {
    background: var(--bg); color: var(--fg); border: 1px solid var(--rule);
    border-radius: 4px; padding: 0.45rem 0.65rem; font-family: inherit;
  }
  .controls input:focus { outline: none; border-color: var(--accent); }
  .hint { color: var(--dim); font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; }
</style>
</head>
<body>

<h1>Fleet TV · Embed Snippet</h1>
<div class="crumb"><a href="/">← wall</a> · <a href="/mosaic.html">mosaic</a> · <a href="/stats.html">stats</a> · <a href="/search.html">search</a> · widget</div>

<div class="layout">

  <div>
    <div class="preview">
      <iframe id="preview-iframe" src="/widget/spotlight.html" referrerpolicy="no-referrer"></iframe>
    </div>
    <div class="hint" style="margin-top:0.75rem;">live preview — rotates every 30s</div>
  </div>

  <div class="right">

    <div class="panel">
      <header>customize</header>
      <div class="body controls">
        <label>width <input id="opt-w" type="text" value="320"></label>
        <label>height <input id="opt-h" type="text" value="420"></label>
        <label>rotate (ms) <input id="opt-r" type="text" value="30000" placeholder="≥ 5000"></label>
        <label>host <input id="opt-host" type="text" value=""></label>
        <p class="hint" style="margin-top:0.25rem;">host = the URL where Fleet TV is reachable. For a local-only widget keep it as 127.0.0.1; for embedding on a public site, expose Fleet TV through your tailnet or a proxy.</p>
      </div>
    </div>

    <div class="panel">
      <header>iframe snippet (paste anywhere)</header>
      <div class="body">
        <pre id="snippet-iframe">—</pre>
        <button class="copy-btn" data-target="snippet-iframe">copy</button>
      </div>
    </div>

    <div class="panel">
      <header>shopify section / liquid</header>
      <div class="body">
        <pre id="snippet-liquid">—</pre>
        <button class="copy-btn" data-target="snippet-liquid">copy</button>
        <p class="hint" style="margin-top:0.5rem;">drop into a Liquid section as a "Featured Cross-Fleet" block.</p>
      </div>
    </div>

    <div class="panel">
      <header>raw JSON endpoint</header>
      <div class="body">
        <pre id="snippet-api">—</pre>
        <button class="copy-btn" data-target="snippet-api">copy</button>
        <p class="hint" style="margin-top:0.5rem;">use this if you want a fully custom card. <code>?count=N</code> returns up to 20 random products.</p>
      </div>
    </div>

  </div>

</div>

<script>
(() => {
  const $ = (id) => document.getElementById(id);
  $('opt-host').value = location.origin;

  function update() {
    const w = ($('opt-w').value || '320').trim();
    const h = ($('opt-h').value || '420').trim();
    const r = ($('opt-r').value || '30000').trim();
    const host = ($('opt-host').value || location.origin).trim().replace(/\/$/, '');
    const src = `${host}/widget/spotlight.html?rotate=${r}`;

    $('snippet-iframe').textContent =
`<iframe src="${src}"
        width="${w}" height="${h}"
        style="border:0;border-radius:6px;overflow:hidden;"
        loading="lazy" referrerpolicy="no-referrer"
        title="Fleet Spotlight"></iframe>`;

    $('snippet-liquid').textContent =
`{%- comment -%} Fleet TV cross-fleet spotlight {%- endcomment -%}
<div class="fleet-spotlight" style="max-width:${w}px;margin:1.5rem auto;">
  <iframe src="${src}"
          width="${w}" height="${h}"
          style="border:0;border-radius:6px;overflow:hidden;display:block;"
          loading="lazy" referrerpolicy="no-referrer"
          title="Featured wallcovering"></iframe>
</div>`;

    $('snippet-api').textContent = `${host}/api/random?count=1`;
    $('preview-iframe').src = `/widget/spotlight.html?rotate=${r}`;
  }

  ['opt-w','opt-h','opt-r','opt-host'].forEach(id => $(id).addEventListener('input', update));

  document.querySelectorAll('.copy-btn').forEach(btn => {
    btn.addEventListener('click', async () => {
      const id = btn.dataset.target;
      const text = $(id).textContent;
      try {
        await navigator.clipboard.writeText(text);
        const original = btn.textContent;
        btn.classList.add('copied');
        btn.textContent = 'copied ✓';
        setTimeout(() => { btn.classList.remove('copied'); btn.textContent = original; }, 1500);
      } catch (e) { alert('clipboard blocked — select & copy manually'); }
    });
  });

  update();
})();
</script>
</body>
</html>