Skip to content

Repository files navigation

A modern learning management system built with Next.js. Dao LMS supports public course discovery, Stripe-powered enrollment, learner dashboards, lesson progress, and an admin workspace for managing courses, chapters, lessons, media, and analytics.

Features

  • Public course catalog with course detail pages
  • Email and OAuth authentication with Better Auth
  • Role-based admin and learner dashboards
  • Course, chapter, and lesson management
  • Drag-and-drop ordering for chapters and lessons
  • Rich markdown lesson content with TipTap editing
  • Markdown tables in the editor and renderer
  • Video and image uploads through S3-compatible storage
  • Stripe checkout and webhook-based enrollment
  • Learner progress tracking
  • Admin analytics with enrollment charts

Project Management

Tech Stack

  • Next.js 16 and React 19
  • TypeScript
  • Tailwind CSS
  • Drizzle ORM
  • Neon Postgres
  • Better Auth
  • Stripe
  • Tigris/S3-compatible object storage
  • TipTap
  • Recharts
  • shadcn-style UI components

Getting Started

Install dependencies:

pnpm install

Create a .env file in the project root and fill in the required variables:

DATABASE_URL=

BETTER_AUTH_SECRET=
BETTER_AUTH_URL=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=

SMTP_USER=
SMTP_PASS=
SENDER_EMAIL=

TIGRIS_STORAGE_ACCESS_KEY_ID=
TIGRIS_STORAGE_SECRET_ACCESS_KEY=
TIGRIS_STORAGE_ENDPOINT=
TIGRIS_STORAGE_BUCKET=
NEXT_PUBLIC_TIGRIS_STORAGE_BUCKET=

STRIPE_SECRET_KEY=
STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=

NEXT_PUBLIC_APP_URL=

Push the database schema:

pnpm db:push

Run the development server:

pnpm dev

Open http://localhost:3000.

Scripts

pnpm dev          # Start the local dev server
pnpm build        # Build the production app
pnpm start        # Start the production server
pnpm lint         # Run ESLint
pnpm db:push      # Push Drizzle schema changes
pnpm db:migrate   # Run Drizzle migrations
pnpm db:generate  # Generate Drizzle migration files
pnpm db:studio    # Open Drizzle Studio

Stripe Webhooks

Enrollments are written from Stripe webhook events after checkout succeeds. In local development, forward Stripe events to:

/api/webhooks/stripe

The webhook must send checkout.session.completed events and use the same signing secret stored in STRIPE_WEBHOOK_SECRET.

Project Structure

src/app                App Router routes and API handlers
src/components         Shared UI, dashboard, auth, and markdown components
src/db                 Drizzle database setup and schemas
src/features           Feature modules for courses, chapters, lessons, enrollments
src/lib                Auth, actions, utilities, and emails
src/services           Stripe and storage integrations

Dashboards

  • /admin shows analytics and recent courses.
  • /admin/courses manages course creation, editing, deletion, chapters, and lessons.
  • /dashboard shows enrolled and available courses for learners.
  • /dashboard/[courseId]/[lessonId] is the lesson player experience.

Notes

  • Course purchases depend on valid Stripe price IDs created for each course.
  • Uploaded media is stored in the configured S3-compatible bucket.
  • Lesson descriptions are stored as markdown and rendered safely through the project markdown renderer.

About

An LMS platform where admins can share courses and learners can purchase them.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages