Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/0xchriswilder/journey/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The progress tracking system uses TypeScript interfaces to structure student progress data across lessons, quizzes, and homework assignments. All progress data is stored in the Zustand store and persisted to local storage.

Type Definitions

LearningMode

type LearningMode = 'self-paced' | 'cohort';
Defines the two learning modes available in the bootcamp:
  • 'self-paced': All weeks and lessons are immediately accessible
  • 'cohort': Sequential access requiring completion of previous content

HomeworkStatus

type HomeworkStatus = 'not-started' | 'in-progress' | 'submitted' | 'graded';
Tracks the lifecycle of homework assignments:
  • 'not-started': Homework has not been started
  • 'in-progress': Student is actively working on homework
  • 'submitted': Homework has been submitted for review
  • 'graded': Homework has been graded by instructor

Progress Interfaces

LessonProgress

Tracks individual lesson completion and engagement metrics.
interface LessonProgress {
  completed: boolean;
  quizScore?: number;
  quizPassed?: boolean;
  timeSpentMinutes: number;
  completedAt?: string;
}
completed
boolean
required
Whether the lesson has been marked as completed.
quizScore
number
The quiz score for this lesson, if a quiz was taken. Typically a value between 0-100.
quizPassed
boolean
Whether the student passed the quiz. Set alongside quizScore.
timeSpentMinutes
number
default:"0"
required
Total time spent on this lesson in minutes. Accumulated via the addTimeSpent action.
completedAt
string
ISO 8601 timestamp of when the lesson was completed. Set automatically by completeLesson.Example: "2026-03-03T15:30:00.000Z"

Example

const lessonProgress: LessonProgress = {
  completed: true,
  quizScore: 85,
  quizPassed: true,
  timeSpentMinutes: 45,
  completedAt: "2026-03-03T15:30:00.000Z"
};

HomeworkProgress

Tracks homework assignment status and checklist completion.
interface HomeworkProgress {
  status: HomeworkStatus;
  checklist: Record<string, boolean>;
  submittedAt?: string;
  grade?: number;
}
status
HomeworkStatus
required
Current status of the homework assignment. See HomeworkStatus.
checklist
Record<string, boolean>
required
Key-value pairs tracking individual checklist items. Keys are item IDs, values indicate completion.Managed via toggleHomeworkChecklistItem action.
submittedAt
string
ISO 8601 timestamp of when the homework was submitted. Automatically set when status changes to 'submitted'.Example: "2026-03-03T18:00:00.000Z"
grade
number
The grade assigned to the homework, typically 0-100. Set when status is 'graded'.

Example

const homeworkProgress: HomeworkProgress = {
  status: 'submitted',
  checklist: {
    'task-1': true,
    'task-2': true,
    'task-3': false
  },
  submittedAt: "2026-03-03T18:00:00.000Z",
  grade: 92
};

WeekProgress

Aggregates all progress data for a single week.
interface WeekProgress {
  lessons: Record<string, LessonProgress>;
  homework: HomeworkProgress;
}
lessons
Record<string, LessonProgress>
required
Progress data for all lessons in the week, indexed by lesson ID.Each lesson ID maps to a LessonProgress object.
homework
HomeworkProgress
required
Progress data for the week’s homework assignment. See HomeworkProgress.

Example

const weekProgress: WeekProgress = {
  lessons: {
    'lesson-1-1': {
      completed: true,
      quizScore: 90,
      quizPassed: true,
      timeSpentMinutes: 30,
      completedAt: "2026-03-01T10:00:00.000Z"
    },
    'lesson-1-2': {
      completed: true,
      timeSpentMinutes: 45,
      completedAt: "2026-03-02T14:30:00.000Z"
    },
    'lesson-1-3': {
      completed: false,
      timeSpentMinutes: 15
    }
  },
  homework: {
    status: 'in-progress',
    checklist: {
      'setup-env': true,
      'deploy-contract': false
    }
  }
};

Initial Progress State

