Skip to content

Commit f4cb519

Browse files
jrollinclaude
andcommitted
feat: enhance statistics page UI with improved visual design
## Visual Improvements ### Mastery Breakdown - Replace ⬤ with ■ symbol for consistency with heatmap legend - Color icons to match mastery level (Green/Yellow/LightRed/Blue) - Display actual keys under each mastery level (not truncated) - Remove empty lines for tighter, cleaner spacing ### Weaknesses List - Update title to "Weakest Keys (Lower = More Practice)" - Change format from "1." to "#1" for emphasis - Add "← WEAKEST" indicator for #1 entry (most practice needed) - Ensure all top 10 keys are displayed ### Common Mistypes - Increase from 5 to 10 items - Display in 2-column layout for efficient space usage - Remove empty lines for compact presentation ### Keyboard Heatmap Legend - Update labels: "Good" → "Proficient", "Weak" → "Beginner" - Change Beginner color from Red to Blue for better distinction from Learning (LightRed) ### Global Padding & Spacing - Add horizontal and top padding to all blocks for breathing room - Statistics blocks: Padding(1, 1, 1, 0) - left, right, top - Menu lists: Padding(1, 1, 1, 0) for consistent spacing - Lesson content blocks: Padding(2, 2, 1, 0) for enhanced readability - Increase typing area height from 10 to 14 lines (7+7 with padding) - Remove initial empty lines from all stat blocks for cleaner presentation ## Layout Adjustments ### Statistics Page - Overall Performance: 8 lines - Mastery Levels: 20 lines (displays all 4 levels with keys) - Weakest Keys: 8 lines (compact, focused) - Common Mistypes: 10+ lines (2-column layout) ### Lesson Screen - Text blocks increased from Length(5) to Length(7) each - Content area increased from 10 to 14 total lines - Proper spacing between text and borders ## Technical Changes - Update mastery breakdown to collect and display keys per level - Implement 2-column layout for common mistypes using div_ceil - Standardize padding across all UI components - Maintain consistent color scheme throughout 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent e26150b commit f4cb519

File tree

11 files changed

+797
-41
lines changed

11 files changed

+797
-41
lines changed

CLAUDE.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Located in `docs/steering/`:
105105
- Maintains category context after session completion
106106

