diff --git a/interface/server-events/UpdateLobbyEvent.ts b/interface/server-events/UpdateLobbyEvent.ts index 90f696a..2f0881d 100644 --- a/interface/server-events/UpdateLobbyEvent.ts +++ b/interface/server-events/UpdateLobbyEvent.ts @@ -3,12 +3,12 @@ import { ServerEvent } from "./ServerEvent"; export type UpdateLobbyEvent = { playerNames: Array; + gameCode: string; }; export function attachHandlerToUpdateLobbyEvent( socket: Socket, handler: (event: UpdateLobbyEvent) => void, -): () => void { - socket.on(ServerEvent.LOBBY_UPDATE, handler); - return () => socket.off(ServerEvent.LOBBY_UPDATE, handler); +): void { + socket.once(ServerEvent.LOBBY_UPDATE, handler); } diff --git a/web/src/App.tsx b/web/src/App.tsx index b1fc803..7b878b6 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,18 +1,43 @@ -import React from "react"; +import React, { useCallback, useState } from "react"; import { Socket } from "socket.io-client"; import LandingPage from "./pages/landing/LandingPage"; import GamePage from "./pages/game/GamePage"; +import LobbyPage from "./pages/lobby/LobbyPage"; +import { attachHandlerToUpdateLobbyEvent } from "interface"; export interface AppProps { socket: Socket; } const App = (props: AppProps) => { - const renderedPage: string = "LANDING"; + const { socket } = props; + const [renderedPage, setRenderedPage] = useState("LANDING"); + + const [initialPlayerNames, setInitialPlayerNames] = useState([""]); + const [gameCode, setGameCode] = useState(""); + + const setupNextPageTransition = useCallback(() => { + if (renderedPage === "LANDING") { + attachHandlerToUpdateLobbyEvent(socket, (event) => { + setInitialPlayerNames(event.playerNames); + setGameCode(event.gameCode); + setRenderedPage("LOBBY"); + }); + } + }, [renderedPage]); + + setupNextPageTransition(); return (
{renderedPage === "LANDING" && } + {renderedPage === "LOBBY" && ( + + )} {renderedPage === "GAME" && }
); diff --git a/web/src/pages/lobby/LobbyPage.scss b/web/src/pages/lobby/LobbyPage.scss new file mode 100644 index 0000000..5a935f7 --- /dev/null +++ b/web/src/pages/lobby/LobbyPage.scss @@ -0,0 +1,50 @@ +.lobby-page { + height: 100%; + width: 100%; + padding: 2%; + margin: 0 auto; + text-align: center; + + background: linear-gradient(-45deg, #03444a, #00a8a8, #f1bc52, #ff8f4b); + background-size: 400% 400%; + animation: gradient 15s ease infinite; + height: 100vh; + + @keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } + } + + .lobby-page-body { + margin: auto; + width: 20%; + min-width: 300px; + + .lobby-user-name { + margin: 0 auto 10px; + padding: 10px; + width: 60%; + border: 2px solid cyan; + border-radius: 10px; + } + + .game-code { + margin: 0 auto 10px; + padding: 10px; + width: 60%; + border: 2px solid blue; + border-radius: 10px; + } + + .start-game-button { + margin: 30px 0; + } + } +} diff --git a/web/src/pages/lobby/LobbyPage.tsx b/web/src/pages/lobby/LobbyPage.tsx new file mode 100644 index 0000000..e92f168 --- /dev/null +++ b/web/src/pages/lobby/LobbyPage.tsx @@ -0,0 +1,38 @@ +import { useState } from "react"; +import "./LobbyPage.scss"; +import { Socket } from "socket.io-client"; +import { attachHandlerToUpdateLobbyEvent } from "interface"; + +export interface LobbyPageProps { + initialPlayerNames: string[]; + gameCode: string; + socket: Socket; +} + +const LobbyPage = (props: LobbyPageProps) => { + const { initialPlayerNames, gameCode, socket } = props; + const [playerNames, setPlayerNames] = useState(initialPlayerNames); + + attachHandlerToUpdateLobbyEvent(socket, (event) => { + setPlayerNames(event.playerNames); + }); + + return ( +
+
+

Trains And Roads

+
+
+ {playerNames.map((name) => ( +
{name}
+ ))} +
+ +
+
Game code: {gameCode}
+
+
+ ); +}; + +export default LobbyPage;