Elevasis LogoElevasis Docs

Content Development Guide

How to create training lessons, quizzes, and courses using the reusable component library

Implementation: packages/ui/src/components/training/

This guide covers how to develop training content using the reusable component library.


Quick Start

// Minimal lesson structure
import { LessonContainer, Callout, KeyTakeaways } from '@repo/ui'
import { Stack, Text } from '@mantine/core'

export default function Lesson01Introduction() {
  return (
    <LessonContainer
      title="Introduction"
      subtitle="Getting started with the platform"
      duration="10 min"
    >
      <Stack>
        <Text>Your lesson content here...</Text>

        <Callout type="info" title="What you'll learn">
          <Text>- First topic</Text>
          <Text>- Second topic</Text>
        </Callout>

        <KeyTakeaways items={[
          'First key point',
          'Second key point'
        ]} />
      </Stack>
    </LessonContainer>
  )
}

Note: Stack uses gap="md" by default from the theme (componentThemes.tsx). Do not override this in lessons.


Component Library Overview

See Training Component Reference for complete component documentation with props and examples.

Layout Components

  • LessonContainer - Wrapper with header, navigation, mark complete
  • LessonContent - Styled content area with proper spacing

Content Highlight Components

  • Callout - Info/warning/tip/danger boxes (4 types)
  • QuickFact - Single-line highlight for facts
  • KeyTakeaways - Summary box for lesson conclusions

Visual Content Components

  • SectionHeader - Section divider with icon and gradient (built-in spacing)
  • FeatureCard - Card for highlighting features with icon
  • ConceptGrid - Grid layout for related concepts
  • StepCard - Numbered step for procedural content
  • ProcessTimeline - Vertical timeline for sequential processes

Code Components

  • CodeBlock - Syntax-highlighted code with copy button

Progress Components

  • ProgressRing - Circular progress indicator
  • LessonNavigation - Prev/next and progress bar (auto-included)

Quiz Components

  • LessonQuiz - Modal quiz for end-of-lesson checks (100% pass required)
  • AssessmentQuiz - Full-page assessment for certifications (80% pass default)

Lesson Structure Pattern

Follow this structure for consistent lessons:

import {
  LessonContainer,
  Callout,
  KeyTakeaways,
  SectionHeader
} from '@repo/ui'
import { Text, Stack } from '@mantine/core'
import { TrainingConceptGrid } from '@/features/training/components'
import { IconTopic } from '@tabler/icons-react'

export default function Lesson01TopicName() {
  return (
    <LessonContainer
      title="Topic Name"
      subtitle="Description of what this covers"
      duration="10 min"
    >
      <Stack>
        {/* 1. Introduction */}
        <Text size="lg">
          Opening paragraph that sets context and hooks the learner.
        </Text>

        {/* 2. Learning objectives */}
        <Callout type="info" title="What you'll learn">
          <Stack gap="xs">
            <Text>- First learning objective</Text>
            <Text>- Second learning objective</Text>
            <Text>- Third learning objective</Text>
          </Stack>
        </Callout>

        {/* 3. Main content sections */}
        <SectionHeader icon={IconTopic} title="Section One" />
        <Text>Content for section one...</Text>

        <SectionHeader icon={IconTopic} title="Section Two" />
        <Text>Content for section two...</Text>

        {/* 4. Key takeaways */}
        <KeyTakeaways
          items={[
            'First key point',
            'Second key point',
            'Third key point'
          ]}
        />

        {/* 5. Transition to next lesson */}
        <Callout type="info" title="Next Up">
          In the next lesson, we'll explore...
        </Callout>
      </Stack>
    </LessonContainer>
  )
}

Spacing Standards:

  • Stack uses theme default gap="md" - do not override
  • SectionHeader has built-in margins (mt="xl", mb="md") - do not add extra spacing
  • List components don't need mt props - Stack gap handles spacing
  • Only use gap="xs" inside Callouts for tightly grouped items

Quiz File Pattern

Each lesson quiz is a separate file:

// Lesson01TopicQuiz.tsx
import { LessonQuiz, type QuizQuestion } from '@repo/ui'

