← back to NationalPaperHangers
Remove 'Schedule install' booking option — initial visit only
d15181aee70b9e6d3e801e95a3c15041b67c3804 · 2026-05-06 16:05:55 -0700 · SteveStudio2
NPH books the initial consultation; install scheduling, pricing, and contract
happen directly between consumer and installer afterward. Keeps NPH on the
lead-coordination side of CSLB $7026 — booking install work through NPH
would expose us to general-contractor classification.
- Drop visit-picker fieldset (consultation+install radio cards)
- Replace with brass-bordered note: 'You're scheduling an initial visit
with {studio}. Install scheduling, contracts, and pricing for the work
itself happen directly between you and the studio.'
- Drop visit-picker JS (no more project_type-swap on click)
- Drop dead .visit-picker / .vp-* CSS
The hidden project_type input still ships 'consultation' to /api/installers/:slug/book.
Existing API still validates the install enum value for legacy bookings already
in the DB; nothing new will hit that path.
Prod-verified: 0 picker strings, replacement note present.
Files touched
Diff
commit d15181aee70b9e6d3e801e95a3c15041b67c3804
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 6 16:05:55 2026 -0700
Remove 'Schedule install' booking option — initial visit only
NPH books the initial consultation; install scheduling, pricing, and contract
happen directly between consumer and installer afterward. Keeps NPH on the
lead-coordination side of CSLB $7026 — booking install work through NPH
would expose us to general-contractor classification.
- Drop visit-picker fieldset (consultation+install radio cards)
- Replace with brass-bordered note: 'You're scheduling an initial visit
with {studio}. Install scheduling, contracts, and pricing for the work
itself happen directly between you and the studio.'
- Drop visit-picker JS (no more project_type-swap on click)
- Drop dead .visit-picker / .vp-* CSS
The hidden project_type input still ships 'consultation' to /api/installers/:slug/book.
Existing API still validates the install enum value for legacy bookings already
in the DB; nothing new will hit that path.
Prod-verified: 0 picker strings, replacement note present.
---
views/public/book.ejs | 59 +++++++++------------------------------------------
1 file changed, 10 insertions(+), 49 deletions(-)
diff --git a/views/public/book.ejs b/views/public/book.ejs
index c0b2662..cad865b 100644
--- a/views/public/book.ejs
+++ b/views/public/book.ejs
@@ -25,16 +25,7 @@
.signin-card .who strong{display:block;font-size:15px}
.signin-card .gbtn{display:inline-flex;align-items:center;gap:8px;background:#fff;color:#222;border:1px solid #ccc;padding:10px 18px;border-radius:8px;font-weight:600;text-decoration:none;font-size:14px}
.signin-card .gbtn svg{width:18px;height:18px}
- .visit-picker{border:0;padding:0;margin:0 0 18px}
- .vp-legend{font-size:14px;font-weight:700;color:var(--ink,#0a0a0a);margin:0 0 10px;padding:0;letter-spacing:-0.01em}
- .vp-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
- .vp-card{display:block;border:2px solid var(--border,#d4d2c8);border-radius:14px;padding:18px 20px;cursor:pointer;background:var(--card-bg,#fff);transition:all .15s;position:relative}
- .vp-card:hover{border-color:#9aa39a}
- .vp-card.is-checked{border-color:var(--ink,#0a0a0a);background:#fff8e6;box-shadow:0 0 0 1px var(--ink,#0a0a0a)}
- .vp-card input{position:absolute;opacity:0;pointer-events:none}
- .vp-card .vp-icon{font-size:24px;margin:0 0 8px;line-height:1}
- .vp-card strong{display:block;font-size:16px;margin:0 0 4px;letter-spacing:-0.01em}
- .vp-card small{display:block;font-size:13px;color:var(--muted,#666);line-height:1.45}
+ /* Visit-kind picker removed 2026-05-06 (NPH only books consultations). */
</style>
<section class="book-page">
@@ -138,28 +129,14 @@
<input type="hidden" name="installer_slug" value="<%= installer.slug %>">
<input type="hidden" name="scheduled_start" id="scheduled_start" required>
<input type="hidden" name="scheduled_end" id="scheduled_end" required>
- <!-- The visit-vs-install picker drives this. Existing /book bookings
- API already validates project_type values (consultation|site_visit|
- quote|install). -->
+ <!-- NPH only books the initial visit (consultation). Install scheduling
+ happens directly between the consumer and the installer after the
+ visit — keeps NPH on the lead-coordination side of CSLB §7026. -->
<input type="hidden" name="project_type" id="project_type" value="consultation">
- <fieldset class="visit-picker" data-visit-picker>
- <legend class="vp-legend">What kind of appointment?</legend>
- <div class="vp-cards">
- <label class="vp-card is-checked" data-vp-card="consultation">
- <input type="radio" name="_visit_kind" value="consultation" checked>
- <div class="vp-icon" aria-hidden="true">🔍</div>
- <strong>Initial visit</strong>
- <small>Walk-through, measurement, recommendations. The studio brings samples and shares a quote after.</small>
- </label>
- <label class="vp-card" data-vp-card="install">
- <input type="radio" name="_visit_kind" value="install">
- <div class="vp-icon" aria-hidden="true">📅</div>
- <strong>Schedule install</strong>
- <small>You've selected the wallpaper and you're ready for the studio to install. (You'll confirm brand & pattern in step 2.)</small>
- </label>
- </div>
- </fieldset>
+ <p class="visit-kind-note" style="margin:0 0 16px;padding:14px 18px;border-left:3px solid var(--brass,#b8860b);background:var(--bg-alt,#f8f7f2);border-radius:0 8px 8px 0;font-size:14px;line-height:1.5">
+ <strong>You're scheduling an initial visit</strong> with <%= installer.business_name %> — walk-through, measurement, and recommendations. The studio brings samples and shares a quote after. Install scheduling, contracts, and pricing for the work itself happen directly between you and the studio.
+ </p>
<ol class="intake-steps">
<li class="is-active" data-step-pill="1">Scope</li>
@@ -377,25 +354,9 @@
form.querySelectorAll('input[name="product_sourced"]').forEach(function(r){ r.addEventListener('change', syncProductFields); });
syncProductFields();
- // Initial visit vs Schedule install picker — sets project_type and, when
- // install is chosen, force-checks product_sourced=Yes (you don't schedule
- // an install without the wallpaper picked) and reveals the brand fields.
- var ptHidden = document.getElementById('project_type');
- var psYes = form.querySelector('input[name="product_sourced"][value="true"]');
- var psNo = form.querySelector('input[name="product_sourced"][value="false"]');
- form.querySelectorAll('[data-vp-card]').forEach(function(card){
- card.addEventListener('click', function(){
- form.querySelectorAll('.vp-card').forEach(function(c){ c.classList.remove('is-checked'); });
- card.classList.add('is-checked');
- var kind = card.getAttribute('data-vp-card'); // 'consultation' | 'install'
- if (ptHidden) ptHidden.value = kind === 'install' ? 'install' : 'consultation';
- if (kind === 'install' && psYes) {
- psYes.checked = true;
- if (psNo) psNo.checked = false;
- syncProductFields();
- }
- });
- });
+ // Visit-kind picker removed 2026-05-06 — NPH only books the initial
+ // consultation; install scheduling stays between consumer + installer.
+ // The hidden project_type input is statically set to 'consultation'.
})();
gtag('event', 'booking_started', {
← 31cdca8 Reposition NPH as referral/lead-coordination service (CSLB §
·
back to NationalPaperHangers
·
fix: /admin/template flash double-clear (route was reading n 6546f0f →