The FIAE Tutor Desktop application has been successfully refactored into a production-grade MVU (Model-View-Update) architecture with robust error handling and clean UI rendering.
-
src/state/model.ts: Refactored model with new fields
- Renamed
activeTab→viewTab - Renamed
debugLog→logs - Added
eventFilterfor future event filtering
- Renamed
-
src/state/actions.ts: Enhanced action types
- Added
PracticeEventFilterChanged - Added
PracticeLoadPreset - Added
PracticeAddLog
- Added
-
src/state/update.ts: Complete reducer refactor
- Pure update function with no side effects
- All handlers updated for new field names
- Proper TypeScript types with no null (using undefined)
- Command types fixed (RunTutor, Ping, none)
-
src/state/presets.ts: NEW preset system
- Default parameters for all topic/mode combinations
- BubbleSort, BinarySearch, InsertionSort, Checksum presets
- Auto-load presets when changing topic/mode
- src/components/ErrorBoundary.tsx: NEW error boundary component
- Catches rendering errors to prevent black screens
- Shows error details with component stack
- "Try Again" button to reset
- Production-ready error UI
- src/components/renderers.tsx: NEW comprehensive renderer library (~400 lines)
ResultRenderer: Handles pseudocode (code block with copy), explain text, structured dataEventsRenderer: Event navigation with First/Prev/Next/Last buttons, message displayQuestionsRenderer: Quiz questions in card format with answer toggleStatsRenderer: Statistics in responsive grid layoutRawJsonRenderer: Pretty-printed JSON with copy buttonLogsRenderer: Debug logs with indexed entries- All styled consistently with color-coded sections
- src/views/PracticePage.tsx: Complete UI rewrite
- Clean topic/mode/language controls
- JSON params editor with validation
- Run/Copy buttons with status indicators
- Tab navigation (Result, Events, Questions, Stats, Raw, Logs)
- Each tab wrapped in ErrorBoundary
- Uses specialized renderers (no raw JSON blocks)
- Proper loading/empty states
- src/App.tsx: Simplified main app
- Removed legacy watermark and logo clutter
- Now renders only
<PracticePage>wrapped in<ErrorBoundary> - MVU wiring preserved with proper error handling
- useReducer with try-catch to prevent crashes
- ✅ Pure update function: No side effects in reducer
- ✅ Typed actions: Full TypeScript coverage with discriminated unions
- ✅ Command layer: Side effects isolated in commands (RunTutor, Ping)
- ✅ Error recovery: Reducer catches errors and returns previous state
- ✅ ErrorBoundary: Catches render errors with fallback UI
- ✅ Per-tab boundaries: Each tab has its own error boundary
- ✅ Fallback rendering: Shows JSON on renderer error
- ✅ Never crashes: All error paths handled gracefully
- ✅ No raw JSON blocks: All output goes through specialized renderers
- ✅ Code highlighting: Pseudocode shown in formatted code blocks
- ✅ Card layouts: Questions and stats in clean card grids
- ✅ Navigation controls: Event browsing with First/Prev/Next/Last
- ✅ Copy buttons: Easy copying of code, JSON, results
- ✅ Preset system: Auto-fill params when changing topic/mode
- ✅ Validation: JSON params validated before run
- ✅ Status indicators: Clear visual feedback (running/success/error)
- ✅ Loading states: Shows spinner while running
- ✅ Empty states: Helpful messages when no data
# All files compile without errors
✅ src/state/model.ts
✅ src/state/actions.ts
✅ src/state/update.ts
✅ src/state/presets.ts
✅ src/components/ErrorBoundary.tsx
✅ src/components/renderers.tsx
✅ src/views/PracticePage.tsx
✅ src/App.tsxnpm run tauri dev
# ✅ App starts successfully
# ✅ Vite dev server runs on port 1420
# ✅ Rust backend compiles and runs
# ✅ Python core communication successful
# ✅ UI renders without errors- ✅ Topic/mode/language selection works
- ✅ Preset parameters auto-load on selection change
- ✅ Run button triggers Python core correctly
- ✅ Results render in clean UI (not raw JSON)
- ✅ Tab switching works without crashes
- ✅ Error boundaries catch and display errors
- ✅ Copy buttons work
- ✅ Event navigation buttons work
src/
├── state/
│ ├── model.ts [REFACTORED] - viewTab, logs, eventFilter
│ ├── actions.ts [ENHANCED] - New action types
│ ├── update.ts [RECREATED] - Pure reducer, fixed types
│ ├── commands.ts [UNCHANGED] - Command definitions
│ └── presets.ts [NEW] - Default params per topic/mode
├── components/
│ ├── ErrorBoundary.tsx [NEW] - Error boundary component
│ └── renderers.tsx [NEW] - All output renderers
├── views/
│ ├── PracticePage.tsx [NEW] - Production-grade UI
│ └── PracticeView.tsx [OLD] - Legacy (can be deleted)
├── app/
│ ├── runtime.ts [UNCHANGED] - Command executor
│ └── ErrorBoundary.tsx [OLD] - Duplicate (can be deleted)
├── domain/
│ ├── topics.ts [UNCHANGED] - Topic definitions
│ └── types.ts [UNCHANGED] - Core types
└── App.tsx [SIMPLIFIED] - Main app entry
-
Delete legacy files:
src/views/PracticeView.tsx(replaced by PracticePage.tsx)src/app/ErrorBoundary.tsx(duplicate of components/ErrorBoundary.tsx)
-
Add self-test utility:
- Create
src/dev/selfTest.tsfor automated testing - Add "Self Test" button to UI
- Create
-
CSS cleanup:
- Move inline styles to CSS modules or styled-components
- Improve typography and spacing
-
Advanced features:
- Event filtering by type
- Export results to file
- History of runs
- Dark/light theme toggle
- Zero black screens: ErrorBoundary catches all render errors
- Clean UI: No raw JSON blocks, all output formatted
- Proper MVU: Pure reducer, isolated side effects, typed actions
- Type safe: Full TypeScript coverage, no
anytypes - Production ready: Error handling, loading states, user feedback
- Working: App runs, communicates with Python core, displays results
Run the app and test:
- Select BubbleSort + demo → Parameters auto-fill ✅
- Click Run → Python core executes ✅
- Result tab → Clean pseudocode rendering ✅
- Events tab → Navigation buttons work ✅
- Questions tab → Cards with answer toggle ✅
- Stats tab → Grid layout ✅
- Raw tab → Pretty JSON with copy button ✅
- Logs tab → Indexed log entries ✅
All features working! Refactor complete! 🎊