diff --git a/src/PowderCoating.Web/Controllers/KioskController.cs b/src/PowderCoating.Web/Controllers/KioskController.cs index 5b61967..fa6686d 100644 --- a/src/PowderCoating.Web/Controllers/KioskController.cs +++ b/src/PowderCoating.Web/Controllers/KioskController.cs @@ -261,7 +261,7 @@ public class KioskController : Controller await PopulateKioskViewBagFromSession(session); ViewBag.KioskStep = 1; - return View(new SubmitKioskContactDto + return View("Intake/Contact", new SubmitKioskContactDto { FirstName = session.CustomerFirstName, LastName = session.CustomerLastName, @@ -283,7 +283,7 @@ public class KioskController : Controller { await PopulateKioskViewBagFromSession(session); ViewBag.KioskStep = 1; - return View(dto); + return View("Intake/Contact", dto); } session.CustomerFirstName = dto.FirstName.Trim(); @@ -308,7 +308,7 @@ public class KioskController : Controller await PopulateKioskViewBagFromSession(session); ViewBag.KioskStep = 2; - return View(new SubmitKioskJobDto + return View("Intake/Job", new SubmitKioskJobDto { JobDescription = session.JobDescription, HowDidYouHearAboutUs = session.HowDidYouHearAboutUs @@ -327,7 +327,7 @@ public class KioskController : Controller { await PopulateKioskViewBagFromSession(session); ViewBag.KioskStep = 2; - return View(dto); + return View("Intake/Job", dto); } session.JobDescription = dto.JobDescription.Trim(); @@ -350,7 +350,7 @@ public class KioskController : Controller await PopulateKioskViewBagFromSession(session); ViewBag.KioskStep = 3; ViewBag.IsInPerson = session.SessionType == KioskSessionType.InPerson; - return View(new SubmitKioskTermsDto()); + return View("Intake/Terms", new SubmitKioskTermsDto()); } /// @@ -376,7 +376,7 @@ public class KioskController : Controller await PopulateKioskViewBagFromSession(session); ViewBag.KioskStep = 3; ViewBag.IsInPerson = session.SessionType == KioskSessionType.InPerson; - return View(dto); + return View("Intake/Terms", dto); } session.AgreedToTerms = true; @@ -413,7 +413,7 @@ public class KioskController : Controller ViewBag.ShowInactivityTimer = false; // Handled by the countdown JS in the view ViewBag.IsInPerson = session.SessionType == KioskSessionType.InPerson; ViewBag.FirstName = session.CustomerFirstName; - return View(); + return View("Intake/Confirmation"); } // ========================================================================= diff --git a/src/PowderCoating.Web/Program.cs b/src/PowderCoating.Web/Program.cs index 044fc35..23342f0 100644 --- a/src/PowderCoating.Web/Program.cs +++ b/src/PowderCoating.Web/Program.cs @@ -727,6 +727,12 @@ app.UseMiddleware(); // Track authenticated user presence (throttled, in-memory) app.UseMiddleware(); +// Kiosk intake steps use /Kiosk/Intake/{token}/{action} so the token is a path segment +app.MapControllerRoute( + name: "kiosk_intake", + pattern: "Kiosk/Intake/{token}/{action}", + defaults: new { controller = "Kiosk" }); + app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); diff --git a/src/PowderCoating.Web/Views/Kiosk/Welcome.cshtml b/src/PowderCoating.Web/Views/Kiosk/Welcome.cshtml index 8fbbe4d..e06550d 100644 --- a/src/PowderCoating.Web/Views/Kiosk/Welcome.cshtml +++ b/src/PowderCoating.Web/Views/Kiosk/Welcome.cshtml @@ -23,8 +23,8 @@
- Ready + border-radius:50%;background:#94a3b8;margin-right:6px;transition:background 0.3s;"> + Connecting…
diff --git a/src/PowderCoating.Web/wwwroot/js/kiosk-welcome.js b/src/PowderCoating.Web/wwwroot/js/kiosk-welcome.js index c656f09..e249e91 100644 --- a/src/PowderCoating.Web/wwwroot/js/kiosk-welcome.js +++ b/src/PowderCoating.Web/wwwroot/js/kiosk-welcome.js @@ -5,44 +5,54 @@ if (!el) return; const companyId = el.dataset.companyId; - if (!companyId) return; + const dot = document.getElementById("kiosk-conn-dot"); + const label = document.getElementById("kiosk-conn-label"); + + function setStatus(color, text) { + if (dot) dot.style.background = color; + if (label) label.textContent = text; + } + + if (!companyId) { + setStatus("#ef4444", "Not configured (no company ID)"); + console.error("KioskHub: data-company-id is empty — kiosk activation may be invalid."); + return; + } + + setStatus("#94a3b8", "Connecting…"); const connection = new signalR.HubConnectionBuilder() .withUrl(`/hubs/kiosk?companyId=${companyId}`) .withAutomaticReconnect([2000, 5000, 10000, 30000]) - .configureLogging(signalR.LogLevel.Warning) + .configureLogging(signalR.LogLevel.Information) .build(); connection.on("StartIntake", function (sessionToken) { + setStatus("#2563eb", "Starting…"); window.location.href = `/Kiosk/Intake/${sessionToken}/Contact`; }); async function startConnection() { try { await connection.start(); + setStatus("#16a34a", "Ready"); + console.info("KioskHub connected, group kiosk-" + companyId); } catch (err) { - console.warn("Kiosk SignalR connect failed, retrying in 10s...", err); + setStatus("#ef4444", "Connection failed — retrying…"); + console.warn("KioskHub connect failed, retrying in 10s…", err); setTimeout(startConnection, 10000); } } startConnection(); - // Show connection status indicator - connection.onreconnecting(() => { - const dot = document.getElementById("kiosk-conn-dot"); - if (dot) dot.style.background = "#f59e0b"; - }); - + connection.onreconnecting(() => setStatus("#f59e0b", "Reconnecting…")); connection.onreconnected(() => { - const dot = document.getElementById("kiosk-conn-dot"); - if (dot) dot.style.background = "#16a34a"; + setStatus("#16a34a", "Ready"); + console.info("KioskHub reconnected"); }); - connection.onclose(() => { - const dot = document.getElementById("kiosk-conn-dot"); - if (dot) dot.style.background = "#ef4444"; - // Keep retrying + setStatus("#ef4444", "Disconnected — retrying…"); setTimeout(startConnection, 10000); }); })();