Skip to content

Repository files navigation

🎓 Saarthi — Mentor Meet Booking

A full-stack, real-time mentor-mentee video meeting platform built with Next.js 14, Convex, Clerk, and Stream Video SDK. Saarthi enables mentors (interviewers) to schedule, manage, and conduct 1-on-1 or group mentoring sessions with mentees (candidates) — complete with live video calls, an in-call notes editor, session ratings, and a comprehensive dashboard.


📑 Table of Contents


✨ Features

Feature Description
🔐 Authentication Clerk-powered sign-in/sign-up with automatic user sync to Convex via webhooks
👥 Role-Based Access Two distinct roles — Mentor (Interviewer) and Mentee (Candidate) — with tailored dashboards
📅 Session Scheduling Mentors can schedule sessions by picking a date, time slot, mentee, and co-mentors
⚡ Instant Meetings Start an ad-hoc video call instantly with a single click
🔗 Join via Link Mentees or mentors can join any meeting by pasting the invitation link
📹 Live Video Calls Powered by Stream Video SDK with Speaker and Grid layout options
📝 In-Call Notes Editor Monaco-based Markdown editor embedded in the meeting room for live note-taking
💬 Comments & Ratings Mentors can leave post-session comments with a 1–5 star rating
✅ Session Outcomes Mark completed sessions as Successful or Needs Work
📊 Mentor Dashboard Grouped view of all sessions — Upcoming, Completed, Succeeded, and Failed
🌗 Dark / Light Mode System-aware theme toggle using next-themes
🎨 Animated Landing Page Beautiful landing page with Framer Motion animations
🔔 Toast Notifications Real-time feedback for all user actions via react-hot-toast
📄 Export Support PDF and DOCX export capabilities via jsPDF and docx

🛠 Tech Stack

Frontend

Backend & Database

  • Convex — Real-time serverless backend with reactive queries and mutations
  • Clerk — Authentication, user management, and webhook-based user sync
  • Svix — Webhook signature verification for Clerk events

Video & Communication

Utilities

  • date-fns — Date formatting and manipulation
  • jsPDF — Client-side PDF generation
  • docx — DOCX document generation
  • react-hot-toast — Lightweight toast notifications

🏗 Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                      Client (Browser)                   │
│  ┌──────────┐  ┌──────────┐  ┌────────────────────────┐ │
│  │  Clerk   │  │  Convex  │  │  Stream Video React    │ │
│  │  Auth UI │  │  React   │  │  SDK (Video Calls)     │ │
│  └────┬─────┘  └────┬─────┘  └──────────┬─────────────┘ │
└───────┼──────────────┼──────────────────┼───────────────┘
        │              │                  │
        ▼              ▼                  ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│  Clerk API   │ │ Convex Cloud │ │  Stream Video    │
│ (Auth + JWT) │ │  (Database   │ │  (WebRTC Calls)  │
│              │ │  + Functions)│ │                  │
└──────┬───────┘ └──────────────┘ └──────────────────┘
       │                                    ▲
       │  Webhook (user.created)            │
       ▼                                    │
┌──────────────┐              ┌─────────────┴──────┐
│ Convex HTTP  │              │  Next.js Server    │
│ Endpoint     │              │  Action (Token     │
│ /clerk-webhook│             │  Generation)       │
└──────────────┘              └────────────────────┘
  1. Clerk handles authentication and emits a user.created webhook on sign-up.
  2. The Convex HTTP endpoint (/clerk-webhook) receives the webhook, verifies the Svix signature, and inserts the user into the Convex users table with a default candidate role.
  3. Convex serves as the real-time database — all queries are reactive and auto-update the UI when data changes.
  4. Stream Video SDK provides the video calling infrastructure. Tokens are generated server-side via a Next.js Server Action using the Stream Node SDK.

🗄 Database Schema

The Convex database consists of three tables:

users

Field Type Description
name string Full name of the user
email string Email address
image string? Profile avatar URL (optional)
role "candidate" | "interviewer" User role — mentee or mentor
clerkId string Clerk user ID (indexed)

interviews (Sessions)

