Skip to main content
Version: 1.0 Last Updated: 2025-11-02 Maintainers: Engineering Team

Table of Contents

  1. Overview
  2. Architecture Principles
  3. System Components
  4. State Management
  5. Data Flow
  6. Navigation System
  7. Step Handler Registry Pattern
  8. Entity Lifecycle Management
  9. Persistence Strategy
  10. Error Handling
  11. Performance Optimizations
  12. Key Design Patterns
  13. Extension Points

Overview

The Instructor Course Editor is a multi-step wizard for creating and editing courses. It implements a sophisticated state-driven architecture using Zustand for state management, with a step-based navigation system, optimistic UI updates, and robust error handling.

Key Features

  • 5-Step Wizard: Basic Info → Advanced Info → Curriculum → Pricing → Publish
  • Optimistic Updates: UI responds immediately, syncs async with backend
  • Persistence: Critical data persists across sessions
  • Permission Control: Owner/manager authorization checks
  • Unsaved Changes Protection: Prevents data loss on navigation
  • Real-time Validation: Per-step validation with error tracking
  • Entity Status Tracking: NEW → UPDATED → SYNCED → DELETED states

Technology Stack

  • State Management: Zustand with slices pattern
  • Forms: React Hook Form + Zod validation
  • Data Fetching: React Query
  • UI Framework: Chakra UI v3
  • Navigation: React Router v6
  • Animations: Framer Motion

Architecture Principles

1. Separation of Concerns

  • Parent Component: Initial data fetch, routing, permission checks
  • Step Components: Individual UI, validation, save logic
  • Store Slices: Domain-specific state management
  • Hooks: Reusable logic encapsulation

2. Single Source of Truth

  • Zustand store is the canonical source for all editor state
  • React Query for server state caching
  • LocalStorage for session persistence

3. Loose Coupling

  • Steps don’t know about each other
  • Navigation logic separated from step logic
  • Save handlers registered dynamically via registry pattern

4. Progressive Enhancement

  • Works with partial data
  • Handles network failures gracefully
  • Supports continue-previous-work flow

5. Type Safety

  • Full TypeScript coverage
  • Zod schemas for runtime validation
  • Interface contracts between layers

System Components

Component Hierarchy

Core Files

Pages (instructor/src/pages/editor/)

  • CourseEditor.tsx - Main wrapper with data fetching
  • BasicInformation.tsx - Course title, category, level, language
  • AdvanceInformation.tsx - Thumbnail, video, description, requirements
  • Curriculum.tsx - Course structure (sections/subsections/items)
  • Pricing.tsx - Pricing configuration
  • PublishCourse.tsx - Final review and submission

Store Slices (instructor/src/stores/course-editor/)

  • index.ts - Main store creator with persistence
  • state.ts - Initial state definition
  • types.ts - Initial values for each step
  • navigation.slice.ts - Step navigation logic
  • form.slice.ts - Form state management
  • curriculum.slice.ts - Course structure operations
  • sync.slice.ts - Backend synchronization
  • step.slice.ts - Step completion tracking
  • step-handler-registry.ts - Handler registry implementation

Hooks (instructor/src/hooks/)

  • useEditorNavigation.ts - Enhanced navigation with validation
  • useCourseEditorInitialization.ts - Editor initialization logic
  • useStepSubmission.ts - Step handler registration

State Management

Zustand Store Structure

Slice Pattern

The store is composed of 5 specialized slices:

1. Navigation Slice

Responsibilities:
  • Step index management
  • Accessibility validation
  • Mode switching (CREATE → EDIT)
  • Step completion checking

2. Form Slice

Responsibilities:
  • Field-level updates
  • Real-time validation
  • Form state tracking

3. Curriculum Slice

Responsibilities:
  • Hierarchical structure management
  • Optimistic UI updates with temp IDs
  • Order management with automatic reindexing
  • Cascade deletion

4. Sync Slice

Responsibilities:
  • Initial data hydration
  • Temp ID → Real ID replacement
  • Entity status updates (SYNCED/ERROR)
  • Error tracking and recovery

5. Step Slice

Responsibilities:
  • Step state lifecycle
  • Completion tracking
  • Unsaved changes detection
  • Step accessibility calculation

Data Flow

1. Initial Load (Edit Mode)

2. Step Save Flow

3. Curriculum Entity Creation Flow

4. Curriculum Entity Update Flow

