Compare commits

...

2 Commits

Author SHA1 Message Date
spouliot 8caaa84eac Hide Start Intake button when kiosk not activated; relabel remote link
- Start Intake button only shows when company has an active kiosk token
- Remote Link button renamed to "Send Intake Link" for clarity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:00:09 -04:00
spouliot e70f7ee9f1 Fix kiosk logo: add anonymous Logo endpoint proxying blob storage
CompanySettings/Logo requires tenant context and fails on anonymous
kiosk pages. Added Kiosk/Logo which resolves the company from the
KioskDevice cookie and proxies the blob directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 16:55:44 -04:00
3 changed files with 37 additions and 8 deletions
@@ -368,6 +368,9 @@ public class DashboardController : Controller
ViewBag.GuidedActivationBanner = BuildGuidedActivationBanner(companyPrefs); ViewBag.GuidedActivationBanner = BuildGuidedActivationBanner(companyPrefs);
ViewBag.ShopProgressWidget = await BuildShopProgressWidgetAsync(currentCompanyId.Value, companyPrefs); ViewBag.ShopProgressWidget = await BuildShopProgressWidgetAsync(currentCompanyId.Value, companyPrefs);
var companyForKiosk = await _unitOfWork.Companies.GetByIdAsync(currentCompanyId.Value);
ViewBag.KioskActivated = !string.IsNullOrEmpty(companyForKiosk?.KioskActivationToken);
} }
return View(vm); return View(vm);
@@ -38,6 +38,7 @@ public class KioskController : Controller
private readonly IEmailService _emailService; private readonly IEmailService _emailService;
private readonly IHubContext<KioskHub> _kioskHub; private readonly IHubContext<KioskHub> _kioskHub;
private readonly ILogger<KioskController> _logger; private readonly ILogger<KioskController> _logger;
private readonly ICompanyLogoService _logoService;
/// <summary>Initialises all dependencies for the kiosk controller.</summary> /// <summary>Initialises all dependencies for the kiosk controller.</summary>
public KioskController( public KioskController(
@@ -47,7 +48,8 @@ public class KioskController : Controller
IInAppNotificationService inApp, IInAppNotificationService inApp,
IEmailService emailService, IEmailService emailService,
IHubContext<KioskHub> kioskHub, IHubContext<KioskHub> kioskHub,
ILogger<KioskController> logger) ILogger<KioskController> logger,
ICompanyLogoService logoService)
{ {
_unitOfWork = unitOfWork; _unitOfWork = unitOfWork;
_mapper = mapper; _mapper = mapper;
@@ -56,6 +58,7 @@ public class KioskController : Controller
_emailService = emailService; _emailService = emailService;
_kioskHub = kioskHub; _kioskHub = kioskHub;
_logger = logger; _logger = logger;
_logoService = logoService;
} }
// ========================================================================= // =========================================================================
@@ -83,6 +86,26 @@ public class KioskController : Controller
return View(); return View();
} }
/// <summary>
/// Serves the company logo for anonymous kiosk pages. Resolves the company from the
/// KioskDevice cookie so no tenant context is needed on the anonymous request.
/// </summary>
[AllowAnonymous]
[HttpGet, ResponseCache(Duration = 3600, Location = ResponseCacheLocation.Any)]
public async Task<IActionResult> Logo()
{
var cookie = ReadKioskCookie();
if (cookie == null) return NotFound();
var company = await _unitOfWork.Companies.GetByIdAsync(cookie.Value.companyId, ignoreQueryFilters: true);
if (company == null || string.IsNullOrEmpty(company.LogoFilePath)) return NotFound();
var (success, fileContent, contentType, _) = await _logoService.GetCompanyLogoAsync(company.LogoFilePath);
if (!success || fileContent.Length == 0) return NotFound();
return File(fileContent, contentType);
}
// ========================================================================= // =========================================================================
// DEVICE ACTIVATION (CompanyAdmin-only) // DEVICE ACTIVATION (CompanyAdmin-only)
// ========================================================================= // =========================================================================
@@ -648,7 +671,7 @@ public class KioskController : Controller
{ {
ViewBag.CompanyName = company.CompanyName; ViewBag.CompanyName = company.CompanyName;
ViewBag.CompanyLogoUrl = !string.IsNullOrEmpty(company.LogoFilePath) ViewBag.CompanyLogoUrl = !string.IsNullOrEmpty(company.LogoFilePath)
? $"/CompanyLogo/{company.Id}" ? Url.Action("Logo", "Kiosk")
: null; : null;
ViewBag.WelcomeUrl = "/Kiosk/Welcome"; ViewBag.WelcomeUrl = "/Kiosk/Welcome";
await Task.CompletedTask; await Task.CompletedTask;
@@ -33,13 +33,16 @@
</p> </p>
<div class="d-flex gap-2 flex-wrap align-items-center"> <div class="d-flex gap-2 flex-wrap align-items-center">
<a asp-controller="Jobs" asp-action="Board" class="btn btn-sm btn-primary">Open Jobs Board</a> <a asp-controller="Jobs" asp-action="Board" class="btn btn-sm btn-primary">Open Jobs Board</a>
<button type="button" class="btn btn-sm btn-outline-info" id="btnStartIntake" @if (ViewBag.KioskActivated == true)
title="Push the intake form to the front-desk tablet"> {
<i class="bi bi-tablet me-1"></i>Start Intake <button type="button" class="btn btn-sm btn-outline-info" id="btnStartIntake"
</button> title="Push the intake form to the front-desk tablet">
<i class="bi bi-tablet me-1"></i>Start Intake
</button>
}
<a href="/Kiosk/SendRemoteLink" class="btn btn-sm btn-outline-secondary" <a href="/Kiosk/SendRemoteLink" class="btn btn-sm btn-outline-secondary"
title="Email a customer a link to fill out the intake form on their own device"> title="Email a customer a link to fill out the intake form remotely">
<i class="bi bi-envelope-at me-1"></i>Remote Link <i class="bi bi-envelope-at me-1"></i>Send Intake Link
</a> </a>
@if (!string.IsNullOrEmpty(Model.TipOfTheDay)) @if (!string.IsNullOrEmpty(Model.TipOfTheDay))
{ {