lmscn

Progress Tracker

A Duolingo-style visual learning path with XP, levels, streaks, and lesson status nodes.

Installation

npx shadcn@latest add https://lmscn.vercel.app/r/progress-tracker.json

Required primitives: badge, card, progress, tooltip

npx shadcn@latest add badge card progress tooltip

Usage

import { ProgressTracker } from "@/components/lms/progress-tracker"
import type { ProgressTrackerData, LessonNode } from "@/components/lms/progress-tracker"

export function MyProgress() {
  return (
    <ProgressTracker
      progressTrackerData={{
        learnerName: "Alex",
        totalXp: 340,
        xpToNextLevel: 500,
        level: 4,
        streak: 7,
        units: [
          {
            id: "u1",
            title: "Biology Unit 1",
            lessons: [
              { id: "l1", title: "The Cell",       status: "completed", xp: 50,  type: "reading",   score: 92 },
              { id: "l2", title: "Cell Organelles", status: "current",   xp: 100, type: "quiz" },
              { id: "l3", title: "Match Functions", status: "available", xp: 75,  type: "match" },
              { id: "l4", title: "Cell Review",     status: "locked",    xp: 120, type: "spaced-repetition" },
            ],
          },
        ],
      }}
      onLessonSelect={(lesson: LessonNode) => {
        console.log("Opening:", lesson.id)
      }}
    />
  )
}

Props

ProgressTrackerProps

PropTypeRequiredDescription
progressTrackerDataProgressTrackerDataLearner state and curriculum
onLessonSelect(lesson: LessonNode) => voidCalled when an "available" or "current" lesson is clicked
classNamestringAdditional CSS classes

Data shape

ProgressTrackerData

FieldTypeDescription
learnerNamestringDisplayed in the header greeting
totalXpnumberCurrent XP total
xpToNextLevelnumberXP required to reach the next level
levelnumberCurrent level number
streaknumberDaily streak in days (hidden if 0 or omitted)
unitsLearningUnit[]Curriculum units, each containing a list of lessons

LearningUnit

FieldTypeDescription
idstringUnique identifier
titlestringUnit heading
lessonsLessonNode[]Ordered list of lessons in this unit

LessonNode

FieldTypeDescription
idstringUnique identifier
titlestringDisplayed beside the node
statusLessonStatusControls the visual state of the node
xpnumberXP earned (completed) or on offer (future)
typeLessonTypeAbbreviation shown inside the node circle
scorenumberScore 0–100 shown beneath the title if the lesson is completed

Types

LessonStatus

ValueAppearanceClickable
"completed"Green with ✓ iconNo
"current"Primary colour with ⚡ icon, pulsing ringYes
"available"Outlined, primary border on hoverYes
"locked"Muted with 🔒 iconNo

LessonType

Controls the abbreviation rendered inside the node for available/locked lessons:

ValueLabel
"quiz"Q
"flashcards"F
"match"M
"reading"R
"video"
"exercise"
"scramble"S
"order"O
"hotspot"H
"spaced-repetition"SR

Behaviour

  • Each unit shows its own progress bar (completed lessons / total lessons).
  • Lessons are laid out in a zigzag path — odd-indexed lessons are offset to the right, even-indexed to the left.
  • Hovering a node shows a tooltip with the lesson title, XP, and score (if completed).
  • The XP progress bar in the header fills from 0 to xpToNextLevel. It caps at 100% if totalXp >= xpToNextLevel.

On this page