Skip to main content

Overview

The course creation process on SkillRise is designed to be intuitive and comprehensive. The course builder guides you through three main sections, with real-time validation and a live preview.

Accessing the Course Builder

Navigate to the course creation page:
/educator/add-course
Or click the “New Course” button from the “My Courses” page.

Course Builder Interface

The builder features:

Left Panel

Main form with three progressive sections (Info, Pricing, Content)

Right Panel

Live preview showing how your course will appear to students

Progress Indicators

Visual checkmarks showing completion status for each section

Auto-Calculations

Automatic totals for lectures, duration, and pricing

Step 1: Basic Information

Course Title

Create a compelling title that describes your course:
courseTitle
string
required
  • Maximum 80 characters
  • Should be descriptive and searchable
  • Examples: “The Complete JavaScript Course 2024”, “Python for Data Science”
<input
  type="text"
  maxLength={80}
  required
  placeholder="e.g. The Complete JavaScript Course 2024"
  value={courseTitle}
  onChange={(e) => setCourseTitle(e.target.value)}
/>

Course Description

Write a comprehensive description using Markdown:
courseDescription
markdown
required
  • Supports full Markdown formatting
  • Describe what students will learn
  • Include prerequisites
  • Mention target audience
  • Highlight unique selling points
# Learn Modern Web Development

Master full-stack web development with this comprehensive course.

## What You'll Learn
- React fundamentals and advanced patterns
- Node.js and Express backend development
- MongoDB database design
- RESTful API development
- Authentication and authorization

## Prerequisites
- Basic JavaScript knowledge
- HTML and CSS fundamentals
- Familiarity with command line

## Who This Is For
- Aspiring web developers
- Students looking to build portfolio projects
- Developers wanting to learn modern frameworks
The description supports bold, italic, lists, code blocks, and more. Use Markdown to create visually appealing course descriptions.

Step 2: Pricing & Thumbnail

Course Thumbnail

Upload an eye-catching course image:
image
file
required
  • Formats: PNG, JPG, WEBP
  • Recommended: 1280 × 720 pixels
  • Maximum file size handled by Cloudinary
  • Drag-and-drop or click to browse
Upload Features:
  • Drag and drop support
  • Instant preview
  • Hover to change image
  • Visual feedback with border highlighting
// Drag and drop handler
const handleDrop = (e) => {
  e.preventDefault()
  setIsDragOver(false)
  const file = e.dataTransfer.files[0]
  if (file?.type.startsWith('image/')) {
    setImage(file)
  } else {
    toast.error('Please drop an image file')
  }
}
The thumbnail is required. Courses without thumbnails cannot be published.

Pricing

Set your course price and optional discount:
coursePrice
number
required
  • Price in Indian Rupees (₹)
  • Minimum: 0 (for free courses)
  • No maximum limit
  • Must be a valid number
discount
number
default:"0"
  • Percentage discount (0-100%)
  • Optional field
  • Applied to course price automatically
Price Calculation:
const price = parseFloat(coursePrice) || 0
const disc = parseFloat(discount) || 0
const finalPrice = price > 0 
  ? Math.floor(price - (disc * price) / 100) 
  : 0

// Example:
// coursePrice = 4999
// discount = 20
// finalPrice = 3999
Price Display:
Shows strikethrough original price, final price, and discount badge
  • ₹4,999 ₹3,999 (20% off badge)

Step 3: Course Content

This is where you structure your course with chapters and lectures.

Content Structure

Course
└── Chapters (ordered sections)
    └── Lectures (individual videos)

Adding Chapters

  1. Click “Add Chapter” button
  2. Enter chapter title in the input field
  3. Press Enter or click “Add”
  4. Chapter is created with a unique ID
Chapter Properties:
{
  chapterId: "unique-uuid",
  chapterTitle: "Chapter 1: Introduction",
  chapterOrder: 1,
  chapterContent: [], // Array of lectures
  collapsed: false // UI state
}
Chapter Actions:
  • Double-click title - Rename the chapter
  • Click arrow - Collapse/expand to hide lectures
  • Click trash icon - Remove entire chapter

Adding Lectures

Within each chapter, you can add multiple lectures:
  1. Expand the chapter
  2. Click “Add Lecture” at the bottom
  3. Fill in the lecture modal:
lectureTitle
string
required
Title of the lecture (e.g., “Introduction to React Hooks”)
lectureDuration
number
required
Duration in minutes (used for calculating total course length)
lectureUrl
url
required
Valid video URL from YouTube, Vimeo, or direct video link
isPreviewFree
boolean
default:"false"
Toggle to allow free preview (students can watch without enrolling)
Lecture Modal Example:
<LectureModal
  onClose={() => setShowModal(false)}
  onAdd={(details) => {
    // Add lecture to chapter with auto-generated ID
    const lecture = {
      ...details,
      lectureId: createId(),
      lectureOrder: lastOrder + 1
    }
    // Update chapter's chapterContent array
  }}
/>

Lecture Properties

