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() {
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