15 KiB
DASH-004: Tutorial Section Redesign
Overview
Redesign the tutorial section (Learn tab) to be more compact, informative, and useful. Move from large tiles to a structured learning center with categories, progress tracking, and better discoverability.
Context
The current tutorial section (projectsview.ts and lessons model) shows tutorials as large tiles with progress bars. The tiles take up significant screen space, making it hard to browse many tutorials. There's no categorization beyond a linear list.
The new launcher has an empty LearningCenter.tsx view that needs to be built out.
Current Tutorial System
The existing system uses:
LessonProjectsModel- manages lesson templates and progresslessonprojectsmodel.ts- fetches from docs endpoint- Templates stored in docs repo with progress in localStorage
Requirements
Functional Requirements
-
Category Organization
- Categories: Getting Started, Building UIs, Data & Logic, Advanced Topics, Integrations
- Collapsible category sections
- Category icons/colors
-
Tutorial Cards (Compact)
- Title
- Short description (1-2 lines)
- Estimated duration
- Difficulty level (Beginner, Intermediate, Advanced)
- Progress indicator (not started, in progress, completed)
- Thumbnail (small, optional)
-
Progress Tracking
- Visual progress bar per tutorial
- Overall progress stats ("5 of 12 completed")
- "Continue where you left off" section at top
- Reset progress option
-
Filtering & Search
- Search tutorials by name/description
- Filter by difficulty
- Filter by category
- Filter by progress (Not Started, In Progress, Completed)
-
Tutorial Detail View
- Expanded description
- Learning objectives
- Prerequisites
- "Start Tutorial" / "Continue" / "Restart" button
- Estimated time remaining (for in-progress)
-
Additional Content Types
- Video tutorials (embedded or linked)
- Written guides
- Interactive lessons (existing)
- External resources
Non-Functional Requirements
- Fast loading (tutorials list cached)
- Works offline for previously loaded tutorials
- Responsive layout
- Accessible navigation
Data Model
Enhanced Tutorial Structure
interface Tutorial {
id: string;
title: string;
description: string;
longDescription?: string;
category: TutorialCategory;
difficulty: 'beginner' | 'intermediate' | 'advanced';
estimatedMinutes: number;
type: 'interactive' | 'video' | 'guide';
thumbnailUrl?: string;
objectives?: string[];
prerequisites?: string[];
// For interactive tutorials
templateUrl?: string;
// For video tutorials
videoUrl?: string;
// For guides
guideUrl?: string;
}
interface TutorialCategory {
id: string;
name: string;
icon: IconName;
color: string;
order: number;
}
interface TutorialProgress {
tutorialId: string;
status: 'not-started' | 'in-progress' | 'completed';
lastAccessedAt: string;
completedAt?: string;
currentStep?: number;
totalSteps?: number;
}
Default Categories
const TUTORIAL_CATEGORIES: TutorialCategory[] = [
{ id: 'getting-started', name: 'Getting Started', icon: IconName.Rocket, color: '#22C55E', order: 0 },
{ id: 'ui', name: 'Building UIs', icon: IconName.Palette, color: '#3B82F6', order: 1 },
{ id: 'data', name: 'Data & Logic', icon: IconName.Database, color: '#8B5CF6', order: 2 },
{ id: 'advanced', name: 'Advanced Topics', icon: IconName.Cog, color: '#F97316', order: 3 },
{ id: 'integrations', name: 'Integrations', icon: IconName.Plug, color: '#EC4899', order: 4 },
];
Technical Approach
1. Tutorial Service
Extend or replace LessonProjectsModel:
// packages/noodl-editor/src/editor/src/services/TutorialService.ts
class TutorialService {
private static instance: TutorialService;
// Data fetching
async fetchTutorials(): Promise<Tutorial[]>;
async getTutorialById(id: string): Promise<Tutorial | null>;
// Progress
getProgress(tutorialId: string): TutorialProgress;
updateProgress(tutorialId: string, progress: Partial<TutorialProgress>): void;
resetProgress(tutorialId: string): void;
// Queries
getInProgressTutorials(): Tutorial[];
getCompletedTutorials(): Tutorial[];
getTutorialsByCategory(categoryId: string): Tutorial[];
}
2. Component Structure
packages/noodl-core-ui/src/preview/launcher/Launcher/
├── views/
│ └── LearningCenter/
│ ├── LearningCenter.tsx # Main view
│ ├── LearningCenter.module.scss
│ ├── ContinueLearning.tsx # "Continue" section
│ ├── TutorialCategory.tsx # Category section
│ └── TutorialFilters.tsx # Filter bar
├── components/
│ ├── TutorialCard/
│ │ ├── TutorialCard.tsx # Compact card
│ │ ├── TutorialCard.module.scss
│ │ └── index.ts
│ ├── TutorialDetailModal/
│ │ ├── TutorialDetailModal.tsx # Expanded detail view
│ │ └── TutorialDetailModal.module.scss
│ ├── DifficultyBadge/
│ │ └── DifficultyBadge.tsx # Beginner/Intermediate/Advanced
│ ├── ProgressRing/
│ │ └── ProgressRing.tsx # Circular progress indicator
│ └── DurationLabel/
│ └── DurationLabel.tsx # "15 min" display
3. Learning Center Layout
┌─────────────────────────────────────────────────────────────────────┐
│ Learn [🔍 Search... ] │
├─────────────────────────────────────────────────────────────────────┤
│ Filters: [All ▾] [All Difficulties ▾] [All Progress ▾] [Clear] │
├─────────────────────────────────────────────────────────────────────┤
│ ⏸️ Continue Learning │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 📚 OpenNoodl Basics 47% [●●●●●○○○○○] [Continue →] │ │
│ │ Data-driven Components 12% [●○○○○○○○○○] [Continue →] │ │
│ └─────────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────┤
│ 🚀 Getting Started ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ AI Walkthru │ │ Basics │ │ Layout │ │
│ │ 🟢 Beginner │ │ 🟢 Beginner │ │ 🟢 Beginner │ │
│ │ 15 min │ │ 15 min │ │ 15 min │ │
│ │ ✓ Complete │ │ ● 47% │ │ ○ Not started│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────────────┤
│ 🎨 Building UIs ▼ │
│ ... │
└─────────────────────────────────────────────────────────────────────┘
Files to Create
packages/noodl-editor/src/editor/src/services/TutorialService.tspackages/noodl-core-ui/src/preview/launcher/Launcher/views/LearningCenter/LearningCenter.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/views/LearningCenter/LearningCenter.module.scsspackages/noodl-core-ui/src/preview/launcher/Launcher/views/LearningCenter/ContinueLearning.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/views/LearningCenter/TutorialCategory.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/views/LearningCenter/TutorialFilters.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/components/TutorialCard/TutorialCard.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/components/TutorialCard/TutorialCard.module.scsspackages/noodl-core-ui/src/preview/launcher/Launcher/components/TutorialDetailModal/TutorialDetailModal.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/components/DifficultyBadge/DifficultyBadge.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/components/ProgressRing/ProgressRing.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/components/DurationLabel/DurationLabel.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/hooks/useTutorials.ts
Files to Modify
-
packages/noodl-core-ui/src/preview/launcher/Launcher/views/LearningCenter.tsx- Replace empty component with full implementation
- Move to folder structure
-
packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx- Update import for LearningCenter
-
packages/noodl-editor/src/editor/src/models/lessonprojectsmodel.ts- Either extend or create adapter for new TutorialService
Implementation Steps
Phase 1: Data Layer
- Create TutorialService
- Define data types
- Create useTutorials hook
- Migrate existing lesson data structure
Phase 2: Core Components
- Create TutorialCard component
- Create DifficultyBadge
- Create ProgressRing
- Create DurationLabel
Phase 3: Main Layout
- Build LearningCenter view
- Create TutorialCategory sections
- Add ContinueLearning section
- Implement category collapse/expand
Phase 4: Filtering
- Create TutorialFilters component
- Implement search
- Implement filter dropdowns
- Wire up filter state
Phase 5: Detail View
- Create TutorialDetailModal
- Add start/continue/restart logic
- Show objectives and prerequisites
Phase 6: Polish
- Add loading states
- Add empty states
- Smooth animations
- Accessibility review
Component Specifications
TutorialCard
┌────────────────────────────┐
│ [📹] OpenNoodl Basics │ <- Type icon + Title
│ Learn the fundamentals │ <- Description (truncated)
│ 🟢 Beginner ⏱️ 15 min │ <- Difficulty + Duration
│ [●●●●●○○○○○] 47% │ <- Progress bar
└────────────────────────────┘
Props:
tutorial: Tutorialprogress: TutorialProgressonClick: () => voidvariant?: 'compact' | 'expanded'
DifficultyBadge
| Level | Color | Icon |
|---|---|---|
| Beginner | Green (#22C55E) | 🟢 |
| Intermediate | Yellow (#EAB308) | 🟡 |
| Advanced | Red (#EF4444) | 🔴 |
ProgressRing
Small circular progress indicator:
- Size: 24px
- Stroke width: 3px
- Background: gray
- Fill: green (completing), green (complete)
- Center: percentage or checkmark
Compatibility Notes
Existing Lesson System
The current system uses:
// lessonprojectsmodel.ts
interface LessonTemplate {
name: string;
description: string;
iconURL: string;
templateURL: string;
progress?: number;
}
The new system should:
- Be backwards compatible with existing templates
- Migrate progress data from old format
- Support new enhanced metadata
Migration Path
- Keep
lessonprojectsmodel.tsworking during transition - Create adapter in TutorialService to read old data
- Enhance existing tutorials with new metadata
- Eventually deprecate old model
Testing Checklist
- Tutorials load from docs endpoint
- Categories display correctly
- Category collapse/expand works
- Progress displays correctly
- Continue Learning section shows in-progress tutorials
- Search filters tutorials
- Difficulty filter works
- Progress filter works
- Clicking card shows detail modal
- Start Tutorial launches tutorial
- Continue Tutorial resumes from last point
- Restart Tutorial resets progress
- Progress persists across sessions
- Empty states display appropriately
- Responsive at different window sizes
Dependencies
- DASH-001 (Tabbed Navigation System)
External Dependencies
None - uses existing noodl-core-ui components.
Blocked By
- DASH-001
Blocks
- None
Estimated Effort
- TutorialService: 2-3 hours
- TutorialCard components: 2-3 hours
- LearningCenter layout: 3-4 hours
- Filtering: 2-3 hours
- Detail modal: 2-3 hours
- Polish & testing: 2-3 hours
- Total: 13-19 hours
Success Criteria
- Tutorials are organized by category
- Users can easily find tutorials by search/filter
- Progress is clearly visible
- "Continue Learning" helps users resume work
- Tutorial cards are compact but informative
- Detail modal provides all needed information
- System is backwards compatible with existing tutorials
Future Enhancements
- Video tutorial playback within app
- Community-contributed tutorials
- Tutorial recommendations based on usage
- Learning paths (curated sequences)
- Achievements/badges for completion
- Tutorial ratings/feedback
Design Notes
The learning center should feel like:
- Duolingo's course browser (compact, progress-focused)
- Coursera's course catalog (categorized, searchable)
- VS Code's Getting Started (helpful, not overwhelming)
Prioritize getting users to relevant content quickly. The most common flow is:
- See "Continue Learning" → resume last tutorial
- Browse category → find new tutorial → start
- Search for specific topic → find tutorial → start
Don't make users click through multiple screens to start learning.