use ratatui::{ layout::{Alignment, Constraint, Direction, Layout}, style::{Color, Modifier, Style}, text::{Line, Span}, widgets::{Block, Borders, Paragraph}, Frame, }; use crate::tui::app::{App, LoginField}; pub fn draw(frame: &mut Frame, app: &App) { let area = frame.size(); // Centre a 50×12 box on screen. let v = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Percentage(30), Constraint::Length(14), Constraint::Min(0), ]) .split(area); let h = Layout::default() .direction(Direction::Horizontal) .constraints([ Constraint::Percentage(25), Constraint::Percentage(50), Constraint::Percentage(25), ]) .split(v[1]); let box_area = h[1]; let mode_label = if app.login_register { "Register" } else { "Login" }; let outer = Block::default() .title(format!(" BackChannel — {} ", mode_label)) .borders(Borders::ALL) .style(Style::default().fg(Color::Cyan)); frame.render_widget(outer, box_area); let inner = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Length(1), // padding Constraint::Length(3), // username Constraint::Length(3), // password Constraint::Length(1), // padding Constraint::Length(1), // hint Constraint::Length(1), // status ]) .margin(1) .split(box_area); // Username field let username_style = if app.login_field == LoginField::Username { Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD) } else { Style::default() }; let username_widget = Paragraph::new(app.login_username.as_str()) .block(Block::default().borders(Borders::ALL).title(" Username ")) .style(username_style); frame.render_widget(username_widget, inner[1]); // Password field (mask with asterisks) let password_style = if app.login_field == LoginField::Password { Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD) } else { Style::default() }; let masked: String = "*".repeat(app.login_password.len()); let password_widget = Paragraph::new(masked.as_str()) .block(Block::default().borders(Borders::ALL).title(" Password ")) .style(password_style); frame.render_widget(password_widget, inner[2]); // Hints let hint = Paragraph::new(Line::from(vec![ Span::raw("Tab: switch field | Enter: submit | "), Span::styled( if app.login_register { "T: switch to Login" } else { "T: switch to Register" }, Style::default().fg(Color::DarkGray), ), ])) .alignment(Alignment::Center); frame.render_widget(hint, inner[4]); // Status / error message if let Some(msg) = &app.status_msg { let status = Paragraph::new(msg.as_str()) .style(Style::default().fg(Color::Red)) .alignment(Alignment::Center); frame.render_widget(status, inner[5]); } }