diff --git a/src/components/layout.rs b/src/components/layout.rs index 868696f..ece5323 100644 --- a/src/components/layout.rs +++ b/src/components/layout.rs @@ -24,15 +24,9 @@ pub fn Layout<'a, G: Html>( div (class = "container mx-auto px-6 py-3") { nav (class = "sm:flex sm:justify-center sm:items-center mt-4 hidden") { div (class = "flex flex-col sm:flex-row"){ - a(href = "add-game-form", + a(href = "inventory", class = "mt-3 text-gray-600 hover:underline sm:mx-3 sm:mt-0" - ) { "Add game result" } - a(href = "one-v-one-board", - class = "mt-3 text-gray-600 hover:underline sm:mx-3 sm:mt-0" - ) { "1v1 Leaderboard" } - a(href = "overall-board", - class = "mt-3 text-gray-600 hover:underline sm:mx-3 sm:mt-0" - ) { "Overall Leaderboard" } + ) { "Inventory" } } } } diff --git a/src/config/color.rs b/src/config/color.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..2c53cf0 --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1 @@ +pub mod color; diff --git a/src/data/mod.rs b/src/data/mod.rs index 68c233a..95ef5e7 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,4 +1,3 @@ -pub mod pool_match; pub mod user; #[cfg(engine)] diff --git a/src/data/pool_match.rs b/src/data/pool_match.rs deleted file mode 100644 index 3ee5b55..0000000 --- a/src/data/pool_match.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::data::user::PlayerId; -use chrono::serde::ts_seconds; -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; - -pub type MatchId = u32; - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub enum MatchType { - Standard8Ball, - Standard9Ball, - CutThroat, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct MatchData { - pub type_: MatchType, - pub winners: Vec, - pub losers: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct PoolMatch { - pub id: MatchId, - pub data: MatchData, - #[serde(with = "ts_seconds")] - pub time: DateTime, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct PoolMatchList { - pub pool_matches: Vec, - pub max_id: MatchId, -} - -impl PoolMatch { - pub fn new(data: MatchData, time: DateTime) -> PoolMatch { - PoolMatch { id: 0, data, time } - } -} - -impl PoolMatchList { - pub fn new() -> PoolMatchList { - PoolMatchList { - pool_matches: vec![], - max_id: 0, - } - } - - pub fn add_pool_match(&mut self, mut pool_match: PoolMatch) { - pool_match.id = self.max_id + 1; - self.max_id += 1; - self.pool_matches.push(pool_match); - } -} diff --git a/src/data/store.rs b/src/data/store.rs index 839a49b..71000be 100644 --- a/src/data/store.rs +++ b/src/data/store.rs @@ -1,13 +1,12 @@ // (Server only) In-memory data storage and persistent storage -use crate::data::pool_match::PoolMatchList; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use std::{fs, path::Path, sync::Mutex}; #[derive(Serialize, Deserialize, Clone)] pub struct Store { - pub matches: PoolMatchList, + // pub matches: PoolMatchList, } impl Store { @@ -15,7 +14,7 @@ impl Store { fs::create_dir_all("data").unwrap(); match Path::new("data/store.json").exists() { false => Store { - matches: PoolMatchList::new(), + // matches: PoolMatchList::new(), }, true => { let contents = fs::read_to_string("data/store.json").unwrap(); diff --git a/src/data/user.rs b/src/data/user.rs index 9815690..c6a6ce3 100644 --- a/src/data/user.rs +++ b/src/data/user.rs @@ -1,3 +1 @@ - pub type PlayerId = u32; - diff --git a/src/main.rs b/src/main.rs index a5c1e32..51dca82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,9 +48,8 @@ pub fn main() -> PerseusApp { PerseusApp::new() .global_state_creator(crate::templates::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()) - .template(crate::templates::overall_board::get_template()) + .template(crate::templates::inventory::get_template()) + .template(crate::templates::preferences::get_template()) .error_views(crate::error_views::get_error_views()) .index_view(|cx| { view! { cx, diff --git a/src/server/mod.rs b/src/server/mod.rs index 9bebc39..6a664ab 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,2 +1 @@ pub mod routes; - diff --git a/src/server/routes.rs b/src/server/routes.rs index 934c557..4ede635 100644 --- a/src/server/routes.rs +++ b/src/server/routes.rs @@ -1,12 +1,6 @@ // (Server only) Routes -use crate::{ - data::{ - pool_match::{PoolMatch, PoolMatchList}, - store::DATA, - }, - endpoints::MATCH, -}; +use crate::{data::store::DATA, endpoints::MATCH}; use axum::{ extract::Json, routing::{post, Router}, @@ -14,21 +8,6 @@ use axum::{ use std::thread; pub fn register_routes(app: Router) -> Router { - let app = app.route(MATCH, post(post_match)); + // let app = app.route(MATCH, post(post_match)); app } - -async fn post_match(Json(pool_match): Json) -> Json { - // Update the store with the new match - let matches = thread::spawn(move || { - // Get the store - let mut data = DATA.lock().unwrap(); - (*data).matches.add_pool_match(pool_match); - println!("{:?}", (*data).matches.pool_matches); - (*data).matches.clone() - }) - .join() - .unwrap(); - - Json(matches) -} diff --git a/src/templates/add_game_form.rs b/src/templates/add_game_form.rs deleted file mode 100644 index 0939d14..0000000 --- a/src/templates/add_game_form.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::data::pool_match::MatchType; -use crate::{components::layout::Layout, data::pool_match::MatchData}; -use perseus::prelude::*; -use serde::{Deserialize, Serialize}; -use sycamore::prelude::*; -use web_sys::Event; - -cfg_if::cfg_if! { - if #[cfg(client)] { - use crate::data::pool_match::{PoolMatch, PoolMatchList}; - use crate::templates::global_state::AppStateRx; - use crate::endpoints::MATCH; - use crate::templates::get_api_path; - use chrono::Utc; - } -} - -// Reactive page - -#[derive(Serialize, Deserialize, Clone, ReactiveState)] -#[rx(alias = "PageStateRx")] -struct PageState { - name: String, -} - -fn add_game_form_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a PageStateRx) -> View { - let handle_add_match = move |_event: Event| { - #[cfg(client)] - { - // state.name.get().as_ref().clone() - spawn_local_scoped(cx, async move { - let new_match = PoolMatch::new( - MatchData { - type_: MatchType::Standard8Ball, - winners: vec![1], - losers: vec![2, 3, 4], - }, - Utc::now(), - ); - let client = reqwest::Client::new(); - let new_matches = client - .post(get_api_path(MATCH).as_str()) - .json(&new_match) - .send() - .await - .unwrap() - .json::() - .await - .unwrap(); - let global_state = Reactor::::from_cx(cx).get_global_state::(cx); - global_state.matches.set(new_matches); - }) - } - }; - - view! { cx, - Layout(title = "Add Game Results") { - div (class = "flex flex-wrap") { - input (bind:value = state.name, - class = "appearance-none block w-full bg-gray-200 text-gray-700 border \ - border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none \ - focus:bg-white",) - } - div (class = "flex flex-wrap") { - button(on:click = handle_add_match, - class = "flex-shrink-0 bg-teal-500 hover:bg-teal-700 border-teal-500 \ - hover:border-teal-700 text-sm border-4 text-white py-1 px-2 rounded", - ) { - "Add result" - } - } - } - } -} - -#[engine_only_fn] -async fn get_request_state( - _info: StateGeneratorInfo<()>, - _req: Request, -) -> Result> { - Ok(PageState { - name: "Ferris".to_string(), - }) -} - -#[engine_only_fn] -fn head(cx: Scope) -> View { - view! { cx, - title { "Add Game Form" } - } -} - -// Template - -pub fn get_template() -> Template { - Template::build("add-game-form") - .request_state_fn(get_request_state) - .view_with_state(add_game_form_page) - .head(head) - .build() -} diff --git a/src/templates/global_state.rs b/src/templates/global_state.rs index 4ac7502..5b52162 100644 --- a/src/templates/global_state.rs +++ b/src/templates/global_state.rs @@ -1,6 +1,5 @@ // Not a page, global state that is shared between all pages -use crate::data::pool_match::PoolMatchList; use perseus::{prelude::*, state::GlobalStateCreator}; use serde::{Deserialize, Serialize}; @@ -14,9 +13,7 @@ cfg_if::cfg_if! { #[derive(Serialize, Deserialize, ReactiveState, Clone)] #[rx(alias = "AppStateRx")] -pub struct AppState { - pub matches: PoolMatchList, -} +pub struct AppState {} pub fn get_global_state_creator() -> GlobalStateCreator { GlobalStateCreator::new() @@ -26,11 +23,7 @@ pub fn get_global_state_creator() -> GlobalStateCreator { #[engine_only_fn] fn get_state() -> AppState { - let matches = thread::spawn(move || DATA.lock().unwrap().deref().matches.clone()) - .join() - .unwrap(); - - AppState { matches } + AppState {} } #[engine_only_fn] diff --git a/src/templates/inventory.rs b/src/templates/inventory.rs new file mode 100644 index 0000000..45a2e37 --- /dev/null +++ b/src/templates/inventory.rs @@ -0,0 +1,24 @@ +use crate::components::layout::Layout; +use perseus::prelude::*; +use sycamore::prelude::*; + +fn inventory_page(cx: Scope) -> View { + view! { cx, + Layout(title = "Index") { + // Anything we put in here will be rendered inside the `
` block of the layout + p { "Hello World!" } + br {} + } + } +} + +#[engine_only_fn] +fn head(cx: Scope) -> View { + view! { cx, + title { "Inventory" } + } +} + +pub fn get_template() -> Template { + Template::build("inventory").view(inventory_page).head(head).build() +} diff --git a/src/templates/mod.rs b/src/templates/mod.rs index 8e589c5..8fbaba8 100644 --- a/src/templates/mod.rs +++ b/src/templates/mod.rs @@ -1,8 +1,7 @@ -pub mod add_game_form; pub mod global_state; pub mod index; -pub mod one_v_one_board; -pub mod overall_board; +pub mod inventory; +pub mod preferences; #[cfg(client)] use perseus::utils::get_path_prefix_client; diff --git a/src/templates/one_v_one_board.rs b/src/templates/one_v_one_board.rs deleted file mode 100644 index cccbe82..0000000 --- a/src/templates/one_v_one_board.rs +++ /dev/null @@ -1,39 +0,0 @@ -use crate::components::layout::Layout; -use perseus::prelude::*; -use serde::{Deserialize, Serialize}; -use sycamore::prelude::*; - -#[derive(Serialize, Deserialize, Clone, ReactiveState)] -#[rx(alias = "PageStateRx")] -struct PageState {} - -fn one_v_one_board_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, _state: &'a PageStateRx) -> View { - view! { cx, - Layout(title = "1v1 Leaderboard") { - p { "leaderboard" } - } - } -} - -#[engine_only_fn] -async fn get_request_state( - _info: StateGeneratorInfo<()>, - _req: Request, -) -> Result> { - Ok(PageState {}) -} - -#[engine_only_fn] -fn head(cx: Scope) -> View { - view! { cx, - title { "1v1 Leaderboard" } - } -} - -pub fn get_template() -> Template { - Template::build("one-v-one-board") - .request_state_fn(get_request_state) - .view_with_state(one_v_one_board_page) - .head(head) - .build() -} diff --git a/src/templates/overall_board.rs b/src/templates/overall_board.rs deleted file mode 100644 index 5bc0f26..0000000 --- a/src/templates/overall_board.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::{components::layout::Layout, templates::global_state::AppStateRx, data::user::PlayerId}; - -use perseus::prelude::*; -use serde::{Deserialize, Serialize}; -use sycamore::prelude::*; - -use crate::data::pool_match::PoolMatch; - -#[derive(Serialize, Deserialize, Clone, ReactiveState)] -#[rx(alias = "PageStateRx")] -struct PageState {} - -fn format_list_or_single(to_format: &Vec) -> String{ - match to_format.len() { - 1 => to_format[0].to_string(), - _ => format!("{:?}", to_format), - } -} - -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") { - ul { - (View::new_fragment( - global_state.matches.get() - .pool_matches - .iter() - .rev() - .map(|item: &PoolMatch| { - let game = item.clone(); - - view! { cx, - li (class = "text-blue-700", id = "ha",) { - (game.id) - (" ") - (format_list_or_single(&game.data.winners)) - (" ") - (format_list_or_single(&game.data.losers)) - } - } - }) - .collect(), - )) - } - } - } -} - -#[engine_only_fn] -async fn get_request_state( - _info: StateGeneratorInfo<()>, - _req: Request, -) -> Result> { - Ok(PageState {}) -} - -#[engine_only_fn] -fn head(cx: Scope) -> View { - view! { cx, - title { "Overall leaderboard" } - } -} - -pub fn get_template() -> Template { - Template::build("overall-board") - .request_state_fn(get_request_state) - .view_with_state(overall_board_page) - .head(head) - .build() -} diff --git a/src/templates/preferences.rs b/src/templates/preferences.rs new file mode 100644 index 0000000..83f3075 --- /dev/null +++ b/src/templates/preferences.rs @@ -0,0 +1,59 @@ +use perseus::prelude::*; +use serde::{Deserialize, Serialize}; +use crate::components::layout::Layout; +use sycamore::prelude::*; +use web_sys::Event; + +cfg_if::cfg_if! { + if #[cfg(client)] { + use crate::templates::get_api_path; + } +} + +// Reactive page + +#[derive(Serialize, Deserialize, Clone, ReactiveState)] +#[rx(alias = "PageStateRx")] +struct PageState { + name: String, +} + +fn add_preferences_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a PageStateRx) -> View { + view! { cx, + Layout(title = "Add Game Results") { + div (class = "flex flex-wrap") { + input (bind:value = state.name, + class = "appearance-none block w-full bg-gray-200 text-gray-700 border \ + border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none \ + focus:bg-white",) + } + } + } +} + +#[engine_only_fn] +async fn get_request_state( + _info: StateGeneratorInfo<()>, + _req: Request, +) -> Result> { + Ok(PageState { + name: "Ferris".to_string(), + }) +} + +#[engine_only_fn] +fn head(cx: Scope) -> View { + view! { cx, + title { "Preferences" } + } +} + +// Template + +pub fn get_template() -> Template { + Template::build("preferences") + .request_state_fn(get_request_state) + .view_with_state(add_preferences_page) + .head(head) + .build() +} diff --git a/style/tailwind.css b/style/tailwind.css index a90f074..0574349 100644 --- a/style/tailwind.css +++ b/style/tailwind.css @@ -1,4 +1,3 @@ @tailwind base; @tailwind components; -@tailwind utilities; - +@tailwind variants; diff --git a/tailwind.config.js b/tailwind.config.js index 596829f..5bbe0a7 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,13 +1,10 @@ module.exports = { - purge: { - mode: "all", - content: [ - "./src/**/*.rs", - "./index.html", - "./src/**/*.html", - "./src/**/*.css", - ], - }, + content: [ + "./src/**/*.rs", + "./index.html", + "./src/**/*.html", + "./src/**/*.css", + ], theme: {}, variants: {}, plugins: [],