register is now separated also

This commit is contained in:
filipriec
2025-08-23 21:47:18 +02:00
parent fc2b65601e
commit e6072d25c5
14 changed files with 216 additions and 206 deletions

View File

@@ -1,4 +0,0 @@
// src/components/form.rs
pub mod register;
pub use register::*;

View File

@@ -2,11 +2,9 @@
pub mod intro;
pub mod admin;
pub mod common;
pub mod auth;
pub mod utils;
pub use intro::*;
pub use admin::*;
pub use common::*;
pub use auth::*;
pub use utils::*;

View File

@@ -21,7 +21,7 @@ use crate::state::app::state::AppState;
use crate::buffer::AppView;
use crate::buffer::state::BufferState;
use crate::modes::handlers::event::EventOutcome;
use crate::tui::functions::common::register;
use crate::pages::register;
use crate::pages::login;
use crate::tui::functions::common::add_table::handle_delete_selected_columns;
use crate::pages::routing::{Router, Page};

View File

@@ -25,21 +25,22 @@ use crate::state::{
},
pages::{
admin::AdminState,
auth::{AuthState, RegisterState},
auth::AuthState,
intro::IntroState,
},
};
use crate::pages::login::LoginState;
use crate::tui::common::register;
use crate::pages::register::RegisterState;
use crate::pages::login;
use crate::pages::login::logic;
use crate::pages::register;
// use crate::pages::login::logic;
use crate::pages::login::logic::LoginResult;
use crate::pages::register::RegisterResult;
use crate::pages::routing::{Router, Page};
use crate::dialog;
use crate::pages::forms::FormState;
use crate::pages::forms::logic::{save, revert, SaveOutcome};
use crate::search::state::SearchState;
use crate::tui::functions::common::register::RegisterResult;
use crate::tui::{
terminal::core::TerminalCore,
{admin, intro},
@@ -811,7 +812,7 @@ impl EventHandler {
match action {
"save" => {
if let Page::Login(login_state) = &mut router.current {
let message = logic::save(
let message = login::logic::save(
auth_state,
login_state,
&mut self.auth_client,
@@ -848,7 +849,7 @@ impl EventHandler {
}
"save_and_quit" => {
let message = if let Page::Login(login_state) = &mut router.current {
logic::save(
login::logic::save(
auth_state,
login_state,
&mut self.auth_client,
@@ -877,9 +878,9 @@ impl EventHandler {
}
"revert" => {
let message = if let Page::Login(login_state) = &mut router.current {
logic::revert(login_state, app_state).await
login::logic::revert(login_state, app_state).await
} else if let Page::Register(register_state) = &mut router.current {
crate::tui::functions::common::register::revert(
register::revert(
register_state,
app_state,
)

View File

@@ -3,3 +3,4 @@
pub mod routing;
pub mod forms;
pub mod login;
pub mod register;

View File

@@ -1,13 +1,13 @@
// src/tui/functions/common/register.rs
// src/pages/register/logic.rs
use crate::services::auth::AuthClient;
use crate::state::{
pages::auth::RegisterState,
app::state::AppState,
};
use crate::ui::handlers::context::DialogPurpose;
use crate::buffer::state::{AppView, BufferState};
use common::proto::komp_ac::auth::AuthResponse;
use crate::pages::register::RegisterState;
use anyhow::Context;
use tokio::spawn;
use tokio::sync::mpsc;

View File

@@ -0,0 +1,11 @@
// src/pages/register/mod.rs
// pub mod state;
pub mod ui;
pub mod state;
pub mod logic;
// pub use state::*;
pub use ui::render_register;
pub use logic::*;
pub use state::*;

View File

@@ -0,0 +1,184 @@
// src/pages/register/state.rs
use canvas::{DataProvider, AppMode};
use lazy_static::lazy_static;
lazy_static! {
pub static ref AVAILABLE_ROLES: Vec<String> = vec![
"admin".to_string(),
"moderator".to_string(),
"accountant".to_string(),
"viewer".to_string(),
];
}
/// Represents the state of the Registration form UI
#[derive(Debug, Clone)]
pub struct RegisterState {
pub username: String,
pub email: String,
pub password: String,
pub password_confirmation: String,
pub role: String,
pub error_message: Option<String>,
pub current_field: usize,
pub current_cursor_pos: usize,
pub has_unsaved_changes: bool,
pub app_mode: AppMode,
pub role_suggestions: Vec<String>,
pub role_suggestions_active: bool,
}
impl Default for RegisterState {
fn default() -> Self {
Self {
username: String::new(),
email: String::new(),
password: String::new(),
password_confirmation: String::new(),
role: String::new(),
error_message: None,
current_field: 0,
current_cursor_pos: 0,
has_unsaved_changes: false,
app_mode: AppMode::Edit,
role_suggestions: AVAILABLE_ROLES.clone(),
role_suggestions_active: false,
}
}
}
impl RegisterState {
pub fn new() -> Self {
Self {
app_mode: AppMode::Edit,
role_suggestions: AVAILABLE_ROLES.clone(),
role_suggestions_active: false,
..Default::default()
}
}
pub fn current_field(&self) -> usize {
self.current_field
}
pub fn current_cursor_pos(&self) -> usize {
self.current_cursor_pos
}
pub fn set_current_field(&mut self, index: usize) {
if index < 5 {
self.current_field = index;
if index == 4 {
self.activate_role_suggestions();
} else {
self.deactivate_role_suggestions();
}
}
}
pub fn set_current_cursor_pos(&mut self, pos: usize) {
self.current_cursor_pos = pos;
}
pub fn get_current_input(&self) -> &str {
match self.current_field {
0 => &self.username,
1 => &self.email,
2 => &self.password,
3 => &self.password_confirmation,
4 => &self.role,
_ => "",
}
}
pub fn get_current_input_mut(&mut self, index: usize) -> &mut String {
match index {
0 => &mut self.username,
1 => &mut self.email,
2 => &mut self.password,
3 => &mut self.password_confirmation,
4 => &mut self.role,
_ => panic!("Invalid current_field index in RegisterState"),
}
}
pub fn current_mode(&self) -> AppMode {
self.app_mode
}
pub fn activate_role_suggestions(&mut self) {
self.role_suggestions_active = true;
let current_input = self.role.to_lowercase();
self.role_suggestions = AVAILABLE_ROLES
.iter()
.filter(|role| role.to_lowercase().contains(&current_input))
.cloned()
.collect();
}
pub fn deactivate_role_suggestions(&mut self) {
self.role_suggestions_active = false;
}
pub fn is_role_suggestions_active(&self) -> bool {
self.role_suggestions_active
}
pub fn get_role_suggestions(&self) -> &[String] {
&self.role_suggestions
}
pub fn has_unsaved_changes(&self) -> bool {
self.has_unsaved_changes
}
pub fn set_has_unsaved_changes(&mut self, changed: bool) {
self.has_unsaved_changes = changed;
}
}
impl DataProvider for RegisterState {
fn field_count(&self) -> usize {
5
}
fn field_name(&self, index: usize) -> &str {
match index {
0 => "Username",
1 => "Email (Optional)",
2 => "Password (Optional)",
3 => "Confirm Password",
4 => "Role (Optional)",
_ => "",
}
}
fn field_value(&self, index: usize) -> &str {
match index {
0 => &self.username,
1 => &self.email,
2 => &self.password,
3 => &self.password_confirmation,
4 => &self.role,
_ => "",
}
}
fn set_field_value(&mut self, index: usize, value: String) {
match index {
0 => self.username = value,
1 => self.email = value,
2 => self.password = value,
3 => self.password_confirmation = value,
4 => self.role = value,
_ => {}
}
self.has_unsaved_changes = true;
}
fn supports_suggestions(&self, field_index: usize) -> bool {
field_index == 4 // only Role field supports suggestions
}
}

View File

@@ -1,8 +1,7 @@
// src/components/auth/register.rs
// src/pages/register/ui.rs
use crate::{
config::colors::themes::Theme,
state::pages::auth::RegisterState,
state::app::state::AppState,
modes::handlers::mode_manager::AppMode,
};
@@ -13,6 +12,7 @@ use ratatui::{
Frame,
};
use crate::dialog;
use crate::pages::register::RegisterState;
use canvas::{FormEditor, render_canvas, render_suggestions_dropdown, DefaultCanvasTheme};
pub fn render_register(

View File

@@ -1,13 +1,14 @@
// src/pages/routing/router.rs
use crate::state::pages::{
admin::AdminState,
auth::{AuthState, RegisterState},
auth::AuthState,
intro::IntroState,
add_logic::AddLogicState,
add_table::AddTableState,
};
use crate::pages::forms::FormState;
use crate::pages::login::LoginState;
use crate::pages::register::RegisterState;
#[derive(Debug)]
pub enum Page {

View File

@@ -1,16 +1,6 @@
// src/state/pages/auth.rs
use canvas::{DataProvider, AppMode};
use lazy_static::lazy_static;
lazy_static! {
pub static ref AVAILABLE_ROLES: Vec<String> = vec![
"admin".to_string(),
"moderator".to_string(),
"accountant".to_string(),
"viewer".to_string(),
];
}
/// Represents the authenticated session state
#[derive(Default)]
@@ -21,179 +11,8 @@ pub struct AuthState {
pub decoded_username: Option<String>,
}
/// Represents the state of the Registration form UI
#[derive(Debug, Clone)]
pub struct RegisterState {
pub username: String,
pub email: String,
pub password: String,
pub password_confirmation: String,
pub role: String,
pub error_message: Option<String>,
pub current_field: usize,
pub current_cursor_pos: usize,
pub has_unsaved_changes: bool,
pub app_mode: AppMode,
pub role_suggestions: Vec<String>,
pub role_suggestions_active: bool,
}
impl Default for RegisterState {
fn default() -> Self {
Self {
username: String::new(),
email: String::new(),
password: String::new(),
password_confirmation: String::new(),
role: String::new(),
error_message: None,
current_field: 0,
current_cursor_pos: 0,
has_unsaved_changes: false,
app_mode: AppMode::Edit,
role_suggestions: AVAILABLE_ROLES.clone(),
role_suggestions_active: false,
}
}
}
impl AuthState {
pub fn new() -> Self {
Self::default()
}
}
impl RegisterState {
pub fn new() -> Self {
Self {
app_mode: AppMode::Edit,
role_suggestions: AVAILABLE_ROLES.clone(),
role_suggestions_active: false,
..Default::default()
}
}
pub fn current_field(&self) -> usize {
self.current_field
}
pub fn current_cursor_pos(&self) -> usize {
self.current_cursor_pos
}
pub fn set_current_field(&mut self, index: usize) {
if index < 5 {
self.current_field = index;
if index == 4 {
self.activate_role_suggestions();
} else {
self.deactivate_role_suggestions();
}
}
}
pub fn set_current_cursor_pos(&mut self, pos: usize) {
self.current_cursor_pos = pos;
}
pub fn get_current_input(&self) -> &str {
match self.current_field {
0 => &self.username,
1 => &self.email,
2 => &self.password,
3 => &self.password_confirmation,
4 => &self.role,
_ => "",
}
}
pub fn get_current_input_mut(&mut self, index: usize) -> &mut String {
match index {
0 => &mut self.username,
1 => &mut self.email,
2 => &mut self.password,
3 => &mut self.password_confirmation,
4 => &mut self.role,
_ => panic!("Invalid current_field index in RegisterState"),
}
}
pub fn current_mode(&self) -> AppMode {
self.app_mode
}
pub fn activate_role_suggestions(&mut self) {
self.role_suggestions_active = true;
let current_input = self.role.to_lowercase();
self.role_suggestions = AVAILABLE_ROLES
.iter()
.filter(|role| role.to_lowercase().contains(&current_input))
.cloned()
.collect();
}
pub fn deactivate_role_suggestions(&mut self) {
self.role_suggestions_active = false;
}
pub fn is_role_suggestions_active(&self) -> bool {
self.role_suggestions_active
}
pub fn get_role_suggestions(&self) -> &[String] {
&self.role_suggestions
}
pub fn has_unsaved_changes(&self) -> bool {
self.has_unsaved_changes
}
pub fn set_has_unsaved_changes(&mut self, changed: bool) {
self.has_unsaved_changes = changed;
}
}
impl DataProvider for RegisterState {
fn field_count(&self) -> usize {
5
}
fn field_name(&self, index: usize) -> &str {
match index {
0 => "Username",
1 => "Email (Optional)",
2 => "Password (Optional)",
3 => "Confirm Password",
4 => "Role (Optional)",
_ => "",
}
}
fn field_value(&self, index: usize) -> &str {
match index {
0 => &self.username,
1 => &self.email,
2 => &self.password,
3 => &self.password_confirmation,
4 => &self.role,
_ => "",
}
}
fn set_field_value(&mut self, index: usize, value: String) {
match index {
0 => self.username = value,
1 => self.email = value,
2 => self.password = value,
3 => self.password_confirmation = value,
4 => self.role = value,
_ => {}
}
self.has_unsaved_changes = true;
}
fn supports_suggestions(&self, field_index: usize) -> bool {
field_index == 4 // only Role field supports suggestions
}
}

View File

@@ -1,5 +1,4 @@
// src/tui/functions/common.rs
pub mod logout;
pub mod register;
pub mod add_table;

View File

@@ -3,11 +3,11 @@
use crate::components::{
admin::add_logic::render_add_logic,
admin::render_add_table,
auth::register::render_register,
intro::intro::render_intro,
render_background,
};
use crate::pages::login::render_login;
use crate::pages::register::render_register;
use crate::bottom_panel::{
command_line::render_command_line,
status_line::render_status_line,

View File

@@ -9,7 +9,7 @@ use crate::modes::common::commands::CommandHandler;
use crate::modes::handlers::event::{EventHandler, EventOutcome};
use crate::modes::handlers::mode_manager::{AppMode, ModeManager};
use crate::state::pages::auth::AuthState;
use crate::state::pages::auth::RegisterState;
use crate::pages::register::RegisterState;
use crate::state::pages::admin::AdminState;
use crate::state::pages::admin::AdminFocus;
use crate::state::pages::intro::IntroState;
@@ -21,11 +21,11 @@ use crate::state::app::state::AppState;
use crate::tui::terminal::{EventReader, TerminalCore};
use crate::ui::handlers::render::render_ui;
use crate::pages::login;
use crate::pages::register;
use crate::pages::login::LoginResult;
use crate::pages::login::LoginState;
use crate::tui::functions::common::register::RegisterResult;
use crate::pages::register::RegisterResult;
use crate::ui::handlers::context::DialogPurpose;
use crate::tui::functions::common::register;
use crate::utils::columns::filter_user_columns;
use canvas::keymap::KeyEventOutcome;
use anyhow::{Context, Result};