setting up routing, cleaning up context

This commit is contained in:
Mikayla Dobson
2022-07-21 14:38:58 -05:00
parent 9959cbf4b1
commit cfae1ddfbb
12 changed files with 285 additions and 72 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>Splendor (clone by Mikayla Dobson)</title>
</head>
<body>
<div id="root"></div>

87
package-lock.json generated
View File

@@ -10,6 +10,7 @@
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0",
"uuid": "^8.3.2"
},
"devDependencies": {
@@ -378,6 +379,17 @@
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/runtime": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
"integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
@@ -1087,6 +1099,14 @@
"node": ">=4"
}
},
"node_modules/history": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
"dependencies": {
"@babel/runtime": "^7.7.6"
}
},
"node_modules/is-core-module": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
@@ -1243,6 +1263,35 @@
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz",
"integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==",
"dependencies": {
"history": "^5.2.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz",
"integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==",
"dependencies": {
"history": "^5.2.0",
"react-router": "6.3.0"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"node_modules/resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@@ -1692,6 +1741,14 @@
"@babel/helper-plugin-utils": "^7.18.6"
}
},
"@babel/runtime": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
"integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@babel/template": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
@@ -2125,6 +2182,14 @@
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true
},
"history": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
"requires": {
"@babel/runtime": "^7.7.6"
}
},
"is-core-module": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
@@ -2232,6 +2297,28 @@
"integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
"dev": true
},
"react-router": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz",
"integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==",
"requires": {
"history": "^5.2.0"
}
},
"react-router-dom": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz",
"integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==",
"requires": {
"history": "^5.2.0",
"react-router": "6.3.0"
}
},
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",

View File

@@ -11,6 +11,7 @@
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0",
"uuid": "^8.3.2"
},
"devDependencies": {

View File

@@ -1,36 +1,27 @@
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Gameboard from './components/Gameboard/Gameboard'
import './App.css'
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useContext, useEffect, useState } from 'react'
import { appState, Context } from './context/Context'
import AvailableChips from './components/Resources/AvailableChips';
import GameConstructor from './util/GameConstructor';
import { PlayerData } from './util/types';
function App() {
const [state, setState] = useState({
gameboard: null,
store: null,
players: null,
round: 0
})
useEffect(() => {
if (!state.players) {
console.log('no players!');
}
}, []);
const getGameboard = useCallback(() => {
}, [])
let AppContext = useContext(Context);
let { players } = AppContext;
return (
<div className="App">
<Gameboard />
{/*
< INVENTORY />
< PLAYERS />
*/}
<h1>SPLENDOR</h1>
<BrowserRouter>
<Routes>
<Route path="/" element={<GameConstructor />} />
<Route path="/game" element={<Gameboard />} />
</Routes>
</BrowserRouter>
</div>
)
);
}
export default App

View File

