use ratatui::prelude::*;
use crate::tui::app::App;
use crate::tui::widgets::card::{self, Card};
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
let wizard = match app.wizard.as_ref() {
Some(w) => w,
None => return,
};
let mut body: Vec<Line> = Vec::new();
match wizard.device_code.as_ref() {
Some(session) => {
body.push(
Line::from(Span::styled(
"ONE-TIME CODE",
Style::default().fg(Color::DarkGray),
))
.alignment(Alignment::Center),
);
body.push(Line::from(""));
let pretty = pretty_code(&session.response.user_code);
body.push(
Line::from(Span::styled(
pretty,
Style::default()
.fg(Color::Rgb(150, 130, 255))
.add_modifier(Modifier::BOLD),
))
.alignment(Alignment::Center),
);
body.push(Line::from(""));
body.push(
Line::from(Span::styled("Visit", Style::default().fg(Color::Gray)))
.alignment(Alignment::Center),
);
body.push(
Line::from(Span::styled(
session.response.verification_uri_complete.clone(),
Style::default()
.fg(Color::Rgb(110, 180, 255))
.add_modifier(Modifier::UNDERLINED),
))
.alignment(Alignment::Center),
);
body.push(Line::from(""));
let elapsed = session.started_at.elapsed().as_secs();
let remaining = session.response.expires_in.saturating_sub(elapsed);
let mm = remaining / 60;
let ss = remaining % 60;
body.push(Line::from(vec![
Span::styled(
"Waiting for browser confirmation… ",
Style::default().fg(Color::Gray),
),
Span::styled("expires in ", Style::default().fg(Color::DarkGray)),
Span::styled(
format!("{:02}:{:02}", mm, ss),
Style::default()
.fg(Color::Gray)
.add_modifier(Modifier::BOLD),
),
]));
}
None => {
body.push(Line::from(Span::styled(
"Requesting one-time code from Auth0…",
Style::default().fg(Color::Gray),
)));
}
}
let footer = Line::from(vec![
Span::styled(
"Browser didn't open? Press ",
Style::default().fg(Color::DarkGray),
),
Span::styled(
" o ",
Style::default()
.fg(Color::White)
.bg(Color::DarkGray)
.add_modifier(Modifier::BOLD),
),
Span::styled(
" to retry or copy the URL above.",
Style::default().fg(Color::DarkGray),
),
]);
card::render(
frame,
area,
&Card {
eyebrow: Some("SIGN IN · STEP 3 OF 3"),
title: Some("Confirm the code in your browser."),
body,
footer: Some(footer),
error: wizard.error.as_deref(),
step: Some("3 / 3"),
max_width: 78,
},
);
}
fn pretty_code(code: &str) -> String {
code.to_uppercase()
.chars()
.collect::<Vec<_>>()
.chunks(1)
.map(|c| c.iter().collect::<String>())
.collect::<Vec<_>>()
.join(" ")
}