use crate::utils::cli_colors::CliColors;
pub struct Colors;
impl Colors {
pub fn yellow() -> &'static str {
CliColors::yellow()
}
pub fn cyan() -> &'static str {
CliColors::cyan()
}
pub fn green() -> &'static str {
CliColors::green()
}
pub fn white() -> &'static str {
CliColors::text()
}
pub fn gray() -> &'static str {
CliColors::gray()
}
pub fn magenta() -> &'static str {
CliColors::magenta()
}
pub fn red() -> &'static str {
CliColors::red()
}
pub fn reset() -> &'static str {
CliColors::reset()
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum StepStatus {
Active,
Completed,
Pending,
}
pub fn render_steps(steps: &[(String, StepStatus)]) {
let mut parts = Vec::new();
for (i, (step, status)) in steps.iter().enumerate() {
if i > 0 {
parts.push(format!("{} {} ", Colors::gray(), "|"));
}
let (indicator, color) = match status {
StepStatus::Active => ("◆", Colors::yellow()),
StepStatus::Completed => ("◆", Colors::green()),
StepStatus::Pending => ("", Colors::gray()),
};
let text_color = match status {
StepStatus::Active => Colors::green(),
StepStatus::Completed => Colors::green(),
StepStatus::Pending => Colors::white(),
};
if !indicator.is_empty() {
parts.push(format!("{}{}{} ", color, indicator, Colors::reset()));
}
parts.push(format!("{}{}{}", text_color, step, Colors::reset()));
}
print!("{}\r\n", parts.join(""));
}
pub fn render_title(title: &str) {
print!("{}{}{}\r\n", Colors::yellow(), title, Colors::reset());
}
pub fn render_subtitle(subtitle: &str) {
print!("{}{}{}\r\n", Colors::cyan(), subtitle, Colors::reset());
}
pub fn render_success(message: &str) {
print!("{}{}{}\r\n", Colors::green(), message, Colors::reset());
}
pub fn render_option(option: &str, is_selected: bool, _is_recommended: bool) {
let indicator = if is_selected {
format!("{}●{}", Colors::green(), Colors::reset())
} else {
format!("{}○{}", Colors::gray(), Colors::reset())
};
let text_color = if is_selected {
Colors::white()
} else {
Colors::gray()
};
print!(
" {} {}{}{}\r\n",
indicator,
text_color,
option,
Colors::reset()
);
}
pub fn render_config_preview(config: &str) {
print!("\r\n");
print!(
"{}Configuration preview:{}\r\n",
Colors::cyan(),
Colors::reset()
);
print!("{}\r\n", Colors::gray());
for line in config.lines() {
if line.trim().starts_with('[') {
print!("{}{}{}\r\n", Colors::yellow(), line, Colors::reset());
} else if line.contains('=') {
if let Some((key, value)) = line.split_once('=') {
print!(
"{}{}{}={}{}{}\r\n",
Colors::cyan(),
key.trim(),
Colors::reset(),
Colors::gray(),
value.trim(),
Colors::reset()
);
} else {
print!("{}\r\n", line);
}
} else {
print!("{}\r\n", line);
}
}
print!("{}\r\n", Colors::reset());
}
pub fn render_footer_shortcuts() {
let enter = format!("{}{}{}", Colors::green(), "Enter", Colors::gray());
let arrows = format!("{}{}{}", Colors::yellow(), " ↑/↓", Colors::gray());
let type_key = format!("{}{}{}", Colors::cyan(), " Type", Colors::gray());
let esc = format!("{}{}{}", Colors::red(), " Esc", Colors::gray());
let gray = Colors::gray();
print!(
"{}{} confirm {}{} select {}{} search {}{} cancel\r\n",
enter, gray, arrows, gray, type_key, gray, esc, gray
);
}
pub fn render_error(message: &str) {
eprint!("{}{}{}\r\n", Colors::red(), message, Colors::reset());
}
pub fn render_warning(message: &str) {
print!("{}⚠️ {}{}\r\n", Colors::yellow(), message, Colors::reset());
}
pub fn render_info(message: &str) {
print!("{}{}{}\r\n", Colors::magenta(), message, Colors::reset());
}
pub fn render_profile_name(profile_name: &str) {
print!(
"{}Profile{} {}{}\r\n",
Colors::gray(),
Colors::reset(),
profile_name,
Colors::reset()
);
}
pub fn render_default_model(model: &str) {
print!(
"{}Default model: {}{}\r\n",
Colors::gray(),
Colors::white(),
model
);
print!("\r\n");
}
pub fn render_telemetry_disclaimer() {
let border = Colors::cyan();
let r = Colors::reset();
print!("\r\n");
print!(
"{}╭──────────────────────────────────────────────────────────╮{}\r\n",
border, r
);
print!(
"{}│{} {}Anonymous Telemetry{} {}│{}\r\n",
border,
r,
Colors::green(),
r,
border,
r
);
print!(
"{}│{} we collect anonymous telemetry to improve stakpak. {}│{}\r\n",
border, r, border, r
);
print!(
"{}│{} no prompts, code, or personal data is collected. {}│{}\r\n",
border, r, border, r
);
print!(
"{}│{} opt-out: set {}collect_telemetry = false{} in config {}│{}\r\n",
border,
r,
Colors::yellow(),
r,
border,
r
);
print!(
"{}╰──────────────────────────────────────────────────────────╯{}\r\n",
border, r
);
print!("\r\n");
}