Login works now
This commit is contained in:
parent
75b3aa7249
commit
43a9beaef8
4 changed files with 122 additions and 49 deletions
|
@ -1,20 +1,68 @@
|
|||
use log::info;
|
||||
use log::{error, info};
|
||||
use serde_json::json;
|
||||
use yew::format::{Json, Text};
|
||||
use yew::prelude::*;
|
||||
use yew::services::fetch::{FetchService, FetchTask, Request, Response};
|
||||
|
||||
use yew::services::fetch::Mode::Cors;
|
||||
|
||||
pub struct LoginComponent {
|
||||
component_link: ComponentLink<LoginComponent>,
|
||||
username: String,
|
||||
password: String,
|
||||
login_button_disabled: bool,
|
||||
fetch_service: FetchService,
|
||||
fetch_task: Option<FetchTask>,
|
||||
fetching: bool,
|
||||
}
|
||||
|
||||
pub enum Message {
|
||||
pub enum Msg {
|
||||
UpdateUsername(String),
|
||||
UpdatePassword(String),
|
||||
HandleForm(),
|
||||
FetchReady(String),
|
||||
FetchError,
|
||||
}
|
||||
|
||||
impl LoginComponent {
|
||||
fn update_button_state(&mut self) {
|
||||
self.login_button_disabled = self.username.is_empty() || self.password.is_empty();
|
||||
}
|
||||
|
||||
fn post_login(&mut self) {
|
||||
self.fetching = true;
|
||||
|
||||
let user = json!({
|
||||
"username": self.username,
|
||||
"password": self.password
|
||||
});
|
||||
|
||||
let request = Request::builder()
|
||||
.method("POST")
|
||||
.header("Content-Type", "application/json")
|
||||
.uri("http://localhost:3880/api/auth/login")
|
||||
.body(Json(&user))
|
||||
.unwrap();
|
||||
|
||||
let callback =
|
||||
self.component_link
|
||||
.callback(|response: Response<Result<String, anyhow::Error>>| {
|
||||
let (meta, body) = response.into_parts();
|
||||
if meta.status.is_success() {
|
||||
Msg::FetchReady(body.unwrap())
|
||||
} else {
|
||||
error!("{}", body.unwrap());
|
||||
Msg::FetchError
|
||||
}
|
||||
});
|
||||
|
||||
let task = self.fetch_service.fetch(request, callback);
|
||||
self.fetch_task = Some(task.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for LoginComponent {
|
||||
type Message = Message;
|
||||
type Message = Msg;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
|
@ -23,6 +71,9 @@ impl Component for LoginComponent {
|
|||
username: String::new(),
|
||||
password: String::new(),
|
||||
login_button_disabled: true,
|
||||
fetch_service: FetchService::new(),
|
||||
fetch_task: None,
|
||||
fetching: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,60 +83,66 @@ impl Component for LoginComponent {
|
|||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||
match msg {
|
||||
Message::UpdateUsername(new_username) => {
|
||||
Msg::UpdateUsername(new_username) => {
|
||||
self.username = new_username;
|
||||
self.update_button_state();
|
||||
}
|
||||
|
||||
Message::UpdatePassword(new_password) => {
|
||||
info!("Password changed");
|
||||
Msg::UpdatePassword(new_password) => {
|
||||
self.password = new_password;
|
||||
self.update_button_state();
|
||||
}
|
||||
Message::HandleForm() => {
|
||||
info!("Submit button clicked");
|
||||
|
||||
Msg::HandleForm() => self.post_login(),
|
||||
|
||||
Msg::FetchReady(response) => {
|
||||
self.fetching = false;
|
||||
info!("Fetch complete. Body: {}", response)
|
||||
}
|
||||
|
||||
Msg::FetchError => {
|
||||
self.fetching = false;
|
||||
error!("There was an error connecting to API")
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn view(&self) -> Html {
|
||||
let onclick = self.component_link.callback(|_| Message::HandleForm());
|
||||
let onclick = self.component_link.callback(|_| Msg::HandleForm());
|
||||
let oninput_username = self
|
||||
.component_link
|
||||
.callback(|e: InputData| Message::UpdateUsername(e.value));
|
||||
.callback(|e: InputData| Msg::UpdateUsername(e.value));
|
||||
let oninput_password = self
|
||||
.component_link
|
||||
.callback(|e: InputData| Message::UpdatePassword(e.value));
|
||||
.callback(|e: InputData| Msg::UpdatePassword(e.value));
|
||||
|
||||
html! {
|
||||
<div class="uk-card uk-card-default uk-card-body uk-width-1-3@s uk-position-center">
|
||||
<h1 class="uk-card-title">{ "Please log in" }</h1>
|
||||
<form>
|
||||
<div>
|
||||
<fieldset class="uk-fieldset">
|
||||
<input class="uk-input uk-margin",
|
||||
placeholder="Username",
|
||||
disabled=self.fetching,
|
||||
value=&self.username,
|
||||
oninput=oninput_username, />
|
||||
<input class="uk-input uk-margin-bottom",
|
||||
placeholder="Password",
|
||||
disabled=self.fetching,
|
||||
type="password",
|
||||
value=&self.password,
|
||||
oninput=oninput_password, />
|
||||
<button
|
||||
class="uk-button uk-button-primary",
|
||||
type="submit", onclick=onclick>
|
||||
{ "Submit" }
|
||||
type="button",
|
||||
disabled=self.fetching,
|
||||
onclick=onclick>
|
||||
{ "Log in" }
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LoginComponent {
|
||||
fn update_button_state(&mut self) {
|
||||
self.login_button_disabled = self.username.is_empty() || self.password.is_empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#![recursion_limit = "256"]
|
||||
|
||||
extern crate log;
|
||||
extern crate web_logger;
|
||||
|
||||
mod component;
|
||||
pub mod utils;
|
||||
|
||||
use component::login::LoginComponent;
|
||||
use yew::prelude::*;
|
||||
|
@ -13,9 +17,9 @@ struct App {}
|
|||
enum AppRoute {
|
||||
#[to = "/login"]
|
||||
Login,
|
||||
PageNotFound(Permissive<String>),
|
||||
#[to = "/"]
|
||||
Root,
|
||||
PageNotFound(Permissive<String>),
|
||||
}
|
||||
|
||||
impl Component for App {
|
||||
|
@ -33,32 +37,27 @@ impl Component for App {
|
|||
fn view(&self) -> VNode {
|
||||
html! {
|
||||
<div>
|
||||
<nav class="menu",>
|
||||
<RouterButton<AppRoute> route=AppRoute::Root>{"Go to Root"}</RouterButton<AppRoute>>
|
||||
<RouterButton<AppRoute> route=AppRoute::Login>{"Go to Login"}</RouterButton<AppRoute>>
|
||||
</nav>
|
||||
<div>
|
||||
<Router<AppRoute>
|
||||
render = Router::render(|switch: AppRoute| {
|
||||
match switch {
|
||||
AppRoute::Login => html!{<LoginComponent />},
|
||||
AppRoute::PageNotFound(Permissive(None)) => html!{"Page not found"},
|
||||
AppRoute::PageNotFound(Permissive(Some(missed_route))) => html!{format!("Page '{}' not found", missed_route)},
|
||||
AppRoute::Root => {
|
||||
html!{"hello there!"}
|
||||
},
|
||||
}
|
||||
})
|
||||
redirect = Router::redirect(|route: Route| {
|
||||
AppRoute::PageNotFound(Permissive(Some(route.route)))
|
||||
})
|
||||
/>
|
||||
</div>
|
||||
<Router<AppRoute>
|
||||
render = Router::render(|switch: AppRoute| {
|
||||
match switch {
|
||||
AppRoute::Login => html!{<LoginComponent />},
|
||||
AppRoute::PageNotFound(Permissive(None)) => html!{"Page not found"},
|
||||
AppRoute::PageNotFound(Permissive(Some(missed_route))) => html!{format!("Page '{}' not found", missed_route)},
|
||||
AppRoute::Root => {
|
||||
html!{"hello there!"}
|
||||
},
|
||||
}
|
||||
})
|
||||
redirect = Router::redirect(|route: Route| {
|
||||
AppRoute::PageNotFound(Permissive(Some(route.route)))
|
||||
})
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
web_logger::init();
|
||||
yew::start_app::<App>();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue