A single-tenant Next.js app for personal trainers to schedule and track events, and manage and invoice clients. Made in collaboration with and used in production by a real personal trainer (PT).
Warning
Client
in this context means the customer of the PT.
- Shared calendar between PT and each client, editable by PT only.
- Three calendar event types:
Workouts
, created by PT, which clients can check as done.Appointments
, with fees for billing.Bootcamps
, which clients can check to confirm attendance.
- Appointment attendance and fee data is viewable in a monthly table.
- Invoices can be generated and emailed to clients with a button click.
- Mobile-friendly calendar list-view for clients with infinite scroll.
- Custom forms via Contentful CMS, emailed to the PT when the client completes them.
- Built with Next.js 15 and React 19.
- Written in TypeScript.
- State management with Redux Toolkit and RTK Query.
- Data persistence with PostgreSQL.
- ORM using Prisma.
- Authentication using Auth.js.
- Styled using Tailwind CSS, Meraki UI, and shadcn/ui (Radix UI, TanStack Table).
- Deployed on Vercel.
- Production and staging databases on Railway.
- Automated database backups, testing and code quality with GitHub Actions.
- Migrate to multi-tenancy.
- You will need a PostgreSQL database.
- With Railway go to https://railway.app/new and click
Provision PostgreSQL
, then click on the new Postgres project, and grab theDATABASE_URL
from theConnect
tab. - Assuming you have
PostgreSQL installed, you could
instead create a local database for development with this command:
-
createdb mydatabase
- Then you can connect to it:
DATABASE_URL=postgresql://postgres:[YOUR_PASSWORD]@localhost:5432/mydatabase
-
- Assuming you have Docker installed,
you could
run Postgres in a Docker container:
-
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_DB=mydatabase -p 5432:5432 -d postgres
- Then you can connect to it:
DATABASE_URL=postgresql://postgres:mysecretpassword@localhost:5432/mydatabase
-
- With Railway go to https://railway.app/new and click
- You will need to set up an email account to work with Auth.js. I used Gmail. See the Auth.js docs and the nodemailer docs.
- The app uses Contentful as a CMS for the personal trainer to create forms for their clients, which are emailed to the PT on completion. To use this feature you will need a Contentful account.
- Clone the repo
git clone https://github.com/james-langridge/personal-trainer-planner.git
- Install NPM packages
npm install
- Copy the environment variable files and update the variables.
cp .env .env.local
- Once you have a Postgres DB running somewhere, and the
DATABASE_URL
env var set, run the Prisma Migrate command:npx prisma migrate dev
- Change the emails in
prisma/seed.ts
so you will be able to log into the app. - Seed the database:
npx prisma db seed
- You can check seeding the database worked with this command:
You can also edit data using this UI in the browser if needed.
npx prisma studio
- Start the development server:
npm run dev
- Open up http://localhost:3000 in a browser and log in. You must have set up an email account and set the environment variables before you can log in. See the Auth.js docs and the nodemailer docs. You will be admin and can create other users. The seed script added demo workouts etc to your admin account.
- As a Next.js app, deploying to Vercel is simple: https://vercel.com/new
You should be able to clone and deploy this project on Vercel using the button below, provided you have completed the prerequisites above (database and email).
Check the deployed project has all the required environment variables, as the
button generator says there cannot be more than 10 Environment Variables per
project, so you will need to manually add the ones from the .env
that are
missing.
See the Next.js deployment documentation for more details.
Distributed under the MIT License.