diff --git a/src/components/game.rs b/src/components/game.rs index 1451b12..33b4adf 100644 --- a/src/components/game.rs +++ b/src/components/game.rs @@ -1,16 +1,28 @@ +use leptos::*; +use leptos::prelude::*; +use leptos::callback::Callback; +use super::board::SavedBoard; +use super::opponent::Opponent; use serde::{Serialize, Deserialize}; -use crate::components::board::SavedBoard; -use crate::components::opponent::Opponent; +use std::time::Duration; +use super::utils::load_saved_boards; + +#[derive(Clone, Serialize, Deserialize, PartialEq)] +pub enum GamePhase { + SelectingBoards, + ShowingResults, +} #[derive(Clone, Serialize, Deserialize)] pub struct GameState { - pub player1: String, // Current player's name - pub player2: Option, // Selected opponent + pub player1: String, + pub player2: Option, pub current_round: usize, pub player1_score: i32, pub player2_score: i32, pub player1_board: Option, pub player2_board: Option, + pub phase: GamePhase, // Add this } impl GameState { @@ -23,6 +35,103 @@ impl GameState { player2_score: 0, player1_board: None, player2_board: None, + phase: GamePhase::SelectingBoards, // Add this } } +} + +#[component] +pub fn Game( + #[prop(into)] player_name: String, + #[prop(into)] opponent: Opponent, + #[prop(into)] on_exit: Callback<()>, +) -> impl IntoView { + let game_state = RwSignal::new(GameState::new(player_name, opponent)); + let boards = Memo::new(|_| load_saved_boards().unwrap_or_default()); + let (timer, set_timer) = signal(5); + + // Update timer every second + if timer.get() > 0 { + set_interval( + move || { + set_timer.update(|t| *t = (*t - 1).max(0)); + }, + Duration::from_secs(1), + ); + } + view! { +
+
+
+

+ "Round " {move || game_state.get().current_round} " of 8" +

+ +
+
+
+ {move || game_state.get().player1} + ": " + + {move || game_state.get().player1_score} + +
+
+ {move || game_state.get().player2.as_ref().map(|p| p.name.clone()).unwrap_or_default()} + ": " + + {move || game_state.get().player2_score} + +
+
+ {move || match game_state.get().phase { + GamePhase::SelectingBoards => view! { +
+
+

+ "Select your board" +

+
+ {move || format!("{} seconds left!", timer.get())} +
+
+
+ + Board option + + } + } + /> +
+
+ }.into_any(), + GamePhase::ShowingResults => view! { +
"Results will go here"
+ }.into_any(), + }} +
+
+ } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5e5467b..c696bd9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ use leptos::*; use leptos::prelude::*; -use leptos::logging::log; use web_sys::{MouseEvent, Storage, window}; use serde::{Serialize, Deserialize}; mod components; use components::board::BoardCreator; +use components::game::Game; use components::saved_boards::SavedBoards; use components::opponent::{ delete_opponent, Opponent, OpponentType, load_opponents, save_opponent @@ -44,6 +44,7 @@ fn App() -> impl IntoView { let (name, set_name) = signal(String::new()); let (greeting, set_greeting) = signal(String::new()); let (show_form, set_show_form) = signal(true); + let (show_game, set_show_game) = signal(None::); let (show_board_creator, set_show_board_creator) = signal(false); let opponent_to_delete = RwSignal::new(None::); let opponents_trigger = RwSignal::new(false); @@ -139,7 +140,8 @@ fn App() -> impl IntoView {