Add example protected route to project

This commit is contained in:
Marko Korhonen 2020-05-08 09:35:28 +03:00
parent 1e83393ad6
commit fb5aa5ee5a
No known key found for this signature in database
GPG key ID: 911B85FBC6003FE5
9 changed files with 161 additions and 36 deletions

View file

@ -1,4 +1,3 @@
use crate::utils::cookie;
use log::{error, info};
use serde_json::json;
use yew::format::Json;
@ -50,7 +49,6 @@ impl LoginComponent {
if meta.status.is_success() {
Msg::FetchReady(body.unwrap())
} else {
error!("{}", body.unwrap());
Msg::FetchError
}
});
@ -97,9 +95,6 @@ impl Component for LoginComponent {
Msg::FetchReady(response) => {
self.fetching = false;
info!("Login successful: {}", response);
cookie::get("thesis")
.map(|cookie| info!("Cookie: {}", cookie))
.map_err(|e| error!("{}", e));
}
Msg::FetchError => {
@ -121,16 +116,16 @@ impl Component for LoginComponent {
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>
<h1 class="uk-card-title">{ "Kirjaudu sisään" }</h1>
<div>
<fieldset class="uk-fieldset">
<input class="uk-input uk-margin",
placeholder="Username",
placeholder="Käyttäjänimi",
disabled=self.fetching,
value=&self.username,
oninput=oninput_username, />
<input class="uk-input uk-margin-bottom",
placeholder="Password",
placeholder="Salasana",
disabled=self.fetching,
type="password",
value=&self.password,
@ -140,7 +135,7 @@ impl Component for LoginComponent {
type="button",
disabled=self.fetching,
onclick=onclick>
{ "Log in" }
{ "Kirjaudu" }
</button>
</fieldset>
</div>

View file

@ -1 +1,2 @@
pub mod login;
pub mod protected;

View file

@ -0,0 +1,104 @@
use log::{error, info};
use yew::format::Nothing;
use yew::prelude::*;
use yew::services::fetch::{FetchService, FetchTask, Request, Response};
pub struct ProtectedComponent {
component_link: ComponentLink<ProtectedComponent>,
fetch_service: FetchService,
fetch_task: Option<FetchTask>,
fetching: bool,
data: String,
}
pub enum Msg {
FetchData(),
FetchReady(String),
FetchError,
}
impl ProtectedComponent {
fn get_data(&mut self) {
self.fetching = true;
let request = Request::get("http://localhost:3880/api/protected")
.body(Nothing)
.unwrap();
info!("Request: {:?}", request);
let callback =
self.component_link
.callback(|response: Response<Result<String, anyhow::Error>>| {
let (meta, body) = response.into_parts();
info!("{}", meta.status);
if meta.status.is_success() {
Msg::FetchReady(body.unwrap())
} else {
Msg::FetchError
}
});
let task = self.fetch_service.fetch(request, callback);
self.fetch_task = Some(task.unwrap());
}
}
impl Component for ProtectedComponent {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
Self {
component_link: link,
fetch_service: FetchService::new(),
fetch_task: None,
fetching: false,
data: String::from(""),
}
}
fn change(&mut self, _: Self::Properties) -> ShouldRender {
true
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::FetchReady(response) => {
self.fetching = false;
info!("Fetch successful: {}", response);
self.data = response;
}
Msg::FetchError => {
self.fetching = false;
error!("There was an error connecting to API");
self.data = String::from("401 Unauthorized");
}
Msg::FetchData() => {
self.fetching = true;
self.get_data();
}
}
true
}
fn view(&self) -> Html {
let onclick = self.component_link.callback(|_| Msg::FetchData());
html! {
<div class="uk-card uk-card-default uk-card-body uk-width-1-3@s uk-position-center">
<h1 class="uk-card-title">{ "Suojattu data" }</h1>
<p>{&self.data}</p>
<button
class="uk-button uk-button-primary",
type="button",
disabled=self.fetching,
onclick=onclick>
{ "Hae data" }
</button>
</div>
}
}
}

View file

@ -6,7 +6,7 @@ extern crate web_logger;
mod component;
pub mod utils;
use component::login::LoginComponent;
use component::{login::LoginComponent, protected::ProtectedComponent};
use yew::prelude::*;
use yew::virtual_dom::VNode;
use yew_router::{prelude::*, switch::Permissive, Switch};
@ -37,6 +37,10 @@ impl Component for App {
fn view(&self) -> VNode {
html! {
<div>
<nav class="menu",>
<RouterButton<AppRoute> route=AppRoute::Login> {"Kirjautuminen"} </RouterButton<AppRoute>>
<RouterButton<AppRoute> route=AppRoute::Root> {"Suojattu data"} </RouterButton<AppRoute>>
</nav>
<Router<AppRoute>
render = Router::render(|switch: AppRoute| {
match switch {
@ -44,7 +48,7 @@ impl Component for App {
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!"}
html!{<ProtectedComponent />}
},
}
})