From 3f41e451328321bc7ef2547aaa7fd8d21c021cbd Mon Sep 17 00:00:00 2001 From: "Kalle (Sendou)" <38327916+Sendouc@users.noreply.github.com> Date: Thu, 14 Jan 2021 13:52:09 +0200 Subject: [PATCH] join team --- lib/constants.ts | 2 ++ lib/postData.ts | 1 - pages/api/teams/code.ts | 53 +++++++++++++++++++++++++++++++++++++++++ pages/t/join.tsx | 43 +++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 pages/api/teams/code.ts create mode 100644 pages/t/join.tsx diff --git a/lib/constants.ts b/lib/constants.ts index 968f86a15..9d913e0ac 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -6,3 +6,5 @@ export const SALMON_RUN_ADMIN_DISCORD_IDS = [ "116999083796725761", // Marty "78546869373906944", // Minaraii ]; + +export const TEAM_ROSTER_LIMIT = 10; diff --git a/lib/postData.ts b/lib/postData.ts index a40084a2e..aa4a2d228 100644 --- a/lib/postData.ts +++ b/lib/postData.ts @@ -2,7 +2,6 @@ import { createStandaloneToast } from "@chakra-ui/react"; import { t } from "@lingui/macro"; export async function sendData(method = "POST", url = "", data = {}) { - // Default options are marked with * const response = await fetch(url, { method, headers: { diff --git a/pages/api/teams/code.ts b/pages/api/teams/code.ts new file mode 100644 index 000000000..2dc99a53f --- /dev/null +++ b/pages/api/teams/code.ts @@ -0,0 +1,53 @@ +import { TEAM_ROSTER_LIMIT } from "lib/constants"; +import { getMySession } from "lib/getMySession"; +import { NextApiRequest, NextApiResponse } from "next"; +import prisma from "prisma/client"; + +const handler = async (req: NextApiRequest, res: NextApiResponse) => { + switch (req.method) { + case "POST": + await postHandler(req, res); + break; + default: + res.status(405).end(); + } +}; + +async function postHandler(req: NextApiRequest, res: NextApiResponse) { + const user = await getMySession(req); + if (!user) return res.status(401).end(); + + const { code, name } = req.body; + + if (typeof code !== "string" || typeof name !== "string") { + return res.status(400).end(); + } + + const userFromDb = await prisma.user.findUnique({ where: { id: user.id } }); + + if (userFromDb?.teamId) { + return res.status(400).json({ message: "Already in a team" }); + } + + const team = await prisma.team.findUnique({ + where: { inviteCode: code }, + include: { roster: true }, + }); + + if (!team || team.nameForUrl !== name) { + return res.status(400).end(); + } + + if (team.roster.length >= TEAM_ROSTER_LIMIT) { + return res.status(400).json({ message: "Team already has 10 members" }); + } + + await prisma.team.update({ + where: { id: team.id }, + data: { roster: { connect: { id: user.id } } }, + }); + + res.status(200).end(); +} + +export default handler; diff --git a/pages/t/join.tsx b/pages/t/join.tsx new file mode 100644 index 000000000..93a551cea --- /dev/null +++ b/pages/t/join.tsx @@ -0,0 +1,43 @@ +import { t } from "@lingui/macro"; +import { useLingui } from "@lingui/react"; +import MyContainer from "components/common/MyContainer"; +import { sendData } from "lib/postData"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; + +const statusMessage = { + LOADING: t`Please wait...`, + ERROR: t`There is an error that needs to be fixed before you can join the team.`, + REDIRECTING: t`Joined the team. Redirecting.`, +} as const; + +const JoinTeamPage = ({}) => { + const { i18n } = useLingui(); + const router = useRouter(); + const [joiningStatus, setJoiningStatus] = useState< + "LOADING" | "ERROR" | "REDIRECTING" + >("LOADING"); + + useEffect(() => { + const joinTeam = async () => { + const { code, name } = router.query; + if (typeof code !== "string" || typeof name !== "string") { + router.push("/404"); + } + + const success = await sendData("POST", "/api/teams/code", { code, name }); + if (!success) { + return setJoiningStatus("ERROR"); + } + + setJoiningStatus("REDIRECTING"); + router.push(`/t/${name}`); + }; + + joinTeam(); + }, []); + + return {i18n._(statusMessage[joiningStatus])}; +}; + +export default JoinTeamPage;