← back to Permit Radar

public/permit.html

297 lines

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Permit Detail — Permit Radar</title>
<style>
:root { --accent: #1d4ed8; --accent-light: #eff6ff; }
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 15px/1.5 -apple-system, Segoe UI, Roboto, sans-serif; color: #1a1a1a; background: #f3f4f6; }

.sample-banner { background: #fef3c7; border-bottom: 2px solid #f59e0b; padding: 8px 20px; font-size: 13px; text-align: center; color: #78350f; }
nav { background: #1e293b; color: #fff; padding: 12px 20px; display: flex; align-items: center; gap: 16px; }
.logo { font-size: 18px; font-weight: 800; color: #fff; text-decoration: none; }
.logo span { color: #60a5fa; }
.nav-links { margin-left: auto; display: flex; gap: 16px; }
.nav-links a { color: #cbd5e1; font-size: 13px; text-decoration: none; }
.nav-links a:hover { color: #fff; }

.container { max-width: 800px; margin: 32px auto; padding: 0 20px 40px; }
.back-link { font-size: 13px; color: var(--accent); text-decoration: none; margin-bottom: 16px; display: inline-block; }
.back-link:hover { text-decoration: underline; }

.permit-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 12px; overflow: hidden; }
.permit-header { background: linear-gradient(135deg, #1e293b 0%, #1d4ed8 100%); color: #fff; padding: 28px; }
.permit-header-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.permit-id-label { font-size: 12px; color: #93c5fd; font-weight: 600; letter-spacing: .5px; margin-bottom: 4px; }
.permit-address-h { font-size: 22px; font-weight: 800; margin: 0 0 2px; }
.permit-location { font-size: 14px; color: #bfdbfe; }
.status-chip { font-size: 12px; font-weight: 700; padding: 4px 12px; border-radius: 99px; white-space: nowrap; margin-top: 4px; }
.status-approved { background: #dcfce7; color: #15803d; }
.status-pending   { background: #fef9c3; color: #854d0e; }

.permit-body { padding: 28px; }
.section-title { font-size: 11px; font-weight: 700; color: #94a3b8; letter-spacing: 1px; text-transform: uppercase; margin: 0 0 12px; }
.fields-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 24px; }
.field { }
.field-label { font-size: 11px; color: #94a3b8; font-weight: 600; margin-bottom: 2px; }
.field-value { font-size: 15px; font-weight: 600; color: #1e293b; }
.field-value.big { font-size: 20px; color: #15803d; }
.permit-desc { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; font-size: 14px; color: #374151; line-height: 1.6; margin-bottom: 24px; }

.cta-box { background: var(--accent-light); border: 1px solid #bfdbfe; border-radius: 10px; padding: 20px; }
.cta-box h3 { font-size: 16px; margin: 0 0 6px; color: #1e40af; }
.cta-box p { font-size: 13px; color: #3b82f6; margin: 0 0 14px; }
.cta-row { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-lead {
  padding: 10px 20px; background: #f59e0b; color: #1a1a1a; border: none;
  border-radius: 8px; font: 700 14px inherit; cursor: pointer;
}
.btn-lead:hover { background: #fbbf24; }
.btn-subscribe {
  padding: 10px 20px; background: var(--accent); color: #fff; border: none;
  border-radius: 8px; font: 700 14px inherit; cursor: pointer; text-decoration: none; display: inline-block;
}
.btn-subscribe:hover { background: #1e40af; }

/* Lead modal */
.modal-bg { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 100; align-items: center; justify-content: center; }
.modal-bg.open { display: flex; }
.modal { background: #fff; border-radius: 12px; padding: 28px; width: 100%; max-width: 420px; margin: 20px; position: relative; }
.modal h3 { margin: 0 0 6px; }
.modal p { color: #64748b; font-size: 13px; margin: 0 0 16px; }
.modal-close { position: absolute; top: 14px; right: 16px; font-size: 20px; cursor: pointer; color: #94a3b8; background: none; border: none; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.form-row.single { grid-template-columns: 1fr; }
label { display: block; font-size: 12px; font-weight: 600; color: #475569; margin-bottom: 4px; }
select, input { width: 100%; padding: 9px 12px; border: 1px solid #d1d5db; border-radius: 6px; font: inherit; font-size: 14px; }
.btn-submit { width: 100%; padding: 12px; background: var(--accent); color: #fff; border: none; border-radius: 8px; font: 700 15px inherit; cursor: pointer; margin-top: 8px; }
.success-msg { background: #dcfce7; color: #15803d; border-radius: 6px; padding: 10px; margin-top: 10px; font-size: 13px; text-align: center; }
.error-msg { background: #fee2e2; color: #991b1b; border-radius: 6px; padding: 10px; margin-top: 10px; font-size: 13px; text-align: center; }
.loading { color: #94a3b8; padding: 60px; text-align: center; }

/* ── SHOPIFY CROSS-SELL (permit detail) ── */
.xsell-strip {
  max-width: 800px; margin: 24px auto 0; padding: 0 20px 40px;
}
.xsell-inner {
  background: #fff; border: 1px solid #e2e8f0; border-radius: 12px; padding: 20px 24px;
}
.xsell-header {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; flex-wrap: wrap;
}
.xsell-label {
  font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  color: #94a3b8; border: 1px solid #e2e8f0; border-radius: 4px; padding: 2px 8px;
}
.xsell-title { font-size: 15px; font-weight: 700; color: #1e293b; margin: 0; }
.xsell-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}
.xsell-card {
  border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden; background: #f8fafc;
  text-decoration: none; color: inherit; display: flex; flex-direction: column;
  transition: box-shadow .15s;
}
.xsell-card:hover { box-shadow: 0 3px 14px rgba(0,0,0,.08); }
.xsell-img-wrap { aspect-ratio: 1; overflow: hidden; background: #e2e8f0; }
.xsell-img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.xsell-info { padding: 7px 9px 9px; flex: 1; }
.xsell-product-title { font-size: 11px; font-weight: 600; color: #1e293b; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.xsell-vendor { font-size: 10px; color: #94a3b8; }
.xsell-price { font-size: 12px; font-weight: 700; color: #15803d; margin-top: 3px; }
.xsell-browse { display: inline-block; margin-top: 12px; font-size: 12px; color: #1d4ed8; font-weight: 600; text-decoration: none; }
.xsell-browse:hover { text-decoration: underline; }
</style>
</head>
<body>

<div class="sample-banner">⚠️ <strong>SAMPLE / REPRESENTATIVE DATA</strong> — not from any county portal.</div>

<nav>
  <a class="logo" href="/"><span>📡</span> Permit Radar</a>
  <div class="nav-links">
    <a href="/">Directory</a>
    <a href="/#get-alerts">Get Alerts</a>
    <a href="/admin">Admin</a>
  </div>
</nav>

<div class="container">
  <a class="back-link" href="/">← Back to Directory</a>
  <div id="content" class="loading">Loading permit…</div>
</div>

<!-- Lead modal -->
<div class="modal-bg" id="lead-modal" onclick="if(event.target===this)closeLead()">
  <div class="modal">
    <button class="modal-close" onclick="closeLead()">×</button>
    <h3>Request This Lead</h3>
    <p id="modal-permit-label">—</p>
    <form id="lead-form" onsubmit="submitLead(event)">
      <input type="hidden" id="modal-permit-id" name="permit_id">
      <div class="form-row">
        <div>
          <label>Your Name</label>
          <input type="text" name="name" placeholder="Jane Smith">
        </div>
        <div>
          <label>Trade Type *</label>
          <select name="trade_type" required>
            <option value="">Select…</option>
            <option value="general_contractor">General Contractor</option>
            <option value="kitchen_bath">Kitchen &amp; Bath</option>
            <option value="interior_designer">Interior Designer</option>
            <option value="roofing">Roofer</option>
            <option value="flooring">Flooring</option>
            <option value="hvac">HVAC</option>
            <option value="home_goods_vendor">Home Goods Vendor</option>
            <option value="wallcovering_vendor">Wallcovering Vendor</option>
            <option value="other">Other</option>
          </select>
        </div>
      </div>
      <div class="form-row">
        <div>
          <label>Email *</label>
          <input type="email" name="email" required placeholder="you@company.com">
        </div>
        <div>
          <label>Phone</label>
          <input type="tel" name="phone" placeholder="555-555-5555">
        </div>
      </div>
      <div class="form-row single">
        <div>
          <label>Message</label>
          <input type="text" name="message" placeholder="Services you offer">
        </div>
      </div>
      <button type="submit" class="btn-submit">Request Lead →</button>
      <div id="lead-msg"></div>
    </form>
  </div>
</div>

<script>
'use strict';
const esc = s => (s||'').replace(/[&<>"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));
const fmtVal  = v => v ? '$' + Number(v).toLocaleString() : '—';
const fmtDate = d => d ? new Date(d + 'T12:00:00').toLocaleDateString('en-US', { month:'long', day:'numeric', year:'numeric' }) : '—';

async function load() {
  const id = decodeURIComponent(location.pathname.replace('/permit/', '').replace(/\/$/, ''));
  const r = await fetch('/api/permits/' + encodeURIComponent(id));
  const content = document.getElementById('content');
  if (!r.ok) { content.innerHTML = '<p style="color:#ef4444">Permit not found.</p>'; return; }
  const { permit: p } = await r.json();
  document.title = p.address + ' — Permit Radar';
  const statusClass = 'status-' + (p.status || 'pending');
  content.innerHTML = `
<div class="permit-card">
  <div class="permit-header">
    <div class="permit-header-top">
      <div>
        <div class="permit-id-label">Permit ${esc(p.id)}</div>
        <div class="permit-address-h">${esc(p.address)}</div>
        <div class="permit-location">${esc(p.city)}, ${esc(p.state)} ${esc(p.zip)} — ${esc(p.jurisdiction)}</div>
      </div>
      <span class="status-chip ${statusClass}">${esc(p.status)}</span>
    </div>
  </div>
  <div class="permit-body">
    <div class="section-title">Permit Details</div>
    <div class="fields-grid">
      <div class="field"><div class="field-label">Date Filed</div><div class="field-value">${fmtDate(p.date_filed)}</div></div>
      <div class="field"><div class="field-label">Permit Type</div><div class="field-value">${esc(p.permit_type_label || p.permit_type)}</div></div>
      <div class="field"><div class="field-label">Valuation</div><div class="field-value big">${fmtVal(p.valuation)}</div></div>
      <div class="field"><div class="field-label">Sq Ft Affected</div><div class="field-value">${p.sqft_affected ? p.sqft_affected.toLocaleString() + ' sq ft' : '—'}</div></div>
      <div class="field"><div class="field-label">Status</div><div class="field-value">${esc(p.status)}</div></div>
      <div class="field"><div class="field-label">Bedrooms (home)</div><div class="field-value">${p.bedrooms || '—'}</div></div>
    </div>
    ${p.contractor ? `
    <div class="section-title">Contractor on Record</div>
    <div class="fields-grid">
      <div class="field"><div class="field-label">Contractor</div><div class="field-value">${esc(p.contractor)}</div></div>
      <div class="field"><div class="field-label">License</div><div class="field-value">${esc(p.contractor_license || '—')}</div></div>
    </div>` : ''}
    <div class="section-title">Description</div>
    <div class="permit-desc">${esc(p.description)}</div>
    <div class="cta-box">
      <h3>Reach this homeowner at the renovation moment</h3>
      <p>Request this lead directly, or subscribe for alerts on every permit like it in your area.</p>
      <div class="cta-row">
        <button class="btn-lead" onclick="openLead('${esc(p.id)}', '${esc(p.address + ', ' + p.city)}')">Request This Lead</button>
        <a class="btn-subscribe" href="/#get-alerts">Get Area Alerts →</a>
      </div>
    </div>
  </div>
</div>`;
}
load();

function openLead(id, label) {
  document.getElementById('modal-permit-id').value = id;
  document.getElementById('modal-permit-label').textContent = label;
  document.getElementById('lead-msg').innerHTML = '';
  document.getElementById('lead-form').reset();
  document.getElementById('modal-permit-id').value = id;
  document.getElementById('lead-modal').classList.add('open');
}
function closeLead() { document.getElementById('lead-modal').classList.remove('open'); }

async function submitLead(e) {
  e.preventDefault();
  const body = Object.fromEntries(new FormData(e.target));
  const msg = document.getElementById('lead-msg');
  msg.innerHTML = '';
  const r = await fetch('/api/lead-request', {
    method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(body)
  });
  const d = await r.json();
  if (d.ok) { msg.innerHTML = '<div class="success-msg">✓ Lead request submitted! ID: ' + esc(d.id) + '</div>'; setTimeout(closeLead, 2500); }
  else { msg.innerHTML = '<div class="error-msg">Error: ' + esc(d.error) + '</div>'; }
}

// ── Shopify cross-sell (permit detail) ───────────────────────────────────────
(async function loadXsell() {
  try {
    const r = await fetch('/api/shopify-crosssell');
    const d = await r.json();
    if (!d.products || !d.products.length) return;
    const strip = document.createElement('div');
    strip.className = 'xsell-strip';
    strip.innerHTML = `
<div class="xsell-inner">
  <div class="xsell-header">
    <span class="xsell-label">Trade cross-sell — links to live DW store</span>
    <p class="xsell-title">Outfit the remodel — shop Designer Wallcoverings</p>
  </div>
  <div class="xsell-grid">
    ${d.products.map(p => `
    <a class="xsell-card" href="${esc(p.url)}" target="_blank" rel="noopener noreferrer" title="${esc(p.title)}">
      <div class="xsell-img-wrap"><img src="${esc(p.image)}" alt="${esc(p.title)}" loading="lazy"></div>
      <div class="xsell-info">
        <div class="xsell-product-title">${esc(p.title)}</div>
        <div class="xsell-vendor">${esc(p.vendor)}</div>
        <div class="xsell-price">${p.price ? '$' + Number(p.price).toFixed(2) : ''}</div>
      </div>
    </a>`).join('')}
  </div>
  <a class="xsell-browse" href="https://www.designerwallcoverings.com" target="_blank" rel="noopener noreferrer">
    Browse full collection at designerwallcoverings.com →
  </a>
</div>`;
    // Insert after .container (the permit detail area)
    const container = document.querySelector('.container');
    if (container) container.parentNode.insertBefore(strip, container.nextSibling);
  } catch (e) {}
})();
</script>
</body>
</html>