Build Your Own Booking System
Calendly-style scheduling with availability, booking widget, and calendar sync.
Solid vibe project! Basic scheduling is doable. The main complexity is timezone handling and calendar sync. Consider using Cal.com (open source) as a starting point instead of building from scratch.
The Prompt
Build me a booking/scheduling system like Calendly with the following specifications:
## Tech Stack
- Next.js 14 with App Router
- Prisma with PostgreSQL
- Google Calendar API for calendar sync
- Tailwind CSS + shadcn/ui
- Resend for email notifications
## Core Features
### 1. Event Types
- Create different event types (e.g., "30-min call", "1-hour consultation")
- Configure: duration, title, description, location (Zoom/Meet/Phone)
- Set buffer time before/after meetings
- Customize booking questions (name, email, notes)
### 2. Availability Settings
- Set weekly availability (e.g., Mon-Fri 9am-5pm)
- Block specific dates
- Sync with Google Calendar to show actual availability
- Timezone handling (detect visitor timezone)
### 3. Booking Page
- Public shareable link (/book/[username]/[event-type])
- Calendar view showing available dates
- Time slot selection
- Booking form with custom questions
- Confirmation page
### 4. Calendar Sync
- OAuth with Google Calendar
- Create calendar event when booking confirmed
- Update availability based on existing events
- Send calendar invites to both parties
### 5. Notifications
- Email confirmation to booker
- Email notification to host
- Reminder emails (24h and 1h before)
- Cancellation/reschedule notifications
### 6. Dashboard
- List of upcoming bookings
- Past bookings history
- Cancel/reschedule bookings
- Event type management
## Database Schema
```prisma
model User {
id String @id @default(cuid())
email String @unique
name String
username String @unique
timezone String @default("America/New_York")
googleTokens Json?
eventTypes EventType[]
bookings Booking[]
availability Availability[]
createdAt DateTime @default(now())
}
model EventType {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])
title String
slug String
description String?
duration Int // minutes
location String // zoom, meet, phone, custom
color String @default("#3b82f6")
questions Json @default("[]")
bufferBefore Int @default(0)
bufferAfter Int @default(0)
active Boolean @default(true)
bookings Booking[]
createdAt DateTime @default(now())
@@unique([userId, slug])
}
model Availability {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])
dayOfWeek Int // 0-6 (Sunday-Saturday)
startTime String // "09:00"
endTime String // "17:00"
@@unique([userId, dayOfWeek])
}
model Booking {
id String @id @default(cuid())
eventTypeId String
eventType EventType @relation(fields: [eventTypeId], references: [id])
userId String
user User @relation(fields: [userId], references: [id])
guestName String
guestEmail String
guestTimezone String
startTime DateTime
endTime DateTime
answers Json @default("{}")
status String @default("confirmed") // confirmed, cancelled, rescheduled
googleEventId String?
createdAt DateTime @default(now())
}
```
## API Routes
```
POST /api/auth/google - OAuth callback
GET /api/availability/[username] - Get user's availability
GET /api/slots/[username]/[eventType]?date=2024-01-15 - Get available slots
POST /api/bookings - Create new booking
GET /api/bookings - List user's bookings
PATCH /api/bookings/[id] - Cancel/reschedule
```
## Key Challenges to Handle
1. Timezone conversion (store in UTC, display in local)
2. Conflicting bookings (check before confirming)
3. Google Calendar rate limits
4. Buffer time calculations
5. DST transitions
## UI Requirements
- Clean, minimal booking page
- Mobile-friendly calendar picker
- Clear timezone display
- Loading states during booking
- Success/error feedback
Please generate all files. Start with the booking page and availability logic.
Follow-Up Prompts
Add Zoom Integration
Add Zoom meeting creation: - OAuth with Zoom - Automatically create Zoom meeting when booking confirmed - Include Zoom link in confirmation email - Add meeting password to booking details
Add Payment (Paid Consultations)
Add Stripe payment for paid bookings: - Set price per event type - Collect payment before confirming booking - Handle refunds on cancellation - Show payment status in dashboard
What You'll Get
✅ Included
- Event types configuration
- Availability settings
- Booking page
- Google Calendar sync
- Email notifications
- Timezone handling
❌ Not Included
- Team scheduling
- Round-robin assignment
- Group bookings
- Recurring events
- Workflows/automation
- Embed widget
Alternative: Consider starting with Cal.com (open source). It's free to self-host and has most features built-in. Fork it and customize rather than building from scratch.