150 lines
5.1 KiB
Rust
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)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|