use ratatui::{ layout::{Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, text::{Line, Span}, widgets::{Block, Borders, List, ListItem, Paragraph}, Frame, }; use crate::state::{AppState, TimeItem}; const ACTIVE_COLOR: Color = Color::Green; const INACTIVE_COLOR: Color = Color::Yellow; pub fn render(frame: &mut Frame, state: &AppState) { let chunks = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Ratio(1, 3), Constraint::Ratio(1, 3), Constraint::Ratio(1, 3), ]) .split(frame.size()); render_section( frame, chunks[0], "Permanent Items", &state.permanent_items, state.current_pane == 0, state.selected_indices[0], state, ); render_section( frame, chunks[1], "Recurring Items", &state.recurring_items, state.current_pane == 1, state.selected_indices[1], state, ); render_section( frame, chunks[2], "Recent Items", &state.recent_items, state.current_pane == 2, state.selected_indices[2], state, ); } fn render_section( frame: &mut Frame, area: Rect, title: &str, items: &[TimeItem], is_active: bool, selected: usize, state: &AppState, ) { let border_color = if is_active { ACTIVE_COLOR } else { INACTIVE_COLOR }; let block = Block::default() .borders(Borders::ALL) .title(title) .style(Style::default().fg(border_color)); let items: Vec = items .iter() .enumerate() .map(|(i, item)| { let is_running = state .active_timer .as_ref() .map(|(active, _)| active.name == item.name) .unwrap_or(false); let style = if is_running { Style::default().fg(ACTIVE_COLOR).add_modifier(Modifier::BOLD) } else if i == selected && is_active { Style::default().fg(border_color).add_modifier(Modifier::REVERSED) } else { Style::default() }; let mut line = item.name.clone(); if !item.tags.is_empty() { line.push_str(" ["); line.push_str(&item.tags.join(", ")); line.push(']'); } ListItem::new(Line::from(vec![Span::styled(line, style)])) }) .collect(); let list = List::new(items).block(block); frame.render_widget(list, area); }