Introduce getLondonTodayCalendarDate(), parseWallClockDate(), and formatLocalDateTime() for reliable Europe/London timezone handling. Replace ad-hoc SvelteDate/new Date() usage with these utilities across all components and stores.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add print receipt feature to UserBookingModal with full VAT breakdown. Fix VAT rate display (remove double *100). Show VAT breakdown (net + VAT) on booking confirmed page. Add VAT info to EditBookingModal. Show incl. VAT label on BookingFlow total, schedule, and today dashboard. Add VAT note to prices page. Show booking total amount on account page. Improve VAT enable toast in BusinessSettings.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add jsdom and vitest dev dependencies. Add total_vat_amount and total_net_amount to PaymentSummary type. Create shared businessInfo store for caching public business settings.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Compute time range dynamically from working hours, bookings, and blockers instead of hardcoded 8-18. Fix gridPxFromTime to use SLOT_HEIGHT instead of HOUR_HEIGHT for accurate pixel positioning.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add BusinessSettings component with edit modal for managing VAT, gift card, voucher and contact settings. Add BusinessSettings and UpdateBusinessSettingsRequest types.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add out_of_hours toggle, slot detection and badge to BookingCreateModal. Show out-of-hours badge on BookingModal detail view. Display warning banner on SelectedTimeSummary for out-of-hours slots. Highlight out-of-hours slots with red styling in TimeSlotList.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add inline name editing on account page with validation, and GDPR data export page with cooldown timer.
- Inline edit first/last name with unicode-aware regex validation
- GDPR export page with countdown timer between exports (12h cooldown)
- Display referral savings instead of calculated estimate
- Add log out button in account settings section
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Update frontend types, stores, and components to support name history display and new API fields.
- Add previousFirstName/previousLastName to User type and BookingUser type
- Add referral discount_source type and refunds array to Booking type
- Create nameDisplay.ts utility for rendering '(formerly ...)' labels
- Create booking.ts utility for booking-related helpers
- Update 25+ admin, payments, today, and account components to display
former names on booking cards, modals, appointment views, and user lists
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Restructure loyalty card: show completed-card banner above card, support multi-card display (stamps % 10), move from gradient to flat bg, update text to reflect multi-card and remaining stamps.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The 14-day refresh threshold was designed for the old 30-day tokens but the backend now emits 1-hour tokens. The threshold caused every page load to trigger an immediate /refresh-token call, which revoked the old JTI mid-flight while concurrent requests (profile, giftcards, bookings, etc.) were still using it, causing 401 errors.
Changes:
- Refresh threshold: 14 days -> 5 minutes (matches 1-hour token lifetime)
- Interval check: 60 min -> 2 min (must be shorter than threshold)
- Race condition: refresh now completes before profile fetch, preventing JTI invalidation during concurrent requests
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Shows the total amount already paid in the cancellation confirmation, plus deposit-specific messaging: forfeiture warning when deposit is paid, and a note that outstanding deposit is no longer due when deposit is required but not yet paid.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace Card component with custom card design: group bookings by month, add color-coded status bars/badges/dots, fly transitions, loading skeletons, empty state with calendar icon, and improved time/date formatting. Remove dependency on shadcn Card component.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Load Playfair Display from Google Fonts via preconnect and stylesheet in root layout, then apply to h1 headings on BookingFlow, Account, and Contact pages for a consistent brand typography.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace current/next card with done-for-day summary state when all appointments are finished. Shows daily stats (payments, tips, duration, customers) and week summary when tomorrow is closed. Fix schedule grid z-index to remove stacking context that caused overlay issues.
Ultraworked with Sisyphus
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Update BookingFlow to support custom service selection, add custom_services to booking types, and link CustomServicesManagement into admin pages. Minor updates to schedules, prices, and today routes.
Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add CustomServicesManagement component for CRUD operations on custom services. Update BookingCreateModal, WalkInCreateModal, and BookingsCard to support custom service selection. Minor improvements to ServicesManagement and ImageUpload.
Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace raw <Input type="email"> with <EmailInput> in login (register + login), account (gift card recipient), BookingFlow (guest email), and GiftCardsManagement (admin gift card email).
Removes 30-line validateEmail() function from login page (now handled by EmailInput internally).
Removes validateEmailFormat() from BookingFlow (EmailInput handles format validation; debounced backend email check preserved via onvaluechange/onblur).
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Changed purchase flow to use generateIdempotencyKey() which uses secure
window.crypto.getRandomValues with a math fallback, avoiding secure-context blocks on HTTP
- Log actual error to console in both Buy and Redeem catch blocks
- Added generic formatAndPreserveCursor() helper on frontend to track
and restore selection caret position during dynamic input sanitization
- Applied to all card inputs, gift card code inputs, and expiry inputs
- Added Luhn validation (isValidLuhn) for saved cards and gift cards
- Rebuilt payments test DB and got 100% green tests
New /gdpr route: skeleton loading state, 2s polling for async export, styled report cards/tables matching /schedule and /account styling. 16 data sections with conditional rendering (empty sections hidden). VAT breakdowns hidden until any payment has non-zero VAT. Deposits Required hidden when 0. PDF export via window.print() with print CSS hiding navbar and verification banner. Raw JSON download button. Export My Data button added to Account page under Change Password. Vite worker format set to 'es' for WASM encoder compatibility.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>