Skip to content

sarwanazhar/CourseHub

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸŽ“ CourseHub - Online Learning Platform

πŸš€ Live Demo: https://course-hub-frontend-phi.vercel.app/

πŸ“š Table of Contents

🎯 Overview

CourseHub is a full-stack online learning platform that enables instructors to create and sell courses, and students to enroll and learn. The platform includes features like video uploads, payment processing, course management, and video compression capabilities. Course Hub Built earlier in my learning journey; later projects improve backend security and auth models.

✨ Key Features

  • πŸ” User Authentication: Google OAuth integration
  • πŸ“ Course Management: Create, update, publish, and manage courses
  • πŸŽ₯ Video Upload & Processing: Support for video uploads with compression
  • πŸ’³ Payment Integration: Stripe payment processing
  • πŸ“š Enrollment System: Students can enroll in courses
  • πŸ—œοΈ Video Compression: Built-in video compression to reduce file sizes
  • ☁️ Cloud Storage: Cloudinary integration for media storage

πŸ› οΈ Technical Note: Media Processing & Resource Management

Important

Note on Video Compression & Production Environment

This project implements a sophisticated FFmpeg pipeline designed to compress video uploads before they reach the cloud. This ensures optimal storage usage on Cloudinary and faster streaming for users.

  • The Implementation: The backend includes logic to process video buffers through FFmpeg, reducing file sizes significantly while maintaining visual fidelity.
  • Environment Constraints: While the code is fully functional and tested in local development, the Render Free Tier used for the live demo has a 512MB RAM limit. Heavy video encoding is a CPU/RAM-intensive process that exceeds these hardware limits, causing the free-tier server to restart.
  • Engineering Insight: To maintain 100% uptime for the live demo, the heavy compression task is limited in production. However, the source code demonstrates a production-ready media pipeline that would scale seamlessly on a dedicated VPS or AWS EC2 instance.

πŸ› οΈ Tech Stack

πŸ”™ Backend (Node.js/TypeScript)

  • Runtime: Node.js
  • Framework: Express.js
  • Language: TypeScript
  • Database: MongoDB (via Prisma ORM)
  • Authentication: Google OAuth (NextAuth.js on frontend)
  • File Storage: Cloudinary
  • Payment: Stripe
  • Video Processing: FFmpeg
  • File Upload: Multer

πŸ”œ Frontend (Next.js)

  • Framework: Next.js 15 with App Router
  • Language: TypeScript
  • Styling: Tailwind CSS
  • UI Components: Radix UI + custom components
  • State Management: Zustand
  • Authentication: NextAuth.js
  • HTTP Client: Axios

πŸ—„οΈ Database (MongoDB)

  • ORM: Prisma
  • Database: MongoDB

🌐 External Services

  • Cloudinary: Image and video storage
  • Stripe: Payment processing
  • Google APIs: OAuth authentication
  • FFmpeg: Video compression

πŸ“ Project Structure

CourseHubFinale/
β”œβ”€β”€ πŸ“¦ CourseHub_backend/          # Node.js/Express backend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ controllers/        # Route controllers
β”‚   β”‚   β”œβ”€β”€ routes/            # API routes
β”‚   β”‚   β”œβ”€β”€ libs/              # Utility functions
β”‚   β”‚   └── app.ts             # Main server file
β”‚   β”œβ”€β”€ prisma/
β”‚   β”‚   └── schema.prisma      # Database schema
β”‚   └── package.json
└── 🎨 CourseHub_Frontend/         # Next.js frontend
    β”œβ”€β”€ app/                   # Next.js app directory
    β”‚   β”œβ”€β”€ api/               # API routes
    β”‚   β”œβ”€β”€ courses/           # Course pages
    β”‚   β”œβ”€β”€ dashboard/         # Dashboard pages
    β”‚   └── login/             # Authentication
    β”œβ”€β”€ components/            # React components
    β”œβ”€β”€ lib/                   # Utilities
    └── package.json

πŸ”Œ Backend API Documentation

🌐 Base URL

http://localhost:8000

πŸ” Authentication

