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 { let users = create_signal(cx, Vec::::new()); let headers = vec!["Username".into(), "Score".into(), "".into()]; let score_edit = create_signal(cx, Option::::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>(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::( 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) } } } } }