use leptos::html::Input; use leptos::prelude::*; use web_sys::SubmitEvent; use super::context::use_auth; use crate::i18n::use_i18n; #[component] pub fn RegisterForm() -> impl IntoView { let auth = use_auth(); let i18n = use_i18n(); // Store contexts in StoredValue to avoid move issues let auth_stored = StoredValue::new(auth); let i18n_stored = StoredValue::new(i18n); let (email, set_email) = signal(String::new()); let (username, set_username) = signal(String::new()); let (password, set_password) = signal(String::new()); let (confirm_password, set_confirm_password) = signal(String::new()); let (display_name, set_display_name) = signal(String::new()); let (show_password, set_show_password) = signal(false); let (show_confirm_password, set_show_confirm_password) = signal(false); let email_ref = NodeRef::::new(); let username_ref = NodeRef::::new(); let password_ref = NodeRef::::new(); let confirm_password_ref = NodeRef::::new(); let password_strength = Memo::new(move |_| { let pwd = password.get(); if pwd.is_empty() { return ("", ""); } let mut score = 0; let mut feedback = Vec::new(); if pwd.len() >= 8 { score += 1; } else { feedback.push("At least 8 characters"); } if pwd.chars().any(|c| c.is_uppercase()) { score += 1; } else { feedback.push("One uppercase letter"); } if pwd.chars().any(|c| c.is_lowercase()) { score += 1; } else { feedback.push("One lowercase letter"); } if pwd.chars().any(|c| c.is_numeric()) { score += 1; } else { feedback.push("One number"); } if pwd.chars().any(|c| !c.is_alphanumeric()) { score += 1; } else { feedback.push("One special character"); } let strength = match score { 0..=1 => ("Very Weak", "bg-red-500"), 2 => ("Weak", "bg-orange-500"), 3 => ("Fair", "bg-yellow-500"), 4 => ("Good", "bg-blue-500"), 5 => ("Strong", "bg-green-500"), _ => ("Strong", "bg-green-500"), }; (strength.0, strength.1) }); let passwords_match = move || { let pwd = password.get(); let confirm = confirm_password.get(); pwd == confirm && !pwd.is_empty() }; let form_is_valid = move || { !email.get().is_empty() && !username.get().is_empty() && !password.get().is_empty() && passwords_match() && password.get().len() >= 8 }; let on_submit = move |ev: SubmitEvent| { ev.prevent_default(); if form_is_valid() { let email_val = email.get(); let username_val = username.get(); let password_val = password.get(); let display_name_val = if display_name.get().is_empty() { None } else { Some(display_name.get()) }; (auth_stored.get_value().0.actions.register)( email_val, username_val, password_val, display_name_val, ); } }; let toggle_password_visibility = move |_| { set_show_password.update(|show| *show = !*show); }; let toggle_confirm_password_visibility = move |_| { set_show_confirm_password.update(|show| *show = !*show); }; let clear_error = move |_| { (auth_stored.get_value().0.actions.clear_error)(); }; view! {

{move || i18n_stored.get_value().t("create-account")}

{move || i18n_stored.get_value().t("join-us-today")}

{move || auth_stored.get_value().0.error().unwrap_or_default()}

{move || i18n_stored.get_value().t("username-format")}

{move || i18n_stored.get_value().t("password-strength")} "text-red-600", "Weak" => "text-orange-600", "Fair" => "text-yellow-600", "Good" => "text-blue-600", "Strong" => "text-green-600", _ => "text-gray-600", })> {move || { let strength = password_strength.get().0; match strength { "Very Weak" => i18n_stored.get_value().t("very-weak"), "Weak" => i18n_stored.get_value().t("weak"), "Fair" => i18n_stored.get_value().t("fair"), "Good" => i18n_stored.get_value().t("good"), "Strong" => i18n_stored.get_value().t("strong"), _ => strength.to_string(), } }}
"20%", "Weak" => "40%", "Fair" => "60%", "Good" => "80%", "Strong" => "100%", _ => "0%", }; format!("width: {}", width) } >

{move || i18n_stored.get_value().t("password-requirements")}

{move || i18n_stored.get_value().t("passwords-dont-match")} } > {move || i18n_stored.get_value().t("passwords-match")}
{move || i18n_stored.get_value().t("continue-with")}

{move || i18n_stored.get_value().t("already-have-account")}{" "} {move || i18n_stored.get_value().t("sign-in")}

} }