You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.4 KiB

use perseus::prelude::*;
use sycamore::{prelude::*, rt::Event};
use crate::{
components::{main_content_container::MainContentContainer, the_header::TheHeader},
global_state::AppStateRx,
};
fn login_page<G: Html>(cx: BoundedScope) -> View<G> {
let reactor = Reactor::<G>::from_cx(cx);
let global_state = reactor.get_global_state::<AppStateRx>(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<G: Html>() -> Template<G> {
Template::build("login").head(head).view(login_page).build()
}
#[engine_only_fn]
fn head(cx: Scope) -> View<SsrNode> {
view! {cx,
title { "Fast Insiders" }
}
}