diff --git a/functions/helloWorld.js b/functions/helloWorld.js index 14d9b34..8b44e8a 100644 --- a/functions/helloWorld.js +++ b/functions/helloWorld.js @@ -1,3 +1,6 @@ exports.handler = async (event, context) => { - // let's return a JSON response that looks like: { hello: "world" } + return { + statusCode: 200, + body: JSON.stringify({ hello: "world" }), + }; }; diff --git a/functions/insertGame.js b/functions/insertGame.js index 2179917..f61c3ff 100644 --- a/functions/insertGame.js +++ b/functions/insertGame.js @@ -1,30 +1,50 @@ -const { createClient } = require("@astrajs/collections"); + const { createClient } = require("@astrajs/collections"); exports.handler = async (event, context) => { + // Step 1: let's return a 400 if we don't recieve a valid game id let gameId; let gamePayload; try { // let's set the game id + gameId = event.path.split("insertGame/")[1]; // let's parse the incoming payload + gamePayload = JSON.parse(event.body); } catch (e) { // let's return a 400 if we can't parse the game id or body + return { + statusCode: 400, + body: JSON.stringify({ message: "must provide a valid game ID" }), + }; } - // let's connect to Astra + // Step 1: let's connect to Astra const astraClient = await createClient({ // let's set our Astra connection configuration + astraDatabaseId: process.env.ASTRA_DB_ID, + astraDatabaseRegion: process.env.ASTRA_DB_REGION, + username: process.env.ASTRA_DB_USERNAME, + password: process.env.ASTRA_DB_PASSWORD, }); const gamesCollection = astraClient .namespace(process.env.ASTRA_DB_KEYSPACE) .collection(process.env.GAMES_COLLECTION); - // let's provision a new game + // Step 1: let's provision a new game try { // let's create a new game with the gamesCollection + const res = await gamesCollection.create(gameId, gamePayload); // let's return a 200 with the resoponse from astra + return { + statusCode: 200, + body: JSON.stringify(res), + }; } catch (e) { console.error(e); // let's return a 500 on error + return { + statusCode: 500, + body: JSON.stringify(e), + }; } -}; +}; \ No newline at end of file diff --git a/package.json b/package.json index b56e0db..244697d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "battlestax", "version": "0.0.1", "dependencies": { - "@astrajs/collections": "0.0.8", + "@astrajs/collections": "^0.0.2", "@material-ui/core": "^4.11.0", "@reduxjs/toolkit": "^1.4.0", "@testing-library/jest-dom": "^5.11.6", @@ -14,7 +14,8 @@ "react-dom": "^16.13.1", "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", - "react-scripts": "4.0.0" + "react-scripts": "4.0.0", + "type-fest": "^0.13.1" }, "scripts": { "dev": "netlify dev", @@ -43,6 +44,6 @@ }, "devDependencies": { "fetch-mock": "^9.11.0", - "netlify-cli": "^2.68.5" + "netlify-cli": "^2.71.0" } } diff --git a/src/pages/Lobby/NewGame/NewGame.js b/src/pages/Lobby/NewGame/NewGame.js index 63194ce..f0279d6 100644 --- a/src/pages/Lobby/NewGame/NewGame.js +++ b/src/pages/Lobby/NewGame/NewGame.js @@ -1,9 +1,13 @@ import React from "react"; import { Button, Grid, Typography } from "@material-ui/core"; //let's import what we need +import { useDispatch, useSelector } from "react-redux"; +import { selectGame, createGame } from "../../../store/gameSlice"; export default function NewGame() { - // let's connect Redux to our Component +// let's connect Redux to our Component +const dispatch = useDispatch(); +const { id, idError, idLoading } = useSelector(selectGame); return ( @@ -15,7 +19,7 @@ export default function NewGame() { game code {/* let's display the game id */} - {"----"} + {id || "----"}
{/* let's make our button create a new game*/} @@ -25,10 +29,16 @@ export default function NewGame() { size="large" variant="contained" color="primary" + disabled={idLoading} + onClick={() => { + dispatch(createGame()); + }} > start new game - {/* let's show an error message if there is one */} + {idError && ( + Error: {idError} +)}
); diff --git a/src/store/gameSlice.js b/src/store/gameSlice.js index 1e011ca..bd00326 100644 --- a/src/store/gameSlice.js +++ b/src/store/gameSlice.js @@ -1,4 +1,5 @@ import { createSlice } from "@reduxjs/toolkit"; +import { generateGameId } from "../util/random"; export const initialState = { id: "", @@ -11,26 +12,57 @@ export const slice = createSlice({ initialState, reducers: { // let's add a reducer that sets the game id +setId: (state, action) => { + state.id = action.payload; +}, // let's add a reducer that sets an error message - // let's add a reducer that sets a loading state +setIdError: (state, action) => { + state.idError = action.payload; +}, +// let's add a reducer that sets a loading state +setIdLoading: (state, action) => { + state.idLoading = action.payload; +}, }, }); // let's export our actions and selectors +export const { setId, setIdLoading, setIdError } = slice.actions; +export const selectGame = (state) => state.game; // let's create an asnyc action to create a new game export const createGame = () => { return async (dispatch) => { // let's set the id state back to the defaults + dispatch(setIdLoading(true)); + dispatch(setIdError("")); + dispatch(setId("")); + try { // let's generate a new game id + const gameId = generateGameId(); + // let's call our insert game netlify function + const res = await fetch(`/.netlify/functions/insertGame/${gameId}`, { + method: "POST", + body: JSON.stringify({ state: "initialized" }), + }); + if (!res.ok) { + throw Error(res.statusText); + } + // let's set the game id + const resJson = await res.json(); + dispatch(setId(resJson.documentId)); } catch (e) { // let's set the id error if there is one + dispatch(setIdError(e.message)); } + // let's set the id state to not loading + dispatch(setIdLoading(false)); }; }; + export default slice.reducer; diff --git a/test/helloWorld.test.js b/test/helloWorld.test.js index 50b6120..33d1d80 100644 --- a/test/helloWorld.test.js +++ b/test/helloWorld.test.js @@ -4,4 +4,4 @@ it("should return a JSON response", async () => { const response = await helloWorld.handler(); const responseJson = JSON.parse(response.body); expect(responseJson.hello).toBe("world"); -}); +}); \ No newline at end of file