fix(GRO-2012): pass portalSessionId to RescheduleFlow for SSO bridge customers (closes#38)
- src/portal/CustomerPortal.tsx:329 - use portalSessionId fallback for RescheduleFlow
- src/__tests__/portal.test.tsx - new regression test
- UAT_PLAYBOOK.md §5.26 - new test cases
cc @cpfarhood
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Root cause: SW remained in waiting phase after redeploy, serving stale
precached assets. Without skipWaiting/clientsClaim the old SW persisted
and controlled the page even after a new SW was installed.
Fixes blank-page regression where React never mounted on login.
App.tsx lines 389-393 redirected ALL authenticated users to /admin,
breaking customer portal access after SSO login.
Now checks `session.user.role === "staff"` before redirecting.
Customers (role !== "staff") can access the portal at /.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
QA regression: PR #26 removed fireEvent and waitFor from the
@testing-library/react import, breaking 21 test cases and typecheck.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Lines 28 and 40 access mock.calls[0] which is possibly undefined under
strict TypeScript. Adding ! to satisfy TS2532.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add a StatusBadge component that renders human-readable labels
(Confirmed, Pending, Waitlisted, etc.) with semantic color classes
for appointment cards in the portal. Replaces raw status strings.
- Added STATUS_LABELS map for human-readable status labels
- Updated STATUS_COLORS to use accessible amber/blue tones
- Exported StatusBadge for testing
- Added unit tests for all 7 badge states plus fallback
- Updated UAT_PLAYBOOK.md §5.12c with status badge test cases
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- analytics.test.ts: add vi to vitest import (was used at lines 24, 37, 66)
- BookingError.test.tsx: use regex matchers so phone/email assertions
match partial text in combined <p> element
Co-Authored-By: Paperclip <noreply@paperclip.ing>
GRO-1793: Dynamic portal time slots (replace hardcoded) (#23)
Replaces hardcoded time slot arrays in portal BookingFlow and RescheduleFlow with API-fetched dynamic availability.
QA review pointed out:
- Lint error: 'act' imported but never used in test file
- 6 test failures: date input lacked accessible label
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Gro-1794 required UAT test cases for the booking funnel analytics events.
Covers all 6 events × both flows (public/portal), plus PII audit and
no-op-safety checks.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- New analytics utility (src/lib/analytics.ts) with ANALYTICS_EVENTS constants
and fireAnalyticsEvent() – thin wrapper over window.dispatchEvent, no-op safe
Built for Plausible/GTM integration later.
- Public booking wizard (Book.tsx): fires step-transition events at each step
(service → time → contact → submit) plus booking_confirmed on the dedicated
confirmation page.
- Portal BookingFlow (Appointments.tsx): fires equivalent events for the
portal booking flow. booking_confirmed fires via useEffect when the inline
success state is shown.
- BookingErrorPage: fires booking_error on mount (no PII in payload).
Events include step name and flow type (public/portal) but contain no PII:
no names, emails, phone numbers, or pet names in any payload.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Both BookingFlow and RescheduleFlow in Appointments.tsx now fetch
from /api/book/availability when a date is selected, matching the
public booking wizard behavior. Loading and error states shown.
- Removed hardcoded availableTimes arrays from both flows
- Added useEffect that fetches availability on date change
- Shows "Checking availability…" while loading
- Shows error message on fetch failure
- Shows "No available slots" when API returns empty
Added tests for RescheduleFlow dynamic slot fetching covering:
loading, fetched slots, error, empty, API params, and re-fetch on
date change.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add "Start a new booking" button to BookingError linking to /admin/book
- Add "Book again" button to BookingCancelled linking to /admin/book
- Add business contact info section to BookingError (from BUSINESS_CONTACT_INFO constant)
- Replace hardcoded colors with CSS variables (--color-error, --color-cancelled, etc.)
- Add page-level string constants to eliminate hardcoded strings
- Add unit tests for both pages (9 tests passing)
Co-Authored-By: Paperclip <noreply@paperclip.ing>