Skip to main content
A consulting booking app where clients browse available consultants, book time slots through an embedded calendar, pay for premium sessions, and receive email confirmations and reminders. The finished product includes user authentication, consultant profiles, calendar-based scheduling, Stripe payments for paid sessions, transactional email notifications, and one-click deployment to Netlify.By the end of this recipe you will have a production-ready booking platform that you can customize, rebrand, and launch as your own service.

Tech stack

You do not need to understand these technologies. Rocket handles them automatically. This table is for reference.
ServiceRole
Next.js + TypeScriptFrontend framework and API routes
Cal.com or CalendlyCalendar scheduling, availability management, and booking widgets
SupabaseUser authentication, consultant profiles, booking records, and reviews
StripePayment processing for paid consultation sessions
ResendBooking confirmation emails, reminders, and cancellation notices
NetlifyProduction deployment and hosting

Architecture overview

Here is how the pieces connect:
  1. A visitor signs up using Supabase Auth (email/password or social login) and creates a client profile.
  2. The client browses consultant profiles stored in Supabase, filtering by specialty, availability, and price.
  3. The client selects a consultant and picks a time slot using an embedded Cal.com or Calendly scheduling widget.
  4. If the session is a paid consultation, the client is redirected to a Stripe Checkout page to complete payment before the booking is confirmed.
  5. Once the booking is confirmed, Resend sends a confirmation email to both the client and the consultant with meeting details and calendar invite.
  6. Before the session, Resend sends a reminder email 24 hours in advance.
  7. The entire app is deployed to Netlify with environment variables configured for each service.

How long does it take?

PhaseWhat you are buildingEstimated time
SetupProject, Supabase, profiles5-10 minutes
SchedulingCalendar, booking management10-15 minutes
PaymentsStripe for paid sessions5 minutes
NotificationsEmail confirmations5 minutes
LaunchDeploy, go live5 minutes
TotalComplete booking app30-40 minutes

Step-by-step build

1

Start a new project

Open rocket.new and create a new project. Give Rocket a detailed description of the app so it scaffolds the right pages, layout, and navigation from the start.
Build a consulting booking platform called "BookPro" using Next.js and TypeScript. Include these pages: landing page with hero section and featured consultants, consultant directory with search and filters, individual consultant profile page with bio and booking widget, client dashboard showing upcoming and past bookings, consultant dashboard for managing availability and viewing bookings, login page, and signup page. Use a clean, professional design with a blue and white color scheme. Add a responsive navbar with logo, navigation links, and login/signup buttons.
Be specific about both the client-facing and consultant-facing pages. Booking apps need views for both sides of the marketplace.
2

Connect Supabase

Go to Integrations in your Rocket project and connect your Supabase account via OAuth. Create a new Supabase project (or select an existing one), then ask Rocket to set up the database schema.
Connect Supabase and create the following database tables:
1. "profiles" - id (uuid, references auth.users), display_name (text), email (text), avatar_url (text), role (text, either 'client' or 'consultant'), created_at (timestamp)
2. "consultants" - id (uuid, references profiles), specialty (text), bio (text), hourly_rate (integer, in cents), is_featured (boolean), calendar_link (text), years_experience (integer), rating (decimal)
3. "bookings" - id (uuid), client_id (uuid, references profiles), consultant_id (uuid, references consultants), scheduled_at (timestamp with timezone), duration_minutes (integer, default 60), status (text, either 'confirmed', 'completed', 'canceled'), notes (text), stripe_payment_id (text), created_at (timestamp)
4. "reviews" - id (uuid), booking_id (uuid, references bookings), client_id (uuid, references profiles), consultant_id (uuid, references consultants), rating (integer, 1 to 5), comment (text), created_at (timestamp)
Add row-level security policies so clients can only access their own bookings and consultants can only see bookings assigned to them. Create a trigger that automatically inserts a profile row when a new user signs up.
Rocket handles the Supabase connection through OAuth, so you never need to copy API keys manually. Your credentials are encrypted and stored securely.
3

Add user profiles and authentication

Wire up authentication so users can create accounts and sign in, then build profile management for both clients and consultants.
Implement user authentication and profiles using Supabase Auth:
- On the signup page, add email/password registration with a role selector (client or consultant). After signup, redirect to the appropriate dashboard.
- On the login page, add email/password login with a "Remember me" checkbox. Redirect to the correct dashboard based on role.
- Add Google sign-in as a social login option on both pages.
- For consultants, build a profile editor where they can set their display name, avatar, specialty, bio, hourly rate, years of experience, and calendar link.
- For clients, build a simpler profile page with display name, avatar, and email.
- Protect dashboard pages so only logged-in users can access them. Redirect unauthenticated visitors to the login page.
After Rocket builds the auth flow, preview the app and create test accounts for both a client and a consultant. Verify that each role sees the correct dashboard.
4

Integrate calendar scheduling

Connect a scheduling service so clients can see availability and book time slots directly from the consultant’s profile.
Integrate Cal.com (or Calendly) for scheduling:
- On each consultant's profile page, embed the Cal.com scheduling widget using the consultant's calendar_link from the database.
- The widget should show available time slots based on the consultant's configured availability.
- When a client selects a time slot, capture the booking details (date, time, duration) and create a booking record in the Supabase bookings table with status 'confirmed'.
- Add a Cal.com webhook handler that listens for booking.created and booking.canceled events to keep the Supabase bookings table in sync.
- Show a confirmation screen after booking with the date, time, consultant name, and session details.
Cal.com offers a free self-hosted option, while Calendly provides a managed service with a generous free tier. Both work well for embedding scheduling widgets.
5

Add booking management