The backend doesn't handle authentication directly. Authentication is managed by the frontend using NextAuth.js, and user information is passed to the backend via request headers/body.

πŸ“‹ API Endpoints

πŸ‘€ User Routes (/user)

Method Endpoint Description Request Body Response
POST /register Register a new user { name, email, imageUrl } User object
GET / Get all users - Array of users
GET /:id Get user by ID - User object with compressed videos
POST /update Update user with profile picture FormData: { id, name, file } Updated user
POST /update/withoutfile Update user without picture { id, name } Updated user

πŸ“š Course Routes (/course)

Method Endpoint Description Request Body Response
POST /create Create a new course FormData: { title, description, userId, price, file } Course object
GET /get-all Get all published courses - Array of courses
GET /:id Get course by ID Query: user_id Course with videos and enrollment status
GET /user/:userId Get courses by user ID - User's courses with videos
POST /publish/:id Publish a course { userId } Updated course
POST /inactive/:id Make course inactive { userId } Updated course
POST /delete/:id Delete a course { userId } Deleted course
POST /update/:id Update course with image FormData: { userId, title, description, price, file } Updated course
POST /update-without-file/:id Update course without image { userId, title, description, price } Updated course

⬆️ Upload Routes (/upload)

Method Endpoint Description Request Body Response
POST /image Upload image file FormData: { file } { public_id, secure_url }
POST /video Upload video file FormData: { title, courseId, userId, file } Video object with URL
POST /video-compressing Upload and compress video FormData: { userId, file } Compressed video object

πŸŽ“ Enrollment Routes (/enrolled)

Method Endpoint Description Request Body Response
GET /:userId Get enrolled courses for user - Array of enrolled courses
POST / Enroll in a course { userId, courseId } Stripe checkout session
GET /course/:courseId Get course details for enrolled user - Course with videos
GET /:courseId/videos/:videoId Get specific video for enrolled user - Video object

πŸ’° Payment Routes (/verify-payment)

Method Endpoint Description Request Body Response
POST / Verify Stripe payment Query: session_id { success: boolean }

πŸ“ Request/Response Examples

βž• Create Course

// Request (FormData)
{
  "title": "React Fundamentals",
  "description": "Learn React from scratch",
  "userId": "user123",
  "price": 99,
  "file": <image_file>
}

// Response
{
  "id": "course123",
  "title": "React Fundamentals",
  "description": "Learn React from scratch",
  "imageUrl": "https://cloudinary.com/image.jpg",
  "userId": "user123",
  "price": 99,
  "status": "INACTIVE",
  "publicId": "coursehub/images/abc123"
}

🎯 Enroll in Course

// Request
{
  "userId": "user123",
  "courseId": "course456"
}

// Response
{
  "sessionId": "cs_test_123",
  "url": "https://checkout.stripe.com/pay/..."
}

πŸ—„οΈ Database Schema

πŸ“Š Models

πŸ‘€ User

model User {
  id              String            @id @default(auto()) @map("_id") @db.ObjectId
  name            String
  imageUrl        String
  imagePublicId   String?
  email           String            @unique
  role            Role              @default(STUDENT)
  courses         Course[]
  enrollments     Enrollment[]
  compressedVideos CompressedVideo[]
  accountBalance  Int               @default(0)
  isPro           Boolean           @default(false)
  createdAt       DateTime          @default(now())
  updatedAt       DateTime          @updatedAt
}

πŸ“š Course

model Course {
  id          String        @id @default(auto()) @map("_id") @db.ObjectId
  title       String
  imageUrl    String
  publicId    String
  description String
  userId      String        @db.ObjectId
  user        User          @relation(fields: [userId], references: [id])
  videos      Video[]
  enrollments Enrollment[]
  price       Int
  status      CourseStatus  @default(INACTIVE)
  createdAt   DateTime      @default(now())
  updatedAt   DateTime      @updatedAt
}

πŸŽ₯ Video

model Video {
  id            String   @id @default(auto()) @map("_id") @db.ObjectId
  courseId      String   @db.ObjectId
  title         String
  course        Course   @relation(fields: [courseId], references: [id])
  videoUrl      String
  videoDuration String
  userId        String   @db.ObjectId
  videoSize     String
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt
}