const questions: QuizQuestion[] = [
  {
    id: 'q1',
    question: 'Question text here?',
    options: [
      { value: 'a', label: 'Option A' },
      { value: 'b', label: 'Option B' },
      { value: 'c', label: 'Option C' },
      { value: 'd', label: 'Option D' }
    ],
    correctAnswer: 'b'
  }
  // Add 3-5 questions per quiz
]

// Export for course.config.ts
export const lesson01TopicQuizConfig = { questions }

interface Props {
  onComplete?: (answers: Record<string, unknown>, score: number) => void
  onContinue?: () => void
}

export default function Lesson01TopicQuiz({ onComplete, onContinue }: Props) {
  return (
    <LessonQuiz
      questions={questions}
      onComplete={(answers, score) => onComplete?.(answers, score)}
      onContinue={onContinue}
    />
  )
}

Course Configuration

Register lessons in course.config.ts:

import type { CourseConfig } from '../../types'

// Lesson imports
import Lesson01Topic from './Lesson01Topic'
import Lesson02Topic from './Lesson02Topic'

// Quiz imports
import Lesson01TopicQuiz, { lesson01TopicQuizConfig } from './Lesson01TopicQuiz'
import Lesson02TopicQuiz, { lesson02TopicQuizConfig } from './Lesson02TopicQuiz'

// Final assessment (if certified)
import FinalAssessment, { finalAssessmentConfig } from './FinalAssessment'

export const myCourse: CourseConfig = {
  slug: 'my-course',
  title: 'My Course',
  description: 'Course description for catalog.',
  audience: 'customer',  // 'internal' | 'developer' | 'customer' | 'public' | 'partner'
  estimatedDuration: '60 min',
  lessons: [
    {
      slug: 'topic-one',
      title: 'Topic One',
      description: 'What this lesson covers.',
      duration: '10 min',
      order: 1,
      component: Lesson01Topic,
      quiz: {
        passingScore: 100,
        questions: lesson01TopicQuizConfig.questions,
        component: Lesson01TopicQuiz
      }
    },
    {
      slug: 'topic-two',
      title: 'Topic Two',
      description: 'What this lesson covers.',
      duration: '15 min',
      order: 2,
      component: Lesson02Topic,
      quiz: {
        passingScore: 100,
        questions: lesson02TopicQuizConfig.questions,
        component: Lesson02TopicQuiz
      }
    }
  ],
  assessments: [
    {
      slug: 'final-assessment',
      title: 'Course Certification',
      passingScore: 80,
      questions: finalAssessmentConfig.questions,
      component: FinalAssessment
    }
  ],
  certification: {
    certificationSlug: 'my-course-certified',
    requiredLessons: 'all',
    requiredAssessments: [{ slug: 'final-assessment', minScore: 80 }]
  }
}

File Structure

apps/command-center/src/features/training/content/courses/{slug}/
├── course.config.ts           # Course metadata and lesson registry
├── Lesson01TopicName.tsx      # Lesson content component
├── Lesson01TopicNameQuiz.tsx  # Inline quiz for lesson
├── Lesson02TopicName.tsx
├── Lesson02TopicNameQuiz.tsx
├── FinalAssessment.tsx        # Final certification assessment (optional)
└── PlaceholderLesson.tsx      # Placeholder for courses in development

Best Practices

Content Guidelines

  1. Keep lessons focused - One concept per lesson, 8-15 minutes reading time
  2. Start with context - Opening paragraph explains why this matters
  3. Use visuals - ConceptGrid, FeatureCard, and diagrams break up text
  4. End with takeaways - KeyTakeaways summarizes key points
  5. Preview next lesson - Callout at end creates continuity

Quiz Guidelines

  1. 3-5 questions per lesson - Tests understanding, not memorization
  2. Clear correct answers - Avoid trick questions or ambiguous options
  3. Test key concepts - Questions should cover KeyTakeaways content

Passing Score Standards:

  • Lesson quizzes: 100% - Users must answer all questions correctly to proceed
  • Final assessments: 80% - Required for certification

Accessibility

  1. Alt text for images - Describe what the image shows
  2. Semantic headings - Use proper heading hierarchy (h2, h3, h4)
  3. Color not sole indicator - Don't rely only on color to convey meaning
  4. Readable font sizes - LessonContent provides proper sizing


Last Updated: 2026-02-14