Coursir is a full-stack Learning Management System (LMS) that enables teachers to create and publish courses, and students to browse, purchase, and track their progress through course content — complete with video playback, Stripe payments, and role-based dashboards.
- Framework: Next.js 15 (App Router) with React 19
- Language: TypeScript
- Styling: Tailwind CSS, tailwindcss-animate
- UI Components: shadcn/ui (Radix UI primitives), Lucide React icons
- State Management: Redux Toolkit with RTK Query
- Authentication: Clerk (role-based — student & teacher)
- Payments: Stripe (Stripe.js + React Stripe Elements)
- Forms: React Hook Form + Zod schema validation
- Animations: Framer Motion
- Video: React Player
- Drag & Drop: @hello-pangea/dnd
- File Upload: FilePond
- Notifications: Sonner (toast)
- Font: DM Sans (Google Fonts via next/font)
- Landing Page — Hero image carousel, featured courses, category tags
- Course Search — Browse all courses, select a course to view details, and enroll
- Multi-step Checkout — Wizard stepper flow (Details → Payment → Completion) with Stripe integration
- View enrolled courses and track progress per section/chapter
- Video player with auto-completion tracking (marks chapter done at 80% watched)
- Chapter sidebar navigation within a course
- Billing page with transaction/payment history
- Profile management (via Clerk)
- Notification settings (email, SMS, frequency)
- Create, edit, delete, and publish/draft courses
- Full course editor — manage sections and chapters with drag-and-drop reordering
- Video upload per chapter (presigned URL upload flow)
- Search and filter courses by title and category
- Billing and profile management
- Role-based access control — Clerk middleware redirects users to the correct dashboard based on their role
- Dark theme — Custom dark color palette with CSS variables
- Responsive design — Mobile-friendly layout with collapsible sidebar
- Optimistic updates — RTK Query optimistic cache updates for course progress
- Toast notifications — Success/error feedback on all API mutations
- Node.js 18+
- A Clerk account (for authentication)
- A Stripe account (for payments)
- A running backend API (set via
NEXT_PUBLIC_API_BASE_URL)
npm installCreate a .env.local file with the required environment variables:
NEXT_PUBLIC_API_BASE_URL=<your-api-url>
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=<your-clerk-publishable-key>
CLERK_SECRET_KEY=<your-clerk-secret-key>
NEXT_PUBLIC_STRIPE_PUBLIC_KEY=<your-stripe-public-key>npm run devOpen http://localhost:3000 to view the app.
src/
├── app/
│ ├── (auth)/ # Sign-in and sign-up pages (Clerk)
│ ├── (dashboard)/ # Authenticated dashboards
│ │ ├── teacher/ # Teacher: courses, billing, profile, settings
│ │ └── user/ # Student: courses, chapters, billing, profile, settings
│ ├── (nondashboard)/ # Public pages: landing, search, checkout
│ ├── layout.tsx # Root layout (Clerk + Redux providers)
│ └── providers.tsx # Client-side provider wrapper
├── components/ # Reusable components (sidebar, navbar, course cards, modals, etc.)
│ └── ui/ # shadcn/ui primitives
├── hooks/ # Custom hooks (carousel, checkout navigation, course progress)
├── lib/ # Utilities, Zod schemas, constants
├── state/ # Redux store, RTK Query API slice, global slice
├── types/ # Global TypeScript type declarations
└── middleware.ts # Clerk auth + role-based route protection
- Next.js 15 App Router — Using route groups
(auth),(dashboard),(nondashboard)to organize layouts and apply different UI shells per section. - RTK Query — Building a custom base query with Clerk token injection, automatic cache invalidation via tags, and optimistic updates for real-time progress tracking.
- Clerk Authentication — Integrating Clerk with Next.js middleware for role-based route protection, and using session claims to gate access per user type.
- Stripe Payments — Creating payment intents on the backend, rendering Stripe Elements on the frontend, and handling the full checkout lifecycle.
- Zod + React Hook Form — Declarative form validation with schema-first design, keeping forms type-safe end-to-end.
- Drag & Drop — Using @hello-pangea/dnd to let teachers reorder course sections and chapters visually.
- Presigned URL Uploads — Requesting signed upload URLs from the backend and uploading video files directly from the browser.
- Optimistic UI Updates — Using RTK Query's
onQueryStartedto instantly reflect progress changes before the server responds, with automatic rollback on failure. - Component Architecture — Building a design system with shadcn/ui (Radix primitives + Tailwind) and keeping components composable and reusable.
- Framer Motion — Adding entrance animations and scroll-triggered transitions to improve perceived performance and polish.