Field Type Description
title string Session title
description string? Optional session description
startTime number Scheduled start time (epoch ms)
endTime number? Actual end time (set when completed)
status string "upcoming" · "completed" · "succeeded" · "failed"
streamCallId string Stream Video call ID (indexed)
candidateId string Clerk ID of the mentee
interviewerIds string[] Clerk IDs of assigned mentors

comments

Field Type Description
content string Comment text
rating number Star rating (1–5)
interviewerId string Clerk ID of the commenting mentor
interviewId Id<"interviews"> Reference to the parent session

📁 Project Structure

Mentor-Meet-Booking/
├── convex/                         # Convex backend
│   ├── schema.ts                   # Database schema definitions
│   ├── users.ts                    # User queries & mutations (sync, getUsers, getByClerkId)
│   ├── interviews.ts               # Interview/session CRUD operations
│   ├── comments.ts                 # Comment & rating mutations/queries
│   ├── http.ts                     # HTTP router for Clerk webhook endpoint
│   ├── auth.config.ts              # Convex ↔ Clerk auth provider config
│   └── _generated/                 # Auto-generated Convex types & API
│
├── src/
│   ├── middleware.ts                # Clerk authentication middleware
│   │
│   ├── actions/
│   │   └── stream.actions.ts       # Server Action — Stream video token generation
│   │
│   ├── app/
│   │   ├── page.tsx                # Landing page (public, animated with Framer Motion)
│   │   ├── layout.tsx              # Root layout (Clerk provider)
│   │   └── app/                    # Authenticated app routes
│   │       ├── layout.tsx          # App layout (Convex + Clerk + Theme + Navbar)
│   │       ├── (root)/
│   │       │   ├── layout.tsx      # Wraps children with StreamClientProvider
│   │       │   ├── (home)/
│   │       │   │   └── page.tsx    # Home — quick actions (mentor) or meeting list (mentee)
│   │       │   ├── schedule/
│   │       │   │   ├── page.tsx    # Guard — only mentors can access
│   │       │   │   └── InterviewScheduleUI.tsx  # Full scheduling form + session list
│   │       │   └── meeting/
│   │       │       └── [id]/
│   │       │           └── page.tsx  # Video meeting room (setup → call)
│   │       ├── (admin)/
│   │       │   └── dashboard/
│   │       │       └── page.tsx    # Mentor dashboard — grouped sessions + outcomes
│   │       └── api/                # API routes (DOCX export, code execution, Gemini)
│   │
│   ├── components/
│   │   ├── Navbar.tsx              # Top navigation bar with role-aware buttons
│   │   ├── MeetingRoom.tsx         # Video call room with resizable code editor panel
│   │   ├── MeetingSetup.tsx        # Pre-call device setup screen
│   │   ├── MeetingModal.tsx        # Start / Join meeting dialog
│   │   ├── MeetingCard.tsx         # Session card with live/upcoming/completed status
│   │   ├── ActionCard.tsx          # Quick action card (New Call, Join, Schedule)
│   │   ├── CodeEditor.tsx          # Monaco-based in-call Markdown notes editor
│   │   ├── CommentDialog.tsx       # Post-session comment + rating dialog
│   │   ├── EndCallButton.tsx       # End call for all participants (owner only)
│   │   ├── DasboardBtn.tsx         # Dashboard nav button (mentors only)
│   │   ├── ModeToggle.tsx          # Dark/Light theme toggle
│   │   ├── LoaderUI.tsx            # Full-screen loading spinner
│   │   ├── providers/
│   │   │   ├── ConvexClerkProvider.tsx   # Convex + Clerk auth integration
│   │   │   ├── StreamClientProvider.tsx  # Stream Video client initialization
│   │   │   └── ThemeProvider.tsx         # next-themes provider
│   │   └── ui/                     # shadcn/ui component library
│   │
│   ├── hooks/
│   │   ├── useUserRole.ts          # Returns { isInterviewer, isCandidate, isLoading }
│   │   ├── useGetCallById.ts       # Fetches a Stream call by ID
│   │   ├── useGetCalls.ts          # Fetches user's calls from Stream
│   │   └── useMeetingActions.ts    # createInstantMeeting() & joinMeeting() helpers
│   │
│   ├── constants/
│   │   └── index.ts                # Quick actions, time slots, interview categories, coding questions
│   │
│   └── lib/
│       └── utils.ts                # Helpers — groupInterviews, getCandidateInfo, getMeetingStatus
│
├── public/                         # Static assets
├── package.json
├── tailwind.config.ts
├── tsconfig.json
├── next.config.mjs
└── postcss.config.mjs

