1use anyhow::Result;
2use console::{style, Term};
3use dialoguer::theme::ColorfulTheme;
4use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
5use spinners::{Spinner, Spinners};
6use std::{thread, time::Duration};
7use crate::api_client::ApiClient;
8
9const LOGO: &str = r#"
10 __ _ _____ __ __
11 / __ \ ____ ___ ____ (_) / ____// / __ __ __ ___/ /
12 / / / // __ `__ \ / __ \ / / ____ / / / // __ \ / / / // __ /
13/ /_/ // / / / / // / / // / /____/ / /___ / // /_/ // /_/ // /_/ /
14\____//_/ /_/ /_//_/ /_//_/ \____//_/ \____/ \__,_/ \__,_/
15"#;
16
17const GRADIENT_COLORS: [&str; 5] = ["#00c6ff", "#0072ff", "#0057ff", "#0053d4", "#00c6ff"];
19
20pub struct PremiumUI {
21 pub term: Term,
22 pub multi_progress: MultiProgress,
23 pub theme: ColorfulTheme,
24 pub api_client: ApiClient,
25}
26
27impl PremiumUI {
28 pub fn new() -> Self {
29 Self {
30 term: Term::stdout(),
31 multi_progress: MultiProgress::new(),
32 theme: ColorfulTheme::default(),
33 api_client: ApiClient::new(),
34 }
35 }
36
37 pub fn display_welcome(&self) -> Result<()> {
38 self.term.clear_screen()?;
39
40 self.print_gradient_logo();
42
43 self.print_info_box();
45
46 Ok(())
47 }
48
49 fn print_gradient_logo(&self) {
50 let logo_lines: Vec<&str> = LOGO.trim_matches('\n').split('\n').collect();
52
53 for (i, line) in logo_lines.iter().enumerate() {
54 let color_index = i % GRADIENT_COLORS.len();
56 println!("{}", style(line).color256(39 + color_index as u8).bold());
57 }
58 println!();
59 }
60
61 fn print_info_box(&self) {
62 println!("┌{:─^53}┐", "");
63 println!(
64 "│ {}{}│",
65 style("OMNICLOUD CLI").bold().cyan(),
66 " ".repeat(39)
67 );
68 println!(
69 "│ {} {}{}│",
70 style("Version").dim(),
71 style(version::version!()).dim(),
72 " ".repeat(39)
73 );
74 println!("│{}│", " ".repeat(53));
75 println!(
76 "│ {} Type {} to see available commands{}│",
77 style("→").cyan(),
78 style("omni help").green(),
79 " ".repeat(10)
80 );
81 println!(
82 "│ {} Documentation: {}{}│",
83 style("→").cyan(),
84 style("https://docs.omnicloud.sh").cyan(),
85 " ".repeat(10)
86 );
87 println!(
88 "│ {} Support: {}{}│",
89 style("→").cyan(),
90 style("[email protected]").cyan(),
91 " ".repeat(21)
92 );
93 println!("└{:─^53}┘", "");
94 println!();
95 }
96
97 fn print_status_indicators(&self) {
98 }
100
101 fn show_initializing_spinner(&self) -> Result<()> {
102 Ok(())
104 }
105
106 pub fn create_spinner(&self, message: &str) -> Spinner {
107 Spinner::with_timer(Spinners::Dots12, message.into())
108 }
109
110 pub fn create_progress_bar(&self, len: u64, message: &str) -> ProgressBar {
111 let pb = self.multi_progress.add(ProgressBar::new(len));
112 pb.set_style(ProgressStyle::default_bar()
113 .template("{spinner:.green} [{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}")
114 .unwrap()
115 .progress_chars("=>-"));
116 pb.set_message(message.to_string());
117 pb
118 }
119
120 pub fn deploy_with_progress(&self, steps: u64) -> Result<()> {
122 let pb = self.create_progress_bar(steps, "Deploying to cloud");
123
124 for i in 0..steps {
125 pb.inc(1);
126
127 match i {
129 1 => pb.set_message("Initializing containers...".to_string()),
130 3 => pb.set_message("Configuring network...".to_string()),
131 5 => pb.set_message("Launching services...".to_string()),
132 7 => pb.set_message("Almost there...".to_string()),
133 _ => {}
134 }
135
136 thread::sleep(Duration::from_millis(300));
137 }
138
139 pb.finish_with_message("Deployment complete!".to_string());
140 Ok(())
141 }
142}