Simple, fast, and reliable slot-based appointment booking for users and service providers.
AppointmentLelo.io is a fullstack role-based scheduling platform:
USERcan browse services, view available slots, and book appointments.SERVICE_PROVIDERcan create services, set availability, and track daily schedules.
It includes a modern SaaS landing page, dark/light theme support, responsive layouts, and secure backend APIs.
/
├── frontend/ # React SPA (Vite + Tailwind)
└── backend/ # Express API (Prisma + PostgreSQL)
- React 19 + TypeScript
- Vite 7
- Tailwind CSS v4
- React Router v7
- Framer Motion
- Lucide React
- Axios
- React Context API (Auth + Theme)
- Modern marketing landing page:
- Sticky navbar with CTA + theme toggle
- Hero, trusted-by, features, workflow, product preview, CTA, credits, footer
- Auth flows:
- Login / Register pages with role support
- User app:
- Service discovery + category filter
- Slot selection and instant booking
- My appointments table
- Provider app:
- Create service
- Set weekly availability
- Daily schedule view
- Theme system:
- Global dark/light mode with persistence (
localStorage)
- Global dark/light mode with persistence (
- Responsive behavior:
- Mobile, tablet, desktop optimized layouts and controls
- Node/Bun runtime
- Express 5 + TypeScript
- Prisma 7
- PostgreSQL
- Zod validation
- JWT auth + bcrypt password hashing
- express-rate-limit
- JWT-based auth with role-based route protection
- Service creation and provider availability management
- Dynamic slot engine from availability windows
- Overlap detection for provider availability
- Slot booking with duplicate booking prevention
- Provider schedule endpoint for selected date
- CORS restricted via
CLIENT_ORIGIN - Global and auth-specific rate limiting
x-powered-bydisabled- Request JSON payload size limit
- No internal error details leaked in auth responses
cd backend
bun installCreate backend/.env:
DATABASE_URL="postgresql://user:password@localhost:5432/appointmentlelo"
PORT=3000
CLIENT_ORIGIN="http://localhost:5173"
JWT_SECRET="replace_with_strong_secret"
SALT_ROUNDS=10Run migrations and start server:
npx prisma migrate dev
bun run devBackend runs on http://localhost:3000.
cd frontend
npm install
npm run devFrontend runs on http://localhost:5173.
POST /auth/registerPOST /auth/login
GET /servicesPOST /services(provider only)POST /services/:serviceId/availability(provider owner only)GET /services/:serviceId/slots?date=YYYY-MM-DD
POST /appointments(user only)GET /appointments/me(user only)
GET /providers/me/schedule?date=YYYY-MM-DD(provider only)
- The README banner points to
./docs/banner.png. - Place your provided banner image at that path to render it at the top in centered layout.
