mentorenwahl/frontend/src/routes/login.rs

117 lines
3.6 KiB
Rust

use graphql_client::reqwest::post_graphql;
use web_sys::HtmlInputElement;
use yew::prelude::*;
use yew_router::prelude::*;
use yew_side_effect::title::Title;
use crate::components;
use crate::cookie_names;
use crate::graphql;
use crate::routes;
pub enum Msg {
Submit,
Login(Option<Vec<String>>),
}
pub struct Login {
username: NodeRef,
password: NodeRef,
errors: Option<Vec<String>>,
}
impl Component for Login {
type Message = Msg;
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self {
username: NodeRef::default(),
password: NodeRef::default(),
errors: None,
}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::Submit => {
if let (Some(username), Some(password)) = (
self.username.cast::<HtmlInputElement>().map(|x| x.value()),
self.password.cast::<HtmlInputElement>().map(|x| x.value()),
) {
if !username.is_empty() && !password.is_empty() {
ctx.link().send_future(async {
let response = post_graphql::<graphql::mutations::login::Login, _>(
&graphql::client(None).unwrap(),
graphql::URL.as_str(),
graphql::mutations::login::login::Variables { username, password },
)
.await
.unwrap();
if response.errors.is_some() {
wasm_cookies::delete(cookie_names::TOKEN);
} else {
wasm_cookies::set(
cookie_names::TOKEN,
&response.data.unwrap().login.unwrap().token,
&wasm_cookies::CookieOptions::default(),
)
}
Msg::Login(components::graphql_errors::convert(response.errors))
});
}
}
false
}
Msg::Login(errors) => {
self.errors = errors;
if self.errors.is_none() {
ctx.link().history().unwrap().push(routes::Route::Home);
false
} else {
true
}
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let onsubmit = ctx.link().callback(|e: FocusEvent| {
e.prevent_default();
Msg::Submit
});
html! {
<>
<Title value="Login" />
<form {onsubmit}>
<label for="username">
{ "Benutzername:" }
<br />
<input ref={self.username.clone()} type="text" id="username" name="username" />
</label>
<br />
<label for="password">
{ "Kennwort:" }
<br />
<input ref={self.password.clone()} type="password" id="password" name="password" />
</label>
<br /><br />
<button type="submit">{ "Login" }</button>
<components::graphql_errors::GraphQLErrors errors={self.errors.clone()} />
</form>
</>
}
}
}