A locked site they couldn't get into.
Every change to the old site meant finding someone who could edit raw HTML. Nobody at the practice could, and access to it had been lost entirely. It also couldn't simply be replaced: the old site stays online and keeps ranking, so the new one had to earn its way past it in search rather than redirect traffic from it.
Therapist profiles, each editable by the practice, with photo and credentials.
Lines of code the practice has to touch to update any page.
Login. Everything from page copy to team photos runs off one admin panel.
Six pages, none of them hardcoded.
Home, psychotherapy, testimonials, meet the team, patient information and contact. Every section on every page reads from the database, so the practice edits content rather than markup. All the real content came across from the old site first — eighteen staff, nine testimonials, eighteen downloadable resources — so nothing launched with placeholder text.


Good Day Therapy
Professional, evidence-based therapy. Helping you overcome difficulties, improve wellbeing, and have more good days.
Learn morePsychotherapy and counselling
Mobile first
The old site was built for desktop. Most people looking for a therapist are on a phone.
Content panel
Fixed sections per page, plus arbitrary extra blocks the practice can add and reorder.
Self-serve pages
They can create whole new pages themselves, with a slug and nav placement.
Enquiries
Contact submissions are written to the database first, then emailed — so none can be lost.
Built for someone who has never used a CMS.
There is one screen per public page, listed down the sidebar in the same order the pages appear in the site's own navigation. Open one and the fields run top to bottom in the order they appear on the live page, so editing feels like looking at the site rather than at a content tree. Nothing is called a “node”, a “block” or an “entity”.
It deliberately borrows the public site's palette but calms it down — a pale mint canvas, white cards, one teal action button per card — so the practice never has to wonder which of five buttons saves their work.
- Site Settings
- Home
- Psychotherapy
- Testimonials
- Meet The Team
- Contact Us
- Patient Information
- Pages
- Accepting bookings
- Accepting bookings
- Not bookable
Lists, not forms
Therapists, testimonials and resources are rows you add, reorder and delete in place — each expands into an inline editor rather than navigating to another screen.
Upload where it's used
Photos and resource files drop onto the row they belong to. No separate media library to browse and no file paths to copy.
Extra sections
Beyond each page's fixed sections, the practice can add their own — optional image, title, body — and drag them into any order.
Whole new pages
They can create pages that don't exist yet: title, URL slug, whether it appears in the nav, and the same section editor.
A safe toggle
Marking a therapist as not accepting bookings pulls them out of the booking search without removing them from the team page.
One login
No roles, no permissions matrix, no per-user setup. The practice is one team sharing one account, so anything else would be furniture.
A request, deliberately not a booking.
Patients search and filter across all eighteen therapists, then ask for a time. It stops there on purpose: no diary sync, no availability promises, no payment. A therapy practice can't have a website auto-confirming appointments it hasn't checked, and money stays off the site entirely. Each therapist has a toggle that takes them out of the search without removing them from the team page.
Find a therapist
- Select
- Select
- Select
Goes to the practice as an enquiry. Nothing is confirmed until they reply.
The unglamorous half of the job.
Most of the last stretch wasn't design. It was moving the database onto managed Postgres, writing the rewrite rules the host needed for clean URLs, and walking a non-technical client through buying a domain and choosing hosting — which meant writing plain-English comparison documents rather than just picking for him.
Moved from local MySQL to Supabase Postgres, with migrations checked in.
Stayed on the host they'd already paid for, which runs PHP natively — no rebuild, no new monthly cost.
Domain attached to Microsoft 365, mail records cut over, site records left untouched.
I built the booking feature before agreeing what it was worth. It was an optional extra in the proposal, it worked, and then it sat unlinked from the navigation waiting on a conversation about scope that should have happened first. Building it was the easy part.