← back to Pattern Vault

public/setup.html

102 lines

<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Pattern Vault — Setup Guide</title>
<style>
:root{--bg:#0d0b10;--card:#17141d;--ink:#efe9f7;--mut:#9a8fb0;--gold:#d4af6a;--line:#2a2436;--ok:#6fcf8f;--warn:#e0a458}
*{box-sizing:border-box;margin:0}
body{background:var(--bg);color:var(--ink);font:15px/1.6 "Avenir Next",system-ui,sans-serif;padding-bottom:80px}
header{padding:48px 6vw 24px;text-align:center;border-bottom:1px solid var(--line)}
h1{font-size:clamp(24px,4vw,42px);font-weight:600;letter-spacing:.12em;text-transform:uppercase}
h1 em{color:var(--gold);font-style:normal}
.tag{color:var(--mut);font-style:italic;margin-top:8px}
main{max-width:820px;margin:0 auto;padding:0 6vw}
.status{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;padding:22px 0}
.pill{padding:6px 16px;border-radius:99px;border:1px solid var(--line);font-size:13px;letter-spacing:.04em}
.pill.on{border-color:var(--ok);color:var(--ok)}
.pill.off{border-color:var(--warn);color:var(--warn)}
section{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:26px 28px;margin:22px 0}
section.done{border-color:var(--ok)}
h2{font-size:17px;letter-spacing:.06em;margin-bottom:4px}
h2 .num{color:var(--gold);margin-right:8px}
.why{color:var(--mut);font-size:13.5px;margin-bottom:14px}
ol{padding-left:22px;display:grid;gap:9px}
li strong{color:var(--gold);font-weight:600}
code,pre{background:var(--bg);border:1px solid var(--line);border-radius:6px;font:13px/1.5 ui-monospace,Menlo,monospace}
code{padding:2px 7px}
pre{padding:12px 14px;margin:6px 0;overflow-x:auto;position:relative}
.copy{position:absolute;top:8px;right:8px;background:transparent;border:1px solid var(--line);color:var(--mut);border-radius:6px;padding:3px 10px;font-size:11px;cursor:pointer}
.copy:hover{border-color:var(--gold);color:var(--gold)}
a{color:var(--gold)}
.gate{display:inline-block;margin-left:8px;padding:2px 10px;border:1px solid var(--warn);border-radius:99px;color:var(--warn);font-size:11px;letter-spacing:.06em;vertical-align:middle}
.check{float:right;font-size:20px}
.mut{color:var(--mut)}
footer{text-align:center;color:var(--mut);font-size:13px;margin-top:36px}
</style></head><body>
<header>
  <h1>Vault <em>Setup</em> Guide</h1>
  <div class="tag">Three switches stand between here and selling licenses — all yours to flip</div>
</header>
<main>
  <div class="status" id="status"><span class="pill">checking status…</span></div>

  <section id="secStripe">
    <h2><span class="num">1</span>Turn on TEST-mode checkout <span class="check" id="chkStripe"></span></h2>
    <div class="why">Right now clicking a license tier only records an <em>inquiry</em>. With a Stripe <strong>test</strong> key installed, the same click opens a real Stripe checkout page in TEST mode — no real money can move. The server refuses live keys outright.</div>
    <ol>
      <li><strong>Use a NEW Stripe account for Pattern Vault</strong> — not the DW live account (standing rail). Create one at <a href="https://dashboard.stripe.com/register" target="_blank" rel="noopener noreferrer">dashboard.stripe.com/register</a> if it doesn't exist yet, then open <a href="https://dashboard.stripe.com/test/apikeys" target="_blank" rel="noopener noreferrer">dashboard.stripe.com/test/apikeys</a>.</li>
      <li>Make sure the <strong>Test mode</strong> toggle in the top-right of the Stripe dashboard is <strong>ON</strong> (orange).</li>
      <li>Under <strong>Standard keys</strong>, find <strong>Secret key</strong> and click <strong>Reveal test key</strong>. It starts with <code>sk_test_</code>.</li>
      <li>Copy it, then either <strong>paste it to Claude</strong> in any session (it gets routed via the secrets skill automatically), or add it by hand:
        <pre><button class="copy">copy</button>echo 'STRIPE_SECRET_KEY=sk_test_PASTE_KEY_HERE' >> ~/Projects/pattern-vault/.env</pre></li>
      <li>Restart the app:
        <pre><button class="copy">copy</button>pm2 restart pattern-vault</pre></li>
      <li>Reload this page — the badge above should flip to <strong>checkout: TEST mode</strong>. Try a purchase with Stripe's test card <code>4242 4242 4242 4242</code>, any future date, any CVC.</li>
    </ol>
  </section>

  <section id="secPublic">
    <h2><span class="num">2</span>Open the vault to the public <span class="check" id="chkPublic"></span></h2>
    <div class="why">The whole site sits behind Basic Auth (<code>admin / DW2024!</code>) until you flip this. Flip it only when the catalog and checkout look right to you.</div>
    <ol>
      <li>Add the switch to the env file:
        <pre><button class="copy">copy</button>echo 'PUBLIC_VAULT=1' >> ~/Projects/pattern-vault/.env</pre></li>
      <li>Restart:
        <pre><button class="copy">copy</button>pm2 restart pattern-vault</pre></li>
      <li>Open <a href="/">the storefront</a> in a private/incognito window — it should load with <strong>no password prompt</strong>. (This setup page stays password-protected either way.)</li>
      <li class="mut">To close it again, change the line to <code>PUBLIC_VAULT=0</code> and restart.</li>
    </ol>
  </section>

  <section id="secKits">
    <h2><span class="num">3</span>Marketplace uploads <span class="gate">STEVE-GATED</span></h2>
    <div class="why">Ready-to-upload listing kits already exist for three marketplaces — titles, descriptions, tags, and preview images for all 24 designs. Nothing uploads until you create the accounts and say go.</div>
    <ol>
      <li>The kits live in <code>~/Projects/pattern-vault/kits/</code> — one folder each for <strong>Spoonflower</strong>, <strong>Etsy</strong>, and <strong>Creative Market</strong>, each with a <code>listings.csv</code>.</li>
      <li>Preview images are in <code>kits/_images/</code> (web-res). The real masters — 150-DPI print-clean tiles — live on Kamatera prod; pulling those down is a separate gated step, done at upload time.</li>
      <li>When you want to proceed: create the marketplace account(s), then tell Claude <em>"upload the &lt;marketplace&gt; kit"</em> — the approval memo is at <code>pending-approval/abramsego-golive-260701.md §5</code>.</li>
    </ol>
  </section>

  <footer>Live status refreshes on page load from <code>/api/config</code> · <a href="/">← back to the vault</a></footer>
</main>
<script>
document.querySelectorAll('.copy').forEach(b=>b.onclick=()=>{
  navigator.clipboard.writeText(b.parentElement.textContent.replace('copy','').trim());
  b.textContent='copied!';setTimeout(()=>b.textContent='copy',1400)});
(async()=>{
  try{
    const c=await(await fetch('/api/config')).json();
    const pills=[
      `<span class="pill ${c.checkoutReady?'on':'off'}">checkout: ${c.checkoutReady?'TEST mode ✓':'inquiries only — needs test key'}</span>`,
      `<span class="pill ${c.publicVault?'on':'off'}">vault: ${c.publicVault?'PUBLIC ✓':'private (Basic Auth)'}</span>`,
      `<span class="pill off">marketplaces: kits ready — gated</span>`];
    document.getElementById('status').innerHTML=pills.join('');
    document.getElementById('chkStripe').textContent=c.checkoutReady?'✅':'⬜';
    document.getElementById('chkPublic').textContent=c.publicVault?'✅':'⬜';
    if(c.checkoutReady)document.getElementById('secStripe').classList.add('done');
    if(c.publicVault)document.getElementById('secPublic').classList.add('done');
  }catch(e){document.getElementById('status').innerHTML='<span class="pill off">status unavailable — is the server running?</span>'}
})();
</script></body></html>