use perseus::prelude::*; use sycamore::{prelude::*, rt::Event}; use crate::{ components::{main_content_container::MainContentContainer, the_header::TheHeader}, global_state::AppStateRx, }; fn login_page(cx: BoundedScope) -> View { let reactor = Reactor::::from_cx(cx); let global_state = reactor.get_global_state::(cx); let api = global_state.api.get(); let api_scope_ref = create_ref(cx, api); let dark_mode_class = create_memo(cx, || { if *global_state.dark_mode.get() { "dark" } else { "" } }); let username = create_signal(cx, "".to_string()); let password = create_signal(cx, "".to_string()); let error_msg = create_signal(cx, "".to_string()); create_effect(cx, move || { if *global_state.logged_in.get() { navigate("/"); } }); let submit_disabled = create_memo(cx, move || { username.get().is_empty() || password.get().is_empty() }); #[cfg(client)] let submit_login = move |e: Event| { use crate::api::routes::user::UserLoginBody; e.prevent_default(); let user_info = UserLoginBody { name: username.get().to_string(), password: password.get().to_string(), }; spawn_local_scoped(cx, async move { match api_scope_ref.login(&user_info).await { Ok(()) => { global_state.logged_in.set(true); } Err(e) => error_msg.set(e.to_string()), }; }) }; #[cfg(engine)] let submit_login = move |_| {}; view! {cx, main (class=format!("{} flex flex-1", dark_mode_class)) { div (class="flex-1 font-sans bg-slate-200 text-slate-700 dark:bg-slate-700 dark:text-slate-100") { TheHeader() MainContentContainer(useless_prop=1) { form(class="flex flex-col justify-center items-center") { label(for="username") { "Username:" } input(id="username", bind:value=username, type="text", class="p-2 m-2 w-1/3 rounded-md bg-slate-300 dark:bg-slate-800") {} label(for="password") { "Password:" } input(id="password", bind:value=password, type="password", class="p-2 m-2 w-1/3 rounded-md bg-slate-300 dark:bg-slate-800") {} input(on:click=submit_login, value="Login", type="submit", class="p-2 m-2 rounded-md hover:cursor-pointer disabled:cursor-not-allowed bg-slate-300 dark:hover:bg-slate-900 dark:bg-slate-800 hover:bg-slate-400", disabled=*submit_disabled.get() ) {} p (class="text-red-700 dark:text-rose-500") { (error_msg.get()) } } a (class="hover:underline", href="/register") { "Don't have an account? Register here." } } } } } } pub fn get_template() -> Template { Template::build("login").head(head).view(login_page).build() } #[engine_only_fn] fn head(cx: Scope) -> View { view! {cx, title { "Fast Insiders" } } }