Unlike the course projects, this one is real and still running: memorylaneadelaide.com, the site for the photography studio I co-founded with my friend Mark Lee. I built it myself in plain HTML, CSS, and JavaScript, no framework, and I'm still the one who maintains and operates it.
It's a static site, but it doesn't behave like one. Supabase handles the backend: a database for booking enquiries, gallery photos, and blog posts, plus storage for the images behind them. On top of that I built a full admin dashboard, gated behind real Supabase Auth login rather than a fake password box, so the business side of the studio doesn't live in my head or a notebook.

The booking flow is the part that actually matters for the business: a client fills in an enquiry form, it lands in Supabase, and a Supabase Edge Function calls the Resend API to send Mark and me an email straight away. Neither of us has to remember to check a dashboard for new leads.

The dashboard turned out to be the bigger build. The main tab is effectively a small CRM for every enquiry that comes in: stat cards for quoted pipeline, booked revenue, completed revenue, and average deal size, three charts tracking status breakdown and enquiries and income by month, and a searchable, filterable table (by date range, service, or status) that carries each enquiry through a proper pipeline from new, to contacted, quoted, booked, completed, or cancelled, with a one-click PDF export of the bookings list.

Alongside the CRM tab, separate tabs manage the Helpful Advice blog, the gallery, and the homepage hero slider, so publishing a new post or photo doesn't need a code change or a deploy. There's also a Free Portrait Planner tab for running our occasional free-portrait-session promotions: create a session, publish the one that's currently open for bookings, and see registration counts against past sessions.
It started out hosted from a home NAS, which worked but showed its limits fast: an ugly URL with a port number in it, browser security warnings, and a router I didn't want exposed to the internet. I moved it to Cloudflare Pages instead, deployed straight from GitHub on every push, with the custom domain and SSL handled properly. Along the way I've fixed the unglamorous real-world problems that come with running an actual site: a 33 MB hero image that broke Cloudflare's asset size limit, an Open Graph image pointing at the wrong file extension so link previews came up blank, and a sitemap and robots.txt so Google actually indexes the right pages.
This is the one project on this page that doesn't stop when it's marked: real enquiries come through this exact form.