lan-party-backend/web/src/pages/users.rs

150 lines
5.1 KiB
Rust

use crate::components::{Button, Table};
use lan_party_core::user::User;
use log::debug;
use reqwasm::http::Method;
use sycamore::{futures::spawn_local_scoped, prelude::*};
use web_sys::Event;
use crate::util::api_request;
#[component]
pub fn UsersPage<'a, G: Html>(cx: Scope<'a>) -> View<G> {
let users = create_signal(cx, Vec::<User>::new());
let headers = vec!["Username".into(), "Score".into(), "".into()];
let score_edit = create_signal(cx, Option::<String>::None);
let new_score = create_signal(cx, String::new());
let new_username = create_signal(cx, String::new());
spawn_local_scoped(cx, async move {
users.set(
api_request::<_, Vec<User>>(Method::GET, "/user", Option::<()>::None)
.await
.map(|inner| inner.unwrap())
.unwrap(),
);
});
let ondelete = move |name: String| {
move |event: Event| {
let name = name.clone();
spawn_local_scoped(cx, async move {
debug!("Delete {:#?}", event);
let users_ref = users.get();
let user: &User = users_ref.iter().find(|user| user.name == name).unwrap();
api_request::<_, ()>(
Method::DELETE,
&format!("/user/{}", user.name),
Option::<()>::None,
)
.await
.unwrap();
let cloned = (*users_ref)
.clone()
.iter()
.cloned()
.filter(|u| u.name != user.name)
.collect();
users.set(cloned);
});
}
};
let oncheck = move |_| {
spawn_local_scoped(cx, async move {
if let (Some(score_edit), Ok(score)) =
(score_edit.get().as_ref(), new_score.get().parse())
{
let score: i64 = score;
let users_ref = users.get();
let user: &User = users_ref
.iter()
.find(|user| &user.name == score_edit)
.unwrap();
api_request::<_, ()>(
Method::POST,
&format!("/user/{}/score", user.name),
Some(score),
)
.await
.unwrap();
let cloned = (*users_ref).clone();
let new_users: Vec<_> = cloned
.into_iter()
.map(|mut user| {
if &user.name == score_edit {
user.score = score
}
user
})
.collect();
users.set(new_users);
}
score_edit.set(None);
})
};
let onadd = move |_| {
spawn_local_scoped(cx, async move {
let user = api_request::<String, User>(
Method::POST,
"/user",
Some((*new_username).get().as_ref().clone()),
)
.await
.unwrap();
users.modify().push(user.unwrap());
});
};
view! { cx,
Table(headers=headers) {
Keyed(
iterable=users,
view=move |cx, user| {
let user = create_ref(cx, user);
view! { cx,
tr {
td { (user.name) }
td {
(if Some(&user.name) == (*score_edit.get()).as_ref() { view! { cx,
span(class="user-score") {
input(bind:value=new_score)
}
Button(icon="mdi-check".into(), onclick=oncheck)
}} else { view! { cx,
span(class="user-score") {
(user.score)
}
Button(
icon="mdi-pencil".into(),
onclick=move |_| {
score_edit.set(Some(user.name.clone()));
new_score.set(user.score.to_string());
}
)
}})
}
td {
Button(icon="mdi-delete".into(),onclick=ondelete(user.name.clone()))
}
}
}
},
key=|user| (user.name.clone(), user.score.clone()),
)
tr {
td {
span {
input(bind:value=new_username)
}
}
td {}
td {
Button(icon="mdi-plus".into(),onclick=onadd)
}
}
}
}
}