NEXSUM_LABS
  1. Home
  2. Work
  3. A fitness-booking startup rebuilt its member dashboard and cut booking time by a third
Book a call

[ Case study ]

FitnessReact 19React ActionsTypeScriptVitest

A fitness-booking startup rebuilt its member dashboard and cut booking time by a third

Members booked classes through a dashboard that had grown feature-by-feature for two years. The booking flow took nine interactions across three pages, support tickets showed members giving up, and the component code had no shared state model — every fix risked breaking another.

CLIENT a fitness-booking startup — FOCUS Model the state before the screens

React DevelopmentWeb DevelopmentReact DevelopmentFitnessRepresentative example
Client
a fitness-booking startup
Industry
Fitness
Engagement
8 weeks — experience pod — frontend engineer + designer
Service
Web Development / React Development
Headline outcome
Median time from dashboard open to confirmed booking, measured over 6 weeks of usage after full rollout: −38%, read from Product analytics event timing

Representative examplesEvery case study in this library is an illustrative composite of the kind of engagement we deliver — written to show our method and standards, not to name clients.

Where they started

This startup runs class booking for boutique fitness studios — members buy passes, browse schedules, and book through the web dashboard. The frontend grew feature-by-feature across two years of startup pace: waitlists, pack purchases, instructor substitutions, each bolted on by whichever developer was free. Members book mostly on phones between classes. The in-house team knew the dashboard had become fragile, and knew equally well that nobody could pause bookings to fix it.

What it was costing

Members booked classes through a dashboard that had grown feature-by-feature for two years. The booking flow took nine interactions across three pages, support tickets showed members giving up, and the component code had no shared state model — every fix risked breaking another.

What they could see

  • Booking a class took nine interactions across three pages, and members abandoned mid-flow on phones.
  • Support tickets showed members double-booking, losing waitlist places, or never learning whether a spot was held.
  • Fixing one screen routinely broke another; every release needed a full manual test pass.
  • Keyboard users couldn't finish a booking at all — the team knew, and had parked it.

The constraints we worked inside

  • The booking API was fixed and rate-limited; the frontend had to live within its quotas.
  • The redesign shipped behind the existing one — members switched over per feature, not in a big-bang release.
  • Accessibility was a stated requirement: keyboard paths and screen-reader labels were acceptance criteria, not aspirations.

What had been tried before

The team rewrote the booking flow as a new page next to the old ones.
Without a shared state model the new page duplicated logic, diverged within weeks, and left members crossing between versions mid-booking.
A third-party scheduling widget was trialed as an embed inside the dashboard.
It couldn't sit behind the fixed booking API's quotas, its styling fought the brand, and accessibility failed review immediately.

What we proposed

We proposed modeling booking state first — schedule, waitlist, and passes in one typed client store — then rebuilding the flow to a single schedule view with an inline confirm, shipped screen by screen behind flags per member cohort. The rate-limited booking API set the rules: reads get cached and batched, mutations get optimistic UI with honest pending states, and the frontend stays inside quota even on Saturday mornings. Accessibility criteria — keyboard paths, screen-reader labels — were acceptance criteria for every screen, not a phase.

Just as important is what we ruled out, and why:

  • A big-bang release of the redesigned dashboardMembers book at predictable peak windows; a single cutover concentrates every unknown risk into one Saturday.
  • Replacing the flow with a third-party booking widgetThe fixed, rate-limited booking API and the accessibility acceptance criteria ruled out anything that couldn't live inside both.
  • Native mobile apps instead of the web dashboardMembers book from links and search on phones; an app build was months of scope against an eight-week window.

How the work ran

01Model the state before the screens

We mapped booking state (schedule, waitlist, passes) into one typed client store, then built screens against it — eliminating the cross-page inconsistencies.

02Cut the flow to three interactions

The nine-step flow became a single schedule view with an inline confirm, designed against the task, not the old page boundaries.

03Ship feature-by-feature behind flags

Each replaced screen toggled per cohort, so regressions surfaced in days on real bookings instead of at a cutover.

Delivered by the experience pod — frontend engineer + designer over 8 weeks, with working increments reviewed with the client every week.

The stack, and the reasoning

React 19
Their two frontend developers already ship React daily; a framework change would have doubled the risk of an already risky rebuild behind a live booking surface.
React Actions
Booking mutations with optimistic updates and honest pending states, co-located with the form — no state library to learn mid-project for flows the store already models.
TypeScript
The disease was cross-page state drift; typing schedule, waitlist, and passes in one store turns a whole class of booking bugs into compile errors.
Vitest
Fast unit tests over the booking store run per commit; feature-flag rollouts need a cheap feedback loop more than they need exhaustive suites.
Playwright
Keyboard paths and screen-reader labels were acceptance criteria, so they were verified as end-to-end tests on real flows, not checked once by hand.

What went wrong

Obstacle

Load testing in week three tripped the booking API's rate limits — the redesigned flow made more calls per booking than the one it replaced.

Handled: Their account manager renegotiated the booking API's quota mid-build — the negotiation we now say belonged in week one — and the caching layer for schedule and capacity reads was sized to the renegotiated headroom rather than asked to absorb the ceiling.

Obstacle

Cohort flag rollouts confused the support team, who were answering two members on the same day who were seeing different dashboards.

Handled: We gave support a flag-state lookup and a one-line explanation script, pinned cohorts to member IDs, and the contradictions stopped within a week.

How we worked together

Cadence
Twice-weekly demo calls aligned to sprint boundaries, with the flag dashboard reviewed on each call; cohort feedback from support arrived in a shared channel daily.
Client side
A product manager owned scope and flag decisions; two frontend developers paired with us from week two; a support lead triaged cohort feedback.
Decisions
Flow decisions were made against the task model in the demo; API quota trade-offs went to their CTO; accessibility criteria were fixed and never traded.
They provided
API documentation and a staging key with realistic quotas, member research and support ticket extracts, design input, and developer pairing time.

What changed

The headline: median time from dashboard open to confirmed booking, measured over 6 weeks of usage after full rollout−38%, read from Product analytics event timing. A second check: booking-abandonment support tickets at −31%.

The developers ship dashboard changes without the pre-change shudder; the typed state model made cross-feature breakage a compile error instead of a support ticket. Support talks to product about features now rather than translating member complaints. Members finish bookings on the first screen they land on, and the cohort flags came down because nobody needed a safety net anymore. The booking flow stopped being the app's apology.

The result was read from Product analytics event timing against the pre-engagement baseline over the stated window, with a guardrail check on booking-abandonment support tickets. Where platform-reported numbers and business outcomes differ, this record says which layer it is quoting.

What they own now

  • The rebuilt dashboard codebase with typed store, tests, and flag definitions documented.
  • The Playwright suite covering keyboard paths, runnable before any release.
  • A flag dashboard for cohort rollouts, with the support team's explanation script.
  • The API caching layer with quota notes and the vendor escalation contact.
  • A component inventory showing which screens are rebuilt and which remain on the old path.

What we would do differently

We would have negotiated API quota headroom earlier — rate limiting forced a caching layer we should have specified in week one.

Web DevelopmentReact DevelopmentFitnessReact 19

Next case study

A nine-school education group went from nine WordPress installs to one admin