← back to NationalPaperHangers
views/admin/bookings.ejs
71 lines
<%- include('../partials/head', { title, admin: true }) %>
<%- include('partials/admin-header') %>
<section class="admin-main">
<header class="admin-page-head">
<h1>Bookings</h1>
<% if (typeof market !== 'undefined' && market) { %>
<p class="muted" style="margin-top:4px">
<strong><%= market.count_paid %></strong> paid ·
<strong>$<%= (market.deposits_paid_cents/100).toFixed(2) %></strong> deposits collected ·
NPH fee <strong>$<%= (market.platform_fee_cents/100).toFixed(2) %></strong>
<% if (market.count_pending > 0) { %> · <%= market.count_pending %> awaiting payment<% } %>
<% if (market.count_failed > 0) { %> · <span style="color:#c44">⚠ <%= market.count_failed %> failed</span><% } %>
</p>
<% } %>
</header>
<nav class="filter-tabs">
<% ['all','upcoming','pending','past','canceled'].forEach(function(f){ %>
<a href="?status=<%= f %>" class="<%= filter === f ? 'is-current' : '' %>"><%= f %></a>
<% }); %>
</nav>
<% if (bookings.length === 0) { %>
<div class="empty-state">No bookings in this view.</div>
<% } else { %>
<table class="data-table">
<thead><tr><th>When</th><th>Customer</th><th>Type / brief</th><th>Address</th><th>Deposit</th><th>Status</th><th>Actions</th></tr></thead>
<tbody>
<% bookings.forEach(function(b){
var briefBits = [];
if (b.brand) briefBits.push(b.brand + (b.brand_sku ? ' / ' + b.brand_sku : ''));
if (b.material) briefBits.push(b.material.replace(/_/g,' '));
if (b.square_feet) briefBits.push(b.square_feet + ' sq ft');
if (b.roll_count_estimate) briefBits.push('~' + b.roll_count_estimate + ' rolls');
if (b.ceiling_height_ft) briefBits.push(b.ceiling_height_ft + 'ft ceil');
if (b.surface_state) briefBits.push(b.surface_state.replace(/_/g,' '));
if (b.access_constraints) briefBits.push(b.access_constraints.replace(/_/g,' '));
%>
<tr>
<td><a href="/admin/bookings/<%= b.id %>" style="color:inherit"><%= new Date(b.scheduled_start).toLocaleString() %></a></td>
<td><a href="/admin/bookings/<%= b.id %>" style="color:inherit"><%= b.customer_name %></a><br><span class="muted"><%= b.customer_email %><% if (b.customer_phone) { %> · <%= b.customer_phone %><% } %></span></td>
<td>
<a href="/admin/bookings/<%= b.id %>" style="color:inherit">
<%= (b.project_type || 'consultation').replace(/_/g,' ') %>
</a>
<% if (briefBits.length) { %><br><span class="muted" style="font-size:12px"><%= briefBits.join(' · ') %></span><% } %>
</td>
<td><%= [b.city, b.state, b.zip].filter(Boolean).join(', ') %></td>
<td>
<% if (b.deposit_amount_cents) { %>
<strong>$<%= (b.deposit_amount_cents/100).toFixed(2) %></strong><br>
<span class="status-badge deposit-<%= b.deposit_status || 'none' %>"><%= b.deposit_status || '—' %></span>
<% } else { %>
<span class="muted">—</span>
<% } %>
</td>
<td><span class="status-badge status-<%= b.status %>"><%= b.status %></span></td>
<td class="actions">
<% if (b.status === 'pending') { %>
<form method="post" action="/admin/bookings/<%= b.id %>/confirm" class="inline-form"><input type="hidden" name="_csrf" value="<%= csrfToken %>"><button class="btn btn-primary btn-sm">Confirm</button></form>
<form method="post" action="/admin/bookings/<%= b.id %>/decline" class="inline-form"><input type="hidden" name="_csrf" value="<%= csrfToken %>"><button class="btn btn-ghost btn-sm">Decline</button></form>
<% } else if (b.status === 'confirmed') { %>
<form method="post" action="/admin/bookings/<%= b.id %>/complete" class="inline-form"><input type="hidden" name="_csrf" value="<%= csrfToken %>"><button class="btn btn-primary btn-sm">Mark complete</button></form>
<% } %>
</td>
</tr>
<% }); %>
</tbody>
</table>
<% } %>
</section>
<%- include('../partials/footer') %>