diff --git a/components/team/EditTeamModal.tsx b/components/team/EditTeamModal.tsx
index b03fdb99..347a7ba6 100644
--- a/components/team/EditTeamModal.tsx
+++ b/components/team/EditTeamModal.tsx
@@ -62,7 +62,8 @@ export default function EditTeamModal(props) {
{member.email !== session.user.email &&
@@ -76,20 +77,20 @@ export default function EditTeamModal(props) {
- {!checkedDisbandTeam && */}
{checkedDisbandTeam &&
Disband Team
}
- Cancel
+ Close
diff --git a/components/team/MemberInvitationModal.tsx b/components/team/MemberInvitationModal.tsx
index e4472b09..36e0d564 100644
--- a/components/team/MemberInvitationModal.tsx
+++ b/components/team/MemberInvitationModal.tsx
@@ -1,8 +1,22 @@
-import {useEffect, useState} from "react";
-import {UsersIcon} from "@heroicons/react/outline";
+import { UsersIcon } from "@heroicons/react/outline";
+import { useState } from "react";
export default function MemberInvitationModal(props) {
+ const [ errorMessage, setErrorMessage ] = useState('');
+
+ const handleError = async (res) => {
+
+ const responseData = await res.json();
+
+ if (res.ok === false) {
+ setErrorMessage(responseData.message);
+ throw new Error(responseData.message);
+ }
+
+ return responseData;
+ };
+
const inviteMember = (e) => {
e.preventDefault();
@@ -19,7 +33,9 @@ export default function MemberInvitationModal(props) {
headers: {
'Content-Type': 'application/json'
}
- }).then(props.onExit);
+ }).then(handleError).then(props.onExit).catch( (e) => {
+ // do nothing.
+ });
};
return (
@@ -60,6 +76,7 @@ export default function MemberInvitationModal(props) {
+ {errorMessage && Error: {errorMessage} }
Invite
diff --git a/pages/api/teams.ts b/pages/api/teams.ts
index abd96c3d..33d1038d 100644
--- a/pages/api/teams.ts
+++ b/pages/api/teams.ts
@@ -1,7 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import prisma from '../../lib/prisma';
import {getSession} from "next-auth/client";
-import {create} from "domain";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
@@ -13,6 +12,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
if (req.method === "POST") {
+
+ // TODO: Prevent creating a team with identical names?
+
const createTeam = await prisma.team.create({
data: {
name: req.body.name,
diff --git a/pages/api/teams/[team]/invite.ts b/pages/api/teams/[team]/invite.ts
index d8170401..1a8f2415 100644
--- a/pages/api/teams/[team]/invite.ts
+++ b/pages/api/teams/[team]/invite.ts
@@ -21,7 +21,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
if (!team) {
- return res.status(404).json({message: "Unable to find team to invite user to."});
+ return res.status(404).json({message: "Invalid team"});
}
const invitee = await prisma.user.findFirst({
@@ -34,17 +34,29 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
if (!invitee) {
- return res.status(404).json({message: "Missing user, currently unsupported."});
+ return res.status(400).json({
+ message: `Invite failed because there is no corresponding user for ${req.body.usernameOrEmail}`});
}
// create provisional membership
- const createMembership = await prisma.membership.create({
- data: {
- teamId: parseInt(req.query.team),
- userId: invitee.id,
- role: req.body.role,
- },
- });
+ try {
+ const createMembership = await prisma.membership.create({
+ data: {
+ teamId: parseInt(req.query.team),
+ userId: invitee.id,
+ role: req.body.role,
+ },
+ });
+ }
+ catch (err) {
+ if (err.code === "P2002") { // unique constraint violation
+ return res.status(409).json({
+ message: 'This user is a member of this team / has a pending invitation.',
+ });
+ } else {
+ throw err; // rethrow
+ }
+ };
// inform user of membership by email
if (req.body.sendEmailInvitation) {
|