lan-party-backend/web/src/state.rs

129 lines
3.4 KiB
Rust

use anyhow::{anyhow, Result};
use lan_party_core::{
event::{Event, EventSpec, EventUpdate},
user::User,
};
use reqwasm::http::Method;
use sycamore::prelude::*;
use crate::util::api_request;
#[derive(Clone, PartialEq, Default)]
pub struct Users(RcSignal<Vec<User>>);
impl Users {
pub fn get(&self) -> &RcSignal<Vec<User>> {
&self.0
}
pub async fn load(&self) -> Result<()> {
self.0.set(
api_request::<_, Vec<User>>(
Method::GET,
"/user?sort=score&order=desc",
Option::<()>::None,
)
.await
.and_then(|inner| inner.ok_or(anyhow!("missing body")))?,
);
Ok(())
}
pub async fn delete(&self, name: &str) -> Result<()> {
let users_ref = self.0.get();
let user: &User = users_ref.iter().find(|user| user.name == name).unwrap();
api_request::<_, ()>(
Method::DELETE,
&format!("/user/{}", user.name),
Option::<()>::None,
)
.await?;
let cloned = (*users_ref)
.clone()
.iter()
.cloned()
.filter(|u| u.name != user.name)
.collect();
self.0.set(cloned);
Ok(())
}
pub async fn update_score(&self, name: &str, score: i64) -> Result<()> {
let users_ref = self.0.get();
let user: &User = users_ref.iter().find(|user| &user.name == name).unwrap();
api_request::<_, ()>(
Method::POST,
&format!("/user/{}/score", user.name),
Some(score),
)
.await?;
let cloned = (*users_ref).clone();
let new_users: Vec<_> = cloned
.into_iter()
.map(|mut user| {
if &user.name == name {
user.score = score
}
user
})
.collect();
self.0.set(new_users);
Ok(())
}
pub async fn add(&self, name: &str) -> Result<()> {
let user = api_request::<&str, User>(Method::POST, "/user", Some(name)).await?;
self.0.modify().push(user.ok_or(anyhow!("missing body"))?);
Ok(())
}
}
#[derive(Clone, PartialEq, Default)]
pub struct Events(RcSignal<Vec<Event>>);
impl Events {
pub fn get(&self) -> &RcSignal<Vec<Event>> {
&self.0
}
pub async fn load(&self) -> Result<()> {
self.0.set(
api_request::<_, Vec<Event>>(Method::GET, "/event", Option::<()>::None)
.await
.and_then(|inner| inner.ok_or(anyhow!("missing body")))?,
);
Ok(())
}
pub async fn add(&self, event_spec: EventSpec) -> Result<()> {
let new_event =
api_request::<EventSpec, Event>(Method::POST, "/event", Some(event_spec)).await?;
self.0
.modify()
.push(new_event.ok_or(anyhow!("missing body"))?);
Ok(())
}
pub async fn update_event(&self, event_name: &str, event_update: EventUpdate) -> Result<()> {
api_request::<EventUpdate, ()>(
Method::POST,
&format!("/event/{}", event_name),
Some(event_update),
)
.await?;
self.load().await?;
Ok(())
}
pub async fn delete(&self, event_name: &str) -> Result<()> {
api_request::<(), ()>(Method::DELETE, &format!("/event/{}", event_name), None).await?;
self.load().await?;
Ok(())
}
}