The store initializes progress data for all weeks and lessons in the curriculum:
function createInitialProgress(): Record<string, WeekProgress> {
  const progress: Record<string, WeekProgress> = {};
  curriculum.weeks.forEach((week) => {
    const lessons: Record<string, LessonProgress> = {};
    week.lessons.forEach((lesson) => {
      lessons[lesson.id] = {
        completed: false,
        timeSpentMinutes: 0,
      };
    });
    progress[week.id] = {
      lessons,
      homework: {
        status: 'not-started',
        checklist: {},
      },
    };
  });
  return progress;
}
Each week starts with:
  • All lessons marked as incomplete
  • Zero time spent on each lesson
  • Homework status set to 'not-started'
  • Empty homework checklist

Progress Methods

These methods are available on the useBootcampStore hook for working with progress data. See bootcamp-store for detailed method documentation.

Lesson Progress Methods

completeLesson
(weekId: string, lessonId: string) => void
Marks a lesson as completed and records the completion timestamp.
setQuizScore
(weekId: string, lessonId: string, score: number, passed: boolean) => void
Records a quiz score and pass/fail status.
addTimeSpent
(weekId: string, lessonId: string, minutes: number) => void
Adds time spent on a lesson to the running total.
isLessonCompleted
(weekId: string, lessonId: string) => boolean
Checks if a specific lesson has been completed.

Homework Progress Methods

updateHomeworkStatus
(weekId: string, status: HomeworkStatus) => void
Updates the status of a week’s homework. Automatically records submission timestamp.
toggleHomeworkChecklistItem
(weekId: string, itemId: string) => void
Toggles a checklist item in a week’s homework.

Week Progress Methods

getWeekProgress
(weekId: string) => { completed: number; total: number; percentage: number }
Calculates progress statistics for a specific week.
isWeekCompleted
(weekId: string) => boolean
Checks if all lessons in a week have been completed.
canAccessWeek
(weekId: string) => boolean
Determines if a week is accessible based on learning mode and progress.

Overall Progress Methods

getOverallProgress
() => { completed: number; total: number; percentage: number }
Calculates progress statistics across all weeks.
resetProgress
() => void
Resets all progress to initial state.

Usage Examples

Tracking Lesson Completion

import { useBootcampStore } from '@/state/bootcampStore';

function LessonCompleteButton({ weekId, lessonId }: { weekId: string; lessonId: string }) {
  const completeLesson = useBootcampStore((state) => state.completeLesson);
  const addTimeSpent = useBootcampStore((state) => state.addTimeSpent);
  const progress = useBootcampStore(
    (state) => state.progress[weekId]?.lessons[lessonId]
  );
  
  const handleComplete = () => {
    // Mark lesson as complete
    completeLesson(weekId, lessonId);
    
    // Add estimated time
    addTimeSpent(weekId, lessonId, 30);
  };
  
  return (
    <div>
      <button onClick={handleComplete} disabled={progress?.completed}>
        {progress?.completed ? 'Completed ✓' : 'Mark as Complete'}
      </button>
      {progress?.completedAt && (
        <p>Completed: {new Date(progress.completedAt).toLocaleDateString()}</p>
      )}
      <p>Time spent: {progress?.timeSpentMinutes || 0} minutes</p>
    </div>
  );
}

Managing Quiz Results

function QuizResults({ weekId, lessonId, score }: { weekId: string; lessonId: string; score: number }) {
  const setQuizScore = useBootcampStore((state) => state.setQuizScore);
  const showCelebration = useBootcampStore((state) => state.showCelebration);
  
  const passingScore = 70;
  const passed = score >= passingScore;
  
  const handleSaveScore = () => {
    setQuizScore(weekId, lessonId, score, passed);
    
    if (passed) {
      showCelebration(
        'Quiz Passed!',
        `You scored ${score}%`,
        1,
        1
      );
    }
  };
  
  return (
    <div>
      <h3>Your Score: {score}%</h3>
      <p>{passed ? 'Passed ✓' : 'Did not pass'}</p>
      <button onClick={handleSaveScore}>Save Score</button>
    </div>
  );
}

