diff --git a/packages/client/src/components/dish-host.tsx b/packages/client/src/components/dish-host.tsx new file mode 100644 index 0000000..205b601 --- /dev/null +++ b/packages/client/src/components/dish-host.tsx @@ -0,0 +1,76 @@ +import { useState } from "react" +import type { Country, Dish } from "@celebrate-esc/shared" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" + +interface DishHostProps { + dishes: Dish[] + countries: Country[] + onAddDish: (name: string, correctCountry: string) => void + onReveal: () => void +} + +export function DishHost({ dishes, countries, onAddDish, onReveal }: DishHostProps) { + const [name, setName] = useState("") + const [country, setCountry] = useState("") + const allRevealed = dishes.length > 0 && dishes.every((d) => d.revealed) + + return ( + + + Dish of the Nation + + + {!allRevealed && ( +
+ setName(e.target.value)} maxLength={100} /> + + +
+ )} + + {dishes.length > 0 && ( +
+

{dishes.length} dish(es) added:

+
    + {dishes.map((d) => ( +
  • + {d.name} → {countries.find((c) => c.code === d.correctCountry)?.name ?? d.correctCountry} + {d.revealed && " (revealed)"} +
  • + ))} +
+
+ )} + + {dishes.length > 0 && !allRevealed && ( + + )} +
+
+ ) +} diff --git a/packages/client/src/components/dish-list.tsx b/packages/client/src/components/dish-list.tsx new file mode 100644 index 0000000..f3ae85e --- /dev/null +++ b/packages/client/src/components/dish-list.tsx @@ -0,0 +1,100 @@ +import { useState } from "react" +import type { Country, Dish, DishGuess } from "@celebrate-esc/shared" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" + +interface DishListProps { + dishes: Dish[] + myGuesses: DishGuess[] + countries: Country[] + onGuess: (dishId: string, guessedCountry: string) => void +} + +export function DishList({ dishes, myGuesses, countries, onGuess }: DishListProps) { + if (dishes.length === 0) { + return ( + + + No dishes yet — the host will add them. + + + ) + } + + return ( + + + Dish of the Nation + + + {dishes.map((dish) => ( + g.dishId === dish.id)} + countries={countries} + onGuess={onGuess} + /> + ))} + + + ) +} + +function DishItem({ + dish, + myGuess, + countries, + onGuess, +}: { + dish: Dish + myGuess: DishGuess | undefined + countries: Country[] + onGuess: (dishId: string, guessedCountry: string) => void +}) { + const [selected, setSelected] = useState(myGuess?.guessedCountry ?? "") + + if (dish.revealed) { + return ( +
+

{dish.name}

+

+ Answer: {countries.find((c) => c.code === dish.correctCountry)?.name} +

+ {myGuess && ( +

+ Your guess: {countries.find((c) => c.code === myGuess.guessedCountry)?.name} + {myGuess.guessedCountry === dish.correctCountry ? " ✓" : " ✗"} +

+ )} +
+ ) + } + + return ( +
+

{dish.name}

+
+ +
+ {myGuess && ( +

+ Guessed: {countries.find((c) => c.code === myGuess.guessedCountry)?.name} +

+ )} +
+ ) +} diff --git a/packages/client/src/components/dish-results.tsx b/packages/client/src/components/dish-results.tsx new file mode 100644 index 0000000..78429ba --- /dev/null +++ b/packages/client/src/components/dish-results.tsx @@ -0,0 +1,39 @@ +import type { GameState, Country } from "@celebrate-esc/shared" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" + +interface DishResultsProps { + results: NonNullable + countries: Country[] +} + +export function DishResults({ results, countries }: DishResultsProps) { + return ( + + + Dish Results + + + {results.map((r) => ( +
+

{r.dish.name}

+

+ Answer: {countries.find((c) => c.code === r.dish.correctCountry)?.name} +

+ {r.guesses.length === 0 ? ( +

No guesses

+ ) : ( +
    + {r.guesses.map((g) => ( +
  • + {g.displayName}: {countries.find((c) => c.code === g.guessedCountry)?.name} + {g.correct ? " ✓" : " ✗"} +
  • + ))} +
+ )} +
+ ))} +
+
+ ) +}