Skip to main content

cli_tutor/ui/
command_list.rs

1use crate::app::App;
2use ratatui::{
3    layout::Rect,
4    style::{Color, Modifier, Style},
5    text::{Line, Span},
6    widgets::{Block, Borders, List, ListItem, ListState},
7    Frame,
8};
9
10// content_display.ENG.2 — each view in its own file under src/ui/
11pub fn render(app: &App, frame: &mut Frame, area: Rect) {
12    let items: Vec<ListItem> = app
13        .modules
14        .iter()
15        .enumerate()
16        .map(|(i, m)| {
17            let ex_count = m.exercises.len();
18            let completed = app
19                .progress
20                .modules
21                .get(&m.module.name)
22                .map(|p| p.completed.len())
23                .unwrap_or(0);
24
25            let badge = if completed == ex_count && ex_count > 0 {
26                " ✓"
27            } else {
28                ""
29            };
30
31            let line = Line::from(vec![
32                Span::styled(
33                    format!("{:<10}", m.module.name),
34                    if i == app.selected_module {
35                        Style::default().add_modifier(Modifier::BOLD)
36                    } else {
37                        Style::default()
38                    },
39                ),
40                Span::styled(
41                    format!("[{:>2}]", ex_count),
42                    Style::default().fg(Color::DarkGray),
43                ),
44                Span::styled(badge, Style::default().fg(Color::Green)),
45            ]);
46            ListItem::new(line)
47        })
48        .collect();
49
50    let mut state = ListState::default();
51    state.select(Some(app.selected_module));
52
53    let list = List::new(items)
54        .block(Block::default().borders(Borders::RIGHT).title("Modules"))
55        // content_display.STYLING.3 — reversed highlight for selected module
56        .highlight_style(Style::default().bg(Color::White).fg(Color::Black));
57
58    frame.render_stateful_widget(list, area, &mut state);
59}