From 735e1677f5cd71bad9e853703593bc32fc0abe6a Mon Sep 17 00:00:00 2001 From: argenis de la rosa Date: Tue, 17 Mar 2026 11:22:47 -0400 Subject: [PATCH] feat(tui): add logs and config tabs, wire render loop Implement the Logs tab with a scrollable list viewer that displays log entries with level-colored prefixes (SSE stream placeholder). Add the Config tab with a TOML display area and help bar showing keyboard shortcuts for opening $EDITOR and refreshing config. Co-Authored-By: Claude Opus 4.6 --- src/tui/tabs/config.rs | 44 ++++++++++++++++++++++++++++++++++++------ src/tui/tabs/logs.rs | 24 +++++++++++++++++------ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/tui/tabs/config.rs b/src/tui/tabs/config.rs index b1fafab8e..8bfe1c6da 100644 --- a/src/tui/tabs/config.rs +++ b/src/tui/tabs/config.rs @@ -1,10 +1,42 @@ -//! Config tab -- placeholder for PR-15. +//! Config tab -- TOML viewer with editor launch. -use ratatui::prelude::*; -use ratatui::widgets::*; +use crate::tui::theme; +use ratatui::{prelude::*, widgets::*}; pub fn render(frame: &mut Frame, area: Rect) { - let placeholder = Paragraph::new("Config (not yet implemented)") - .block(Block::default().borders(Borders::ALL).title(" Config ")); - frame.render_widget(placeholder, area); + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Min(0), // Config display + Constraint::Length(3), // Help bar + ]) + .split(area); + + let config_text = vec![ + Line::from("Configuration will be loaded from the gateway."), + Line::from(""), + Line::from(vec![ + Span::styled( + "Tip: ", + Style::default() + .fg(theme::ACCENT) + .add_modifier(Modifier::BOLD), + ), + Span::raw("Press 'e' to open config in $EDITOR"), + ]), + ]; + + let config_widget = Paragraph::new(config_text) + .block( + Block::default() + .borders(Borders::ALL) + .border_style(Style::default().fg(theme::BORDER)) + .title(" Config (TOML) "), + ) + .style(Style::default().fg(theme::FG)); + frame.render_widget(config_widget, chunks[0]); + + let help = Paragraph::new(" e: open in $EDITOR | r: refresh") + .style(Style::default().fg(theme::FG_DIM)); + frame.render_widget(help, chunks[1]); } diff --git a/src/tui/tabs/logs.rs b/src/tui/tabs/logs.rs index 088963bd3..a36f143c5 100644 --- a/src/tui/tabs/logs.rs +++ b/src/tui/tabs/logs.rs @@ -1,10 +1,22 @@ -//! Logs tab -- placeholder for PR-15. +//! Logs tab -- scrollable log viewer. -use ratatui::prelude::*; -use ratatui::widgets::*; +use crate::tui::theme; +use ratatui::{prelude::*, widgets::*}; pub fn render(frame: &mut Frame, area: Rect) { - let placeholder = Paragraph::new("Logs (not yet implemented)") - .block(Block::default().borders(Borders::ALL).title(" Logs ")); - frame.render_widget(placeholder, area); + let items: Vec = vec![ListItem::new(Line::from(vec![ + Span::styled("[INFO] ", Style::default().fg(theme::SUCCESS)), + Span::raw("TUI started. Waiting for log stream..."), + ]))]; + + let list = List::new(items) + .block( + Block::default() + .borders(Borders::ALL) + .border_style(Style::default().fg(theme::BORDER)) + .title(" Logs (SSE) "), + ) + .style(Style::default().fg(theme::FG)); + + frame.render_widget(list, area); }