diff --git a/components/t/CreateNewTeamModal.tsx b/components/t/CreateNewTeamModal.tsx
index dd55e9f9c..db388c6c7 100644
--- a/components/t/CreateNewTeamModal.tsx
+++ b/components/t/CreateNewTeamModal.tsx
@@ -43,8 +43,6 @@ const CreateNewTeamModal = () => {
setIsOpen(false);
};
- console.log(getError());
-
return (
<>
+ {isOpen && (
+ setIsOpen(false)} size="xl">
+
+
+
+ Managing team
+
+
+
+ {/*
+
+ Team name
+
+ setName(e.target.value)}
+ />
+ {getError()}
+ */}
+
+
+
+
+ )}
+ >
+ );
+};
+
+export default TeamManagementModal;
diff --git a/lib/validators/team.ts b/lib/validators/team.ts
new file mode 100644
index 000000000..60a4822da
--- /dev/null
+++ b/lib/validators/team.ts
@@ -0,0 +1,14 @@
+import * as z from "zod";
+
+const TEAM_BIO_CHARACTER_LIMIT = 7000;
+const TEAM_RECRUITING_POST_CHARACTER_LIMIT = 2000;
+
+export const teamSchema = z.object({
+ twitterName: z.string().max(15).optional().nullable(),
+ bio: z.string().max(TEAM_BIO_CHARACTER_LIMIT).optional().nullable(),
+ recruitingPost: z
+ .string()
+ .max(TEAM_RECRUITING_POST_CHARACTER_LIMIT)
+ .optional()
+ .nullable(),
+});
diff --git a/pages/api/teams/code.ts b/pages/api/teams/code.ts
index 2dc99a53f..c11963447 100644
--- a/pages/api/teams/code.ts
+++ b/pages/api/teams/code.ts
@@ -3,7 +3,7 @@ import { getMySession } from "lib/getMySession";
import { NextApiRequest, NextApiResponse } from "next";
import prisma from "prisma/client";
-const handler = async (req: NextApiRequest, res: NextApiResponse) => {
+const joinHandler = async (req: NextApiRequest, res: NextApiResponse) => {
switch (req.method) {
case "POST":
await postHandler(req, res);
@@ -50,4 +50,4 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).end();
}
-export default handler;
+export default joinHandler;
diff --git a/pages/api/teams/index.tsx b/pages/api/teams/index.ts
similarity index 100%
rename from pages/api/teams/index.tsx
rename to pages/api/teams/index.ts
diff --git a/pages/api/teams/leave.ts b/pages/api/teams/leave.ts
new file mode 100644
index 000000000..c7f2be335
--- /dev/null
+++ b/pages/api/teams/leave.ts
@@ -0,0 +1,35 @@
+import { getMySession } from "lib/getMySession";
+import { NextApiRequest, NextApiResponse } from "next";
+import prisma from "prisma/client";
+
+const leaveHandler = 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 userFromDb = await prisma.user.findUnique({
+ where: { id: user.id },
+ include: { team: true },
+ });
+ if (!userFromDb?.team || userFromDb.team.captainId === user.id) {
+ return res.status(400).end();
+ }
+
+ await prisma.user.update({
+ where: { id: user.id },
+ data: { team: { disconnect: true } },
+ });
+
+ res.status(200).end();
+}
+
+export default leaveHandler;
diff --git a/pages/t/[team].tsx b/pages/t/[team].tsx
index 47d8d468e..2ccf99b64 100644
--- a/pages/t/[team].tsx
+++ b/pages/t/[team].tsx
@@ -1,15 +1,80 @@
-import { Box } from "@chakra-ui/react";
+import { Box, Button, Heading, useToast } from "@chakra-ui/react";
+import { t, Trans } from "@lingui/macro";
+import MyContainer from "components/common/MyContainer";
+import TeamManagementModal from "components/t/TeamManagementModal";
+import { getEmojiFlag } from "countries-list";
+import { getToastOptions } from "lib/getToastOptions";
+import { sendData } from "lib/postData";
+import useUser from "lib/useUser";
import { GetStaticPaths, GetStaticProps } from "next";
import { getTeam, GetTeamData } from "prisma/queries/getTeam";
+import { useState } from "react";
+import { FiTrash } from "react-icons/fi";
interface Props {
team: GetTeamData;
}
const TeamPage: React.FC = (props) => {
+ const [sending, setSending] = useState(false);
+ const [user] = useUser();
+ const toast = useToast();
+
const team = props.team!;
- console.log({ team });
- return {team.name};
+
+ const leaveTeam = async () => {
+ if (!window.confirm(t`Leave the team?`)) {
+ return;
+ }
+
+ setSending(true);
+
+ const success = await sendData("POST", "/api/teams/leave");
+ setSending(false);
+ if (!success) return;
+
+ //mutate("/api/freeagents");
+
+ toast(getToastOptions(t`Left the team`, "success"));
+ };
+
+ return (
+
+
+ {team.name}
+
+
+ {team.roster
+ .reduce((acc: [string, number][], cur) => {
+ if (!cur.profile?.country) return acc;
+
+ const countryTuple = acc.find(
+ ([country]) => country === cur.profile?.country
+ );
+ if (!countryTuple) acc.push([cur.profile.country, 1]);
+ else countryTuple[1]++;
+
+ return acc;
+ }, [])
+ .sort((a, b) => b[1] - a[1])
+ .map(([country]) => getEmojiFlag(country))}
+
+ {user?.id === team.captainId && }
+ {user &&
+ user.id !== team.captainId &&
+ team.roster.some((teamMember) => user.id === teamMember.id) && (
+ }
+ variant="outline"
+ colorScheme="red"
+ onClick={leaveTeam}
+ isLoading={sending}
+ >
+ Leave team
+
+ )}
+
+ );
};
export const getStaticPaths: GetStaticPaths = async () => {
diff --git a/prisma/queries/getTeam.ts b/prisma/queries/getTeam.ts
index a83c0d79b..f32c2d0ad 100644
--- a/prisma/queries/getTeam.ts
+++ b/prisma/queries/getTeam.ts
@@ -14,6 +14,7 @@ export const getTeam = async (nameForUrl: string) =>
captainId: true,
roster: {
select: {
+ id: true,
discordId: true,
discordAvatar: true,
username: true,