diff --git a/src/capsules/login_form.rs b/src/capsules/login_form.rs index d669b7d..5f765fe 100644 --- a/src/capsules/login_form.rs +++ b/src/capsules/login_form.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use sycamore::prelude::*; use web_sys::Event; -use crate::state_enums::OpenState; +use crate::{state_enums::OpenState, templates::global_state::AppStateRx}; lazy_static! { pub static ref LOGIN_FORM: Capsule = get_capsule(); @@ -19,7 +19,6 @@ struct LoginFormState { #[derive(Clone)] pub struct LoginFormProps { - pub open_state: RcSignal, pub remember_me: bool, pub endpoint: String, pub lost_password_url: Option, @@ -35,17 +34,16 @@ fn login_form_capsule( let close_modal = move |_event: Event| { #[cfg(client)] { - let open_state = props.open_state.clone(); spawn_local_scoped(cx, async move { - open_state.set(OpenState::Closed); + let global_state = Reactor::::from_cx(cx).get_global_state::(cx); + global_state.modals_open.login.set(OpenState::Closed) }); } }; - view! { - cx, + view! { cx, div (class="overflow-x-hidden overflow-y-auto fixed h-modal md:h-full top-4 left-0 right-0 md:inset-0 z-50 justify-center items-center"){ - div (class="relative w-full max-w-md px-4 h-full md:h-auto") { + div (class="relative md:mx-auto w-full md:w-1/2 lg:w-1/3 z-0 my-10") { div (class="bg-white rounded-lg shadow relative dark:bg-gray-700"){ div (class="flex justify-end p-2"){ button (on:click = close_modal, class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-800 dark:hover:text-white"){ diff --git a/src/components/header.rs b/src/components/header.rs index 940d689..3b495ae 100644 --- a/src/components/header.rs +++ b/src/components/header.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use perseus::prelude::*; use sycamore::prelude::*; use web_sys::Event; @@ -18,18 +20,14 @@ pub struct HeaderProps<'a> { pub fn Header<'a, G: Html>(cx: Scope<'a>, HeaderProps { game, title }: HeaderProps<'a>) -> View { // Get global state to get authentication info let global_state = Reactor::::from_cx(cx).get_global_state::(cx); - // Create signal for opening/closing the login modal - let login_modal_state = create_rc_signal(OpenState::Closed); - let handle_log_in = { - let login_modal_state = login_modal_state.clone(); - move |_event: Event| { - #[cfg(client)] - { - spawn_local_scoped(cx, async move { - login_modal_state.set(OpenState::Open); - }); - } + let handle_log_in = move |_event: Event| { + #[cfg(client)] + { + spawn_local_scoped(cx, async move { + let global_state = Reactor::::from_cx(cx).get_global_state::(cx); + global_state.modals_open.login.set(OpenState::Open); + }); } }; @@ -76,28 +74,24 @@ pub fn Header<'a, G: Html>(cx: Scope<'a>, HeaderProps { game, title }: HeaderPro } } - section { - div(class = "flex-1 py-2") {( - match *login_modal_state.get() { - OpenState::Open => { - let login_modal_state = login_modal_state.clone(); - view! { cx, - (LOGIN_FORM.widget(cx, "", - LoginFormProps{ - open_state: login_modal_state.clone(), - remember_me: true, - endpoint: "".to_string(), - lost_password_url: Some("".to_string()), - forgot_password_url: Some("".to_string()), - } - )) - } + section(class = "flex-2") { + (match *global_state.modals_open.login.get() { + OpenState::Open => { + view! { cx, + (LOGIN_FORM.widget(cx, "", + LoginFormProps{ + remember_me: true, + endpoint: "".to_string(), + lost_password_url: Some("".to_string()), + forgot_password_url: Some("".to_string()), + } + )) } - OpenState::Closed => { - view!{ cx, } - } - }) - } + } + OpenState::Closed => { + view!{ cx, } + } + }) } } } diff --git a/src/templates/global_state.rs b/src/templates/global_state.rs index bff16af..b96d6ec 100644 --- a/src/templates/global_state.rs +++ b/src/templates/global_state.rs @@ -3,7 +3,7 @@ use perseus::{prelude::*, state::GlobalStateCreator}; use serde::{Deserialize, Serialize}; -use crate::state_enums::LoginState; +use crate::state_enums::{LoginState, OpenState}; cfg_if::cfg_if! { if #[cfg(engine)] { @@ -16,6 +16,8 @@ cfg_if::cfg_if! { pub struct AppState { #[rx(nested)] pub auth: AuthData, + #[rx(nested)] + pub modals_open: ModalOpenData, } #[derive(Serialize, Deserialize, ReactiveState, Clone)] @@ -26,6 +28,12 @@ pub struct AuthData { pub claims: Claims, } +#[derive(Serialize, Deserialize, ReactiveState, Clone)] +#[rx(alias = "ModalOpenDataRx")] +pub struct ModalOpenData { + pub login: OpenState, +} + #[derive(Serialize, Deserialize, ReactiveState, Clone)] #[rx(alias = "ClaimsRx")] pub struct Claims {} @@ -42,6 +50,9 @@ pub async fn get_build_state() -> AppState { username: None, claims: Claims {}, }, + modals_open: ModalOpenData { + login: OpenState::Closed, + }, } }