← back to Ventura Claw Leads
views/admin/dashboard.ejs
124 lines
<%- include('../partials/head', { title }) %>
<%- include('../partials/header') %>
<section class="long-form" style="max-width:1100px">
<% if (welcome) { %>
<div class="callout" style="background:#dcfce7;border-left:3px solid #16a34a;color:#166534;padding:14px 18px;margin:0 0 24px;border-radius:4px">
<strong>Welcome to Ventura Claw.</strong> Your listing is now claimed. Edit your profile and pick a tier to unlock featured placement.
</div>
<% } %>
<p class="kicker">Dashboard</p>
<h1 class="display-sm"><%= currentBusiness.business_name %></h1>
<p class="lede">Tier: <strong><%= currentBusiness.tier === 'free' ? 'Free' : (currentBusiness.tier.charAt(0).toUpperCase() + currentBusiness.tier.slice(1)) %></strong> · Subscription: <strong><%= currentBusiness.subscription_status || 'inactive' %></strong></p>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin:32px 0">
<div class="side-card" style="text-align:center">
<h3>Total leads</h3>
<p style="font-family:var(--serif);font-size:36px;color:var(--brass);margin:0"><%= stats.total_leads %></p>
</div>
<div class="side-card" style="text-align:center">
<h3>Last 30 days</h3>
<p style="font-family:var(--serif);font-size:36px;color:var(--brass);margin:0"><%= stats.last_30d %></p>
</div>
<div class="side-card" style="text-align:center">
<h3>Delivered</h3>
<p style="font-family:var(--serif);font-size:36px;color:var(--brass);margin:0"><%= stats.delivered %></p>
</div>
<div class="side-card" style="text-align:center">
<h3>Pending</h3>
<p style="font-family:var(--serif);font-size:36px;color:var(--brass);margin:0"><%= stats.pending %></p>
</div>
<div class="side-card" style="text-align:center<%= stats.unread > 0 ? ';border-color:var(--brass)' : '' %>">
<h3>Unread<% if (stats.unread > 0) { %> <span style="color:#dc2626">●</span><% } %></h3>
<p style="font-family:var(--serif);font-size:36px;color:<%= stats.unread > 0 ? '#dc2626' : 'var(--fg-muted)' %>;margin:0"><%= stats.unread %></p>
<% if (stats.unread > 0) { %><a href="/admin/leads?filter=unread" style="font-size:11px;color:var(--brass);border:none">Triage →</a><% } %>
</div>
<div class="side-card" style="text-align:center">
<h3>Profile views</h3>
<p style="font-family:var(--serif);font-size:36px;color:var(--brass);margin:0"><%= stats.views_30d %></p>
<p style="font-size:11px;color:var(--fg-muted);margin:4px 0 0;letter-spacing:0.06em;text-transform:uppercase">last 30 days · <%= stats.views_today %> today</p>
</div>
<div class="side-card" style="text-align:center">
<h3>Shares</h3>
<p style="font-family:var(--serif);font-size:36px;color:var(--brass);margin:0"><%= stats.shares_total %></p>
<p style="font-size:11px;color:var(--fg-muted);margin:4px 0 0;letter-spacing:0.06em;text-transform:uppercase">all-time</p>
</div>
</div>
<%
// Sparkline: 30 day-bins. Width fluid; height fixed at 60px.
var sparkW = 480; var sparkH = 60; var pad = 2;
var binW = (sparkW - pad * 2) / Math.max(1, trend.length);
var maxV = Math.max(1, trendPeak); // avoid /0 — flat zero shows as flat baseline
%>
<div class="side-card" style="margin-bottom:24px">
<div style="display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:8px">
<h3 style="margin:0">30-day lead trend</h3>
<p class="muted" style="margin:0;font-size:12px">peak <%= trendPeak %> · total <%= trend.reduce(function(s,p){return s+p.n;},0) %></p>
</div>
<svg viewBox="0 0 <%= sparkW %> <%= sparkH %>" style="width:100%;height:80px;display:block" preserveAspectRatio="none" aria-label="30-day lead trend">
<% trend.forEach(function(p, i){
var h = p.n > 0 ? Math.max(2, (p.n / maxV) * (sparkH - pad * 2)) : 0;
var x = pad + i * binW;
var y = sparkH - pad - h;
var w = Math.max(1, binW - 2);
var isPeak = trendPeak > 0 && p.n === trendPeak;
var dayLabel = new Date(p.day).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
%>
<% if (h > 0) { %>
<rect x="<%= x.toFixed(2) %>" y="<%= y.toFixed(2) %>" width="<%= w.toFixed(2) %>" height="<%= h.toFixed(2) %>"
fill="<%= isPeak ? 'var(--brass)' : 'var(--fg-muted)' %>"
opacity="<%= isPeak ? '1' : '0.55' %>">
<title><%= dayLabel %>: <%= p.n %> lead<%= p.n === 1 ? '' : 's' %></title>
</rect>
<% } else { %>
<rect x="<%= x.toFixed(2) %>" y="<%= (sparkH - pad - 1).toFixed(2) %>" width="<%= w.toFixed(2) %>" height="1"
fill="var(--border)" opacity="0.6">
<title><%= dayLabel %>: 0 leads</title>
</rect>
<% } %>
<% }); %>
</svg>
<div style="display:flex;justify-content:space-between;font-size:11px;color:var(--fg-muted);margin-top:4px">
<span><%= new Date(trend[0].day).toLocaleDateString('en-US',{ month:'short', day:'numeric' }) %></span>
<span>today</span>
</div>
</div>
<h2>Recent leads</h2>
<% if (recent.length === 0) { %>
<p class="muted">No leads yet — your listing is live; consumers will start finding you. Make sure your <a href="/admin/profile">profile</a> is filled out.</p>
<% } else { %>
<table style="width:100%;border-collapse:collapse;margin:16px 0">
<thead>
<tr style="border-bottom:1px solid var(--border);text-align:left">
<th style="padding:8px 0;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">When</th>
<th style="padding:8px 0;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">From</th>
<th style="padding:8px 0;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Status</th>
</tr>
</thead>
<tbody>
<% recent.forEach(function(l){ %>
<tr style="border-bottom:1px solid var(--border)">
<td style="padding:10px 0;font-size:13px;color:var(--fg-muted)"><%= new Date(l.created_at).toLocaleString('en-US',{ dateStyle:'medium', timeStyle:'short' }) %></td>
<td style="padding:10px 0;font-size:13px"><strong><%= l.consumer_name %></strong> · <%= l.consumer_email %></td>
<td style="padding:10px 0;font-size:13px"><%= l.delivered_at ? '<span style="color:#16a34a">Delivered</span>' : '<span style="color:var(--fg-muted)">Pending</span>' %></td>
</tr>
<% }); %>
</tbody>
</table>
<p style="margin-top:16px"><a href="/admin/leads" class="btn btn-ghost btn-sm">See all leads →</a></p>
<% } %>
<h2 style="margin-top:48px">Next steps</h2>
<ul>
<li><a href="/admin/profile">Edit your public profile</a> — make sure description, hours, contact, and Instagram are current.</li>
<li><a href="/admin/billing">Pick a tier</a> — Free is fine; paid tiers unlock featured placement and category-sidebar feature.</li>
<li><a href="/admin/team">Invite a teammate</a> — let multiple people respond to leads.</li>
<li><a href="/business/<%= currentBusiness.slug %>" target="_blank" rel="noopener noreferrer">View your live profile ↗</a></li>
</ul>
</section>
<%- include('../partials/footer') %>