- /Jobs now redirects to ?statusGroup=active so completed jobs don't clutter the default view
- Add Completed pill (filters Completed + ReadyForPickup + Delivered)
- Pill badge counts are now global DB counts, not page-local item counts
- Ready pill badge now shows ReadyForPickup-only count
- All pill links to ?statusGroup=all to bypass the redirect
- Fix double-encoded & in Completed filter alert label
- Fix corrupted em dash (â€") in Customers/Details billing email fallback text
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When kiosk consent is completed, the staff-facing customer Details page
now updates the SMS badge instantly via SignalR — no page refresh needed.
Added customerId to the NewInAppNotification SignalR payload so the
KioskConsent handler can match the current URL and swap the badge in place.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Route param renamed customerId→id so /Kiosk/SmsConsent/15307 binds correctly
(default MVC route uses {id}; mismatched name caused GetByIdAsync(0)→404→loop)
- Cache entry cleared in GET (not just POST) so returning to Welcome after seeing
the form never redirects again
- Added POST /Kiosk/CancelSmsConsent for staff to free the kiosk if they pushed
consent accidentally — Customer Details shows a Cancel button after pushing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Notification bell:
- Bell now polls /InAppNotifications/Recent every 60s as a SignalR fallback
- Bell dropdown refresh on open so count is always current when staff looks at it
SMS consent → kiosk flow:
- Staff clicks "Get SMS Consent" on Customer Details → AJAX POST to
/Kiosk/PushSmsConsent stores customer in IMemoryCache (10 min TTL)
- Kiosk PollSession returns smsConsentPending + customerId so tablet navigates
to /Kiosk/SmsConsent/{customerId} automatically
- Customer reads TCPA consent on tablet, taps I Agree or No Thanks
- On agree: NotifyBySms/SmsConsentedAt/SmsConsentMethod set; in-app notification
fires; cache cleared; tablet returns to Welcome
- Removed Customers/SmsConsent (staff-browser version); moved view to Kiosk/
Button alignment:
- kiosk.css: added display:flex + align-items:center + justify-content:center to
all kiosk body buttons so content is centred vertically in tall button outlines
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New GET/POST Customers/SmsConsent/{id}: full-screen kiosk-layout page staff
opens and hands to the customer to read TCPA consent language and tap I Agree
- On agreement: sets Customer.NotifyBySms, SmsConsentedAt (UTC), SmsConsentMethod
= "InPerson", clears SmsOptedOutAt
- Redirects back if customer has already consented (no double-consent)
- Customer Details: "Get SMS Consent" badge link shown when NotifyBySms is false;
SMS on badge shows consent date on hover when consented
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Customer entity + DTO: new BillingEmail field (accounting/invoicing address)
- Email fields now accept comma-separated lists; DTO validates each address individually
- NotificationService: SendToEmailListAsync helper fans out to all addresses in a list;
NotifyQuoteSentAsync accepts optional overrideEmail so staff can send to an ad-hoc address
- Migration: AddCustomerBillingEmail
- Customer Create/Edit/Details views updated to show Billing Email field
- customer-billing-email.js: client-side helpers for billing email input
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added notification preference indicators to both views so staff can
see at a glance whether a customer has email/SMS enabled without
opening edit mode.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>