From a49b6597016677a9cbab9e1a6793511584cea368 Mon Sep 17 00:00:00 2001 From: Kritik Jiyaviya Date: Fri, 22 Mar 2024 20:05:49 +0530 Subject: [PATCH] feat: Ability to revoke an invite to an org (#902) * feat: Ability to revoke an invite to an org * Resolve a conflict with main --------- Co-authored-by: Matt Aitken --- apps/webapp/app/models/member.server.ts | 33 ++++++++++++++++ .../route.tsx | 29 ++++++++++++-- apps/webapp/app/routes/invite-revoke.tsx | 39 +++++++++++++++++++ apps/webapp/app/utils/pathBuilder.ts | 4 ++ 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 apps/webapp/app/routes/invite-revoke.tsx diff --git a/apps/webapp/app/models/member.server.ts b/apps/webapp/app/models/member.server.ts index 716590898..bfb51bdf7 100644 --- a/apps/webapp/app/models/member.server.ts +++ b/apps/webapp/app/models/member.server.ts @@ -225,3 +225,36 @@ export async function resendInvite({ inviteId }: { inviteId: string }) { }, }); } + +export async function revokeInvite({ + userId, + slug, + inviteId, +}: { + userId: string; + slug: string; + inviteId: string; +}) { + const org = await prisma.organization.findFirst({ + where: { slug, members: { some: { userId } } }, + }); + + if (!org) { + throw new Error("User does not have access to this organization"); + } + const invite = await prisma.orgMemberInvite.delete({ + where: { + id: inviteId, + }, + select: { + email: true, + organization: true, + }, + }); + + if (!invite) { + throw new Error("Invite not found"); + } + + return { email: invite.email, organization: invite.organization }; +} diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.team/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.team/route.tsx index 80718a213..f6cd7a4fc 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.team/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.team/route.tsx @@ -31,7 +31,12 @@ import { useUser } from "~/hooks/useUser"; import { getTeamMembersAndInvites, removeTeamMember } from "~/models/member.server"; import { redirectWithSuccessMessage } from "~/models/message.server"; import { requireUserId } from "~/services/session.server"; -import { inviteTeamMemberPath, organizationTeamPath, resendInvitePath } from "~/utils/pathBuilder"; +import { + inviteTeamMemberPath, + organizationTeamPath, + resendInvitePath, + revokeInvitePath, +} from "~/utils/pathBuilder"; export const loader = async ({ request, params }: LoaderFunctionArgs) => { const userId = await requireUserId(request); @@ -147,8 +152,9 @@ export default function Page() { Invite sent {} -
+
+
))} @@ -272,7 +278,7 @@ function LeaveTeamModal({ function ResendButton({ invite }: { invite: Invite }) { return ( -
+