From 3d52cd0a246e8325c7791809e27c3195f7e7f05b Mon Sep 17 00:00:00 2001 From: matkam7 Date: Wed, 20 Sep 2023 21:32:19 -0400 Subject: [PATCH] Add API --- Cargo.toml | 10 +++++-- README.md | 4 +-- src/data/mod.rs | 3 +- src/data/store.rs | 2 -- src/main.rs | 51 +++++++++++++++++++++++++++++++++- src/templates/add_game_form.rs | 34 ++++++++++++++++++++--- src/templates/mod.rs | 17 ++++++++++++ src/templates/overall_board.rs | 23 +++++---------- 8 files changed, 116 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 50d469a..08bf1cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,18 +6,24 @@ edition = "2021" [dependencies] perseus = { version = "0.4.2", features = [ "hydrate" ] } -sycamore = "0.8.2" +sycamore = {version = "0.8.2", features = ["suspense", "web", "wasm-bindgen-interning",]} serde = { version = "1", features = ["derive"] } serde_json = "1" env_logger = "0.10.0" log = "0.4.20" once_cell = "1.18.0" +web-sys = "0.3.64" + [target.'cfg(engine)'.dev-dependencies] fantoccini = "0.19" [target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } -perseus-axum = { version = "0.4.2", features = [ "dflt-server" ] } +perseus-axum = { version = "0.4.2" } +axum = "0.6" +tower-http = { version = "0.3", features = [ "fs" ] } [target.'cfg(client)'.dependencies] +wasm-bindgen = "0.2" +reqwest = "0.11" diff --git a/README.md b/README.md index 4db8f72..4266666 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ https://nodejs.org/en ## 3. Install Perseus, for real-time updates while developing `cargo install perseus-cli` -`cargo build --target wasm32-unknown-unknown` +`rustup target add wasm32-unknown-unknown` ## 4. Install tailwindcss, for styling @@ -43,7 +43,7 @@ To build CSS run: `npm run build` To build the project for testing, run -`perseus serve` +`perseus serve --verbose` # Deploying the project diff --git a/src/data/mod.rs b/src/data/mod.rs index 733a262..e7ca638 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,2 +1,3 @@ pub mod pool_match; -pub mod store; \ No newline at end of file +pub mod store; +pub mod global_state; diff --git a/src/data/store.rs b/src/data/store.rs index a3c3889..f1016b9 100644 --- a/src/data/store.rs +++ b/src/data/store.rs @@ -1,5 +1,3 @@ -#![cfg(engine)] - use std::collections::HashMap; use once_cell::sync::Lazy; use std::sync::Mutex; diff --git a/src/main.rs b/src/main.rs index e7e5f1f..116d524 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,11 +6,60 @@ mod error_views; use perseus::prelude::*; use sycamore::prelude::view; -#[perseus::main(perseus_axum::dflt_server)] +#[cfg(engine)] +use axum::{ + body::Body, + extract::{Path, Query}, + http::{Request, StatusCode}, + response::{IntoResponse, Response}, + routing::{get, get_service}, + Router, +}; +#[cfg(engine)] +use perseus::turbine::ApiResponse as PerseusApiResponse; +#[cfg(engine)] +use perseus::{ + i18n::TranslationsManager, + path::*, + server::ServerOptions, + stores::MutableStore, + turbine::{SubsequentLoadQueryParams, Turbine}, +}; +#[cfg(engine)] +use tower_http::services::{ServeDir, ServeFile}; + + + +async fn print_something() { + println!("haha"); +} + +#[cfg(engine)] +pub async fn dflt_server( + turbine: &'static Turbine, + opts: ServerOptions, + (host, port): (String, u16), +) { + use std::net::SocketAddr; + + let addr: SocketAddr = format!("{}:{}", host, port) + .parse() + .expect("Invalid address provided to bind to."); + let mut app = perseus_axum::get_router(turbine, opts).await; + app = app.route("/api/test", get(print_something)); + + axum::Server::bind(&addr) + .serve(app.into_make_service()) + .await + .unwrap(); +} + +#[perseus::main(dflt_server)] pub fn main() -> PerseusApp { env_logger::init(); PerseusApp::new() + .global_state_creator(crate::data::global_state::get_global_state_creator()) .template(crate::templates::index::get_template()) .template(crate::templates::add_game_form::get_template()) .template(crate::templates::one_v_one_board::get_template()) diff --git a/src/templates/add_game_form.rs b/src/templates/add_game_form.rs index 3fb2d8e..017e798 100644 --- a/src/templates/add_game_form.rs +++ b/src/templates/add_game_form.rs @@ -1,21 +1,48 @@ +use std::ops::Deref; use crate::components::layout::Layout; use perseus::prelude::*; use serde::{Deserialize, Serialize}; use sycamore::prelude::*; +use crate::data::global_state::AppStateRx; +use web_sys::{window, Event}; +use crate::data::pool_match::PoolMatch; +#[cfg(client)] +use perseus::utils::get_path_prefix_client; +use crate::templates::get_api_path; + // Reactive page #[derive(Serialize, Deserialize, Clone, ReactiveState)] #[rx(alias = "PageStateRx")] -struct PageState { +struct PageState {} + -} fn add_game_form_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a PageStateRx) -> View { + let global_state = Reactor::::from_cx(cx).get_global_state::(cx); + let api_path = get_api_path("/api/test"); + + let handle_add_match = move |event: Event| { + #[cfg(client)] + { + let path = get_api_path("/api/test"); + println!("{}", path); + spawn_local_scoped(cx, async move { + reqwest::get(get_api_path("/api/test").as_str()).await.unwrap(); + }) + } + }; + view! { cx, Layout(title = "Add Game Results") { // Anything we put in here will be rendered inside the `
` block of the layout - p { "Results" } + button(on:click=handle_add_match) { + "Add result" + } + p { + (api_path) + } } } } @@ -35,7 +62,6 @@ fn head(cx: Scope) -> View { } } - // Template pub fn get_template() -> Template { diff --git a/src/templates/mod.rs b/src/templates/mod.rs index 697dd20..19b6c4e 100644 --- a/src/templates/mod.rs +++ b/src/templates/mod.rs @@ -2,3 +2,20 @@ pub mod index; pub mod add_game_form; pub mod one_v_one_board; pub mod overall_board; + +#[cfg(client)] +use perseus::utils::get_path_prefix_client; + +pub fn get_api_path(path: &str) -> String { + #[cfg(engine)] + { + path.to_string() + } + #[cfg(client)] + { + let path = web_sys::window().unwrap().location().pathname().unwrap(); + // let base_path = get_path_prefix_client(); + // format!("{}{}", base_path, path) + path.to_string() + } +} \ No newline at end of file diff --git a/src/templates/overall_board.rs b/src/templates/overall_board.rs index acbed55..f8024cf 100644 --- a/src/templates/overall_board.rs +++ b/src/templates/overall_board.rs @@ -6,6 +6,7 @@ use crate::data::store::DATA; #[cfg(engine)] use std::thread; use sycamore::prelude::*; +use crate::data::global_state::AppStateRx; use crate::data::pool_match::{ PoolMatchList, PoolMatch @@ -16,16 +17,19 @@ use crate::data::pool_match::{ #[derive(Serialize, Deserialize, Clone, ReactiveState)] #[rx(alias = "PageStateRx")] struct PageState { - matches: PoolMatchList, + } fn overall_board_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a PageStateRx) -> View { + let global_state = Reactor::::from_cx(cx).get_global_state::(cx); + view! { cx, Layout(title = "Overall Leaderboard") { // Anything we put in here will be rendered inside the `
` block of the layout ul { (View::new_fragment( - state.matches.get() + global_state.store.get() + .matches .pool_matches .iter() .rev() @@ -50,20 +54,7 @@ async fn get_request_state( _info: StateGeneratorInfo<()>, req: Request, ) -> Result> { - - let matches = thread::spawn(move || { - let mut db = DATA.lock().unwrap(); - db.matches.pool_matches.push(PoolMatch { - players: vec![], - winner: "lol".to_string(), - }); - db.write(); - db.matches.clone() - }).join().unwrap(); - - Ok(PageState { - matches - }) + Ok(PageState {}) } #[engine_only_fn]