Files
PowderCoatingLogix/src/PowderCoating.Web/Views/Shared/_KioskLayout.cshtml
T
spouliot 4ec55e7290 Restore all zeroed views + add bulk gift certificate creation
The HTML entity sweep script had a bug where it wrote empty files for any
view that contained no target Unicode characters, zeroing out 215 view files.
All views restored from the pre-sweep commit (cefdf3e).

Bulk gift certificate feature:
- BulkCreateGiftCertificateDto with Quantity (1-500), Amount, Reason, Expiry, Notes
- GenerateBulkGiftCertificatePdfAsync on IPdfService / PdfService: one Letter page
  per cert, reusing the same purple/gold branded ComposeGiftCertificateContent helper
- GiftCertificatesController: BulkCreate GET/POST, BulkResult GET, BulkDownloadPdf POST
- Views: BulkCreate.cshtml (form with live total preview), BulkResult.cshtml (table +
  Download All PDF button that POSTs cert IDs to avoid URL length limits)
- gift-certificate-bulk.js: live preview + spinner/disable on submit
- Index.cshtml: Bulk Create button added alongside New Certificate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 20:09:22 -04:00

94 lines
3.1 KiB
Plaintext

<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>@(ViewData["Title"] ?? "Customer Intake") — @(ViewBag.CompanyName ?? "Intake Form")</title>
<link href="~/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="~/lib/bootstrap-icons/font/bootstrap-icons.css" />
<link rel="stylesheet" href="~/css/kiosk.css" />
@await RenderSectionAsync("Styles", required: false)
</head>
<body class="kiosk-body">
@{
int kioskStep = ViewBag.KioskStep ?? 0; // 1, 2, or 3 — 0 means no step dots
int kioskSteps = ViewBag.KioskSteps ?? 3;
}
<div class="container py-4" style="max-width:720px;">
@* Logo — hidden on Welcome screen which renders its own centered logo *@
@if (!(bool)(ViewBag.HideLayoutLogo ?? false))
{
<div class="text-center mb-3">
@if (!string.IsNullOrEmpty(ViewBag.CompanyLogoUrl as string))
{
<img src="@ViewBag.CompanyLogoUrl" alt="@ViewBag.CompanyName"
style="max-height:80px;max-width:220px;object-fit:contain;" />
}
else
{
<span class="fw-bold fs-5 text-muted">@ViewBag.CompanyName</span>
}
</div>
}
@* Step dots *@
@if (kioskStep > 0)
{
<div class="kiosk-steps mb-4" aria-label="Step @kioskStep of @kioskSteps">
@for (int i = 1; i <= kioskSteps; i++)
{
string dotClass = i < kioskStep ? "done" : (i == kioskStep ? "active" : "");
<div class="kiosk-step-dot @dotClass" title="Step @i"></div>
}
</div>
}
@* Validation summary *@
@if (ViewData.ModelState.IsValid == false)
{
<div class="alert alert-danger alert-permanent mb-4">
<i class="bi bi-exclamation-triangle me-2"></i>
Please correct the highlighted fields below.
</div>
}
@RenderBody()
</div>
@* Inactivity timer — redirect to Welcome when idle too long.
Intake steps set ViewBag.InactivityTimeoutMs = 45000 (45 s).
Welcome screen keeps the default 5-minute timeout. *@
@{
bool showInactivityTimer = (bool)(ViewBag.ShowInactivityTimer ?? true);
string welcomeUrl = ViewBag.WelcomeUrl as string ?? "/Kiosk/Welcome";
int inactivityMs = ViewBag.InactivityTimeoutMs as int? ?? (5 * 60 * 1000);
}
@if (showInactivityTimer)
{
<script>
(function () {
var TIMEOUT_MS = @inactivityMs;
var timer;
function reset() {
clearTimeout(timer);
timer = setTimeout(function () {
window.location.href = "@Html.Raw(welcomeUrl)";
}, TIMEOUT_MS);
}
["touchstart", "touchmove", "click", "keydown", "scroll"].forEach(function (evt) {
document.addEventListener(evt, reset, { passive: true });
});
reset();
})();
</script>
}
<script src="~/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>