use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::style::Style;
use ratatui::text::{Line, Span};
use ratatui::widgets::{Paragraph, Row, Table};
use ratatui::Frame;
use seer_core::output::sanitize_line;
use crate::tui::action::LensData;
use crate::tui::theme::Theme;
use crate::tui::widgets::{or_dash, panel, row_style, scroll_to};
pub fn render(
f: &mut Frame,
area: Rect,
theme: &Theme,
data: &LensData,
filter: &str,
focused: bool,
sel: usize,
) {
let LensData::History(entries) = data else {
return;
};
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Min(0), Constraint::Length(1)])
.split(area);
let inner = panel::render(f, chunks[0], theme, "Lookup History", theme.teal, focused);
let header = Row::new(["WHEN", "DOMAIN", "SOURCE", "REGISTRAR"])
.style(Style::default().fg(theme.overlay0));
let rows = crate::tui::filter::history_rows(entries, filter)
.enumerate()
.map(|(i, e)| {
let when = e.timestamp.format("%Y-%m-%d %H:%M").to_string();
let source = e.result.protocol().unwrap_or("—");
let registrar = sanitize_line(&or_dash(e.result.registrar()));
Row::new(vec![
when,
sanitize_line(&e.domain),
source.to_string(),
registrar,
])
.style(row_style(theme, focused && i == sel))
});
let table = Table::new(
rows,
[
Constraint::Length(17),
Constraint::Percentage(30),
Constraint::Length(6),
Constraint::Percentage(40),
],
)
.header(header)
.column_spacing(1);
let mut state = scroll_to(focused.then_some(sel));
f.render_stateful_widget(table, inner, &mut state);
f.render_widget(
Paragraph::new(Line::from(Span::styled(
"↵ replay · c clear all (press twice)",
Style::default().fg(theme.overlay0),
))),
chunks[1],
);
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tui::test_util::render_text;
#[test]
fn renders_empty_history_without_panic() {
let theme = Theme::frappe();
let data = LensData::History(vec![]);
let text = render_text(80, 12, |f| render(f, f.area(), &theme, &data, "", false, 0));
assert!(text.contains("History"), "panel title missing: {text:?}");
assert!(text.contains("replay"), "hint line missing: {text:?}");
}
}