diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 56ef57c..bb89e2a 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -1,4 +1,6 @@ -import PublicGames from "@/components/PublicGames"; +import PublicGames from "@/components/home/PublicGames"; +import JoinGame from "@/components/home/JoinGame"; +import CreateGame from "@/components/home/CreateGame"; export default function Home() { return ( @@ -8,39 +10,14 @@ export default function Home() {

Join from invite

-
-
- - -
-
+
or

Create game

-
- - -
- - -
-
+
diff --git a/client/src/components/home/CreateGame.tsx b/client/src/components/home/CreateGame.tsx new file mode 100644 index 0000000..41dd306 --- /dev/null +++ b/client/src/components/home/CreateGame.tsx @@ -0,0 +1,59 @@ +"use client"; + +import type { FormEvent } from "react"; +import { useState, useContext } from "react"; +import { SessionContext } from "@/context/session"; +import { createGame } from "@/lib/game"; +import { useRouter } from "next/navigation"; + +export default function CreateGame() { + const session = useContext(SessionContext); + const [buttonLoading, setButtonLoading] = useState(false); + const router = useRouter(); + + async function submitCreateGame(e: FormEvent) { + e.preventDefault(); + if (!session?.user?.id) return; + setButtonLoading(true); + + const target = e.target as HTMLFormElement; + const unlisted = target.elements.namedItem("createUnlisted") as HTMLInputElement; + const startingSide = (target.elements.namedItem("createStartingSide") as HTMLSelectElement) + .value; + + const game = await createGame(startingSide, unlisted.checked); + + if (game) { + router.push(`/game/${game.code}`); + } else { + setButtonLoading(false); + // TODO: Show error message + } + } + + return ( +
+ + +
+ + +
+
+ ); +} diff --git a/client/src/components/home/JoinGame.tsx b/client/src/components/home/JoinGame.tsx new file mode 100644 index 0000000..65ec2b7 --- /dev/null +++ b/client/src/components/home/JoinGame.tsx @@ -0,0 +1,52 @@ +"use client"; + +import type { FormEvent } from "react"; +import { useState, useContext } from "react"; +import { SessionContext } from "@/context/session"; +import { findGame } from "@/lib/game"; +import { useRouter } from "next/navigation"; + +export default function JoinGame() { + const session = useContext(SessionContext); + const [buttonLoading, setButtonLoading] = useState(false); + const router = useRouter(); + + async function submitJoinGame(e: FormEvent) { + e.preventDefault(); + if (!session?.user?.id) return; + setButtonLoading(true); + + const target = e.target as HTMLFormElement; + const codeEl = target.elements.namedItem("joinGameCode") as HTMLInputElement; + + let code = codeEl.value; + if (code.startsWith("http") || code.startsWith("ches.su")) { + code = new URL(code).pathname.split("/")[2]; + } + + const game = await findGame(code); + + if (game) { + router.push(`/game/${game.code}`); + } else { + setButtonLoading(false); + codeEl.value = ""; + // TODO: Show error message + } + } + + return ( +
+ + +
+ ); +} diff --git a/client/src/components/PublicGames.tsx b/client/src/components/home/PublicGames.tsx similarity index 100% rename from client/src/components/PublicGames.tsx rename to client/src/components/home/PublicGames.tsx