From 452ac1d2a9e238684605acc8820a4dd365e70cf8 Mon Sep 17 00:00:00 2001
From: Kai Stevenson <kai@kaistevenson.com>
Date: Sat, 28 Jun 2025 13:36:02 -0700
Subject: MVP

---
 frontend/src/App.tsx | 68 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 17 deletions(-)

(limited to 'frontend/src/App.tsx')

diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 4eb26bd..b3203bc 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,13 +1,27 @@
 import React, { useEffect, useState } from "react";
-import logo from "./kaistevenson.svg";
+import logo from "./kaistevenson_white.svg";
 import "./App.css";
 
 import { Grid } from "./Grid";
-import { getWords } from "./serverHelper";
+import { getCategory, getWords } from "./serverHelper";
 
 export type GameState = {
   words: { word: string; selected: boolean; used: boolean }[];
-  groups: { title: string; words: string[] }[];
+  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<GameState> => ({
@@ -46,6 +60,12 @@ const Game = () => {
     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! };
 
@@ -65,26 +85,40 @@ const Game = () => {
       })
     );
 
-    //mock the server response for this selection
-    const response = "Four letter verbs";
-    const newGroup: GameState["groups"][number] = {
-      title: response,
+    const loadingGroup: GameState["groups"][number] = {
+      title: "LOADING",
       words: selectedWords,
+      reason: "LOADING",
+      flipped: false,
     };
-    candidateState.groups = [...candidateState.groups, newGroup];
 
-    setGameState(candidateState);
+    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 gameState ? (
-    <Grid
-      selectWordHandler={selectWordHandler}
-      submitSelectionHandler={submitSelectionHandler}
-      gameState={gameState!}
-    />
-  ) : (
-    <h1>Loading...</h1>
+  return (
+    <div className="Game-main">
+      <Grid
+        selectWordHandler={selectWordHandler}
+        flipGroupHandler={flipGroupHandler}
+        submitSelectionHandler={submitSelectionHandler}
+        gameState={gameState ?? loadingGameState}
+      />
+    </div>
   );
 };
 
-- 
cgit v1.2.3-70-g09d2

