// src/tui/functions/common/register.rs use crate::{ services::auth::AuthClient, state::{ pages::auth::RegisterState, app::state::AppState, pages::canvas_state::CanvasState, }, ui::handlers::context::DialogPurpose, }; /// Attempts to register the user using the provided details via gRPC. /// Updates RegisterState and AppState on success or failure. pub async fn save( register_state: &mut RegisterState, auth_client: &mut AuthClient, app_state: &mut AppState, ) -> Result> { let username = register_state.username.clone(); let email = register_state.email.clone(); // Handle optional passwords: send None if empty, Some(value) otherwise let password = if register_state.password.is_empty() { None } else { Some(register_state.password.clone()) }; let password_confirmation = if register_state.password_confirmation.is_empty() { None } else { Some(register_state.password_confirmation.clone()) }; let role = if register_state.role.is_empty() { None } else { Some(register_state.role.clone()) }; // Basic client-side validation (example) if username.is_empty() { app_state.show_dialog( "Registration Failed", "Username cannot be empty.", vec!["OK".to_string()], DialogPurpose::RegisterFailed, ); register_state.error_message = Some("Username cannot be empty.".to_string()); return Ok("Registration failed: Username cannot be empty.".to_string()); } if password.is_some() && password != password_confirmation { app_state.show_dialog( "Registration Failed", "Passwords do not match.", vec!["OK".to_string()], DialogPurpose::RegisterFailed, ); register_state.error_message = Some("Passwords do not match.".to_string()); return Ok("Registration failed: Passwords do not match.".to_string()); } // Clear previous error/dialog state before attempting register_state.error_message = None; app_state.hide_dialog(); // Call the gRPC register method match auth_client.register(username, email, password, password_confirmation, role).await { Ok(response) => { // Clear fields on success? Optional, maybe wait for dialog confirmation. // register_state.username.clear(); // register_state.email.clear(); // register_state.password.clear(); // register_state.password_confirmation.clear(); register_state.set_has_unsaved_changes(false); let success_message = format!( "Registration Successful!\n\n\ User ID: {}\n\ Username: {}\n\ Email: {}\n\ Role: {}", response.id, response.username, response.email, response.role ); // Show success dialog app_state.show_dialog( "Registration Success", &success_message, vec!["OK".to_string()], // Simple OK for now DialogPurpose::RegisterSuccess, ); Ok("Registration successful, details shown in dialog.".to_string()) } Err(e) => { let error_message = format!("{}", e); register_state.error_message = Some(error_message.clone()); register_state.set_has_unsaved_changes(true); // Keep changes on error // Show error dialog app_state.show_dialog( "Registration Failed", &error_message, vec!["OK".to_string()], DialogPurpose::RegisterFailed, ); Ok(format!("Registration failed: {}", error_message)) } } } /// Clears the registration form fields. pub async fn revert( register_state: &mut RegisterState, _app_state: &mut AppState, // Keep signature consistent if needed elsewhere ) -> String { register_state.username.clear(); register_state.email.clear(); register_state.password.clear(); register_state.password_confirmation.clear(); register_state.role.clear(); register_state.error_message = None; register_state.set_has_unsaved_changes(false); register_state.current_field = 0; // Reset focus to first field register_state.current_cursor_pos = 0; "Registration form cleared".to_string() } /// Clears the form and returns to the intro screen. pub async fn back_to_main( register_state: &mut RegisterState, app_state: &mut AppState, ) -> String { // Clear fields first let _ = revert(register_state, app_state).await; // Ensure dialog is hidden app_state.hide_dialog(); // Navigation logic app_state.ui.show_register = false; app_state.ui.show_intro = true; // Reset focus state app_state.ui.focus_outside_canvas = false; app_state.button_focus_index = 0; "Returned to main menu".to_string() }