- 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>
- 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>
- PetForm interface: add sizeCategory and coatType fields
- EMPTY_PET: initialise new fields as empty strings
- openEditPet: pre-populate from pet.petSizeCategory and pet.coatType
- submitPet body: include petSizeCategory and coatType in POST/PATCH
- Pet form UI: add Size Category and Coat Type dropdowns after Breed field
- Size: Small / Medium / Large / X-Large (maps to enum values)
- Coat: Smooth / Double / Curly / Wire / Long / Hairless (maps to CoatType union)
- Both optional — blank "Not set" option matches API optional semantics
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit ports the GRO-1173 admin UI changes from the app monorepo
into the extracted groombook/web repo, using the correct source paths
(src/ instead of apps/web/src/):
- New BufferRulesSection component (full CRUD UI for /api/buffer-rules)
- Default Buffer (minutes) field added to service create/edit form
- Size Category and Coat Type dropdowns added to PetForm (portal)
- @groombook/types Service interface extended with defaultBufferMinutes
- BufferRulesSection embedded in Settings page
The PetForm already had coatType — this commit adds petSizeCategory
and renders both fields with proper dropdown selectors.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add Pet Size dropdown (Small, Medium, Large, X-Large) after breed field
- Add Coat Type dropdown (Smooth, Double, Curly, Wire, Long, Hairless)
- Pass petSizeCategory + petCoatType as query params to availability endpoint
- Include petSizeCategory + petCoatType in POST /appointments body
- Show "appointment" duration label on confirm (service duration only)
- Display pet size/coat on confirmation card when provided
- Pre-fill from URL params
- Reset form resets all new fields
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Copy apps/web/ with all src, components, pages, portal
- Inline packages/types/ as local packages/types module
- Add tsconfig path aliases for @groombook/types
- Port Dockerfile and CI workflow
- Image name: ghcr.io/groombook/web
Co-Authored-By: Paperclip <noreply@paperclip.ing>