110 lines
4.9 KiB
Rust
110 lines
4.9 KiB
Rust
use crate::{
|
|
bind, bind_change, bind_value, clone, clone_cb, clone_cb_spawn,
|
|
components::{Binding, Button, Loading, Page, Table, TextInput},
|
|
init,
|
|
util::api_request,
|
|
};
|
|
use lan_party_core::user::User;
|
|
use wasm_bindgen_futures::spawn_local;
|
|
use yew::prelude::*;
|
|
use yew_hooks::*;
|
|
|
|
#[function_component(UsersPage)]
|
|
pub fn users_page() -> Html {
|
|
let headers = vec!["Username".into(), "Score".into(), "".into()];
|
|
|
|
let new_username = use_state(|| String::new());
|
|
let score_edit: UseStateHandle<Option<usize>> = use_state(|| Option::None);
|
|
let current_score = use_state(|| String::new());
|
|
let users = use_state(|| Vec::new());
|
|
|
|
init!(users => {
|
|
users.set(api_request::<_, Vec<User>>(reqwasm::http::Method::GET, "/user", Option::<()>::None)
|
|
.await
|
|
.map(|inner| inner.unwrap())
|
|
.unwrap());
|
|
});
|
|
|
|
let oncheck = clone_cb_spawn!(score_edit, current_score, users => {
|
|
if let (Some(score_edit), Ok(score)) = (*score_edit, current_score.parse()) {
|
|
let user: &User = &users[score_edit];
|
|
api_request::<_, ()>(reqwasm::http::Method::POST, &format!("/user/{}/score", user.name), Some(score))
|
|
.await
|
|
.unwrap();
|
|
let mut cloned = (*users).clone();
|
|
cloned[score_edit].score = score;
|
|
users.set(cloned);
|
|
}
|
|
score_edit.set(None);
|
|
});
|
|
|
|
let onedit = clone_cb!(current_score, score_edit, users => i => move |_| {
|
|
let user: &User = &users[i];
|
|
current_score.set(user.score.to_string());
|
|
score_edit.set(Some(i));
|
|
});
|
|
|
|
let ondelete = clone_cb_spawn!(users => i => {
|
|
let user: &User = &users[i];
|
|
api_request::<_, ()>(reqwasm::http::Method::DELETE, &format!("/user/{}", user.name), Option::<()>::None).await.unwrap();
|
|
let cloned = users.iter().cloned().filter(|u| u.name != user.name).collect();
|
|
users.set(cloned);
|
|
});
|
|
|
|
let onadd = clone_cb_spawn!(new_username, users => {
|
|
let user = api_request::<String, User>(reqwasm::http::Method::POST, "/user", Some((*new_username).clone())).await.unwrap();
|
|
let mut cloned = (*users).clone();
|
|
cloned.push(user.unwrap());
|
|
users.set(cloned);
|
|
});
|
|
|
|
html! {
|
|
<Page>
|
|
<Table headers={headers.clone()} loading=false rows={vec![]}>
|
|
{users.iter().enumerate().map(move |(i, user)| html! {
|
|
<tr>
|
|
<td class="whitespace-nowrap px-3 py-4 text-sm text-slate-400">{&user.name}</td>
|
|
<td class="whitespace-nowrap px-3 text-sm text-slate-400">
|
|
{if Some(i) == *score_edit.clone() { html! {
|
|
<>
|
|
<span class="inline-block">
|
|
<TextInput
|
|
class={"mx-2 appearance-none block bg-gray-700 text-slate-400 border border-gray-600 rounded py-2 px-2 w-20 leading-tight focus:outline-none focus:ring-1 focus:ring-gray-500 focus:border-gray-500"}
|
|
bind={bind!(current_score)}
|
|
/>
|
|
</span>
|
|
<Button icon={"mdi-check"} onclick={oncheck.clone()} />
|
|
</>
|
|
}} else { html! {
|
|
<>
|
|
<span class="my-3 w-20">
|
|
{user.score}
|
|
</span>
|
|
<Button icon={"mdi-pencil"} onclick={onedit.clone()(i)} />
|
|
</>
|
|
}}}
|
|
</td>
|
|
<td class="whitespace-nowrap py-4 text-sm text-slate-400">
|
|
<Button icon={"mdi-delete"} onclick={ondelete.clone()(i)} />
|
|
</td>
|
|
</tr>
|
|
}).collect::<Html>()}
|
|
<tr>
|
|
<td class="whitespace-nowrap px-3 text-sm text-slate-400">
|
|
<span class="inline-block">
|
|
<TextInput
|
|
class={"mx-2 appearance-none block bg-gray-700 text-slate-400 border border-gray-600 rounded py-2 px-2 w-50 leading-tight focus:outline-none focus:ring-1 focus:ring-gray-500 focus:border-gray-500"}
|
|
bind={bind!(new_username)}
|
|
/>
|
|
</span>
|
|
</td>
|
|
<td class="whitespace-nowrap px-3 py-4 text-sm text-slate-400"></td>
|
|
<td class="whitespace-nowrap py-4 text-sm text-slate-400">
|
|
<Button icon={"mdi-plus"} onclick={onadd} />
|
|
</td>
|
|
</tr>
|
|
</Table>
|
|
</Page>
|
|
}
|
|
}
|