d5ad9fa073
- New CompanyPreferences.KioskIntakeOutput setting ("Quote" default / "Job"): controls
what the kiosk creates on submission; shown as a card-style radio toggle in
Company Settings → Kiosk tab
- KioskSession.LinkedQuoteId added so quote-first sessions link back to the draft quote
- Migration AddKioskIntakeOutputSetting applies both schema changes
- ProcessSubmissionAsync branches on setting: creates Draft quote (quote-first) or
Pending job (job-first); save order fixed (CompleteAsync before using DB-assigned Id as FK)
- Terms.cshtml pricing paragraph is now dynamic: "subject to formal quote" for Quote mode,
"team member will reach out about pricing" for Job mode
- Customer Intakes list: "View Quote" button appears when LinkedQuoteId is set
- Notification label fixed: Remote sessions now say "Remote Intake", not "Walk-in Intake"
- Inactivity reset shortened to 45 s on intake steps
- Signature pad: hosted locally (no CDN), canvas resize deferred via requestAnimationFrame
- AI photo upload: client-side compression to ≤1200px + AbortController 120 s timeout
- Help article and AI knowledge base updated with kiosk feature
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
4.7 KiB
Plaintext
108 lines
4.7 KiB
Plaintext
@model PowderCoating.Application.DTOs.Kiosk.SubmitKioskTermsDto
|
|
@{
|
|
Layout = "~/Views/Shared/_KioskLayout.cshtml";
|
|
ViewData["Title"] = "Terms & Consent";
|
|
var token = ViewBag.SessionToken as Guid? ?? Guid.Empty;
|
|
bool isInPerson = ViewBag.IsInPerson as bool? ?? false;
|
|
bool quoteFirst = !string.Equals(ViewBag.KioskIntakeOutput as string, "Job", StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
<div class="kiosk-card">
|
|
<h2 class="fw-bold mb-1" style="font-size:1.6rem;">Terms & Consent</h2>
|
|
<p class="text-muted mb-4">Please read and agree to the following before we proceed.</p>
|
|
|
|
<form method="post" action="/Kiosk/Intake/@token/Terms" id="termsForm">
|
|
@Html.AntiForgeryToken()
|
|
|
|
@* Terms scroll box *@
|
|
<div class="kiosk-terms-scroll mb-4">
|
|
<strong>Work Authorization & Liability Waiver</strong>
|
|
<p class="mt-2">
|
|
By signing below (or checking the box), you authorize @(ViewBag.CompanyName ?? "this shop")
|
|
to perform the powder coating services described in your intake form.
|
|
</p>
|
|
<p>
|
|
You acknowledge that you are the owner of the items submitted for coating, or you
|
|
have authority to authorize work on them. You release the shop from liability for
|
|
pre-existing damage, hidden defects, or items left unclaimed after 30 days.
|
|
</p>
|
|
@if (quoteFirst)
|
|
{
|
|
<p>
|
|
Final pricing is subject to a formal quote. Work will not begin until you approve
|
|
the quoted amount. Payment is due upon pickup unless otherwise agreed in writing.
|
|
</p>
|
|
}
|
|
else
|
|
{
|
|
<p>
|
|
A team member will review your intake and reach out about pricing before work begins.
|
|
Payment is due upon pickup unless otherwise agreed in writing.
|
|
</p>
|
|
}
|
|
<p class="mb-0">
|
|
You agree to comply with all pickup and payment terms provided by the shop.
|
|
</p>
|
|
</div>
|
|
|
|
@* SMS consent — separate checkbox per plan *@
|
|
<div class="p-3 rounded-3 mb-3" style="background:#f0f9ff;border:1px solid #bae6fd;">
|
|
<div class="form-check">
|
|
<input asp-for="SmsOptIn" class="form-check-input" type="checkbox" />
|
|
<label asp-for="SmsOptIn" class="form-check-label">
|
|
I consent to receive SMS text messages with updates about my order.
|
|
<span class="text-muted d-block mt-1" style="font-size:0.85rem;">
|
|
Message and data rates may apply. Reply STOP to opt out at any time.
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
@* Terms agreement *@
|
|
<div class="p-3 rounded-3 mb-4" style="background:#f8fafc;border:1px solid #e2e8f0;">
|
|
<div class="form-check">
|
|
<input asp-for="AgreedToTerms" class="form-check-input" type="checkbox" required />
|
|
<label asp-for="AgreedToTerms" class="form-check-label fw-semibold">
|
|
I have read and agree to the terms above.
|
|
</label>
|
|
<span asp-validation-for="AgreedToTerms" class="text-danger d-block small mt-1"></span>
|
|
</div>
|
|
</div>
|
|
|
|
@* Signature pad — in-person only *@
|
|
@if (isInPerson)
|
|
{
|
|
<div class="mb-4">
|
|
<label class="form-label fw-semibold">Your Signature</label>
|
|
<canvas id="signatureCanvas"></canvas>
|
|
<div id="signatureError" class="text-danger small mt-1 d-none">
|
|
Please sign above before continuing.
|
|
</div>
|
|
<input type="hidden" id="SignatureDataBase64" name="SignatureDataBase64" />
|
|
<button type="button" id="clearSignatureBtn"
|
|
class="btn btn-sm btn-outline-secondary mt-2">
|
|
<i class="bi bi-eraser me-1"></i> Clear
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
<div class="d-flex gap-3">
|
|
<a href="/Kiosk/Intake/@token/Job" class="btn btn-outline-secondary"
|
|
style="min-height:64px;border-radius:12px;font-size:1.1rem;flex:0 0 auto;padding:0 2rem;">
|
|
<i class="bi bi-arrow-left me-1"></i> Back
|
|
</a>
|
|
<button type="submit" class="btn btn-success kiosk-btn">
|
|
<i class="bi bi-check-circle me-2"></i> Submit
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
@if (isInPerson)
|
|
{
|
|
@section Scripts {
|
|
<script src="~/lib/signature-pad/signature_pad.umd.min.js"></script>
|
|
<script src="~/js/kiosk-terms.js"></script>
|
|
}
|
|
}
|