initial find & create game functionality

and restructure homepage components
This commit is contained in:
Nathaniel Tampus
2023-03-04 18:43:32 +08:00
parent 6de9943dca
commit dd0a097a48
4 changed files with 116 additions and 28 deletions

View File

@@ -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<HTMLFormElement>) {
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 (
<form className="form-control" onSubmit={submitCreateGame}>
<label className="label cursor-pointer">
<span className="label-text">Unlisted/invite-only</span>
<input type="checkbox" className="checkbox" name="createUnlisted" id="createUnlisted" />
</label>
<label className="label" htmlFor="createStartingSide">
<span className="label-text">Select your side</span>
</label>
<div className="input-group">
<select
className="select select-bordered"
name="createStartingSide"
id="createStartingSide"
>
<option value="random">Random</option>
<option value="white">White</option>
<option value="black">Black</option>
</select>
<button className={"btn" + (buttonLoading ? " loading" : "")} type="submit">
Create
</button>
</div>
</form>
);
}

View File

@@ -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<HTMLFormElement>) {
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 (
<form className="input-group" onSubmit={submitJoinGame}>
<input
type="text"
placeholder="Invite link or code"
className="input input-bordered"
name="joinGameCode"
id="joinGameCode"
/>
<button className={"btn btn-square" + (buttonLoading ? " loading" : "")} type="submit">
Join
</button>
</form>
);
}