5. Curriculum Entity Deletion Flow


The useEditorNavigation hook is the central navigation controller for the editor.

Core Methods

URL Synchronization

Unsaved Changes Protection

Step States

Each step tracks its own state:

Visual Feedback

Steps are visually styled based on their state:

Step Handler Registry Pattern

Overview

The Step Handler Registry decouples navigation logic from step-specific business logic. Each step registers a handler that implements a common interface, allowing the navigation system to call step-specific functions without knowing implementation details.

Handler Interface

Registry Implementation

Step Registration Hook

Usage in Step Components

Benefits

  1. Decoupling: Navigation doesn’t know about step internals
  2. Testability: Each handler can be tested independently
  3. Flexibility: Easy to add new steps without modifying navigation
  4. Type Safety: Common interface ensures consistency
  5. Reusability: Handler logic can be shared across steps

Entity Lifecycle Management

Entity Status Enum

Entity Structure

Lifecycle Transitions

Update Flow

Delete Flow

Temporary IDs

Error Recovery


Persistence Strategy

LocalStorage Persistence

Only critical data is persisted to avoid bloating localStorage:
Not Persisted:
  • sections, subsections, items (curriculum)
  • stepStates (recomputed on mount)
  • navigationState (derived)
  • optimisticUpdates (transient)
  • UI state flags
Rationale:
  • Curriculum can be large and is fetched from server
  • Step states are derived from validated data
  • Reduces localStorage quota usage
  • Prevents stale curriculum data

Continue Work Modal

When the editor mounts:

Error Handling

Multi-Layer Error Boundaries

1. Application Level

2. Step Level

  • React Hook Form validation errors
  • Zod schema validation
  • Displayed inline near fields

3. API Level

4. Navigation Guards

Retry Logic

Permission Errors


Performance Optimizations

1. Memoization

2. Shallow Equality Checking

3. Debounced Validation

4. Conditional Queries

5. Optimistic UI Updates

6. Selective Re-renders

7. Animation Performance


Key Design Patterns

1. Command Pattern (Step Handlers)

  • Encapsulates save/discard operations as objects
  • Allows queuing, undo, and retry

2. Registry Pattern (Handler Registry)

  • Dynamic registration of step handlers
  • Loose coupling between navigation and steps

3. Observer Pattern (Zustand Subscriptions)

  • Components subscribe to specific slices
  • Automatic re-renders on state changes

4. State Machine (Step Progression)

  • Finite states: pending → current → completed → error
  • Well-defined transitions

5. Optimistic Concurrency (Entity Status)

  • UI updates immediately
  • Backend syncs asynchronously
  • Handles conflicts gracefully

6. Repository Pattern (Services)

  • CourseService, CourseSectionService, etc.
  • Abstracts API communication

7. Facade Pattern (Navigation Hook)

  • Simplifies complex navigation logic
  • Single interface for step navigation

8. Strategy Pattern (Validation)

  • Different validation strategies per step
  • Zod schemas define validation rules

Extension Points

Adding a New Step

  1. Create step component (pages/editor/NewStep.tsx)
  2. Add to initial state (stores/course-editor/types.ts)
  3. Create form slice methods (if needed)
  4. Add validation schema (utils/schema/course.schema.ts)
  5. Register in navigation (EditorStep enum)
  6. Add to tabs array (CourseEditor.tsx)
  7. Implement step handler (using useStepSubmission)

Adding a New Entity Type

  1. Define interface (utils/types.ts)
  2. Add to store state (stores/course-editor/state.ts)
  3. Create CRUD methods (new or existing slice)
  4. Add sync methods (sync.slice.ts)
  5. Create service (services/new-entity.service.ts)
  6. Build UI component (components/course/NewEntity.tsx)

Custom Validation

Additional Hooks


Conclusion

The Instructor Course Editor demonstrates a sophisticated, production-ready architecture that balances:
  • User Experience: Instant feedback, clear progression, unsaved changes protection
  • Data Integrity: Validation at multiple levels, optimistic updates with rollback
  • Performance: Memoization, shallow equality, debounced validation
  • Maintainability: Clear separation of concerns, typed interfaces, extensible patterns
  • Resilience: Retry logic, error boundaries, graceful degradation
This architecture can serve as a template for other multi-step wizards and complex form flows in the application.
Document History:
  • v1.0 (2025-11-02): Initial architecture documentation