Work · Case study
Seven breakpoints, one basket, and a customer who can see what they are buying.
01 / Challenge
The online booking interface selected a venue from a plain text dropdown and hid services behind a popup overlay. There was no persistent basket, so a customer part-way through lost track of what they had chosen and what it cost, and the confirmation was a line of text inside the form. Mobile had two breakpoints. Drop-off was highest exactly where the flow was worst.
02 / Approach
The new flow was built as a parallel module inside the same Angular application rather than as a migration. Routing switched only once the new experience was complete and stable, which meant the legacy flow kept serving customers throughout and there was never a half-finished checkout in production.
Keeping feature parity was harder than the redesign. The old popup service selector carried complex dependencies around venue changes and cached service data, and reproducing that behaviour in a card-based inline UI meant lifting shared state into the parent component, driving it with RxJS BehaviorSubjects, and clearing cached services whenever the venue changed. The result is less code than it replaced.
The journey is now explicit — venue, services, date and time, confirm, confirmation — with a persistent order bar carrying a cart count and running total at every step. Seven breakpoints from 325px to 1440px replaced two, and skeleton shimmer loaders replaced a blank screen during data fetches.
03 / Outcome
responsive breakpoints, up from 2
reusable components
Venue selection is a visual card grid with imagery, address and opening hours instead of a dropdown. Services browse inline. The order bar keeps the total visible, and confirmation is a dedicated success screen. Behind it, ten-plus isolated reusable components replaced a monolith of nested popups, with lazy-loaded imagery, trackBy on lists and proper subscription cleanup.