diff --git a/client/src/components/intro/intro.rs b/client/src/components/intro/intro.rs index f28d850..77f63f1 100644 --- a/client/src/components/intro/intro.rs +++ b/client/src/components/intro/intro.rs @@ -8,103 +8,80 @@ use ratatui::{ Frame, }; use crate::config::colors::themes::Theme; +use crate::state::pages::intro::IntroState; -pub struct IntroState { - pub selected_option: usize, +pub fn render_intro(f: &mut Frame, intro_state: &IntroState, area: Rect, theme: &Theme) { + let block = Block::default() + .borders(Borders::ALL) + .border_type(BorderType::Rounded) + .border_style(Style::default().fg(theme.accent)) + .style(Style::default().bg(theme.bg)); + + let inner_area = block.inner(area); + f.render_widget(block, area); + + // Center layout + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage(40), + Constraint::Length(5), + Constraint::Percentage(40), + ]) + .split(inner_area); + + // Title + let title = Line::from(vec![ + Span::styled("multieko2", Style::default().fg(theme.highlight)), + Span::styled(" v", Style::default().fg(theme.fg)), + Span::styled(env!("CARGO_PKG_VERSION"), Style::default().fg(theme.secondary)), + ]); + let title_para = Paragraph::new(title) + .alignment(Alignment::Center); + f.render_widget(title_para, chunks[1]); + + // Buttons - now with 4 options + let button_area = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(25), + Constraint::Percentage(25), + Constraint::Percentage(25), + Constraint::Percentage(25), + ]) + .split(chunks[1].inner(Margin { + horizontal: 1, + vertical: 1 + })); + + let buttons = ["Continue", "Admin", "Login", "Register"]; + for (i, &text) in buttons.iter().enumerate() { + render_button(f, button_area[i], text, intro_state.selected_option == i, theme); + } } -impl IntroState { - pub fn new() -> Self { - Self { selected_option: 0 } - } +fn render_button(f: &mut Frame, area: Rect, text: &str, selected: bool, theme: &Theme) { + let button_style = Style::default() + .fg(if selected { theme.highlight } else { theme.fg }) + .bg(theme.bg) + .add_modifier(if selected { + ratatui::style::Modifier::BOLD + } else { + ratatui::style::Modifier::empty() + }); - pub fn render(&self, f: &mut Frame, area: Rect, theme: &Theme) { - let block = Block::default() + let border_style = Style::default() + .fg(if selected { theme.accent } else { theme.border }); + + let button = Paragraph::new(text) + .style(button_style) + .alignment(Alignment::Center) + .block( + Block::default() .borders(Borders::ALL) - .border_type(BorderType::Rounded) - .border_style(Style::default().fg(theme.accent)) - .style(Style::default().bg(theme.bg)); + .border_type(BorderType::Double) + .border_style(border_style), + ); - let inner_area = block.inner(area); - f.render_widget(block, area); - - // Center layout - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([ - Constraint::Percentage(40), - Constraint::Length(5), - Constraint::Percentage(40), - ]) - .split(inner_area); - - // Title - let title = Line::from(vec![ - Span::styled("multieko2", Style::default().fg(theme.highlight)), - Span::styled(" v", Style::default().fg(theme.fg)), - Span::styled(env!("CARGO_PKG_VERSION"), Style::default().fg(theme.secondary)), - ]); - let title_para = Paragraph::new(title) - .alignment(Alignment::Center); - f.render_widget(title_para, chunks[1]); - - // Buttons - now with 4 options - let button_area = Layout::default() - .direction(Direction::Horizontal) - .constraints([ - Constraint::Percentage(25), - Constraint::Percentage(25), - Constraint::Percentage(25), - Constraint::Percentage(25), - ]) - .split(chunks[1].inner(Margin { - horizontal: 1, - vertical: 1 - })); - - let buttons = ["Continue", "Admin", "Login", "Register"]; - for (i, &text) in buttons.iter().enumerate() { - self.render_button( - f, - button_area[i], - text, - self.selected_option == i, - theme, - ); - } - } - - fn render_button(&self, f: &mut Frame, area: Rect, text: &str, selected: bool, theme: &Theme) { - let button_style = Style::default() - .fg(if selected { theme.highlight } else { theme.fg }) - .bg(theme.bg) - .add_modifier(if selected { - ratatui::style::Modifier::BOLD - } else { - ratatui::style::Modifier::empty() - }); - - let border_style = Style::default() - .fg(if selected { theme.accent } else { theme.border }); - - let button = Paragraph::new(text) - .style(button_style) - .alignment(Alignment::Center) - .block( - Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Double) - .border_style(border_style), - ); - - f.render_widget(button, area); - } - - pub fn next_option(&mut self) { - self.selected_option = (self.selected_option + 1) % 4; - } - - pub fn previous_option(&mut self) { - self.selected_option = if self.selected_option == 0 { 3 } else { self.selected_option - 1 }; - } + f.render_widget(button, area); } diff --git a/client/src/state/app/state.rs b/client/src/state/app/state.rs index c2ae1fb..f1f4ecb 100644 --- a/client/src/state/app/state.rs +++ b/client/src/state/app/state.rs @@ -2,7 +2,7 @@ use std::env; use common::proto::multieko2::table_definition::ProfileTreeResponse; -use crate::components::IntroState; +use crate::state::pages::intro::IntroState; use crate::modes::handlers::mode_manager::AppMode; use crate::ui::handlers::context::DialogPurpose; diff --git a/client/src/state/pages.rs b/client/src/state/pages.rs index 9ac984b..1e02fd9 100644 --- a/client/src/state/pages.rs +++ b/client/src/state/pages.rs @@ -3,4 +3,5 @@ pub mod form; pub mod auth; pub mod admin; +pub mod intro; pub mod canvas_state; diff --git a/client/src/state/pages/intro.rs b/client/src/state/pages/intro.rs new file mode 100644 index 0000000..d71464c --- /dev/null +++ b/client/src/state/pages/intro.rs @@ -0,0 +1,26 @@ +// src/state/pages/intro.rs +use ratatui::style::Modifier; + +#[derive(Default, Clone, Debug)] +pub struct IntroState { + pub selected_option: usize, +} + +impl IntroState { + pub fn new() -> Self { + Self::default() + } + + pub fn next_option(&mut self) { + self.selected_option = (self.selected_option + 1) % 4; + } + + pub fn previous_option(&mut self) { + self.selected_option = if self.selected_option == 0 { + 3 + } else { + self.selected_option - 1 + }; + } +} + diff --git a/client/src/ui/handlers/render.rs b/client/src/ui/handlers/render.rs index 91c455b..0b9cff7 100644 --- a/client/src/ui/handlers/render.rs +++ b/client/src/ui/handlers/render.rs @@ -4,6 +4,7 @@ use crate::components::{ render_background, render_command_line, render_status_line, + intro::intro::render_intro, handlers::sidebar::{self, calculate_sidebar_layout}, form::form::render_form, auth::{login::render_login, register::render_register}, @@ -48,7 +49,7 @@ pub fn render_ui( let main_content_area = root[0]; if app_state.ui.show_intro { - app_state.ui.intro_state.render(f, main_content_area, theme); + render_intro(f, &app_state.ui.intro_state, main_content_area, theme); } else if app_state.ui.show_register { render_register( f,