Compare commits

...

4 Commits

Author SHA1 Message Date
the-all-good
6ecc1dd7e0 MOAR STILE 2024-12-15 16:39:51 +11:00
the-all-good
8f8c4fb267 The man said unto me, "dont you mean create pool?" 2024-12-12 21:20:21 +11:00
the-all-good
4c4d977401 Big things for the stock portfolio 2024-12-12 21:06:19 +11:00
the-all-good
db7f75feb4 Include Tailwind & Start Component 2024-12-11 23:11:53 +11:00
14 changed files with 273 additions and 37 deletions

View File

@ -13,8 +13,12 @@
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-router-dom": "^7.0.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
},
"devDependencies": {
"tailwindcss": "^3.4.16"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@ -3716,6 +3720,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"license": "MIT"
},
"node_modules/@types/eslint": { "node_modules/@types/eslint": {
"version": "8.56.12", "version": "8.56.12",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz",
@ -8122,9 +8132,9 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.21.1", "version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
@ -8146,7 +8156,7 @@
"methods": "~1.1.2", "methods": "~1.1.2",
"on-finished": "2.4.1", "on-finished": "2.4.1",
"parseurl": "~1.3.3", "parseurl": "~1.3.3",
"path-to-regexp": "0.1.10", "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7", "proxy-addr": "~2.0.7",
"qs": "6.13.0", "qs": "6.13.0",
"range-parser": "~1.2.1", "range-parser": "~1.2.1",
@ -8161,6 +8171,10 @@
}, },
"engines": { "engines": {
"node": ">= 0.10.0" "node": ">= 0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
} }
}, },
"node_modules/express/node_modules/debug": { "node_modules/express/node_modules/debug": {
@ -12285,9 +12299,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
"version": "0.1.10", "version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/path-type": { "node_modules/path-type": {
@ -14154,6 +14168,55 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-router": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.0.2.tgz",
"integrity": "sha512-m5AcPfTRUcjwmhBzOJGEl6Y7+Crqyju0+TgTQxoS4SO+BkWbhOrcfZNq6wSWdl2BBbJbsAoBUb8ZacOFT+/JlA==",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0",
"turbo-stream": "2.4.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/react-router-dom": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.0.2.tgz",
"integrity": "sha512-VJOQ+CDWFDGaWdrG12Nl+d7yHtLaurNgAQZVgaIy7/Xd+DojgmYLosFfZdGz1wpxmjJIAkAMVTKWcvkx1oggAw==",
"license": "MIT",
"dependencies": {
"react-router": "7.0.2"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
},
"node_modules/react-router/node_modules/cookie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/react-scripts": { "node_modules/react-scripts": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
@ -15037,6 +15100,12 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/set-cookie-parser": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
"license": "MIT"
},
"node_modules/set-function-length": { "node_modules/set-function-length": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
@ -15993,9 +16062,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "3.4.15", "version": "3.4.16",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.16.tgz",
"integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==", "integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@alloc/quick-lru": "^5.2.0", "@alloc/quick-lru": "^5.2.0",
@ -16007,7 +16076,7 @@
"glob-parent": "^6.0.2", "glob-parent": "^6.0.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
"jiti": "^1.21.6", "jiti": "^1.21.6",
"lilconfig": "^2.1.0", "lilconfig": "^3.1.3",
"micromatch": "^4.0.8", "micromatch": "^4.0.8",
"normalize-path": "^3.0.0", "normalize-path": "^3.0.0",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
@ -16029,6 +16098,18 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/tailwindcss/node_modules/lilconfig": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antonk52"
}
},
"node_modules/tapable": { "node_modules/tapable": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@ -16357,6 +16438,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/turbo-stream": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
"integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
"license": "ISC"
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View File

@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-router-dom": "^7.0.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
@ -34,5 +35,8 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"tailwindcss": "^3.4.16"
} }
} }

View File

@ -29,15 +29,5 @@
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body> </body>
</html> </html>

View File

