use ratatui::{ layout::{Alignment, Constraint, Direction, Layout}, style::{Color, Modifier, Style}, text::Line, widgets::{Block, Borders, Paragraph}, Frame, }; use crate::app::App; use crate::tdlib::client::AuthState; pub fn render(f: &mut Frame, app: &App) { let area = f.area(); let vertical_chunks = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Percentage(30), Constraint::Length(15), Constraint::Percentage(30), ]) .split(area); let horizontal_chunks = Layout::default() .direction(Direction::Horizontal) .constraints([ Constraint::Percentage(25), Constraint::Percentage(50), Constraint::Percentage(25), ]) .split(vertical_chunks[1]); let auth_area = horizontal_chunks[1]; let auth_chunks = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Length(3), // Title Constraint::Length(4), // Instructions Constraint::Length(3), // Input Constraint::Length(2), // Error/Status message Constraint::Min(0), // Spacer ]) .split(auth_area); // Title let title = Paragraph::new("TTUI - Telegram Authentication") .style( Style::default() .fg(Color::Cyan) .add_modifier(Modifier::BOLD), ) .alignment(Alignment::Center) .block(Block::default().borders(Borders::ALL)); f.render_widget(title, auth_chunks[0]); // Instructions and Input based on auth state match &app.td_client.auth_state { AuthState::WaitPhoneNumber => { let instructions = vec![ Line::from("Введите номер телефона в международном формате"), Line::from("Пример: +79991111111"), ]; let instructions_widget = Paragraph::new(instructions) .style(Style::default().fg(Color::Gray)) .alignment(Alignment::Center) .block(Block::default().borders(Borders::NONE)); f.render_widget(instructions_widget, auth_chunks[1]); let input_text = format!("📱 {}", app.phone_input); let input = Paragraph::new(input_text) .style(Style::default().fg(Color::Yellow)) .alignment(Alignment::Center) .block( Block::default() .borders(Borders::ALL) .title(" Phone Number "), ); f.render_widget(input, auth_chunks[2]); } AuthState::WaitCode => { let instructions = vec![ Line::from("Введите код подтверждения из Telegram"), Line::from("Код был отправлен на ваш номер"), ]; let instructions_widget = Paragraph::new(instructions) .style(Style::default().fg(Color::Gray)) .alignment(Alignment::Center) .block(Block::default().borders(Borders::NONE)); f.render_widget(instructions_widget, auth_chunks[1]); let input_text = format!("🔐 {}", app.code_input); let input = Paragraph::new(input_text) .style(Style::default().fg(Color::Yellow)) .alignment(Alignment::Center) .block( Block::default() .borders(Borders::ALL) .title(" Verification Code "), ); f.render_widget(input, auth_chunks[2]); } AuthState::WaitPassword => { let instructions = vec![ Line::from("Введите пароль двухфакторной аутентификации"), Line::from(""), ]; let instructions_widget = Paragraph::new(instructions) .style(Style::default().fg(Color::Gray)) .alignment(Alignment::Center) .block(Block::default().borders(Borders::NONE)); f.render_widget(instructions_widget, auth_chunks[1]); let masked_password = "*".repeat(app.password_input.len()); let input_text = format!("🔒 {}", masked_password); let input = Paragraph::new(input_text) .style(Style::default().fg(Color::Yellow)) .alignment(Alignment::Center) .block(Block::default().borders(Borders::ALL).title(" Password ")); f.render_widget(input, auth_chunks[2]); } _ => {} } // Error or status message if let Some(error) = &app.error_message { let error_widget = Paragraph::new(error.as_str()) .style(Style::default().fg(Color::Red)) .alignment(Alignment::Center); f.render_widget(error_widget, auth_chunks[3]); } else if let Some(status) = &app.status_message { let status_widget = Paragraph::new(status.as_str()) .style(Style::default().fg(Color::Yellow)) .alignment(Alignment::Center); f.render_widget(status_widget, auth_chunks[3]); } }