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

108 lines
3.8 KiB
Rust

use crate::components::{Button, Page, Table, TextInput};
use lan_party_core::user::User;
use wasm_bindgen_futures::spawn_local;
use yew::prelude::*;
#[derive(Debug, Default)]
pub struct UsersPage {
headers: Vec<String>,
users: Vec<User>,
score_edit: Option<usize>,
current_score: String,
}
pub enum Msg {
UpdateList(Vec<User>),
UpdateScoreInput(String),
UpdateScore(usize),
EditScore(usize),
DeleteUser(usize),
}
impl Component for UsersPage {
type Message = Msg;
type Properties = ();
fn create(ctx: &Context<Self>) -> Self {
Self {
headers: vec!["Username".into(), "Score".into(), "".into()],
..Default::default()
}
}
fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
let link = ctx.link().clone();
if first_render {
spawn_local(async move {
let res: Result<Vec<User>, _> =
crate::util::api_request("GET", "/user", Option::<()>::None).await;
link.send_message(Msg::UpdateList(res.unwrap()))
});
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::UpdateList(list) => {
self.users = list;
true
}
Msg::UpdateScoreInput(value) => {
self.current_score = value;
true
}
Msg::EditScore(i) => {
self.current_score = self.users[i].score.to_string();
self.score_edit = Some(i);
true
}
Msg::UpdateScore(i) => {
self.score_edit = None;
true
}
Msg::DeleteUser(i) => true,
_ => todo!(),
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let link = ctx.link().clone();
html! {
<Page>
<Table headers={self.headers.clone()} loading=false rows={vec![]}>
{self.users.iter().enumerate().map(|(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) == self.score_edit { html! {
<>
<span class="inline-block">
<TextInput
on_change={link.callback(Msg::UpdateScoreInput)}
value={self.current_score.clone()}
/>
</span>
<Button icon={"mdi-check"} onclick={link.callback(move |_| Msg::UpdateScore(i))} />
</>
}} else { html! {
<>
<span class="my-3 w-20">
{user.score}
</span>
<Button icon={"mdi-pencil"} onclick={link.callback(move |_| Msg::EditScore(i))} />
</>
}}}
</td>
<td class="whitespace-nowrap py-4 text-sm text-slate-400">
<Button icon={"mdi-delete"} onclick={link.callback(move |_| Msg::DeleteUser(i))} />
</td>
</tr>
}).collect::<Html>()}
</Table>
</Page>
}
}
}