diff --git a/app/page.tsx b/app/page.tsx index d5701b0..0a7731e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -15,7 +15,7 @@ import GitHubLink from "@/components/GitHubLink"; import CustomGameDialog from "@/components/CustomGameDialog"; import { Switch } from "@/components/ui/switch"; import { WORD_LIST } from "@/data/wordsList"; -import testGame from "@/data/testGame.json"; +import testGame from "@/data/testGame2.json"; import { ClueResponse, GuessResponse } from "@/types/requests"; export default function Home() { @@ -362,10 +362,6 @@ export default function Home() { // Replay each turn for (const turn of testGame.history) { - if (window.innerWidth < 768) { - window.scrollBy({ top: 100, behavior: "smooth" }); - } - setGameState((prev) => { if (!prev) return prev; @@ -391,6 +387,10 @@ export default function Home() { (word) => word.toLowerCase() === guess.word.toLowerCase(), ); + if (window.innerWidth < 768) { + window.scrollBy({ top: 200, behavior: "smooth" }); + } + if (cardIndex !== -1) { setGameState((prev) => { if (!prev) return prev; diff --git a/components/GameHistory.tsx b/components/GameHistory.tsx index a3413f8..d2a3d5b 100644 --- a/components/GameHistory.tsx +++ b/components/GameHistory.tsx @@ -1,4 +1,9 @@ +"use client"; + import { GameTurn } from "@/types/game"; +import { useEffect, useState } from "react"; +import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; interface GameHistoryProps { history: GameTurn[]; @@ -7,10 +12,17 @@ interface GameHistoryProps { export default function GameHistory({ history, winner }: GameHistoryProps) { const redTurns = history.filter((turn) => turn.team === "red"); + const [selectedRedTurn, setSelectedRedTurn] = useState(0); + const [selectedBlueTurn, setSelectedBlueTurn] = useState(0); const blueTurns = history.filter((turn) => turn.team === "blue"); + useEffect(() => { + setSelectedRedTurn(redTurns.length - 1); + setSelectedBlueTurn(blueTurns.length - 1); + }, [history]); + return ( -
+

Game History

{winner && (
)} +
-
-

Red Team

- {redTurns.length > 0 ? ( - redTurns.map((turn, index) => ( -
-
-
-
-
- - Clue: - - - {turn.clue.word} ({turn.clue.number}) - -
-
- - Guesses: - -
- {turn.guesses.map((guess, guessIndex) => ( - - {guess.word} - {guess.word === "SKIP" ? ( - ⏭️ - ) : guess.wasCorrect ? ( - - ) : ( - - )} +
+
+

+ Red Team +

+
+ {redTurns.map((_, index) => ( + + ))} +
+
+ {redTurns.map((turn, index) => ( +
+
+
+ + Turn #{index + 1} + +
+
+
+ + Clue: + + + {turn.clue.word} ({turn.clue.number}) + +
+

+ {turn.clue.reasoning} +

+
+
+ + Guesses: + +
+ {turn.guesses.map((guess, guessIndex) => ( +
+ + {guess.word} + {guess.word === "SKIP" ? ( + ⏭️ + ) : guess.wasCorrect ? ( + + ) : ( + + )} + + {guess.reasoning && ( + + {guess.reasoning} - ))} + )}
-
+ ))}
- )) - ) : ( -
-
-
-
-
- )} + ))}
-
-

Blue Team

- {blueTurns.length > 0 ? ( - blueTurns.map((turn, index) => ( -
-
-
-
-
- - Clue: - - - {turn.clue.word} ({turn.clue.number}) - -
-
- - Guesses: - -
- {turn.guesses.map((guess, guessIndex) => ( - - {guess.word} - {guess.wasCorrect ? ( - - ) : ( - - )} + +
+
+

+ Blue Team +

+
+ {blueTurns.map((_, index) => ( + + ))} +
+
+ {blueTurns.map((turn, index) => ( +
+
+
+ + Turn #{index + 1} + +
+
+
+ + Clue: + + + {turn.clue.word} ({turn.clue.number}) + +
+

+ {turn.clue.reasoning} +

+
+
+ + Guesses: + +
+ {turn.guesses.map((guess, guessIndex) => ( +
+ + {guess.word} + {guess.word === "SKIP" ? ( + ⏭️ + ) : guess.wasCorrect ? ( + + ) : ( + + )} + + {guess.reasoning && ( + + {guess.reasoning} - ))} + )}
-
+ ))}
- )) - ) : ( -
-
-
-
-
- )} + ))}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..d09a695 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,57 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", + outline: + "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2", + sm: "h-8 rounded-md px-3 text-xs", + lg: "h-10 rounded-md px-8", + icon: "h-9 w-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + }, +); +Button.displayName = "Button"; + +export { Button, buttonVariants }; diff --git a/data/testGame2.json b/data/testGame2.json new file mode 100644 index 0000000..ac304ef --- /dev/null +++ b/data/testGame2.json @@ -0,0 +1,322 @@ +{ + "date": "2025-01-16 22-24-07", + "initialOptions": { + "words": [ + "MONA LISA", + "FIGURE", + "PRICK", + "BLOCK", + "AMERICA", + "AGENT", + "AFRICA", + "SHARK", + "SPOT", + "LINK", + "STAR", + "AIR", + "BATTERY", + "ALIEN", + "LASER", + "RANCH", + "VIKING", + "RING", + "SUMO", + "CHERRY", + "BOOT", + "CONE", + "LINE", + "ASTRONAUT", + "BRIDGE" + ], + "cardTypes": [ + "neutral", + "red", + "neutral", + "neutral", + "neutral", + "blue", + "blue", + "neutral", + "red", + "neutral", + "red", + "blue", + "red", + "red", + "blue", + "blue", + "red", + "red", + "blue", + "blue", + "red", + "neutral", + "red", + "assassin", + "blue" + ] + }, + "winner": "red", + "finalScore": { + "red": 9, + "blue": 4 + }, + "history": [ + { + "team": "red", + "clue": { + "word": "Drawing", + "number": 3, + "reasoning": "Connects SPOT, LINE, and FIGURE; all are fundamental elements involved in drawing." + }, + "guesses": [ + { + "word": "LINE", + "wasCorrect": true, + "reasoning": "Line is fundamental to drawing, as drawings are composed of lines." + }, + { + "word": "FIGURE", + "wasCorrect": true, + "reasoning": "Figure drawing is a common art practice, so 'FIGURE' is likely related to the clue 'Drawing'." + }, + { + "word": "MONA LISA", + "wasCorrect": false, + "reasoning": "Mona Lisa is a famous artwork that relates to drawing." + } + ] + }, + { + "team": "blue", + "clue": { + "word": "007", + "number": 2, + "reasoning": "James Bond's code number connects 'Agent' and 'Laser'" + }, + "guesses": [ + { + "word": "AGENT", + "wasCorrect": true, + "reasoning": "James Bond, also known as 007, is a secret agent." + }, + { + "word": "LASER", + "wasCorrect": true, + "reasoning": "In the James Bond film 'Goldfinger', Bond is famously threatened with a laser. This connects 'LASER' to the clue '007'." + }, + { + "word": "SKIP", + "wasCorrect": false + } + ] + }, + { + "team": "red", + "clue": { + "word": "Invader", + "number": 2, + "reasoning": "Connects VIKING and ALIEN" + }, + "guesses": [ + { + "word": "ALIEN", + "wasCorrect": true, + "reasoning": "I choose 'ALIEN' because 'Invader' is commonly associated with 'Alien Invaders' or 'Space Invaders'." + }, + { + "word": "VIKING", + "wasCorrect": true, + "reasoning": "VIKING is closely associated with 'Invader' because Vikings were known for invading and raiding territories during the Viking Age." + }, + { + "word": "STAR", + "wasCorrect": true, + "reasoning": "I think 'STAR' relates to the previous clue 'Drawing', as you can draw a star." + } + ] + }, + { + "team": "blue", + "clue": { + "word": "Japan", + "number": 2, + "reasoning": "To help the team guess SUMO and CHERRY, both strongly associated with Japan." + }, + "guesses": [ + { + "word": "SUMO", + "wasCorrect": true, + "reasoning": "SUMO is a traditional Japanese sport strongly associated with Japan, making it a likely match for the clue 'Japan'" + }, + { + "word": "CHERRY", + "wasCorrect": true, + "reasoning": "Cherry blossoms are iconic in Japan." + }, + { + "word": "RING", + "wasCorrect": false, + "reasoning": "I believe 'RING' connects to our previous clue '007'. In the James Bond movie 'Spectre', the ring with the octopus symbol is a key plot element related to the secret organization. Therefore, 'RING' might be one of our words." + } + ] + }, + { + "team": "red", + "clue": { + "word": "Car", + "number": 3, + "reasoning": "Battery, boot, and spot are all associated with cars." + }, + "guesses": [ + { + "word": "BATTERY", + "wasCorrect": true, + "reasoning": "Cars have batteries." + }, + { + "word": "BOOT", + "wasCorrect": true, + "reasoning": "I associate 'boot' with 'car' because in British English, the trunk of a car is called a boot." + }, + { + "word": "SPOT", + "wasCorrect": true, + "reasoning": "I believe 'SPOT' relates to 'Parking spot', which is associated with a car." + }, + { + "word": "BLOCK", + "wasCorrect": false, + "reasoning": "I believe 'BLOCK' relates to the clue 'Car' as in 'engine block'. Additionally, it doesn't seem to be associated with the opponent's previous clues, so it's a safe guess." + } + ] + } + ], + "cards": [ + { + "word": "MONA LISA", + "type": "neutral", + "revealed": true + }, + { + "word": "FIGURE", + "type": "red", + "revealed": true + }, + { + "word": "PRICK", + "type": "neutral", + "revealed": false + }, + { + "word": "BLOCK", + "type": "neutral", + "revealed": true + }, + { + "word": "AMERICA", + "type": "neutral", + "revealed": false + }, + { + "word": "AGENT", + "type": "blue", + "revealed": true + }, + { + "word": "AFRICA", + "type": "blue", + "revealed": false + }, + { + "word": "SHARK", + "type": "neutral", + "revealed": true + }, + { + "word": "SPOT", + "type": "red", + "revealed": true + }, + { + "word": "LINK", + "type": "neutral", + "revealed": false + }, + { + "word": "STAR", + "type": "red", + "revealed": true + }, + { + "word": "AIR", + "type": "blue", + "revealed": false + }, + { + "word": "BATTERY", + "type": "red", + "revealed": true + }, + { + "word": "ALIEN", + "type": "red", + "revealed": true + }, + { + "word": "LASER", + "type": "blue", + "revealed": true + }, + { + "word": "RANCH", + "type": "blue", + "revealed": false + }, + { + "word": "VIKING", + "type": "red", + "revealed": true + }, + { + "word": "RING", + "type": "red", + "revealed": true + }, + { + "word": "SUMO", + "type": "blue", + "revealed": true + }, + { + "word": "CHERRY", + "type": "blue", + "revealed": true + }, + { + "word": "BOOT", + "type": "red", + "revealed": true + }, + { + "word": "CONE", + "type": "neutral", + "revealed": false + }, + { + "word": "LINE", + "type": "red", + "revealed": true + }, + { + "word": "ASTRONAUT", + "type": "assassin", + "revealed": false + }, + { + "word": "BRIDGE", + "type": "blue", + "revealed": false + } + ] +} diff --git a/package-lock.json b/package-lock.json index 66832d3..0de3609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@next/third-parties": "^15.1.3", "@radix-ui/react-dialog": "^1.1.4", + "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-switch": "^1.1.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/package.json b/package.json index 6832b1d..5183127 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "@next/third-parties": "^15.1.3", "@radix-ui/react-dialog": "^1.1.4", + "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-switch": "^1.1.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1",