πŸŽ“ Enrollment

model Enrollment {
  id                  String   @id @default(auto()) @map("_id") @db.ObjectId
  userId              String   @db.ObjectId
  courseId            String   @db.ObjectId
  course              Course   @relation(fields: [courseId], references: [id])
  user                User     @relation(fields: [userId], references: [id])
  courseName          String
  courseImageUrl      String
  courseDescription   String
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt
}

πŸ—œοΈ CompressedVideo

model CompressedVideo {
  id              String   @id @default(auto()) @map("_id") @db.ObjectId
  videoUrl        String
  videoDuration   String
  videoSize       String
  originalSize    String
  compressionRate String
  date            String
  userId          String   @db.ObjectId
  user            User     @relation(fields: [userId], references: [id])
}

🏷️ Enums

enum Role {
  STUDENT
  INSTRUCTOR
  ADMIN
}

enum CourseStatus {
  PUBLISHED
  INACTIVE
}

πŸ” Authentication

πŸ”„ Authentication Flow

  1. Frontend Authentication:

    • Uses NextAuth.js with Google Provider
    • Google OAuth credentials are configured
    • Session management handled by NextAuth.js
  2. User Registration:

    • When a user signs in with Google for the first time, the app automatically creates a user record in the database
    • Subsequent logins update the session with user information from the database
  3. Backend Communication:

    • The backend expects user ID/email in request bodies for user-specific operations
    • No JWT tokens or session management on the backend
    • Backend trusts the frontend to provide valid user information

βš™οΈ NextAuth Configuration

// Key features:
- Google OAuth provider
- Automatic user creation on first sign-in
- Session callback to enrich session with user data
- Database integration via Prisma

🎨 Frontend Architecture

πŸ“‚ App Router Structure

app/
β”œβ”€β”€ api/auth/[...nextauth]/    # NextAuth.js API route
β”œβ”€β”€ courses/                   # Course-related pages
β”‚   β”œβ”€β”€ [id]/                 # Individual course page
β”‚   └── create/               # Create course page
β”œβ”€β”€ dashboard/                 # User dashboard
β”œβ”€β”€ compress-video/           # Video compression tool
β”œβ”€β”€ compressed-videos/        # View compressed videos
β”œβ”€β”€ login/                    # Login page
β”œβ”€β”€ payment/                  # Payment success/cancel pages
β”œβ”€β”€ layout.tsx                # Root layout
└── page.tsx                  # Homepage

🧩 Key Components

πŸ—οΈ Layout Components

  • Navbar: Top navigation with authentication status
  • Sidebar: Mobile-friendly navigation menu
  • Footer: Site footer
  • SessionWrapper: NextAuth session provider

πŸ“„ Page Components

  • HomeComponent: Landing page with course showcase
  • Dashboard: User dashboard for managing courses/enrollments
  • CourseCreate: Course creation form
  • CourseView: Individual course viewing page
  • VideoCompression: Video compression utility

πŸŽ›οΈ UI Components (Radix UI + Custom)

  • Button variants with Tailwind CSS
  • Modal dialogs
  • Progress indicators
  • Form controls
  • Tabs and navigation elements

🧠 State Management

  • Uses Zustand for client-side state management
  • NextAuth for authentication state
  • React hooks for local component state

🎨 Styling

  • Tailwind CSS for utility-first styling
  • Custom component library with class-variance-authority
  • Responsive design with mobile-first approach
  • Dark/light mode support (via Tailwind)

✨ Features

πŸ‘¨β€πŸŽ“ For Students

  • πŸ“– Browse published courses
  • πŸ’° Enroll in courses via Stripe payment
  • πŸŽ₯ Access enrolled course content
  • πŸ“Ί Watch course videos
  • πŸ“Š View course progress

πŸ‘¨β€πŸ« For Instructors

  • βž• Create and manage courses
  • ⬆️ Upload course images and videos
  • πŸ“€ Publish/unpublish courses
  • ✏️ Edit course details
  • πŸ“ˆ Track enrollments
  • πŸ—œοΈ Use video compression to reduce file sizes

