feat: implemented signin api call
This commit is contained in:
parent
8c756a4eb6
commit
d0e119eabc
|
@ -128,8 +128,13 @@ name = "frontend"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"futures-channel",
|
||||||
"gloo 0.10.0",
|
"gloo 0.10.0",
|
||||||
|
"gloo-net 0.4.0",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"yew",
|
"yew",
|
||||||
"yew-router",
|
"yew-router",
|
||||||
|
@ -877,9 +882,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.105"
|
version = "1.0.107"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
|
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
|
14
Cargo.toml
14
Cargo.toml
|
@ -6,9 +6,19 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# Misc
|
||||||
|
anyhow = "1.0.75"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
futures-channel = "0.3.28"
|
||||||
|
|
||||||
|
# Yew
|
||||||
yew = { version = "0.20.0", features = ["csr"] }
|
yew = { version = "0.20.0", features = ["csr"] }
|
||||||
yew-router = "0.17.0"
|
yew-router = "0.17.0"
|
||||||
web-sys = { version = "0.3.64", features = ["HtmlInputElement"] }
|
|
||||||
|
# Web
|
||||||
wasm-bindgen = "0.2.87"
|
wasm-bindgen = "0.2.87"
|
||||||
|
wasm-bindgen-futures = "0.4"
|
||||||
|
web-sys = { version = "0.3.64", features = ["HtmlInputElement"] }
|
||||||
gloo = "0.10.0"
|
gloo = "0.10.0"
|
||||||
anyhow = "1.0.75"
|
gloo-net = "0.4.0"
|
|
@ -0,0 +1,6 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct AccountAuthenticateResponse {
|
||||||
|
pub token: String,
|
||||||
|
}
|
|
@ -1,4 +1,10 @@
|
||||||
|
mod data;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use gloo_net::http::Request;
|
||||||
|
use serde_json::json;
|
||||||
|
use web_sys::RequestMode;
|
||||||
|
use yew::Callback;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
|
@ -23,12 +29,33 @@ impl Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn login(&mut self, username: &str, password: &str) -> Result<()> {
|
pub fn login(&self, username: String, password: String, callback: Callback<Result<String>>) {
|
||||||
gloo::console::log!("Login: ", username, " || ", password);
|
let url = format!("{}/account/authenticate", &self.base_url);
|
||||||
Ok(())
|
|
||||||
|
let body = json!({
|
||||||
|
"username": username,
|
||||||
|
"password": password
|
||||||
|
});
|
||||||
|
|
||||||
|
let call = async move {
|
||||||
|
let request = Request::post(&url).mode(RequestMode::Cors).json(&body)?;
|
||||||
|
let response = request
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.json::<data::AccountAuthenticateResponse>()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(response.token)
|
||||||
|
};
|
||||||
|
|
||||||
|
wasm_bindgen_futures::spawn_local(async move { callback.emit(call.await) });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_token(&mut self, token: String) {
|
||||||
|
self.auth_token = Some(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_authenticated(&self) -> bool {
|
pub fn is_authenticated(&self) -> bool {
|
||||||
self.auth_token.is_some()
|
self.auth_token.is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -2,6 +2,7 @@ mod backend;
|
||||||
mod content;
|
mod content;
|
||||||
mod topbar;
|
mod topbar;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
use backend::Session;
|
use backend::Session;
|
||||||
use content::{error, home::Home};
|
use content::{error, home::Home};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -36,20 +37,20 @@ fn switch(routes: Route) -> Html {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct Callbacks {
|
pub struct Callbacks {
|
||||||
pub sign_in_callback: Callback<(String, String)>,
|
pub sign_in_callback: Callback<Result<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
fn App() -> Html {
|
fn App() -> Html {
|
||||||
let state = use_state(Session::default);
|
// let state = use_state(Session::default);
|
||||||
|
let state = use_state(|| Session::new("http://localhost:8080".to_string()));
|
||||||
|
|
||||||
let cloned_state = state.clone();
|
let cloned_state = state.clone();
|
||||||
let callbacks = use_state(move || Callbacks {
|
let callbacks = use_state(move || Callbacks {
|
||||||
sign_in_callback: Callback::from(move |data: (String, String)| {
|
sign_in_callback: Callback::from(move |response: Result<String>| {
|
||||||
let mut new_state = cloned_state.deref().clone();
|
let mut new_state = cloned_state.deref().clone();
|
||||||
new_state
|
|
||||||
.login(data.0.as_str(), data.1.as_str())
|
new_state.set_token(response.expect("!!! remove this temporary expect !!!"));
|
||||||
.expect("Login failed");
|
|
||||||
cloned_state.set(new_state);
|
cloned_state.set(new_state);
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,6 @@ mod signin;
|
||||||
mod signup;
|
mod signup;
|
||||||
|
|
||||||
use crate::topbar::Tab;
|
use crate::topbar::Tab;
|
||||||
use crate::Callbacks;
|
|
||||||
use signin::SignIn;
|
use signin::SignIn;
|
||||||
use signup::SignUp;
|
use signup::SignUp;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -50,7 +49,6 @@ impl Reducible for State {
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn TopBar() -> Html {
|
pub fn TopBar() -> Html {
|
||||||
let state = use_reducer(State::default);
|
let state = use_reducer(State::default);
|
||||||
let callbacks = use_context::<Callbacks>().expect("Callbacks context not available!");
|
|
||||||
|
|
||||||
let sign_in_onclick = {
|
let sign_in_onclick = {
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
|
@ -77,7 +75,7 @@ pub fn TopBar() -> Html {
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
if state.sign_in {
|
if state.sign_in {
|
||||||
<SignIn callback={callbacks.sign_in_callback}/>
|
<SignIn/>
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.sign_up {
|
if state.sign_up {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::backend::Session;
|
||||||
|
use crate::Callbacks;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::HtmlInputElement;
|
use web_sys::HtmlInputElement;
|
||||||
|
@ -9,14 +11,11 @@ struct Data {
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Properties, PartialEq)]
|
|
||||||
pub struct Props {
|
|
||||||
pub callback: Callback<(String, String)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn SignIn(props: &Props) -> Html {
|
pub fn SignIn() -> Html {
|
||||||
let state = use_state(|| Data::default());
|
let state = use_state(|| Data::default());
|
||||||
|
let callbacks = use_context::<Callbacks>().expect("Callbacks context not available!");
|
||||||
|
let session = use_context::<Session>().unwrap_or_default();
|
||||||
|
|
||||||
let cloned_state = state.clone();
|
let cloned_state = state.clone();
|
||||||
let on_username_changed = Callback::from(move |event: Event| {
|
let on_username_changed = Callback::from(move |event: Event| {
|
||||||
|
@ -44,14 +43,16 @@ pub fn SignIn(props: &Props) -> Html {
|
||||||
cloned_state.set(data);
|
cloned_state.set(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
let cloned_state = state.clone();
|
|
||||||
let callback = props.callback.clone();
|
|
||||||
let onsubmit = Callback::from(move |event: SubmitEvent| {
|
let onsubmit = Callback::from(move |event: SubmitEvent| {
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
|
|
||||||
let data = cloned_state.deref().clone();
|
let state = state.deref().clone();
|
||||||
|
|
||||||
callback.emit((data.username, data.password));
|
session.login(
|
||||||
|
state.username,
|
||||||
|
state.password,
|
||||||
|
callbacks.sign_in_callback.clone(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
|
|
Loading…
Reference in New Issue