Login and Showing of all Users implemented
At /login and /users
This commit is contained in:
@@ -156,8 +156,8 @@ pub fn submit_ticket_component() -> Html {
|
||||
}
|
||||
}
|
||||
|
||||
#[component(ShowTicketByID)]
|
||||
pub fn show_ticket_by_id_component(props: &TicketProps) -> Html {
|
||||
#[component(TicketByID)]
|
||||
pub fn ticket_by_id_component(props: &TicketProps) -> Html {
|
||||
let ticket = use_state(|| None::<Ticket>);
|
||||
let error = use_state(|| None::<String>);
|
||||
let loading = use_state(|| false);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use gloo_net::http::Request;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use web_sys::js_sys::Atomics::load;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -37,6 +38,11 @@ pub struct FilteredUser {
|
||||
pub is_admin: bool,
|
||||
}
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct UserProps {
|
||||
id: i16,
|
||||
}
|
||||
|
||||
#[component(Register)]
|
||||
pub fn register_component() -> Html {
|
||||
let first_name = use_state(|| "".to_string());
|
||||
@@ -146,3 +152,138 @@ pub fn register_component() -> Html {
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
#[component(Login)]
|
||||
pub fn login_component() -> Html {
|
||||
let username = use_state(|| "".to_string());
|
||||
let pwd = use_state(|| "".to_string());
|
||||
let loading = use_state(|| false);
|
||||
let error = use_state(|| String::new());
|
||||
let success = use_state(|| false);
|
||||
|
||||
let onsubmit = {
|
||||
let username = username.clone();
|
||||
let pwd = pwd.clone();
|
||||
let loading = loading.clone();
|
||||
let error = error.clone();
|
||||
let success = success.clone();
|
||||
|
||||
Callback::from(move |e: SubmitEvent| {
|
||||
e.prevent_default();
|
||||
let username = (*username).clone();
|
||||
let pwd = (*pwd).clone();
|
||||
let loading = loading.clone();
|
||||
let error = error.clone();
|
||||
let success = success.clone();
|
||||
|
||||
loading.set(true);
|
||||
error.set(String::new());
|
||||
success.set(false);
|
||||
|
||||
spawn_local(async move {
|
||||
let payload = LoginScheme { username, pwd };
|
||||
|
||||
let response = Request::post("/api/login")
|
||||
.header("Content-Type", "application/json")
|
||||
.credentials(web_sys::RequestCredentials::Include)
|
||||
.json(&payload)
|
||||
.unwrap()
|
||||
.send()
|
||||
.await;
|
||||
|
||||
loading.set(false);
|
||||
|
||||
match response {
|
||||
Ok(r) if r.status() == 200 => success.set(true),
|
||||
Ok(r) => {
|
||||
let text = r.text().await.unwrap_or_else(|_| "unknown".into());
|
||||
error.set(format!("HTTP {}: {}", r.status(), text));
|
||||
}
|
||||
Err(err) => error.set(format!("Network error: {}", err)),
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
html! {
|
||||
<form {onsubmit}>
|
||||
<input
|
||||
placeholder="username"
|
||||
value={(*username).clone()}
|
||||
oninput={Callback::from(move |e: InputEvent| {
|
||||
let input: web_sys::HtmlInputElement = e.target_unchecked_into();
|
||||
username.set(input.value());
|
||||
})}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="password"
|
||||
value={(*pwd).clone()}
|
||||
oninput={Callback::from(move |e: InputEvent| {
|
||||
let input: web_sys::HtmlInputElement = e.target_unchecked_into();
|
||||
pwd.set(input.value());
|
||||
})}
|
||||
/>
|
||||
<button type="submit" disabled={*loading}>{ if *loading { "Logging in..." } else { "Login" } }</button>
|
||||
if *success { <p>{"Logged in — cookie set by server"}</p> }
|
||||
if !error.is_empty() { <p style="color:red">{(*error).clone()}</p> }
|
||||
</form>
|
||||
}
|
||||
}
|
||||
|
||||
#[component(AllUsers)]
|
||||
pub fn all_users_component() -> Html {
|
||||
let users = use_state(|| Vec::<FilteredUser>::new());
|
||||
let error = use_state(|| None::<String>);
|
||||
let loading = use_state(|| false);
|
||||
|
||||
{
|
||||
let users = users.clone();
|
||||
let error = error.clone();
|
||||
let loading = loading.clone();
|
||||
|
||||
use_effect_with((), move |_| {
|
||||
loading.set(true);
|
||||
spawn_local(async move {
|
||||
let url = format!("/api/users");
|
||||
match Request::get(&url).send().await {
|
||||
Ok(response) if response.status() == 200 => {
|
||||
match response.json::<Vec<FilteredUser>>().await {
|
||||
Ok(u) => users.set(u),
|
||||
Err(err) => error.set(Some(format!("Parse error: {}", err))),
|
||||
}
|
||||
}
|
||||
Ok(response) => {
|
||||
if let Ok(text) = response.text().await {
|
||||
error.set(Some(text));
|
||||
} else {
|
||||
error.set(Some(format!("status {}", response.status())));
|
||||
}
|
||||
}
|
||||
Err(err) => error.set(Some(format!("Network error: {}", err))),
|
||||
}
|
||||
loading.set(false);
|
||||
});
|
||||
|| ()
|
||||
});
|
||||
}
|
||||
|
||||
if *loading {
|
||||
html! {<p>{ "Loading" }</p>}
|
||||
} else if let Some(e) = &*error {
|
||||
html! { <p>{ format!("Error: {}", e) }</p> }
|
||||
} else {
|
||||
html! {
|
||||
<ul>
|
||||
{ for users.iter().map(|t| html! {
|
||||
<li key={t.id.to_string()}>
|
||||
<h3>{ format!("{} {}- #{}", t.first_name, t.last_name, t.id) }</h3>
|
||||
</li>
|
||||
})}
|
||||
</ul>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#[component(UserByID)]
|
||||
//pub fn user_by_id_component()
|
||||
|
||||
Reference in New Issue
Block a user