A self-service gym rental MVP. Users book an hourly time slot, pay online, and receive a time-limited door code by email — no staff involvement required.
Live demo: gym-rental2.vercel.app
- User picks an available hourly slot on the booking page.
- Stripe PaymentElement collects payment; a webhook confirms it server-side.
- On confirmed payment, a time-limited door code is generated via the Nuki Smart Lock API.
- The code is emailed to the user via Resend (React Email templates).
- Hourly slot booking with real-time availability
- Stripe PaymentElement with webhook-driven payment confirmation
- Automated door code generation via Nuki API
- Transactional email with React Email + Resend
- Password-protected admin dashboard
- Double-booking prevention enforced at the database level
- Next.js 16 (App Router)
- Supabase — database + auth
- Stripe — payments + webhooks
- Resend + React Email — transactional email
- Nuki Smart Lock API — door code generation
- Deployed on Vercel
A single bookings table tracks the full lifecycle of a reservation:
```sql create table bookings ( id uuid primary key default gen_random_uuid(), email text not null, name text not null, start_time timestamptz not null, end_time timestamptz not null, status text not null default 'pending_payment', stripe_payment_intent_id text unique, nuki_auth_id integer, access_code text, created_at timestamptz default now() );
-- Prevents two bookings from sharing the same start time create unique index bookings_start_time_confirmed on bookings (start_time); ```
``` app/ book/ booking page (slot picker + payment) booking/confirmation/ post-payment confirmation page admin/ password-protected dashboard api/ slots/ GET available time slots bookings/create/ POST to create a pending booking webhooks/stripe/ Stripe payment confirmation webhook admin/bookings/ admin booking management lib/ supabase/ DB client (browser + server/admin) stripe.ts Stripe SDK setup resend.ts Resend email client nuki.ts Nuki Smart Lock API client emails/ React Email templates ```
- Clone the repo and install dependencies: ```bash npm install ```
- Copy
.env.exampleto.env.localand fill in your Supabase, Stripe, Resend, and Nuki credentials. - Run the dev server: ```bash npm run dev ```
- Open http://localhost:3000.