πŸ‘₯ For All Users

  • πŸ” Google OAuth authentication
  • πŸ‘€ Profile management
  • πŸ“Š Dashboard for courses and enrollments
  • πŸ—œοΈ Video compression utility (saves to user's account)

πŸ—œοΈ Video Compression Feature

  • πŸ”§ Built-in FFmpeg compression
  • πŸ“‰ Reduces video file sizes by up to 90%
  • 🎯 Maintains reasonable video quality
  • πŸ’Ύ Saves compressed videos to user's account
  • πŸ“Š Shows compression statistics (original size, compressed size, compression rate)

πŸš€ Getting Started

πŸ“‹ Prerequisites

  • Node.js (v18 or higher)
  • MongoDB database
  • Cloudinary account
  • Stripe account
  • Google OAuth credentials

βš™οΈ Installation

  1. Clone the repository
git clone https://github.com/sarwanazhar/CourseHub
cd CourseHubFinale
  1. Install backend dependencies
cd CourseHub_backend
npm install
  1. Install frontend dependencies
cd ../CourseHub_Frontend
npm install
# or if using pnpm
pnpm install
  1. Set up environment variables (see Environment Variables section)

  2. Set up database

cd ../CourseHub_backend
npx prisma generate
npx prisma db push
  1. Start the backend server
npm run dev
  1. Start the frontend development server (in a new terminal)
cd ../CourseHub_Frontend
npm run dev
  1. Access the application

πŸ”§ Environment Variables

πŸ”™ Backend (CourseHub_backend/.env)

# Database
DATABASE_URL="mongodb://localhost:27017/coursehub"

# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret

# Stripe
STRIPE_SECRET_KEY=sk_test_...

# Frontend URL (for Stripe redirects)
FRONTEND_URL=http://localhost:3000

πŸ”œ Frontend (CourseHub_Frontend/.env.local)

# Backend API URL
NEXT_PUBLIC_API_URL=http://localhost:8000

# NextAuth
NEXTAUTH_SECRET=your_nextauth_secret
NEXTAUTH_URL=http://localhost:3000

# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
API_URL=your_backend_url

# Database (for Prisma)
DATABASE_URL="mongodb://localhost:27017/coursehub"

πŸ’‘ API Usage Examples

βž• Creating a Course (cURL)

curl -X POST http://localhost:8000/course/create \
  -F "title=React Fundamentals" \
  -F "description=Learn React from scratch" \
  -F "userId=user123" \
  -F "price=99" \
  -F "file=@course-image.jpg"

🎯 Enrolling in a Course (JavaScript)

const response = await fetch('http://localhost:8000/enrolled', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    userId: 'user123',
    courseId: 'course456'
  })
});

const { sessionId, url } = await response.json();
// Redirect user to Stripe checkout URL
window.location.href = url;

⬆️ Uploading a Video (JavaScript)

const formData = new FormData();
formData.append('file', videoFile);
formData.append('title', 'Introduction to React');
formData.append('courseId', 'course123');
formData.append('userId', 'user123');

const response = await fetch('http://localhost:8000/upload/video', {
  method: 'POST',
  body: formData
});

const videoData = await response.json();

🚒 Deployment

πŸ”™ Backend Deployment

The backend includes a Dockerfile for containerized deployment:

cd CourseHub_backend
docker build -t coursehub-backend .
docker run -p 8000:8000 coursehub-backend

πŸ”œ Frontend Deployment

The frontend is configured for Vercel deployment and is currently live at: https://course-hub-frontend-phi.vercel.app/

For manual deployment:

cd CourseHub_Frontend
npm run build
npm start

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

πŸ†˜ Support

For support or questions, please open an issue on the GitHub repository.


πŸ’‘ Note: This is a comprehensive documentation of the CourseHub project. The live demo is available at https://course-hub-frontend-phi.vercel.app/ for testing the application's features.

πŸ‘¨β€πŸ’» Developed and Managed by Sarwan Azhar

πŸ”— GitHub Repository: https://github.com/sarwanazhar/CourseHub

About

this is the source code of coursehub demo: https://course-hub-frontend-phi.vercel.app/

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages