import React, { useEffect, useState } from "react"; import logo from "./kaistevenson_white.svg"; import "./App.css"; import { Grid } from "./Grid"; import { getCategory, getWords } from "./serverHelper"; export type GameState = { words: { word: string; selected: boolean; used: boolean }[]; groups: { title: string; reason: string; words: string[]; flipped: boolean; }[]; }; const loadingGameState: GameState = { words: new Array(16).fill({ word: "Loading...", selected: false, used: false, }), groups: [], }; const initializeGameState = async (): Promise => ({ words: (await getWords()).map((word) => ({ word, selected: false, used: false, })), groups: [], }); const Game = () => { //state const [gameState, setGameState] = useState(undefined); //initialize useEffect(() => { if (!gameState) { initializeGameState() .then((state) => setGameState(state)) .catch(console.error); } }); //handlers const selectWordHandler = (idx: number) => { const candidateState = { ...gameState! }; if (candidateState.words.filter((word) => word.selected).length === 4) { if (!candidateState.words[idx].selected) { //if we've already selected 4 words and we would select another, //do nothing return; } } //FIXME don't mutate state candidateState.words[idx].selected = !candidateState.words[idx].selected; setGameState(candidateState); }; const flipGroupHandler = (idx: number) => { const candidateState = { ...gameState! }; //FIXME don't mutate state candidateState.groups[idx].flipped = !candidateState.groups[idx].flipped; setGameState(candidateState); }; const submitSelectionHandler = () => { const candidateState = { ...gameState! }; const selectedWords = candidateState.words .filter(({ selected }) => selected) .map(({ word }) => word); if (selectedWords.length !== 4) { return; } candidateState.words = candidateState.words.map( ({ selected, word, used }) => ({ used: used || selected, selected: false, word, }) ); const loadingGroup: GameState["groups"][number] = { title: "LOADING", words: selectedWords, reason: "LOADING", flipped: false, }; setGameState((prevState) => ({ ...candidateState!, groups: [...prevState!.groups, loadingGroup], })); getCategory(selectedWords).then(({ categoryName, reason }) => { setGameState((prevState) => { const updatedGroups = prevState!.groups.map((group) => group === loadingGroup ? { ...group, title: categoryName, reason } : group ); return { ...candidateState!, groups: updatedGroups }; }); }); }; //display logic return (
); }; export const App = () => (
logo
);