From f382ec567e1292cedee7c01e721ddc38bdc4dc4e Mon Sep 17 00:00:00 2001 From: "SOGYO\\bvdoord" Date: Tue, 26 Jan 2021 11:22:58 +0100 Subject: Front-end met Snowpack toegevoegd --- client/src/About/About.tsx | 12 +++++++ client/src/App.css | 9 +++++ client/src/App.tsx | 29 +++++++++++++++ client/src/Header/Header.css | 30 ++++++++++++++++ client/src/Header/Header.tsx | 20 +++++++++++ client/src/Header/logo.jpg | Bin 0 -> 5184 bytes client/src/Mancala/Mancala.css | 1 + client/src/Mancala/Mancala.tsx | 24 +++++++++++++ client/src/Mancala/Play.css | 1 + client/src/Mancala/Play.tsx | 17 +++++++++ client/src/Mancala/StartGame.css | 10 ++++++ client/src/Mancala/StartGame.tsx | 74 +++++++++++++++++++++++++++++++++++++++ client/src/gameState.ts | 19 ++++++++++ client/src/index.tsx | 15 ++++++++ 14 files changed, 261 insertions(+) create mode 100644 client/src/About/About.tsx create mode 100644 client/src/App.css create mode 100644 client/src/App.tsx create mode 100644 client/src/Header/Header.css create mode 100644 client/src/Header/Header.tsx create mode 100644 client/src/Header/logo.jpg create mode 100644 client/src/Mancala/Mancala.css create mode 100644 client/src/Mancala/Mancala.tsx create mode 100644 client/src/Mancala/Play.css create mode 100644 client/src/Mancala/Play.tsx create mode 100644 client/src/Mancala/StartGame.css create mode 100644 client/src/Mancala/StartGame.tsx create mode 100644 client/src/gameState.ts create mode 100644 client/src/index.tsx (limited to 'client/src') diff --git a/client/src/About/About.tsx b/client/src/About/About.tsx new file mode 100644 index 0000000..e7a9c69 --- /dev/null +++ b/client/src/About/About.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +export function About() { + return
+

Mancala

+

+ Mancala is one of the oldest known board games. It has many different variations and is known under several different names. + The objective of the game is obtaining as many stones, beads or seeds as possible. + It is a game of skill that does not rely on any sort of randomness, making it similar to chess. +

+
+} \ No newline at end of file diff --git a/client/src/App.css b/client/src/App.css new file mode 100644 index 0000000..8eebe3a --- /dev/null +++ b/client/src/App.css @@ -0,0 +1,9 @@ +body { + margin: 0px; + padding: 0px; + background-color: #eeeeee; +} + +.main-content { + padding: 8px; +} \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx new file mode 100644 index 0000000..edd9504 --- /dev/null +++ b/client/src/App.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; +import { Header } from "./Header/Header"; +import { About } from "./About/About"; +import { Mancala } from "./Mancala/Mancala"; +import "./App.css"; + +export function App() { + return ( + + {/* The header with navigation options is always on top of every page */} +
+ +
+ + {/* If the user goes to the url /about, show the about page */} + + + + + {/* If the user goes to any other url, show the play page */} + + + + +
+ + ) +} \ No newline at end of file diff --git a/client/src/Header/Header.css b/client/src/Header/Header.css new file mode 100644 index 0000000..6744f32 --- /dev/null +++ b/client/src/Header/Header.css @@ -0,0 +1,30 @@ +.main-header { + background-color: white; + color: green; + font-size: 2rem; + margin-bottom: 8px; +} + +.main-navigation { + display: flex; + justify-content: space-around; + align-items: center; + background-color: green; + font-size: 1.3rem; + height: 45px; +} + +.main-navigation a { + color: white; + text-decoration: none; +} + +.main-header div { + display: flex; + align-items: center; +} + +.main-header img { + height: 50px; + margin: 6px; +} \ No newline at end of file diff --git a/client/src/Header/Header.tsx b/client/src/Header/Header.tsx new file mode 100644 index 0000000..9f96d0c --- /dev/null +++ b/client/src/Header/Header.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import "./Header.css"; +import urlLogo from "./logo.jpg"; + +/** + * A Header component with a Sogyo logo, the name of the application and several links to different pages + */ +export function Header() { + return
+
+ + Mancala +
+
+ Play + About +
+
+} \ No newline at end of file diff --git a/client/src/Header/logo.jpg b/client/src/Header/logo.jpg new file mode 100644 index 0000000..9104922 Binary files /dev/null and b/client/src/Header/logo.jpg differ diff --git a/client/src/Mancala/Mancala.css b/client/src/Mancala/Mancala.css new file mode 100644 index 0000000..8f73945 --- /dev/null +++ b/client/src/Mancala/Mancala.css @@ -0,0 +1 @@ +/** Add some styles */ \ No newline at end of file diff --git a/client/src/Mancala/Mancala.tsx b/client/src/Mancala/Mancala.tsx new file mode 100644 index 0000000..42c31a2 --- /dev/null +++ b/client/src/Mancala/Mancala.tsx @@ -0,0 +1,24 @@ +import React, { useState } from "react"; +import { StartGame } from "./StartGame"; +import { Play } from "./Play"; +import type { GameState } from "../gameState"; +import "./Mancala.css"; + +/** + * The base component for the Mancala game. If there's no active game, the `StartGame` component allows + * users to enter two player names and start a new game. + * If there's an active game this component holds the game state. This game state can be passed as a prop + * to child components as needed. + * + * Child components can modify the game state by calling the setGameState (which they recieve as prop.) + */ +export function Mancala() { + + const [ gameState, setGameState ] = useState(undefined); + + if (!gameState) { + return + } + + return +} \ No newline at end of file diff --git a/client/src/Mancala/Play.css b/client/src/Mancala/Play.css new file mode 100644 index 0000000..8f73945 --- /dev/null +++ b/client/src/Mancala/Play.css @@ -0,0 +1 @@ +/** Add some styles */ \ No newline at end of file diff --git a/client/src/Mancala/Play.tsx b/client/src/Mancala/Play.tsx new file mode 100644 index 0000000..3b8ff25 --- /dev/null +++ b/client/src/Mancala/Play.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import type { GameState } from "../gameState"; +import "./Play.css"; + +type PlayProps = { + gameState: GameState; + setGameState(newGameState: GameState): void; +} + +export function Play({ gameState, setGameState }: PlayProps) { + return ( +
+

{gameState.players[0].name} vs {gameState.players[1].name}

+ To do... +
+ ) +} \ No newline at end of file diff --git a/client/src/Mancala/StartGame.css b/client/src/Mancala/StartGame.css new file mode 100644 index 0000000..3ab5872 --- /dev/null +++ b/client/src/Mancala/StartGame.css @@ -0,0 +1,10 @@ +.startGameButton { + font-size: 2em; + background-color: lightgreen; + border: 2px solid black; +} + +.errorMessage { + height: 1em; + color: red; +} \ No newline at end of file diff --git a/client/src/Mancala/StartGame.tsx b/client/src/Mancala/StartGame.tsx new file mode 100644 index 0000000..9d5be2c --- /dev/null +++ b/client/src/Mancala/StartGame.tsx @@ -0,0 +1,74 @@ +import React, { useState } from "react"; +import type { GameState } from "../gameState"; +import "./StartGame.css"; + +type StartGameProps = { + setGameState(newGameState: GameState): void; +} + +/** + * Allows the players to enter their name. A name is required for both players. They can't have the same names. + */ +export function StartGame({ setGameState }: StartGameProps) { + + const [errorMessage, setErrorMessage] = useState(""); + const [playerOne, setPlayerOne] = useState(""); + const [playerTwo, setPlayerTwo] = useState(""); + + async function tryStartGame(e: React.FormEvent) { + e.preventDefault(); // Prevent default browser behavior of submitting forms + if (!playerOne) { + setErrorMessage("A name is required for player 1"); + return; + } + if (!playerTwo) { + setErrorMessage("A name is required for player 2"); + return; + } + if (playerOne === playerTwo) { + setErrorMessage("Each player should have a unique name"); + return; + } + setErrorMessage(""); + + try { + const response = await fetch('mancala/api/start', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ nameplayer1: playerOne, nameplayer2: playerTwo }) + }); + + if (response.ok) { + const gameState = await response.json(); + setGameState(gameState); + } else { + console.error(response.statusText); + } + } catch (error) { + console.error(error.toString()); + } + } + + return ( +
tryStartGame(e)}> + setPlayerOne(e.target.value)} + /> + + setPlayerTwo(e.target.value)} + /> + +

