← back to Small Business Builder

src/render/templates/_helpers.js

60 lines

import { esc, safeColor } from '../../lib/escape.js';

export function pickColors(b) {
  return {
    primary: safeColor(b.color_primary, '#1f2937'),
    accent: safeColor(b.color_accent, '#d97706'),
    bg: '#ffffff',
    fg: '#0b0b0b',
  };
}

export function safeHero(b) {
  return b.hero_image_url ||
    `https://images.weserv.nl/?url=&w=1600&h=900&t=letterbox&bg=${encodeURIComponent(safeColor(b.color_primary, '#1f2937').replace('#',''))}` ||
    '';
}

export function placeholderHero(b, label) {
  // Inline SVG hero — never breaks, no external image needed
  const c = pickColors(b);
  const text = esc(label || b.name || 'Your Salon');
  return `data:image/svg+xml;utf8,` + encodeURIComponent(
    `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1600 900'>
      <defs><linearGradient id='g' x1='0' x2='1' y1='0' y2='1'>
        <stop offset='0%' stop-color='${safeColor(c.primary, '#1f2937')}'/><stop offset='100%' stop-color='${safeColor(c.accent, '#d97706')}'/>
      </linearGradient></defs>
      <rect width='1600' height='900' fill='url(#g)'/>
      <text x='800' y='470' text-anchor='middle' font-family='Georgia, serif' font-size='90' fill='white' opacity='0.9'>${text}</text>
    </svg>`
  );
}

export function shell(title, bodyHtml, b) {
  const c = pickColors(b);
  return `<!doctype html>
<html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>${esc(title)}</title>
<style>
  :root{--p:${c.primary};--a:${c.accent};--bg:${c.bg};--fg:${c.fg}}
  *{box-sizing:border-box}
  html,body{margin:0;padding:0;background:var(--bg);color:var(--fg);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}
  a{color:var(--a)}
  .wrap{max-width:1200px;margin:0 auto;padding:0 20px}
  .btn{display:inline-block;padding:12px 22px;border-radius:6px;background:var(--a);color:#fff;text-decoration:none;font-weight:600}
  .btn.ghost{background:transparent;border:2px solid currentColor;color:var(--fg)}
</style>
</head><body>
${bodyHtml}
</body></html>`;
}

export function brandStrip(b) {
  if (b.tier === 'plus' || b.tier === 'premium') return '';
  return `<div style="background:#111;color:#fff;padding:8px 12px;text-align:center;font-size:12px;letter-spacing:.3px">
    Built free with <a href="/" style="color:#fff;font-weight:600">Small-Business Builder</a> — upgrade to Plus to remove this strip.
  </div>`;
}