Build dashboards for both clients and consultants to view and manage their bookings.
Build booking management dashboards:
- Client dashboard: show a list of upcoming bookings sorted by date with consultant name, date and time, duration, and status badge. Add a "Past Bookings" tab showing completed sessions. Include a "Cancel Booking" button that sets the status to 'canceled' (only allowed more than 24 hours before the session).
- Consultant dashboard: show all upcoming bookings with client name, date and time, duration, and any notes. Add a calendar view that displays bookings visually across the week. Include a "Past Sessions" tab with completed bookings.
- Add a booking detail page that both the client and consultant can access, showing full session information and a notes field.
6

Connect Stripe for paid sessions

Go to Integrations and connect Stripe using your test mode API keys. Then set up payment processing for paid consultation sessions.
Connect Stripe and set up payment for bookings:
- When a client books a paid session, redirect them to a Stripe Checkout page before confirming the booking. The checkout should show the consultant's name, session duration, and the hourly rate.
- Add a webhook handler that listens for checkout.session.completed. When payment succeeds, update the booking status to 'confirmed' and store the Stripe payment ID in the bookings table.
- If the client cancels a booking more than 24 hours before the session, issue an automatic refund through Stripe and update the booking status.
- Add a billing history page in the client dashboard showing all past payments with date, consultant, amount, and receipt link.
- For consultants, show an earnings summary with total revenue, completed sessions, and a payout history section.
Use Stripe test mode keys during development. The test card number 4242 4242 4242 4242 with any future expiration and any CVC will simulate a successful payment.
7

Add email notifications with Resend

Go to Integrations and connect Resend by pasting your API key. Then set up transactional emails for key booking events.
Connect Resend and add email notifications:
- Send a booking confirmation email to both the client and consultant when a session is booked. Include the date, time, duration, consultant/client name, and a calendar invite (.ics) attachment.
- Send a reminder email 24 hours before the scheduled session to both parties with the meeting details and any join link.
- Send a cancellation email when a booking is canceled, including refund details if a payment was made.
- Send a follow-up email to the client 1 hour after the session ends, asking them to leave a review for the consultant.
- Use a clean, professional email template with the BookPro logo, a white background, and blue accent buttons.
Resend provides a free tier of 100 emails per day, which is plenty for development and early launch. You can upgrade later as your booking volume grows.
8

Deploy to Netlify

Go to Integrations and connect Netlify, then deploy your app to the web.Use the Launch button in your Rocket project to deploy to the web. Rocket handles the Netlify build configuration automatically. Make sure all required environment variables are set in your project’s integration settings before launching.
After deploying, update your Supabase redirect URLs to include your Netlify domain. Go to your Supabase dashboard, navigate to Authentication > URL Configuration, and add https://your-app.netlify.app to the allowed redirect URLs.

Customization ideas

Once the base booking platform is running, here are ways to extend it.
Generate unique video meeting links automatically when a booking is confirmed so clients and consultants can meet virtually without any extra setup.
Add video call support. When a booking is confirmed, automatically generate a unique meeting room link using Daily.co or a similar video API. Include the video link in the confirmation email and on the booking detail page. Add a "Join Call" button that appears 15 minutes before the scheduled session.
Let consulting firms create a team page where clients can book with any available consultant in the group, or pick a specific team member.
Add team support. Create a "teams" table with team name, description, and owner. Consultants can join a team. Add a team profile page that shows all team members with their specialties and availability. Clients can book with a specific consultant or choose "Next Available" to be matched with whoever has the earliest open slot.
Let clients book a recurring series of sessions (weekly, biweekly, or monthly) with their preferred consultant.
Add recurring booking support. When a client books a session, offer an option to make it recurring: weekly, biweekly, or monthly. Generate all future bookings in the series (up to 12 weeks out) and charge via Stripe on a recurring schedule. Add the ability to cancel a single session or the entire series.
When a consultant’s slots are fully booked, let clients join a waitlist and get notified automatically when a slot opens up.
Add a waitlist feature. When no time slots are available for a consultant, show a "Join Waitlist" button instead. Create a "waitlist" table in Supabase with client_id, consultant_id, and preferred_times. When a booking is canceled, automatically notify the first person on the waitlist via Resend and give them 2 hours to claim the slot before offering it to the next person.
Let clients rate and review consultants after completed sessions to build trust and help other clients make informed decisions.
Add a review system. After a session is marked as completed, prompt the client to leave a 1-5 star rating and an optional written review. Display reviews on the consultant's profile page with the average rating shown prominently. Update the consultant's rating field in Supabase as a running average. Only clients who have completed a session with that consultant can leave a review.

Troubleshooting

If the scheduling widget is empty, the consultant may not have availability set up in Cal.com or Calendly. Make sure their calendar link is correct in the database and that they have configured at least one availability window.If the widget loads but bookings do not appear in your app, ask Rocket to debug the sync:
Bookings made through the Cal.com widget are not showing up in the Supabase bookings table. Check the webhook connection between Cal.com and my app and make sure new bookings are being saved to the database when the webhook fires.
If the client and consultant see different times for the same booking, there may be a timezone issue. Ask Rocket to fix it:
Booking times are showing incorrectly for one party. Make sure all timestamps in the bookings table use timezone-aware storage. Display booking times in both the client's and consultant's local timezone on the confirmation page and in emails.
Also check that the consultant’s timezone is set correctly in their Cal.com or Calendly settings.
If you are using Cal.com or Calendly, the scheduling tool should prevent conflicts automatically. Make sure the consultant has only one active event type with the correct duration.If conflicts are still happening, ask Rocket to add a safeguard:
Two clients were able to book the same consultant at the same time. Add a server-side check that prevents creating a new booking if the consultant already has a confirmed booking at that time. Show a friendly error message asking the client to pick a different slot.