{errorMessage}

+ + +
+ ) +} \ No newline at end of file diff --git a/client/src/gameState.ts b/client/src/gameState.ts new file mode 100644 index 0000000..2d5ec3e --- /dev/null +++ b/client/src/gameState.ts @@ -0,0 +1,19 @@ + +export interface GameState { + players: [ Player, Player ]; // a player array contains exactly two Players + gameStatus: { + endOfGame: boolean; + }; +} + +interface Player { + name: string; + pits: Pit[]; + type: "player1" | "player2"; // only "player1" and "player2" are valid options for this string + hasTurn: boolean; +} + +interface Pit { + index: number; + nrOfStones: number; +} diff --git a/client/src/index.tsx b/client/src/index.tsx new file mode 100644 index 0000000..c92ef7e --- /dev/null +++ b/client/src/index.tsx @@ -0,0 +1,15 @@ +import * as React from "react"; +import ReactDOM from "react-dom"; +import { App } from "./App"; + +ReactDOM.render( + , + document.getElementById("root") +) + +// Hot Module Replacement (HMR) - Remove this snippet to remove HMR. +// Learn more: https://www.snowpack.dev/#hot-module-replacement +const hotMudleReplacement = import.meta.hot; +if (hotMudleReplacement) { + hotMudleReplacement.accept(); +} -- cgit v1.2.3