//! Create new realm page component. use leptos::prelude::*; #[cfg(feature = "hydrate")] use leptos::task::spawn_local; use crate::components::{Card, PageHeader}; /// Realm new page component. #[component] pub fn RealmNewPage() -> impl IntoView { // Form state let (name, set_name) = signal(String::new()); let (slug, set_slug) = signal(String::new()); let (tagline, set_tagline) = signal(String::new()); let (description, set_description) = signal(String::new()); let (privacy, set_privacy) = signal("public".to_string()); let (max_users, set_max_users) = signal(100i32); let (is_nsfw, set_is_nsfw) = signal(false); let (allow_guest_access, set_allow_guest_access) = signal(false); let (theme_color, set_theme_color) = signal("#7c3aed".to_string()); // Owner selection let (owner_mode, set_owner_mode) = signal("existing".to_string()); let (owner_id, set_owner_id) = signal(String::new()); let (new_username, set_new_username) = signal(String::new()); let (new_email, set_new_email) = signal(String::new()); let (new_display_name, set_new_display_name) = signal(String::new()); // UI state let (message, set_message) = signal(Option::<(String, bool)>::None); let (pending, set_pending) = signal(false); let (created_slug, _set_created_slug) = signal(Option::::None); let (temp_password, _set_temp_password) = signal(Option::::None); #[cfg(feature = "hydrate")] let (set_created_slug, set_temp_password) = (_set_created_slug, _set_temp_password); let (slug_auto, set_slug_auto) = signal(true); let update_name = move |ev: leptos::ev::Event| { let new_name = event_target_value(&ev); set_name.set(new_name.clone()); if slug_auto.get() { let new_slug = new_name .to_lowercase() .chars() .map(|c| if c.is_alphanumeric() { c } else { '-' }) .collect::() .trim_matches('-') .to_string(); set_slug.set(new_slug); } }; let on_submit = move |ev: leptos::ev::SubmitEvent| { ev.prevent_default(); set_pending.set(true); set_message.set(None); #[cfg(feature = "hydrate")] { use gloo_net::http::Request; let mut data = serde_json::json!({ "name": name.get(), "slug": slug.get(), "description": if description.get().is_empty() { None:: } else { Some(description.get()) }, "tagline": if tagline.get().is_empty() { None:: } else { Some(tagline.get()) }, "privacy": privacy.get(), "is_nsfw": is_nsfw.get(), "max_users": max_users.get(), "allow_guest_access": allow_guest_access.get(), "theme_color": theme_color.get() }); if owner_mode.get() == "existing" { if owner_id.get().is_empty() { set_message.set(Some(("Please enter an owner User ID".to_string(), false))); set_pending.set(false); return; } data["owner_id"] = serde_json::json!(owner_id.get()); } else { if new_username.get().is_empty() || new_email.get().is_empty() || new_display_name.get().is_empty() { set_message.set(Some(("Please fill in all new owner fields".to_string(), false))); set_pending.set(false); return; } data["new_owner"] = serde_json::json!({ "username": new_username.get(), "email": new_email.get(), "display_name": new_display_name.get() }); } spawn_local(async move { let response = Request::post("/api/admin/realms") .json(&data) .unwrap() .send() .await; set_pending.set(false); match response { Ok(resp) if resp.ok() => { #[derive(serde::Deserialize)] struct CreateResponse { slug: String, owner_temporary_password: Option, } if let Ok(result) = resp.json::().await { set_created_slug.set(Some(result.slug)); set_temp_password.set(result.owner_temporary_password); set_message.set(Some(("Realm created successfully!".to_string(), true))); } } Ok(resp) => { #[derive(serde::Deserialize)] struct ErrorResp { error: String, } if let Ok(err) = resp.json::().await { set_message.set(Some((err.error, false))); } else { set_message.set(Some(("Failed to create realm".to_string(), false))); } } Err(_) => { set_message.set(Some(("Network error".to_string(), false))); } } }); } }; view! { "Back to Realms"

"Realm Details"

"Lowercase letters, numbers, hyphens only"

"Realm Owner"

"A random temporary password will be generated for the new owner."

{move || { let (msg, is_success) = message.get().unwrap_or_default(); let class = if is_success { "alert alert-success" } else { "alert alert-error" }; view! { } }}

"New Owner Temporary Password:"

{move || temp_password.get().unwrap_or_default()}

"Copy this password now - it will not be shown again!"

} }