Homework Checklist

function HomeworkChecklist({ weekId, items }: { weekId: string; items: Array<{ id: string; label: string }> }) {
  const homework = useBootcampStore(
    (state) => state.progress[weekId]?.homework
  );
  const toggleItem = useBootcampStore(
    (state) => state.toggleHomeworkChecklistItem
  );
  const updateStatus = useBootcampStore(
    (state) => state.updateHomeworkStatus
  );
  
  const allComplete = items.every((item) => homework?.checklist[item.id]);
  
  const handleSubmit = () => {
    if (allComplete) {
      updateStatus(weekId, 'submitted');
    }
  };
  
  return (
    <div>
      <h3>Homework Tasks</h3>
      {items.map((item) => (
        <label key={item.id}>
          <input
            type="checkbox"
            checked={homework?.checklist[item.id] || false}
            onChange={() => toggleItem(weekId, item.id)}
          />
          {item.label}
        </label>
      ))}
      <button onClick={handleSubmit} disabled={!allComplete}>
        Submit Homework
      </button>
      {homework?.submittedAt && (
        <p>Submitted: {new Date(homework.submittedAt).toLocaleString()}</p>
      )}
      {homework?.grade && <p>Grade: {homework.grade}%</p>}
    </div>
  );
}

Week Progress Display

function WeekProgressCard({ weekId }: { weekId: string }) {
  const getWeekProgress = useBootcampStore((state) => state.getWeekProgress);
  const isCompleted = useBootcampStore((state) => state.isWeekCompleted(weekId));
  const canAccess = useBootcampStore((state) => state.canAccessWeek(weekId));
  
  const progress = getWeekProgress(weekId);
  
  return (
    <div>
      <h3>Week {weekId}</h3>
      <div>
        <div style={{ width: `${progress.percentage}%` }}>
          {progress.percentage}%
        </div>
      </div>
      <p>
        {progress.completed} of {progress.total} lessons completed
      </p>
      {isCompleted && <p>✓ Week Complete!</p>}
      {!canAccess && <p>🔒 Complete previous week to unlock</p>}
    </div>
  );
}

Overall Bootcamp Progress

function BootcampDashboard() {
  const getOverallProgress = useBootcampStore((state) => state.getOverallProgress);
  const progress = getOverallProgress();
  
  return (
    <div>
      <h2>Bootcamp Progress</h2>
      <div>
        <div style={{ width: `${progress.percentage}%` }}>
          {progress.percentage}%
        </div>
      </div>
      <p>
        {progress.completed} of {progress.total} total lessons completed
      </p>
    </div>
  );
}

Access Control

Progress data is used to determine access to content in cohort mode:
// Week access: previous week must be complete
const canAccessWeek = (weekId: string) => {
  if (learningMode === 'self-paced') return true;
  
  const weekIndex = curriculum.weeks.findIndex((w) => w.id === weekId);
  if (weekIndex <= 0) return true;
  
  const prevWeekId = curriculum.weeks[weekIndex - 1].id;
  return isWeekCompleted(prevWeekId);
};

// Lesson access: previous lesson must be complete
const canAccessLesson = (weekId: string, lessonId: string) => {
  if (!canAccessWeek(weekId)) return false;
  if (learningMode === 'self-paced') return true;
  
  const week = curriculum.weeks.find((w) => w.id === weekId);
  if (!week) return false;
  
  const lessonIndex = week.lessons.findIndex((l) => l.id === lessonId);
  if (lessonIndex <= 0) return true;
  
  const prevLessonId = week.lessons[lessonIndex - 1].id;
  return isLessonCompleted(weekId, prevLessonId);
};

Data Persistence

All progress data is persisted to local storage via Zustand’s persist middleware under the key 'fhevm-bootcamp-progress'. This includes:
  • All lesson completion data
  • Quiz scores and results
  • Homework status and checklists
  • Time tracking data
  • Completion timestamps
Progress data is automatically loaded when the store initializes and saved whenever it changes.

Build docs developers (and LLMs) love