107107
**Phase 3.4 (Completed):**
108-
- **menu-grouping/** (`src/ui/render.rs`, `src/app.rs`) - Visual lesson grouping within categories ✅ NEW
108+
- **menu-grouping/** (`src/ui/render.rs`, `src/app.rs`) - Visual lesson grouping within categories
109109
- Category-aware lesson grouping with visual separators
110110
- **Languages category**: Grouped by language (French, English) with cyan separators
111111
- **Finger Training category**: Grouped by finger pair (Pinky, Ring, Middle, Index) with green separators
@@ -115,6 +115,17 @@ Located in `docs/steering/`:
115115
- Lesson ordering optimized for logical grouping
116116
- Improves navigation and lesson discovery within large categories
117117

118+
**Phase 3.5 (Completed):**
119+
- **statistics-page/** (`src/ui/render.rs`, `src/app.rs`) - Comprehensive performance dashboard ✅ NEW
120+
- Overall session statistics (sessions, keystrokes, WPM, accuracy)
121+
- Mastery level breakdown (counts per classification: Mastered, Proficient, Learning, Beginner)
122+
- Top 10 weaknesses list (< 80% accuracy with error details)
123+
- Common mistype patterns (top 5 error patterns showing which keys are confused)
124+
- Visual keyboard heatmap with accuracy-based color coding
125+
- Accessible from main menu with 's' key
126+
- Graceful placeholder when no analytics data exists
127+
- Two-column layout optimized for terminal display (40% stats / 60% heatmap)
128+
118129
**Complete documentation index**: See `docs/README.md` for navigation guide and feature details.
119130

120131
### User Documentation

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,28 @@ Typer CLI is a terminal-based keyboard typing training tool. It provides an inte
5757
-**Smart ESC Navigation**: Lessons → Categories → Quit
5858
-**Context Preservation**: Returns to same category after completing session
5959

60-
### Menu Grouping (Phase 3.4) ✅ NEW
60+
### Menu Grouping (Phase 3.4) ✅
6161
-**Visual Separators**: Lessons organized with colored dividers within categories
6262
-**Language Grouping**: Languages category groups French and English lessons separately
6363
-**Finger Grouping**: Finger Training groups by finger pair (Pinky, Ring, Middle, Index)
6464
-**Code Grouping**: Code category groups Code Patterns, TypeScript, Rust, and Python
6565
-**Color-Coded**: Separators match category colors for visual consistency
6666
-**Improved Navigation**: Easier to find and browse lessons within large categories
6767

68+
### Statistics Dashboard (Phase 3.5) ✅
69+
-**Overall Metrics**: View total sessions, keystrokes, average WPM, and accuracy
70+
-**Visual Keyboard Heatmap**: See per-key accuracy with color-coded visualization
71+
- Green: Mastered (90%+ accuracy)
72+
- Yellow: Proficient (80-90% accuracy)
73+
- Light Red: Learning (70-80% accuracy)
74+
- Blue: Beginner (<70% accuracy)
75+
- Heatmap always shown (optimized for analytics view)
76+
-**Mastery Breakdown**: Colored icons (■) showing keys in each mastery level
77+
-**Weakness Identification**: Top 10 weakest keys with error counts (#1 = most practice needed)
78+
-**Error Patterns**: Top 10 common mistypes in 2-column layout
79+
-**Polished UI**: Enhanced padding and spacing for better readability
80+
-**Access**: Press `s` key from the main menu (after completing your first session)
81+
6882
**Total Lessons**: 77 (52 standard + 24 finger training + 1 adaptive)
6983

7084
## Installation

docs/README.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,23 @@ Hierarchical navigation system for improved lesson discovery.
184184
- ESC navigation: Lessons → Categories → Quit
185185
- Context preservation after session completion
186186

187+
#### [statistics-page/](features/statistics-page/) ✅ COMPLETED
188+
Performance analytics dashboard with visual keyboard heatmap.
189+
190+
**Module**: `src/ui/render.rs`, `src/app.rs`
191+
192+
- Overall session statistics (sessions, keystrokes, WPM, accuracy)
193+
- Mastery level breakdown (Mastered, Proficient, Learning, Beginner counts)
194+
- Top 10 weaknesses list (< 80% accuracy with error details)
195+
- Common mistype patterns (top 5 error patterns)
196+
- Visual keyboard heatmap with accuracy-based color coding
197+
- Two-column layout (40% stats / 60% heatmap)
198+
- Accessible via 's' key from main menu
199+
- Graceful placeholder when no analytics data exists
200+
187201
### Future Features (Phase 3+)
188202

189-
- **Analytics visualization** - Heat maps, trend graphs, progress charts
203+
- **Enhanced analytics** - Trend graphs, progress charts over time, session history visualization
190204
- **Enhanced adaptive UI** - Pre/post-session feedback, progress indicators
191205
- **Data export** - JSON/CSV export for external analysis
192206
- **Themes** - Multiple color schemes, high contrast options
@@ -257,16 +271,16 @@ Module locations are documented in each feature's design.md:
257271

258272
## Project Status
259273

260-
**Current Phase**: Phase 3.3 Complete (Two-Level Menu System) ✓
274+
**Current Phase**: Phase 3.5 Complete (Statistics Dashboard) ✓
261275

262276
**Total Tests**: 129 passing
263277
- 13 tests: typing-session
264278
- 7 tests: home-row-lessons
265279
- 12 tests: bigram-training
266280
- 12 tests: code-symbols
267-
- 9 tests: analytics (NEW)
268-
- 9 tests: adaptive algorithms (NEW)
269-
- 6 tests: adaptive generator (NEW)
281+
- 9 tests: analytics
282+
- 9 tests: adaptive algorithms
283+
- 6 tests: adaptive generator
270284
- 7 tests: session-storage
271285
- 2 tests: keyboard-layout
272286
- 3 tests: content generation
@@ -284,10 +298,12 @@ Module locations are documented in each feature's design.md:
284298
- Phase 3.1: Layout improvements ✓
285299
- Phase 3.2: Finger training ✓
286300
- Phase 3.3: Two-level menu system ✓
301+
- Phase 3.4: Menu grouping ✓
302+
- Phase 3.5: Statistics dashboard ✓
287303

288304
**Total Lessons**: 77 (52 standard + 24 finger training + 1 adaptive)
289305

290-
**Next Phase**: Analytics visualization and data export (Phase 3+)
306+
**Next Phase**: Enhanced analytics (trend graphs, data export) and gamification (Phase 3+)
291307

292308
## Additional Resources
293309

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Statistics Page - Design
2+
3+
## Architecture
4+
5+
### State Machine
6+
- Add `Statistics` variant to `AppState` enum
7+
- Navigation: LessonTypeMenu ↔ Statistics
8+
- Render statistics via `ui::render_statistics()`
9+
10+
### Layout Structure
11+
Two-column layout (40% / 60%):
12+
- Left: Overall stats, Mastery breakdown, Weaknesses, Mistypes
13+
- Right: Keyboard heatmap visualization
14+
15+
### Data Flow
16+
```
17+
Stats (loaded from disk)
18+
├─→ adaptive_analytics: Option<AdaptiveAnalytics>
19+
├─→ key_stats: HashMap<char, KeyStats>
20+
├─→ total_sessions, total_keystrokes
21+
└─→ session_history
22+
└─→ sessions: Vec<SessionRecord>
23+
```
24+
25+
### Component Breakdown
26+
1. `render_statistics()` - Main orchestrator
27+
2. `render_overall_stats_block()` - Session summary
28+
3. `render_mastery_breakdown()` - Key classification counts
29+
4. `render_weaknesses_list()` - Top 10 weak keys
30+
5. `render_common_mistypes()` - Error pattern analysis
31+
6. `render_keyboard_with_heatmap()` - Keyboard visualization with heatmap always enabled
32+
33+
### Statistics-Specific Behavior
34+
- Heatmap is **always enabled** in statistics context (cannot be toggled off)
35+
- Finger color hints are **disabled** (heatmap takes priority)
36+
- Footer keyboard shortcuts are **hidden** (not needed, we have our own instructions)
37+
- This creates a cleaner, more focused analytics view
38+
39+
### Color Scheme
40+
- Headers: Cyan + Bold
41+
- Metric values: Yellow
42+
- Mastery levels: Green/Yellow/LightRed/Red
43+
- Instructions: Gray
44+
45+
### Edge Cases
46+
- No analytics data → Show placeholder
47+
- No weak keys → Congratulatory message
48+
- No mistypes → Perfect accuracy message
49+
- Terminal < 25 lines → Compact layout
50+
51+
## Technical Decisions
52+
53+
### Why Two-Column Layout?
54+
- Efficient use of horizontal space
55+
- All info visible at once (no scrolling)
56+
- Keyboard is central visual feature
57+
58+
### Why Show 's' Option Always?
59+
- Simplifies menu logic
60+
- Statistics page handles no-data case internally
61+
- Encourages users to complete sessions
62+
63+
### Why Filter < 5 Attempts?
64+
- Prevents noise from newly introduced keys
65+
- Ensures statistically meaningful weakness identification
66+
67+
## Dependencies
68+
- Existing: `src/ui/keyboard.rs` (render_keyboard)
69+
- Existing: `src/data/stats.rs` (all analytics methods)
70+
- Existing: `src/engine/analytics.rs` (KeyStats, MasteryLevel)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Statistics Page - Requirements
2+
3+
## Purpose
4+
Provide users with comprehensive performance analytics to track progress and identify areas for improvement.
5+
6+
## User Stories
7+
8+
### US-1: Access Statistics
9+
WHEN a user presses 's' from the category menu
10+
THE SYSTEM SHALL display the statistics visualization page
11+
12+
### US-2: View Overall Performance
13+
WHEN a user views the statistics page
14+
THE SYSTEM SHALL display overall session metrics including:
15+
- Total sessions completed
16+
- Total keystrokes typed
17+
- Average WPM across all sessions
18+
- Average accuracy across all sessions
19+
20+
### US-3: View Mastery Breakdown
21+
WHEN a user views the statistics page
22+
THE SYSTEM SHALL display a count of keys in each mastery level:
23+
- Mastered (>95% accuracy)
24+
- Proficient (85-95% accuracy)
25+
- Learning (70-85% accuracy)
26+
- Beginner (<70% accuracy)
27+
28+
### US-4: Identify Weaknesses
29+
WHEN a user views the statistics page
30+
THE SYSTEM SHALL display the top 10 keys with accuracy below 80%
31+
AND sort them by accuracy (lowest first)
32+
AND exclude keys with fewer than 5 attempts
33+
34+
### US-5: View Common Errors
35+
WHEN a user views the statistics page
36+
THE SYSTEM SHALL display the top 5 most common mistype patterns
37+
AND show which key was expected and which was typed instead
38+
39+
### US-6: Visual Keyboard Heatmap
40+
WHEN a user views the statistics page
41+
THE SYSTEM SHALL display a visual AZERTY keyboard with heatmap coloring
42+
AND color each key based on its accuracy:
43+
- Green: 90%+ (Mastered)
44+
- Yellow: 80-90% (Good)
45+
- LightRed: 70-80% (Learning)
46+
- Red: <70% (Weak)
47+
48+
### US-7: No Data Handling
49+
WHEN a user accesses statistics with no session data
50+
THE SYSTEM SHALL display a placeholder message encouraging first session completion
51+
52+
### US-8: Navigation
53+
WHEN a user presses ESC or 'q' on the statistics page
54+
THE SYSTEM SHALL return to the category menu
55+
56+
## Acceptance Criteria
57+
- Statistics accessible via 's' key from main menu
58+
- Layout responsive to terminal size (minimum 80x24)
59+
- Colors consistent with application theme
60+
- All metrics calculated accurately from stored analytics
61+
- Placeholder shown gracefully when no data exists
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Statistics Page - Implementation Tasks
2+
3+
## Phase 1: Core Implementation
4+
5+
### State Machine Changes (src/app.rs)
6+
- [x] Add `Statistics` variant to AppState enum (line 24)
7+
- [x] Add render call in main loop (~line 295)
8+
- [x] Add 's' key handler in LessonTypeMenu state (~line 375)
9+
- [x] Add ESC/q handler for Statistics state (~line 510)
10+
11+
### UI Rendering (src/ui/render.rs)
12+
- [x] Create `render_statistics()` main function (~line 923)
13+
- [x] Implement 3-section layout (Header | Content | Instructions)
14+
- [x] Implement 2-column content split (40% / 60%)
15+
- [x] Create `render_overall_stats_block()` helper
16+
- [x] Create `render_mastery_breakdown()` helper
17+
- [x] Create `render_weaknesses_list()` helper
18+
- [x] Create `render_common_mistypes()` helper
19+
- [x] Integrate keyboard heatmap rendering
20+
- [x] Add placeholder for no data scenario
21+
- [x] Update category menu instructions (line 843)
22+
23+
## Phase 2: Testing
24+
- [x] Test with no data (fresh install)
25+
- [x] Test with analytics data (10+ sessions)
26+
- [x] Test perfect performance (no weaknesses)
27+
- [x] Test navigation flow (menu → stats → menu)
28+
- [x] Test terminal resize (80x24, 100x30, 120x40)
29+
- [x] Verify color accuracy matches mastery levels
30+
- [x] Cross-check displayed stats with JSON file
31+
32+
## Phase 3: Documentation
33+
- [x] Update CLAUDE.md with Phase 3.5 section
34+
- [x] Update README.md with Statistics Dashboard feature
35+
- [x] Create feature documentation (requirements.md, design.md, tasks.md)
36+
- [x] Update docs/README.md index if needed
37+
38+
## Phase 4: Polish
39+
- [x] Verify consistent color scheme
40+
- [x] Test edge cases (no weaknesses, no mistypes)
41+
- [x] Ensure proper error handling
42+
- [x] Code review for consistency with app patterns

src/app.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::ui::keyboard::KeyboardConfig;
1717
#[derive(Debug, PartialEq)]
1818
enum AppState {
1919
LessonTypeMenu,
20+
Statistics,
2021
LessonMenu,
2122
DurationMenu,
2223
Running,
@@ -241,6 +242,14 @@ impl App {
241242
AppState::LessonTypeMenu => {
242243
ui::render_lesson_type_menu(f, &self.categories, self.selected_category);
243244
}
245+
AppState::Statistics => {
246+
ui::render_statistics(
247+
f,
248+
&self.stats,
249+
&self.keyboard_layout,
250+
&self.keyboard_config,
251+
);
252+
}
244253
AppState::LessonMenu => {
245254
let filtered_lessons: Vec<_> =
246255
self.filtered_lessons().into_iter().cloned().collect();
@@ -343,6 +352,9 @@ impl App {
343352
KeyCode::Esc | KeyCode::Char('q') => {
344353
self.state = AppState::Quit;
345354
}
355+
KeyCode::Char('s') | KeyCode::Char('S') => {
356+
self.state = AppState::Statistics;
357+
}
346358
KeyCode::Up | KeyCode::Char('k') => {
347359
if self.selected_category > 0 {
348360
self.selected_category -= 1;
@@ -504,6 +516,12 @@ impl App {
504516
_ => {}
505517
}
506518
}
519+
AppState::Statistics => match key.code {
520+
KeyCode::Esc | KeyCode::Char('q') => {
521+
self.state = AppState::LessonTypeMenu;
522+
}
523+
_ => {}
524+
},
507525
AppState::Quit => {}
508526
}
509527

src/engine/analytics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::types::CharInput;
99
use super::types::TypingSession;
1010

1111
/// Mastery level classification for keys and bigrams
12-
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
12+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
1313
pub enum MasteryLevel {
1414
Beginner, // < 70% accuracy or < 5 attempts
1515
Learning, // 70-85% accuracy

0 commit comments

Comments
 (0)