You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Empowering learners and educators — one course at a time.
StudyNotion is a full-stack EdTech platform where Students can discover, purchase, and stream courses, Instructors can build and monetize their content, and Admins can govern the entire ecosystem — all in one seamless, cloud-powered experience.
Live Demo
🚀 The application is live and fully functional. Click below to try it out!
StudyNotion is a production-grade, full-stack EdTech SaaS platform built on the MERN stack (MongoDB, Express, React, Node.js). It replicates the core experience of platforms like Udemy or Coursera, offering:
🎓 Students — browse categories, enroll in courses via Razorpay, stream video lectures, and track their progress.
🧑🏫 Instructors — create structured courses with sections & video sub-sections, manage drafts, publish content, and view earnings analytics.
🛡️ Admins — manage course categories and platform governance.
The platform supports OTP-based email verification, JWT authentication, Cloudinary media uploads, Razorpay payment gateway, and automated email notifications — making it a complete, real-world EdTech solution.
✨ Key Features
Role
Features
🎓 Student
Browse & search courses by category, cart & checkout via Razorpay, video lecture streaming, progress tracking, ratings & reviews
🧑🏫 Instructor
Course creation wizard (sections + video sub-sections), draft/publish toggle, earnings dashboard via Chart.js, edit/delete courses
sequenceDiagram
participant U as 🧑 User (Browser)
participant C as React Client
participant S as Express Server
participant DB as MongoDB
participant Mail as Nodemailer
U->>C: Clicks Sign Up
C->>S: POST /api/v1/auth/sendotp {email}
S->>DB: Check if email exists
S->>DB: Save OTP (TTL: 5 min)
S->>Mail: Send OTP email
Mail-->>U: OTP delivered to inbox
U->>C: Enters OTP + form details
C->>S: POST /api/v1/auth/signup {otp, ...details}
S->>DB: Verify OTP
S->>DB: Create User + Profile documents
S-->>C: { success: true, token, user }
C->>C: Store token in localStorage + Redux
U->>C: Clicks Login
C->>S: POST /api/v1/auth/login {email, password}
S->>DB: Find user, bcrypt.compare(password)
S-->>C: JWT token (signed with JWT_SECRET)
C->>C: Persist token, redirect to Dashboard
Loading
Course Purchase Flow
sequenceDiagram
participant S as Student
participant C as React Client
participant API as Express API
participant RZ as Razorpay
participant DB as MongoDB
participant Mail as Nodemailer
S->>C: Click "Buy Now"
C->>API: POST /api/v1/payment/capturePayment (auth + isStudent)
API->>RZ: Create Order (amount, currency)
RZ-->>API: { orderId, amount }
API-->>C: Order details
C->>RZ: Open Razorpay Checkout
S->>RZ: Completes payment
RZ-->>C: { razorpay_payment_id, razorpay_signature }
C->>API: POST /api/v1/payment/verifyPayment
API->>API: HMAC-SHA256 signature verification
API->>DB: Enroll student in course
API->>Mail: Send enrollment confirmation email
API-->>C: { success: true }
C->>C: Navigate to enrolled courses
Loading
📊 Database Schema
erDiagram
USER {
ObjectId _id
String firstName
String lastName
String email
String password
String accountType
Boolean active
String image
String token
Date resetPasswordExpires
}
PROFILE {
ObjectId _id
String gender
String dateOfBirth
String about
String contactNumber
}
COURSE {
ObjectId _id
String courseName
String courseDescription
String whatYouWillLearn
Number price
String thumbnail
String[] tag
String[] instructions
String status
Date createdAt
}
SECTION {
ObjectId _id
String sectionName
}
SUBSECTION {
ObjectId _id
String title
String timeDuration
String description
String videoUrl
}
CATEGORY {
ObjectId _id
String name
String description
}
RATINGANDREVIEW {
ObjectId _id
Number rating
String review
}
COURSEPROGRESS {
ObjectId _id
ObjectId[] completedVideos
}
OTP {
ObjectId _id
String email
String otp
Date createdAt
}
USER ||--|| PROFILE : "additionalDetails"
USER ||--o{ COURSE : "courses (enrolled)"
USER ||--o{ COURSEPROGRESS : "courseProgress"
COURSE ||--|| USER : "instructor"
COURSE ||--o{ SECTION : "courseContent"
COURSE ||--|| CATEGORY : "category"
COURSE ||--o{ RATINGANDREVIEW : "ratingAndReviews"
COURSE ||--o{ USER : "studentsEnrolled"
SECTION ||--o{ SUBSECTION : "subSection"
COURSEPROGRESS ||--o{ SUBSECTION : "completedVideos"
RATINGANDREVIEW ||--|| USER : "user"
RATINGANDREVIEW ||--|| COURSE : "course"
Loading
🔁 Request Lifecycle
flowchart LR
A([Browser Request]) --> B[React Axios\naxiosToastError interceptor]
B -->|HTTPS| C[Express Router]
C --> D{Route\nPublic?}
D -->|Yes| G[Controller]
D -->|No| E[auth middleware\nJWT Verify]
E --> F{Role\nCheck}
F -->|isStudent| G
F -->|isInstructor| G
F -->|isAdmin| G
F -->|Fail 401| Z([Error Response])
G --> H{Operation\nType}
H -->|DB Query| I[(MongoDB)]
H -->|File Upload| J[Cloudinary]
H -->|Email| K[Nodemailer]
H -->|Payment| L[Razorpay]
I --> M([JSON Response])
J --> M
K --> M
L --> M
M --> N[Redux\nState Update]
N --> O([UI Re-render])