🚀 Getting Started

Prerequisites

  • Node.js ≥ 18
  • npm or yarn or pnpm
  • A Clerk account
  • A Convex account
  • A Stream account (Video & Audio API)

Installation

# 1. Clone the repository
git clone https://github.com/your-username/Mentor-Meet-Booking.git
cd Mentor-Meet-Booking

# 2. Install dependencies
npm install

# 3. Set up environment variables (see section below)
cp .env.example .env.local

# 4. Start the Convex dev server (in a separate terminal)
npx convex dev

# 5. Start the Next.js dev server
npm run dev

The app will be running at http://localhost:3000.


🔑 Environment Variables

Create a .env.local file in the project root with the following variables:

# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
CLERK_WEBHOOK_SECRET=whsec_...

# Convex
NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud

# Stream Video
NEXT_PUBLIC_STREAM_API_KEY=your_stream_api_key
STREAM_SECRET_KEY=your_stream_secret_key

Setup Notes

  1. Clerk Webhook: In the Clerk Dashboard, create a webhook endpoint pointing to your Convex HTTP endpoint (https://<your-convex-deployment>.convex.site/clerk-webhook) and subscribe to the user.created event.
  2. Convex Auth: The Convex auth config is already set up in convex/auth.config.ts — update the domain field with your Clerk issuer URL.
  3. Stream: Create a Stream app with Video & Audio enabled and copy the API key and secret.

👤 User Roles & Permissions

Capability Mentor (Interviewer) Mentee (Candidate)
View Home Dashboard ✅ (Quick Actions) ✅ (Meeting List)
Start Instant Meeting
Join Meeting via Link
Schedule Sessions
Access Mentor Dashboard
End Meeting for All ✅ (Owner only)
Leave Comments & Ratings
Mark Session Outcome
Use In-Call Notes Editor

New users are assigned the candidate (mentee) role by default. Roles can be updated directly in the Convex database.


🗺 Key Pages & Routes

Route Access Description
/ Public Animated landing page with sign-in CTA
/app Auth Home — Quick actions (mentors) or meeting list (mentees)
/app/schedule Mentors only Schedule new mentoring sessions
/app/meeting/[id] Auth Live video meeting room with notes editor
/app/dashboard Mentors only Manage all sessions, mark outcomes, add comments

⚙️ How It Works

1. User Registration

When a user signs up via Clerk, a user.created webhook fires. The Convex HTTP endpoint at /clerk-webhook verifies the Svix signature and creates a user record in the users table with the default candidate role.

2. Scheduling a Session

A mentor navigates to /app/schedule, fills in the session title, description, date, time slot, selects a mentee, and optionally adds co-mentors. This:

  • Creates a Stream Video call with the scheduled start time
  • Inserts an interview record in Convex with status "upcoming"

3. Joining a Meeting

  • Mentees see their scheduled sessions on the home page and click "Join Meeting" when the session is live.
  • Mentors can start instant meetings or join via invitation link.
  • The meeting page (/app/meeting/[id]) loads a pre-call setup screen for camera/mic configuration, then transitions to the full meeting room.

4. In the Meeting Room

The meeting room features a resizable split layout:

  • Left panel: Live video call with Speaker or Grid layout, call controls, and participant list
  • Right panel: Monaco-based Markdown notes editor for real-time note-taking

The meeting owner (creator) has an End Meeting button that ends the call for all participants and updates the session status to "completed".

5. Post-Session Review

On the mentor dashboard, completed sessions can be:

  • Marked as Successful ✅ or Needs Work
  • Annotated with comments and star ratings (1–5) by any mentor

Sessions are grouped into four categories: Upcoming, Completed, Succeeded, and Failed.


📸 Screenshots

Add screenshots of your landing page, home dashboard, scheduling UI, meeting room, and mentor dashboard here.


📜 License

This project is private. All rights reserved.


Built with ❤️ using Next.js, Convex, Clerk & Stream

Releases

Packages

Used by

Contributors

Languages