← back to NationalPaperHangers
views/admin/profile.ejs
199 lines
<%- include('../partials/head', { title, admin: true }) %>
<%- include('partials/admin-header') %>
<section class="admin-main">
<header class="admin-page-head"><h1>Profile</h1><p class="muted">Customers see this information on your public profile.</p></header>
<% if (flash && flash.ok) { %><div class="callout callout-success"><%= flash.ok %></div><% } %>
<% if (flash && flash.error) { %><div class="callout callout-warn"><%= flash.error %></div><% } %>
<form method="post" action="/admin/profile" class="profile-form">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<fieldset>
<legend>Studio</legend>
<label>Business name <input type="text" name="business_name" value="<%= installer.business_name %>" required></label>
<label>Contact name <input type="text" name="contact_name" value="<%= installer.contact_name || '' %>"></label>
<label>Phone <input type="tel" name="phone" value="<%= installer.phone || '' %>"></label>
<label>Headline (one line shown under your name)
<input type="text" name="headline" value="<%= installer.headline || '' %>" maxlength="120">
</label>
<label>Bio (3–4 sentences)
<textarea name="bio" rows="4"><%= installer.bio || '' %></textarea>
</label>
<label>Website <input type="url" name="website" value="<%= installer.website || '' %>"></label>
</fieldset>
<fieldset>
<legend>Location & travel</legend>
<div class="row3">
<label>City <input type="text" name="city" value="<%= installer.city || '' %>"></label>
<label>State <input type="text" name="state" maxlength="2" value="<%= installer.state || '' %>"></label>
<label>ZIP <input type="text" name="zip" maxlength="10" value="<%= installer.zip || '' %>"></label>
</div>
<label>Service radius (miles) <input type="number" name="service_radius_miles" value="<%= installer.service_radius_miles %>"></label>
<label class="check"><input type="checkbox" name="travel_available" <%= installer.travel_available ? 'checked' : '' %>> Available to travel for projects</label>
<p class="muted" style="margin:18px 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:0.08em">Service area (additive to radius — match any line)</p>
<label>Counties you service (comma-separated, no "County" suffix)
<input type="text" name="service_counties"
value="<%= (installer.service_counties || []).join(', ') %>"
placeholder="e.g. Los Angeles, Ventura, Orange">
</label>
<label>Towns/cities you service (comma-separated)
<input type="text" name="service_towns"
value="<%= (installer.service_towns || []).join(', ') %>"
placeholder="e.g. Beverly Hills, Malibu, Santa Monica">
</label>
<label>ZIPs you explicitly service (comma-separated)
<input type="text" name="service_zips"
value="<%= (installer.service_zips || []).join(', ') %>"
placeholder="e.g. 90210, 90402, 90272">
</label>
</fieldset>
<fieldset>
<legend>Specialty</legend>
<label class="tag-input-label">Market segments
<div class="tag-input-wrapper"
data-tag-input="market_segments"
data-allowed='["luxury_residential","hospitality","retail","museum","yacht"]'>
<input type="hidden" name="market_segments" value="<%= (installer.market_segments || []).join(', ') %>">
</div>
</label>
<label class="tag-input-label">Materials
<div class="tag-input-wrapper"
data-tag-input="materials"
data-allowed='["hand_painted","silk","grasscloth","vinyl","mural","metallic_leaf","hand_screened","digital_print"]'>
<input type="hidden" name="materials" value="<%= (installer.materials || []).join(', ') %>">
</div>
</label>
<label class="tag-input-label">Brands handled
<span class="tag-input-hint">Type a brand name and press Enter</span>
<div class="tag-input-wrapper" data-tag-input="brands_handled">
<input type="hidden" name="brands_handled" value="<%= (installer.brands_handled || []).join(', ') %>">
</div>
</label>
<label class="tag-input-label">Accreditations
<span class="tag-input-hint">Type a credential and press Enter</span>
<div class="tag-input-wrapper" data-tag-input="accreditations">
<input type="hidden" name="accreditations" value="<%= (installer.accreditations || []).join(', ') %>">
</div>
</label>
</fieldset>
<fieldset>
<legend>Operations</legend>
<label>Team size <input type="number" name="team_size" value="<%= installer.team_size || '' %>"></label>
<label>Founded year <input type="number" name="founded_year" value="<%= installer.founded_year || '' %>"></label>
<label>Response SLA (hours) <input type="number" name="response_time_hours" value="<%= installer.response_time_hours %>"></label>
</fieldset>
<fieldset>
<legend>Studio capacity</legend>
<p class="muted" style="font-size:13px;margin:0 0 12px">Trade buyers specifying $4K/roll papers want to know you can reach the entryway and have the right tools. Surfacing this distinguishes you from contractors.</p>
<% var eq = installer.equipment || {}; %>
<label>Maximum reach (feet)
<input type="number" name="eq_max_reach_ft" min="0" max="200" value="<%= eq.max_reach_ft || '' %>" placeholder="e.g. 22">
</label>
<label>Lift / ladder
<select name="eq_lift_type">
<option value="">— Select —</option>
<% [['extension_ladder','Extension ladder'],['scaffold','Scaffold'],['scissor_lift','Scissor lift'],['boom_lift','Boom lift']].forEach(function(o){ %>
<option value="<%= o[0] %>" <%= eq.lift_type === o[0] ? 'selected' : '' %>><%= o[1] %></option>
<% }); %>
</select>
</label>
<label>Pasting table
<select name="eq_paper_table">
<option value="">— Select —</option>
<% [['none','None / paste-the-wall only'],['folding','Folding table'],['dedicated_60','Dedicated 60" table'],['dedicated_72_plus','Dedicated 72"+ table']].forEach(function(o){ %>
<option value="<%= o[0] %>" <%= eq.paper_table === o[0] ? 'selected' : '' %>><%= o[1] %></option>
<% }); %>
</select>
</label>
<label>Vehicle
<select name="eq_vehicle">
<option value="">— Select —</option>
<% [['van','Van'],['box_truck','Box truck'],['trailer','Trailer-equipped']].forEach(function(o){ %>
<option value="<%= o[0] %>" <%= eq.vehicle === o[0] ? 'selected' : '' %>><%= o[1] %></option>
<% }); %>
</select>
</label>
<label class="check"><input type="checkbox" name="eq_dust_extraction" <%= eq.dust_extraction ? 'checked' : '' %>> HEPA dust extraction on-site</label>
<label>Notes <input type="text" name="eq_notes" maxlength="400" value="<%= eq.notes || '' %>" placeholder="e.g. Genie GS-1932 lift available on request"></label>
</fieldset>
<button type="submit" class="btn btn-primary btn-lg">Save profile</button>
</form>
<% if (typeof credentials !== 'undefined') {
var typeLabel = {
brand_trained: 'Brand-trained',
brand_certified: 'Brand-certified',
brand_approved: 'Brand-approved',
manufacturer_partner: 'Manufacturer partner',
trade_member: 'Trade member'
};
%>
<section class="admin-section" style="margin-top:48px">
<h2>Brand-trained credentials</h2>
<p class="muted" style="font-size:13px">Trade buyers specifying $4K/roll papers care that you've been trained by the brand. Add each credential separately — NPH ops reviews each entry before it appears on your public profile.</p>
<% if (credentials.length) { %>
<table class="data-table" style="margin-bottom:24px">
<thead><tr><th>Brand</th><th>Type</th><th>Year</th><th>Expires</th><th>Cert</th><th>Status</th><th></th></tr></thead>
<tbody>
<% credentials.forEach(function(c){ %>
<tr>
<td><strong><%= c.brand %></strong><% if (c.notes) { %><br><span class="muted" style="font-size:12px"><%= c.notes %></span><% } %></td>
<td><%= typeLabel[c.credential_type] || c.credential_type %></td>
<td><%= c.year_issued || '—' %></td>
<td><%= c.year_expires || '—' %></td>
<td><% if (c.certificate_url) { %><a href="<%= c.certificate_url %>" target="_blank" rel="noopener">View ↗</a><% } else { %>—<% } %></td>
<td>
<% if (c.ops_verified) { %>
<span class="status-badge status-confirmed">Verified</span>
<% } else { %>
<span class="status-badge status-pending">Pending review</span>
<% } %>
</td>
<td>
<form method="post" action="/admin/credentials/<%= c.id %>/delete" class="inline-form" onsubmit="return confirm('Remove this credential?')">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button class="btn btn-ghost btn-sm">Remove</button>
</form>
</td>
</tr>
<% }); %>
</tbody>
</table>
<% } else { %>
<p class="muted" style="margin-bottom:24px">No credentials added yet.</p>
<% } %>
<h3 style="margin-top:24px">Add a credential</h3>
<form method="post" action="/admin/credentials" class="profile-form">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<div class="row3">
<label>Brand <input type="text" name="brand" required maxlength="100" placeholder="e.g. de Gournay"></label>
<label>Type
<select name="credential_type">
<option value="brand_trained">Brand-trained</option>
<option value="brand_certified">Brand-certified</option>
<option value="brand_approved">Brand-approved</option>
<option value="manufacturer_partner">Manufacturer partner</option>
<option value="trade_member">Trade member</option>
</select>
</label>
<label>Year issued <input type="number" name="year_issued" min="1900" max="2100" placeholder="e.g. 2019"></label>
</div>
<div class="row3">
<label>Year expires <input type="number" name="year_expires" min="1900" max="2200" placeholder="optional"></label>
<label>Certificate URL <input type="url" name="certificate_url" placeholder="https://… (PDF or page)"></label>
<label>Notes <input type="text" name="notes" maxlength="400" placeholder="optional"></label>
</div>
<button type="submit" class="btn btn-primary">Add credential</button>
</form>
</section>
<% } %>
</section>
<%- include('../partials/footer') %>
<script src="/js/tag-input.js"></script>