Skip to content

Service booking · Nuxt & Laravel

JACOBS Drycleaners

Booking and customer management for a UK service business.

Product
JACOBS Dry Cleaners — booking and customer management, UK
Role
Full-stack developer, Global Shopaholics LLC
Scope
Nuxt.js front end on a Laravel 8 API, booking flow, staff admin
JACOBS Drycleaners case study cover

The tension

Two audiences, one system, and only one of them will ever read a manual.

What was happening

A dry cleaner with collection and delivery across a defined coverage area, taking bookings by phone and tracking them on paper.

What changed the brief

Staff needed an admin area at least as much as customers needed a booking form, so the build was two interfaces over one data model rather than a website with a form on it.

Success looked like

A customer booking a collection without calling, and staff managing that order without transcribing it.

The constraint

The service is geographically bounded. A booking outside the coverage area is worse than no booking, because someone has to unwind it.

The product story

Answer the two questions that stop a booking.

The offer

Professional cleaning, a few clicks away.

The landing view states the service and puts booking in reach, with the service promise close enough to be read before committing.

JACOBS Dry Cleaners — landing view
Booking is the primary action.Everything above the fold serves the decision to book.

Narrow first

Booked from a phone, usually.

The Nuxt layout reflows to one column and keeps the booking action reachable without scrolling back up.

JACOBS Dry Cleaners — mobile view
Same flow, one column.Server-rendered so the first paint is content, not a spinner.

The two blockers

Do you cover me, and what does it cost?

Coverage area and price list are first-class pages rather than footer links, because they are the two questions that end a booking before it starts.

JACOBS Dry Cleaners — full page
How we work, coverage, prices, FAQ.The nav is ordered by what a hesitant customer needs next.

Walkthrough

The booking flow in motion

Recorded from the live site.

The trust test

The happy path is only half the product.

The address is outside the coverage area

Coverage is checked against the booking rather than assumed, so an out-of-area request is refused at entry instead of being accepted and unwound by a person.

A staff member and a customer act at once

Order state lives on the API and both interfaces read it, so a status change is not something one side can miss because it was holding a stale copy.

The visitor arrives from search, mid-funnel

Every page is server-rendered and self-contained, so a customer landing directly on prices or coverage gets a page that works rather than a fragment of a flow.

The decisions

Three moves carried the story.

Make coverage a page, not a footnote

The service only exists inside a delivery radius, so the coverage area is navigation-level content — the cheapest possible place to lose an out-of-area booking is before it is made.

Server-render the marketing surface

Nuxt SSR so the service, coverage and pricing pages are indexable for a business whose customers find it by searching its town.

One API, two consumers

The Laravel 8 API serves the customer booking flow and the staff admin from the same models, so an order has one representation rather than two that drift.

What I would test next

The coverage check runs at booking time. Whether it should run at first visit, from the browser location, is a trade against asking for a permission nobody expects.