From 45fff34c4c72ca0e5d511bb4f343aa99e18d9cf1 Mon Sep 17 00:00:00 2001 From: filipriec Date: Tue, 25 Mar 2025 16:02:23 +0100 Subject: [PATCH] login page being implemented slowly --- client/src/components/auth/login.rs | 111 +++++++++++++++++++++++++++ client/src/components/intro/intro.rs | 34 +++++--- client/src/state/state.rs | 2 + 3 files changed, 138 insertions(+), 9 deletions(-) diff --git a/client/src/components/auth/login.rs b/client/src/components/auth/login.rs index e69de29..eae711a 100644 --- a/client/src/components/auth/login.rs +++ b/client/src/components/auth/login.rs @@ -0,0 +1,111 @@ +// src/components/login/login.rs +use ratatui::{ + widgets::{Block, BorderType, Borders, List, ListItem, ListState, Paragraph}, + style::Style, + text::{Line, Span, Text}, + layout::{Alignment, Constraint, Direction, Layout, Rect}, + Frame, +}; +use crate::config::colors::themes::Theme; + +pub struct LoginState { + pub fields: Vec, + pub values: Vec, + pub selected_field: usize, +} + +impl LoginState { + pub fn new() -> Self { + Self { + fields: vec!["Username".to_string(), "Password".to_string()], + values: vec![String::new(), String::new()], + selected_field: 0, + } + } + + pub fn next_field(&mut self) { + self.selected_field = (self.selected_field + 1) % self.fields.len(); + } + + pub fn previous_field(&mut self) { + self.selected_field = if self.selected_field == 0 { + self.fields.len() - 1 + } else { + self.selected_field - 1 + }; + } + + pub fn render(&mut self, f: &mut Frame, 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); + + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(3), + Constraint::Length(5), + Constraint::Min(1), + ]) + .split(inner_area); + + // Title + let title = Line::from(Span::styled("Login", Style::default().fg(theme.highlight))); + let title_widget = Paragraph::new(title).alignment(Alignment::Center); + f.render_widget(title_widget, chunks[0]); + + // Login form + let form_chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + ]) + .split(chunks[1]); + + // Username field + let username_block = Block::default() + .title("Username") + .borders(Borders::ALL) + .border_style(if self.selected_field == 0 { + Style::default().fg(theme.highlight) + } else { + Style::default().fg(theme.border) + }); + let username = Paragraph::new(self.values[0].as_str()) + .block(username_block); + f.render_widget(username, form_chunks[0]); + + // Password field + let password_block = Block::default() + .title("Password") + .borders(Borders::ALL) + .border_style(if self.selected_field == 1 { + Style::default().fg(theme.highlight) + } else { + Style::default().fg(theme.border) + }); + let password = Paragraph::new("*".repeat(self.values[1].len())) + .block(password_block); + f.render_widget(password, form_chunks[1]); + + // Submit button + let submit_block = Block::default() + .borders(Borders::ALL) + .border_style(if self.selected_field == 2 { + Style::default().fg(theme.highlight) + } else { + Style::default().fg(theme.border) + }); + let submit = Paragraph::new("Submit") + .block(submit_block) + .alignment(Alignment::Center); + f.render_widget(submit, form_chunks[2]); + } +} diff --git a/client/src/components/intro/intro.rs b/client/src/components/intro/intro.rs index 85993fc..6b97f85 100644 --- a/client/src/components/intro/intro.rs +++ b/client/src/components/intro/intro.rs @@ -1,4 +1,4 @@ -// src/components/handlers/intro.rs +// src/components/intro/intro.rs use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::Style, @@ -33,7 +33,7 @@ impl IntroState { .direction(Direction::Vertical) .constraints([ Constraint::Percentage(35), - Constraint::Length(5), + Constraint::Length(7), // Increased to accommodate 3 buttons Constraint::Percentage(35), ]) .split(inner_area); @@ -48,10 +48,14 @@ impl IntroState { .alignment(Alignment::Center); f.render_widget(title_para, chunks[1]); - // Buttons + // Buttons - now with 3 options let button_area = Layout::default() .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)]) + .constraints([ + Constraint::Percentage(33), + Constraint::Percentage(33), + Constraint::Percentage(33), + ]) .split(chunks[1].inner(Margin { horizontal: 1, vertical: 1 @@ -73,9 +77,9 @@ impl IntroState { ); self.render_button( f, - button_area[1], + button_area[2], "Login", - self.selected_option == 1, + self.selected_option == 2, theme, ); } @@ -107,11 +111,23 @@ impl IntroState { f.render_widget(button, area); } - pub fn next_option(&mut self) { - self.selected_option = (self.selected_option + 1) % 2; + pub fn next_option(&mut self) { + self.selected_option = (self.selected_option + 1) % 3; // Now 3 options } pub fn previous_option(&mut self) { - self.selected_option = if self.selected_option == 0 { 1 } else { 0 }; + self.selected_option = if self.selected_option == 0 { 2 } else { self.selected_option - 1 }; + } + + pub fn handle_selection(&self, app_state: &mut crate::state::state::AppState) { + match self.selected_option { + 0 => { /* Continue logic */ } + 1 => { /* Admin logic */ } + 2 => { + app_state.ui.show_intro = false; + app_state.ui.show_login = true; + } + _ => {} + } } } diff --git a/client/src/state/state.rs b/client/src/state/state.rs index ce520ed..8b8f101 100644 --- a/client/src/state/state.rs +++ b/client/src/state/state.rs @@ -11,6 +11,7 @@ pub struct UiState { pub show_intro: bool, pub show_admin: bool, pub show_form: bool, + pub show_login: bool, pub intro_state: IntroState, } @@ -75,6 +76,7 @@ impl Default for UiState { show_intro: true, show_admin: false, show_form: false, + show_login: false, intro_state: IntroState::new(), } }