@@ -1,4 +1,5 @@
import { CardData } from '../../util/types';
import { v4 } from 'uuid';
type CardProps = {
data: CardData
@@ -14,7 +15,7 @@ export default function Card({ data }: CardProps) {
{ Object.keys(data.resourceCost).map((key, value) => {
return (
// @ts-ignore
<p>{key}: {data.resourceCost[key]}</p>
<p key={v4()}>{key}: {data.resourceCost[key]}</p>
)
}) }
</div>

View File

@@ -1,48 +1,37 @@
import { useEffect, useState } from 'react';
import { CardData, NobleData } from '../../util/types';
import { useContext, useEffect, useState } from 'react';
import { Context } from '../../context/Context';
import GameConstructor from '../../util/GameConstructor';
import { NobleData } from '../../util/types';
import AvailableChips from '../Resources/AvailableChips';
import CardRow from './CardRow';
import CardDeck from '../../data/cards.json';
import Nobles from '../../data/nobles.json';
export default function Gameboard() {
const [state, setState] = useState({
deck: CardDeck,
nobles: Nobles.nobles,
cardRows: {
tierOne: new Array<CardData>,
tierTwo: new Array<CardData>,
tierThree: new Array<CardData>
},
tradingResources: {
ruby: 7,
sapphire: 7,
emerald: 7,
diamond: 7,
onyx: 7,
gold: 5
}
})
let AppContext = useContext(Context);
let { gameboard, players } = AppContext;
const [view, setView] = useState(<p>Loading...</p>)
useEffect(() => {
initializeBoard();
console.log(state);
}, [])
useEffect(() => {
setView(
<>
<CardRow tier={3} cards={state.cardRows.tierThree} />
<CardRow tier={2} cards={state.cardRows.tierTwo} />
<CardRow tier={1} cards={state.cardRows.tierOne} />
</>
)
}, [state.cardRows]);
if (!players.length) {
setView(<GameConstructor />);
} else {
setView(
<div className="gameboard-rows">
<CardRow tier={3} cards={gameboard.cardRows.tierThree} />
<CardRow tier={2} cards={gameboard.cardRows.tierTwo} />
<CardRow tier={1} cards={gameboard.cardRows.tierOne} />
<AvailableChips />
</div>
)
}
}, [players]);
const shuffleDeck = () => {
if (!state.deck) return;
let newDeck = state.deck;
if (!gameboard.deck) return;
let newDeck = gameboard.deck;
for (const [key, value] of Object.entries(newDeck)) {
for (let i = value.length - 1; i > 0; i--) {
@@ -53,11 +42,12 @@ export default function Gameboard() {
}
}
setState({ ...state, deck: newDeck });
gameboard.deck = newDeck;
// setState({ ...gameboard, deck: newDeck });
}
const setNobles = () => {
let newNobles = state.nobles;
let newNobles = gameboard.nobles;
let shuffledNobles = new Array<NobleData>;
while (shuffledNobles.length < 4) {
@@ -66,16 +56,17 @@ export default function Gameboard() {
shuffledNobles.push(randNoble);
}
setState({ ...state, nobles: shuffledNobles });
// setState({ ...gameboard, nobles: shuffledNobles });
gameboard.nobles = shuffledNobles;
}
const initializeBoard = () => {
shuffleDeck();
setNobles();
let newState = state;
let newState = gameboard;
for (const [key, value] of Object.entries(state.deck)) {
for (const [key, value] of Object.entries(gameboard.deck)) {
// @ts-ignore
while (newState.cardRows[key].length < 4) {
const nextCard = value.shift();
@@ -84,13 +75,8 @@ export default function Gameboard() {
}
}
setState(newState);
gameboard = newState;
}
return (
<div>
<h1>SPLENDOR</h1>
{ view }
</div>
)
return view;
}

View File

@@ -0,0 +1,11 @@
import { useContext } from "react"
import { Context } from "../../context/Context"
export default function AllPlayers() {
const AppContext = useContext(Context);
return (
<>
</>
)
}

View File

@@ -0,0 +1,22 @@
import { useContext } from "react"
import { Context } from "../../context/Context"
import { v4 } from "uuid";
export default function AvailableChips() {
const { gameboard } = useContext(Context);
return (
<div className="available-chips">
{
Object.keys(gameboard.tradingResources).map((key: string) => {
return (
<div key={v4()} className={`chips-${key}`}>
{/* @ts-ignore */}
<p>{key}: {gameboard.tradingResources[key]}</p>
</div>
)
})
}
</div>
)
}

28
src/context/Context.ts Normal file
View File

@@ -0,0 +1,28 @@
import { CardData, NobleData, PlayerData } from '../util/types';
import CardDeck from '../data/cards.json';
import { createContext } from 'react';
import { AppState } from './types';
export const appState: AppState = {
gameboard: {
nobles: new Array<NobleData>,
cardRows: {
tierOne: new Array<CardData>,
tierTwo: new Array<CardData>,
tierThree: new Array<CardData>,
},
tradingResources: {
ruby: 7,
sapphire: 7,
emerald: 7,
diamond: 7,
onyx: 7,
gold: 5
},
deck: CardDeck,
},
round: 0,
players: new Array<PlayerData>,
}
export const Context = createContext(appState);

16
src/context/types.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
import { CardData, FullDeck, NobleData, PlayerData, ResourceCost } from "../util/types"
export interface AppState {
gameboard: {
nobles: Array<NobleData>,
cardRows: {
tierOne: Array<CardData>
tierTwo: Array<CardData>
tierThree: Array<CardData>
},
tradingResources: ResourceCost
deck: FullDeck,
},
round: number,
players: Array<PlayerData>
}

View File

@@ -0,0 +1,70 @@
import { useContext, useState } from "react"
import { useNavigate } from "react-router-dom"
import { Context } from "../context/Context";
import { CardData, NobleData, PlayerData } from "./types";
export default function GameConstructor() {
const AppContext = useContext(Context);
const navigate = useNavigate();
const [input, setInput] = useState({
playerOne: '',
playerTwo: '',
playerThree: '',
playerFour: '',
})
const newGame = () => {
if (!input.playerOne || !input.playerTwo) return;
if (input.playerFour && !input.playerThree) return;
const newPlayers = Object.values(input).map((name: string): PlayerData => {
return {
name: name,
starter: false,
points: 0,
nobles: new Array<NobleData>,
cards: new Array<CardData>,
inventory: {
ruby: 0,
sapphire: 0,
emerald: 0,
diamond: 0,
onyx: 0,
gold: 0
}
}
})
for (let player of newPlayers) {
if (!player.name) newPlayers.splice(newPlayers.indexOf(player));
}
AppContext.players = newPlayers;
console.log(AppContext)
navigate('/game');
}
return (
<div className="game-constructor App">
<h1>Configure a new game:</h1>
<div>
<label htmlFor="P1-NAME">Player 1 Name:</label>
<input type="text" id="P1-NAME" required onChange={(e) => setInput({ ...input, playerOne: e.target.value})}></input>
<label htmlFor="P2-NAME">Player 2 Name:</label>
<input type="text" id="P2-NAME" required onChange={(e) => setInput({ ...input, playerTwo: e.target.value})}></input>
</div>
<div>
<label htmlFor="P3-NAME">Player 3 Name:</label>
<input type="text" id="P3-NAME" onChange={(e) => setInput({ ...input, playerThree: e.target.value})}></input>
<label htmlFor="P4-NAME">Player 4 Name:</label>
<input type="text" id="P4-NAME" onChange={(e) => setInput({ ...input, playerFour: e.target.value})}></input>
</div>
<button onClick={newGame}>Start Game</button>
</div>
)
}