Compare commits

...

3 Commits

4 changed files with 118 additions and 5 deletions

View File

@ -3,12 +3,12 @@ import { ServerEvent } from "./ServerEvent";
export type UpdateLobbyEvent = { export type UpdateLobbyEvent = {
playerNames: Array<string>; playerNames: Array<string>;
gameCode: string;
}; };
export function attachHandlerToUpdateLobbyEvent( export function attachHandlerToUpdateLobbyEvent(
socket: Socket, socket: Socket,
handler: (event: UpdateLobbyEvent) => void, handler: (event: UpdateLobbyEvent) => void,
): () => void { ): void {
socket.on(ServerEvent.LOBBY_UPDATE, handler); socket.once(ServerEvent.LOBBY_UPDATE, handler);
return () => socket.off(ServerEvent.LOBBY_UPDATE, handler);
} }

View File

@ -1,18 +1,43 @@
import React from "react"; import React, { useCallback, useState } from "react";
import { Socket } from "socket.io-client"; import { Socket } from "socket.io-client";
import LandingPage from "./pages/landing/LandingPage"; import LandingPage from "./pages/landing/LandingPage";
import GamePage from "./pages/game/GamePage"; import GamePage from "./pages/game/GamePage";
import LobbyPage from "./pages/lobby/LobbyPage";
import { attachHandlerToUpdateLobbyEvent } from "interface";
export interface AppProps { export interface AppProps {
socket: Socket; socket: Socket;
} }
const App = (props: AppProps) => { 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 ( return (
<div className="app"> <div className="app">
{renderedPage === "LANDING" && <LandingPage {...props} />} {renderedPage === "LANDING" && <LandingPage {...props} />}
{renderedPage === "LOBBY" && (
<LobbyPage
{...props}
initialPlayerNames={initialPlayerNames}
gameCode={gameCode}
/>
)}
{renderedPage === "GAME" && <GamePage />} {renderedPage === "GAME" && <GamePage />}
</div> </div>
); );

View File

@ -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;
}
}
}

View File

@ -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 (
<div className="lobby-page">
<div className="landing-page-title">
<h1>Trains And Roads</h1>
</div>
<div className="lobby-page-body">
{playerNames.map((name) => (
<article className="lobby-user-name">{name}</article>
))}
<div className="start-game-button">
<button>Start Game</button>
</div>
<article className="game-code">Game code: {gameCode}</article>
</div>
</div>
);
};
export default LobbyPage;