Case study

Running a neighbourhood gym from one screen

Related project

Challenge

Željezna Generacija in Hrasnica was run from a notebook and a group chat. Three questions took manual counting every time: who is a member right now, whose membership expires this week, and did this month cover its costs. Off-the-shelf gym software wanted card payments, turnstiles and an app on every member’s phone — none of which describes a gym where most people pay cash at the counter.

Approach

We designed around the counter, not around a feature list. The first question was never which modules the gym wants — it was what happens in the ninety seconds while a member pays, who touches the record, and what the owner needs to see on the first of the month. That produced one decision the rest follows from: a member record is not a login account. Members exist in the system whether or not they ever install anything, and the app is an option for those who want it, not a precondition for being counted.

Solution

One Next.js 16 application over one Postgres database, with three surfaces: a public website, a members’ portal built for the phone, and the owner’s panel. Memberships, cash and card-free payments, supplement stock and sales, orders, equipment, expenses and website enquiries all live in the same system, so the monthly picture assembles itself instead of being reconstructed. Prices and stock are computed by database functions — the client sends a plan code and a quantity, never an amount — and row-level security on every table keeps finances, cost prices and other members’ data away from member accounts. The public site’s content is edited from the panel, so changing a price or adding a photo does not require a developer.

Technology

Next.js 16 (App Router, server components), TypeScript, React 19, Tailwind CSS v4 on Base UI, Recharts, and Supabase for Postgres, auth and object storage — 15 tables, 38 row-level policies and 12 SQL functions, with a test script that stands up a throwaway database and checks the security rules instead of trusting them. Hosting on Vercel, database in Frankfurt.

Outcome

The owner opens one screen and the month is there: revenue, expenses, net, active members, who expires within seven days, which supplements are running out, which enquiries are unanswered. Members whose membership is ending get an email on their own. The gym’s website is no longer a thing that needs a developer to change — pricing, gallery, opening hours and transformation stories are edited in the panel, and a 51-step guided tour explains the whole panel in the language the owner actually speaks.

← View all case studies
Similar problem?

Let's talk.