@ -2,6 +2,10 @@
text-align: center; text-align: center;
} }
html, body, #app, #app>div {
height: 100%
}
.App-logo { .App-logo {
height: 40vmin; height: 40vmin;
pointer-events: none; pointer-events: none;

View File

@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
body { body {
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',

View File

@ -1,18 +1,19 @@
import logo from '../resources/logo.svg'; import { BrowserRouter, Routes, Route } from 'react-router-dom';
import '../css/App.css'; import '../css/App.css';
import Leaderboard from './components/leaderboard'; import GameView from './pages/gameView';
import GameCard from './components/gameCard'; import Home from './pages/home';
import Button from './components/button'; import { GameProvider } from './contexts/GameContext';
function App() { function App() {
return ( return (
<div className="App"> <GameProvider>
<header className="App-header"> <BrowserRouter>
<Leaderboard /> <Routes>
<GameCard /> <Route path="/" element={<Home />} />
<Button displayValue="Click Me" /> <Route path="/game/:id" element={<GameView />} />
</header> </Routes>
</div> </BrowserRouter>
</GameProvider>
); );
} }

View File

@ -1,12 +1,22 @@
import React from 'react'; import React from 'react';
import { Link} from "react-router-dom";
function Button(props){ function Button(props){
return ( return (
<button> <Link
{console.log(props)} to={props.link}
{props.displayValue} disabled={props.disabled}
</button> className={`p-2 m-2 rounded-2xl text-center font-bold border-2
${props.disabled ? 'pointer-events-none text-gray-400 bg-slate-700' : 'text-white hover:font-bold hover:text-black hover:bg-slate-400 border-black bg-slate-600'}`}>
{props.displayValue}
</Link>
); );
} }
Button.defaultProps = {
disabled: false,
link: "/",
displayValue: "Missing displayValue"
}
export default Button; export default Button;

View File

@ -0,0 +1,17 @@
import React from 'react';
import ListGameCell from '../components/listGameCell';
function GameList(props){
return (
<div className="bg-gray-500 min-h-1/2 border-solid rounded-xl min-w-40 border-2 border-black w-1/3 p-4 m-4">
{props.games.map((game) => (
<ListGameCell
key={game.gameId}
data={game}
/>
))}
</div>
)
}
export default GameList;

View File

@ -1,7 +1,11 @@
import React from 'react'; import React from 'react';
function Leaderboard(){ function Leaderboard(){
return <h1>Leaderboard</h1>; return (
<div className="bg-gray-500 min-h-1/2 border-solid rounded-xl border-2 border-black min-w-40 w-1/3 p-4 m-4">
</div>
);
} }
export default Leaderboard; export default Leaderboard;

View File

@ -0,0 +1,23 @@
import React, { useContext } from 'react';
import { GameContext } from '../contexts/GameContext';
function ListGameCell(props){
const { selectedGame, setSelectedGame } = useContext(GameContext);
const isSelected = selectedGame === props.data.gameId;
return (
<div
className={`w-full p-2 my-1 border-2 rounded-sm border-black ${
isSelected ? 'bg-blue-400' : 'bg-slate-200 hover:bg-slate-400'
}`}
onClick={() => isSelected ? setSelectedGame(null) : setSelectedGame(props.data.gameId)}
>
<p>Game ID: {props.data.gameId}</p>
<p>
{props.data.completed}/{props.data.gameSize}
</p>
</div>
);
}
export default ListGameCell;

View File

@ -0,0 +1,16 @@
import React, { createContext, useState } from 'react';
// Create a context
export const GameContext = createContext(null);
// Context Provider
export function GameProvider({ children }) {
const [selectedGame, setSelectedGame] = useState({ selectedGame: null });
return (
<GameContext.Provider value={{ selectedGame, setSelectedGame }}>
{children}
</GameContext.Provider>
);
}

View File

@ -0,0 +1,20 @@
import React from 'react';
import {useParams} from 'react-router-dom';
import GameCard from '../components/gameCard';
import Button from '../components/button';
function GameView(){
const {id} = useParams();
return (
<div>
<h1>Game ID: {id}</h1>
<GameCard />
<div className="w-full flex flex-row-reverse">
<Button displayValue="Back" link="/"/>
<Button displayValue="BINGO" />
</div>
</div>
);
}
export default GameView;

View File

@ -0,0 +1,45 @@
import React, { useContext } from 'react';
import Leaderboard from '../components/leaderboard';
import GameList from '../components/gameList';
import Button from '../components/button';
import { GameContext } from '../contexts/GameContext';
function Home(){
let {selectedGame, setSelectedGame} = useContext(GameContext);
const games = [
{
"gameId": 1,
"completed": 3,
"gameSize": 9,
},{
"gameId": 2,
"completed": 16,
"gameSize": 25,
},{
"gameId": 4,
"completed": 14,
"gameSize": 25,
},{
"gameId": 7,
"completed": 3,
"gameSize": 9,
}
]
return (
<div className="min-h-full h-full flex flex-row">
<Leaderboard />
<GameList games={games}/>
<div className="flex flex-col">
<Button displayValue="New Game" link="/game/1"/>
<Button displayValue="Join Game" link={`/game/${selectedGame}`} disabled={selectedGame ? false : true}/>
<Button displayValue="List Pools"/>
<Button displayValue="Create Pool"/>
</div>
</div>
);
}
export default Home;

View File

@ -0,0 +1,11 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}