A photographer's site, and the private admin app that runs the business
A two-part build for a Dutch wedding photographer. A bilingual public portfolio that treats every photo as a deliverable, and a private admin dashboard that handles bookings, contracts, invoices and reviews. The brief: "I want to focus on the photography, not the admin."
What was built
A two-part platform that splits the photographer's workflow cleanly between what visitors see and what the photographer manages.
The public site is a fully static, bilingual portfolio with seven category pages, a discovery-call booking flow, transparent pricing for every package tier, a service contract, and a reviews surface. Performance-optimised, mobile-first, with proper SEO: canonical tags, hreflang, JSON-LD LocalBusiness markup, sitemap, structured author info.
The admin app is a private dashboard that runs every operational side of the business: a calendar that's the source of truth for availability, a clients table with auto-generated client codes, a contract module that produces tokenised click-to-accept signing links, an invoice module with Dutch-format numbering and Mollie-powered payment links, a review request flow that emails clients tokenised submission links and gates publication behind admin approval, a photo manager backed by Supabase Storage, and a settings module for business details.
Both halves are connected through Supabase RPCs so the public booking form lands directly in the admin's calendar with no manual sync.
Three challenges, three solutions
1 Photo display: full-frame versus cropped thumbnails
The problemThe first version of the portfolio used a tiled mosaic where every card was forced into a fixed aspect ratio. Landscape and portrait shots got cropped to fit, which meant heads, hands, or context were chopped out of the photographer's actual work. For a photographer, the photo is the product, so any auto-crop was eroding the value of every visit.
What we consideredTightening the crop with object-position per image was the cheapest fix, but it just moved the problem around. The proper fix was to abandon the tiled mosaic and let each photo show at its own natural aspect ratio.
A natural-aspect masonry layout: two columns on mobile, three on tablet, four on desktop. Photos flow into columns at their full composition, never cropped. Tap any photo to open a full-screen lightbox with arrow-key and on-screen navigation through that gallery.
Why it mattersMobile especially: the previous wide-card layout was cutting off portrait shots top-and-bottom on phones, which is where most of the inbound traffic comes from. The masonry preserves every frame, the lightbox treats each photo as a deliverable rather than a swatch, and engagement (time-on-page and scroll-depth) climbed measurably after the change. There's a trade-off. A tiled mosaic of identical card sizes looks "designed", and natural-aspect masonry looks more honest but less curated. For a photographer, honest wins; for a different industry the call could go the other way.
2 Book-a-call: from three steps to two with a popup date picker
The problemThe original book-a-call page was a three-card flow: Step 1 pick a date, Step 2 pick a time slot, Step 3 fill in your details. On desktop the three cards spread across the screen and looked balanced; on mobile they stacked into a long scroll where Step 2's slot grid sat between Step 1's calendar and Step 3's form fields. Tapping a slot didn't feel like a commitment because the actual "Confirm booking" button was hundreds of pixels below, after seven form fields. Drop-off was high.
The solutionConsolidated to two steps. A "Pick your date and time" surface with a popup date picker that opens on tap, hands the chosen date to a slot grid, and slides shut once the slot is selected. The form fields drop into the same screen, and the submit button is always reachable without a scroll. The slot pulses once on tap and the page smooth-scrolls to the submit so the visitor sees the next action immediately.
Why it mattersThe decision to book is emotional. Every extra scroll, every "wait, where's the button" moment, is a chance to lose the visitor. Two screens of focused decision-making converts dramatically better than three loosely-coupled cards. The popup pattern also fixed an iOS-specific issue where the slot grid was being briefly hidden by the keyboard appearing for the form fields.
3 Mollie API integration versus manual payment links
The problemOriginally the photographer sent invoices as PDFs and chased payment by hand: copy the IBAN, paste into a WhatsApp message with the invoice number as reference, wait, follow up, mark paid in the admin once the bank notification arrived. This was friction for both sides. The photographer was a part-time accountant; the client was navigating a foreign-bank IBAN flow without confirmation that the right reference was used.
The solutionMollie integration via API. Invoices generated in the admin app now produce a hosted Mollie checkout URL automatically. The client clicks the URL in the invoice email, pays with iDEAL or card, and Mollie webhooks the admin app to flip the invoice status from sent to paid without anyone touching the dashboard. The Mollie payment description shows the actual line item, for example "Photography services — Half Bloom · Invoice 2026-611-00004-001", so the customer's bank statement is recognisable rather than a cryptic accounting reference.
Two specific gains. First, time saved per invoice: roughly fifteen minutes of back-and-forth replaced by a single click for the client and zero clicks for the photographer. Second, faster cash-in: clients pay in the moment rather than letting an invoice sit in their inbox for a week, which directly improves cashflow. Overdue ratios dropped after the integration shipped.
What's behind the scenes
A few things worth highlighting that aren't visible on the public surface but make the platform robust:
-
Two-factor admin login.
Email-based step-up codes, session idle timeout, and a 30-day re-verification cycle. The admin app is a strict whitelist of two emails.
-
Tokenised click-to-accept contracts.
Each contract records the signed timestamp, IP, and user-agent for legal validity, replacing third-party DocuSign overhead.
-
Invoice numbering.
A Dutch-format sequential pattern,
{year}-{package_code}-{client_code}-{invoice_seq}, that's both human-readable and audit-friendly. -
Image protection layer.
The public portfolio deters casual saving (right-click block, drag-prevention, copy-suppression) while remaining accessible to legitimate users and search engines.
-
Bilingual everything.
Every public page exists in EN and NL with proper hreflang tags, so each language is indexed separately by Google.
What the photographer gets out of this
The split between public site and admin app means Leemar can manage everything from the dashboard and visitors only see the polished surface. New inquiries land in the calendar in real time. Contracts go out as tokenised links instead of email attachments. Invoices get paid faster through Mollie. Reviews are gated through approval before they go public.
I want to focus on the photography, not the admin. Original brief, Leemar H. Ritual
Most importantly, the system gets out of his way. The platform that's now running does about eighty percent of the operational work he used to do by hand.
What we'd take from this build
The big lesson is the value of splitting "what visitors see" from "how the business runs". Plenty of photographer sites try to be both: a portfolio with a back-office bolted on. That works until the back-office needs grow, at which point the public site starts feeling either over-engineered or hostile to edit. Treating them as two products that share data, but not chrome, kept both halves clean.
The other one: pick the integrations that remove a recurring fifteen minutes from the week, not the ones that look impressive in a demo. Mollie was unglamorous to wire up, and it's the single biggest quality-of-life change in the build.
Have a business that needs a clean public face and a serious back-office?
Engaging UX Design builds two-part platforms like this for service businesses across the Netherlands. A polished public portfolio for visitors, and a private admin app that handles the operational work: bookings, contracts, invoices, payments, reviews. Same stack, same care, scoped to your actual workflow.
Get a free estimate →