{
  lectureId: "unique-uuid",
  lectureTitle: "Introduction to Hooks",
  lectureDuration: 15, // minutes
  lectureUrl: "https://youtube.com/watch?v=abc123",
  isPreviewFree: true,
  lectureOrder: 1
}
Lectures with isPreviewFree: true display a FREE badge and can be viewed by anyone.

Managing Lectures

  • View duration - Shown next to each lecture (e.g., “15m”)
  • See preview status - FREE badge for preview lectures
  • Delete lecture - Hover over lecture and click the X icon
  • Reorder - Lectures are ordered sequentially within chapters

Auto-Calculations

The system automatically calculates:

Total Lectures

const totalLectures = chapters.reduce(
  (sum, chapter) => sum + chapter.chapterContent.length, 
  0
)

Total Duration

let totalDurationMinutes = 0
chapters.forEach(chapter => {
  chapter.chapterContent.forEach(lecture => {
    totalDurationMinutes += lecture.lectureDuration
  })
})

Final Price

Calculated with discount applied (shown in real-time).

Live Preview Panel

As you build your course, the right panel shows:
1

Course Thumbnail

Preview of uploaded image (or placeholder)
2

Course Title

Your entered title
3

Description Preview

First 120 characters (markdown stripped)
4

Pricing

Original price, final price, and discount badge
5

Content Overview

Chapter count, lecture count, total duration
// Description preview generation
const descPreview = description
  .replace(/[#*`_>[\]()!-]/g, ' ')
  .replace(/\s+/g, ' ')
  .trim()
  .slice(0, 120)

Validation & Publishing

Section Completion

Each section has completion criteria:
const step1Complete = courseTitle.trim().length > 0
const step2Complete = price > 0 && !!image
const step3Complete = chapters.length > 0 && totalLectures > 0

Pre-Submit Validation

Before submission, the form validates:
if (!courseTitle.trim()) {
  toast.error('Course title is required')
  return
}
if (!description.trim()) {
  toast.error('Course description is empty')
  return
}
if (!image) {
  toast.error('Please select a thumbnail')
  return
}
if (chapters.length === 0) {
  toast.error('Add at least one chapter')
  return
}
if (totalLectures === 0) {
  toast.error('Add at least one lecture')
  return
}

Course Submission

When you click “Publish Course”:

1. Data Preparation

const courseData = {
  courseTitle: courseTitle.trim(),
  courseDescription: description,
  coursePrice: price,
  discount: disc,
  courseContent: chapters
}

2. FormData Creation

const formData = new FormData()
formData.append('courseData', JSON.stringify(courseData))
formData.append('image', image) // File object

3. API Request

const token = await getToken()
const { data } = await axios.post(
  backendUrl + '/api/educator/add-course',
  formData,
  {
    headers: { Authorization: `Bearer ${token}` }
  }
)

4. Backend Processing

The server:
  1. Validates educator authentication
  2. Parses course data
  3. Calculates total lectures and duration
  4. Uploads thumbnail to Cloudinary
  5. Creates course in MongoDB
  6. Returns success/failure response
// Server-side calculation
let totalLectures = 0
let totalDurationMinutes = 0

courseContent.forEach((chapter) => {
  if (Array.isArray(chapter.chapterContent)) {
    totalLectures += chapter.chapterContent.length
    
    chapter.chapterContent.forEach((lecture) => {
      totalDurationMinutes += lecture.lectureDuration
    })
  }
})

const newCourse = await Course.create({
  courseTitle,
  courseDescription,
  coursePrice,
  discount,
  courseContent,
  isPublished,
  educatorId,
  totalLectures,
  totalDurationMinutes
})

// Upload thumbnail
const imageUpload = await cloudinary.uploader.upload(imageFile.path)
newCourse.courseThumbnail = imageUpload.secure_url
await newCourse.save()

Best Practices

  • Start with an introduction chapter
  • Group related lectures into logical chapters
  • Keep lectures focused (5-20 minutes ideal)
  • End with a conclusion or summary chapter
  • Consider adding a “Getting Started” chapter with setup instructions
  • Use clear, descriptive chapter titles
  • Number chapters if teaching a progression
  • Make first lecture free for previews
  • Break complex topics across multiple lectures
  • Include practical examples in each section
  • Test all video URLs before submitting
  • Ensure videos are publicly accessible
  • Use consistent video quality across lectures
  • Add captions/subtitles when possible
  • Keep intro/outro segments brief
  • Use high-contrast colors for readability
  • Include course topic in the image
  • Avoid cluttered designs
  • Use readable fonts if adding text
  • Maintain 16:9 aspect ratio
  • Research similar courses in your niche
  • Consider course length and depth
  • Use discounts for launch promotions
  • Price competitively but don’t undervalue
  • Update pricing based on content additions

Troubleshooting

Common Issues:
IssueSolution
”Thumbnail Not Attached”Ensure image file is selected before submitting
Video URL invalidVerify URL is accessible and properly formatted
Can’t add lectureCheck that chapter is expanded and fields are filled
Preview not updatingBrowser cache - try hard refresh (Ctrl+Shift+R)
Form won’t submitCheck all three sections have green checkmarks

Next Steps