From e6017854fd48bad96eae3068ea2f4d7e212b5f92 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Mon, 5 Feb 2024 10:40:39 +0000 Subject: [PATCH] From now on, when a student accepts an invite from a corporate, they are removed from previous corporate groups --- src/pages/api/invites/accept/[id].ts | 225 +++++++++++++-------------- 1 file changed, 108 insertions(+), 117 deletions(-) diff --git a/src/pages/api/invites/accept/[id].ts b/src/pages/api/invites/accept/[id].ts index ed2bb136..b12db506 100644 --- a/src/pages/api/invites/accept/[id].ts +++ b/src/pages/api/invites/accept/[id].ts @@ -1,137 +1,128 @@ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from "next"; -import { app } from "@/firebase"; -import { - getFirestore, - getDoc, - doc, - deleteDoc, - setDoc, - getDocs, - collection, - where, - query, -} from "firebase/firestore"; -import { withIronSessionApiRoute } from "iron-session/next"; -import { sessionOptions } from "@/lib/session"; -import { Ticket } from "@/interfaces/ticket"; -import { Invite } from "@/interfaces/invite"; -import { Group, User } from "@/interfaces/user"; -import { v4 } from "uuid"; -import { sendEmail } from "@/email"; -import { updateExpiryDateOnGroup } from "@/utils/groups.be"; +import type {NextApiRequest, NextApiResponse} from "next"; +import {app} from "@/firebase"; +import {getFirestore, getDoc, doc, deleteDoc, setDoc, getDocs, collection, where, query} from "firebase/firestore"; +import {withIronSessionApiRoute} from "iron-session/next"; +import {sessionOptions} from "@/lib/session"; +import {Ticket} from "@/interfaces/ticket"; +import {Invite} from "@/interfaces/invite"; +import {CorporateUser, Group, User} from "@/interfaces/user"; +import {v4} from "uuid"; +import {sendEmail} from "@/email"; +import {updateExpiryDateOnGroup} from "@/utils/groups.be"; const db = getFirestore(app); export default withIronSessionApiRoute(handler, sessionOptions); async function handler(req: NextApiRequest, res: NextApiResponse) { - if (req.method === "GET") return await get(req, res); + if (req.method === "GET") return await get(req, res); - res.status(404).json(undefined); + res.status(404).json(undefined); +} + +async function addToInviterGroup(user: User, invitedBy: User) { + const invitedByGroupsRef = await getDocs(query(collection(db, "groups"), where("admin", "==", invitedBy.id))); + const invitedByGroups = invitedByGroupsRef.docs.map((g) => ({ + ...g.data(), + id: g.id, + })) as Group[]; + + const typeGroupName = user.type === "student" ? "Students" : user.type === "teacher" ? "Teachers" : undefined; + + if (typeGroupName) { + const typeGroup: Group = invitedByGroups.find((g) => g.name === typeGroupName) || { + id: v4(), + admin: invitedBy.id, + name: typeGroupName, + participants: [], + disableEditing: true, + }; + await setDoc( + doc(db, "groups", typeGroup.id), + { + ...typeGroup, + participants: [...typeGroup.participants.filter((x) => x !== user.id), user.id], + }, + {merge: true}, + ); + } + + const invitationsGroup: Group = invitedByGroups.find((g) => g.name === "Invited") || { + id: v4(), + admin: invitedBy.id, + name: "Invited", + participants: [], + disableEditing: true, + }; + await setDoc( + doc(db, "groups", invitationsGroup.id), + { + ...invitationsGroup, + participants: [...invitationsGroup.participants.filter((x) => x !== user.id), user.id], + }, + { + merge: true, + }, + ); +} + +async function deleteFromPreviousCorporateGroups(user: User, invitedBy: User) { + const corporatesRef = await getDocs(query(collection(db, "users"), where("type", "==", "corporate"))); + const corporates = (corporatesRef.docs.map((x) => ({...x.data(), id: x.id})) as CorporateUser[]).filter((x) => x.id !== invitedBy.id); + + const userGroupsRef = await getDocs(query(collection(db, "groups"), where("participants", "array-contains", user.id))); + const userGroups = userGroupsRef.docs.map((x) => ({...x.data(), id: x.id})) as Group[]; + + const corporateGroups = userGroups.filter((x) => corporates.map((c) => c.id).includes(x.admin)); + await Promise.all( + corporateGroups.map(async (group) => { + await setDoc(doc(db, "groups", group.id), {participants: group.participants.filter((x) => x !== user.id)}, {merge: true}); + }), + ); } async function get(req: NextApiRequest, res: NextApiResponse) { - if (!req.session.user) { - res.status(401).json({ ok: false }); - return; - } + if (!req.session.user) { + res.status(401).json({ok: false}); + return; + } - const { id } = req.query as { id: string }; - const snapshot = await getDoc(doc(db, "invites", id)); + const {id} = req.query as {id: string}; + const snapshot = await getDoc(doc(db, "invites", id)); - if (snapshot.exists()) { - const invite = { ...snapshot.data(), id: snapshot.id } as Invite; - if (invite.to !== req.session.user.id) - return res.status(403).json({ ok: false }); + if (snapshot.exists()) { + const invite = {...snapshot.data(), id: snapshot.id} as Invite; + if (invite.to !== req.session.user.id) return res.status(403).json({ok: false}); - await deleteDoc(snapshot.ref); - const invitedByRef = await getDoc(doc(db, "users", invite.from)); - if (!invitedByRef.exists()) return res.status(404).json({ ok: false }); + await deleteDoc(snapshot.ref); + const invitedByRef = await getDoc(doc(db, "users", invite.from)); + if (!invitedByRef.exists()) return res.status(404).json({ok: false}); - await updateExpiryDateOnGroup(invite.to, invite.from); + await updateExpiryDateOnGroup(invite.to, invite.from); - const invitedBy = { ...invitedByRef.data(), id: invitedByRef.id } as User; - const invitedByGroupsRef = await getDocs( - query(collection(db, "groups"), where("admin", "==", invitedBy.id)), - ); - const invitedByGroups = invitedByGroupsRef.docs.map((g) => ({ - ...g.data(), - id: g.id, - })) as Group[]; + const invitedBy = {...invitedByRef.data(), id: invitedByRef.id} as User; - const typeGroupName = - req.session.user.type === "student" - ? "Students" - : req.session.user.type === "teacher" - ? "Teachers" - : undefined; + if (invitedBy.type === "corporate") await deleteFromPreviousCorporateGroups(req.session.user, invitedBy); + await addToInviterGroup(req.session.user, invitedBy); - if (typeGroupName) { - const typeGroup: Group = invitedByGroups.find( - (g) => g.name === typeGroupName, - ) || { - id: v4(), - admin: invitedBy.id, - name: typeGroupName, - participants: [], - disableEditing: true, - }; - await setDoc( - doc(db, "groups", typeGroup.id), - { - ...typeGroup, - participants: [ - ...typeGroup.participants.filter((x) => x !== req.session.user!.id), - req.session.user.id, - ], - }, - { merge: true }, - ); - } + try { + await sendEmail( + "respondedInvite", + { + corporateName: invitedBy.name, + name: req.session.user.name, + decision: "accept", + }, + [invitedBy.email], + `${req.session.user.name} has accepted your invite!`, + ); + } catch (e) { + console.log(e); + } - const invitationsGroup: Group = invitedByGroups.find( - (g) => g.name === "Invited", - ) || { - id: v4(), - admin: invitedBy.id, - name: "Invited", - participants: [], - disableEditing: true, - }; - await setDoc( - doc(db, "groups", invitationsGroup.id), - { - ...invitationsGroup, - participants: [ - ...invitationsGroup.participants.filter( - (x) => x !== req.session.user!.id, - ), - req.session.user.id, - ], - }, - { - merge: true, - }, - ); - - try { - await sendEmail( - "respondedInvite", - { - corporateName: invitedBy.name, - name: req.session.user.name, - decision: "accept", - }, - [invitedBy.email], - `${req.session.user.name} has accepted your invite!`, - ); - } catch (e) { - console.log(e); - } - - res.status(200).json({ ok: true }); - } else { - res.status(404).json(undefined); - } + res.status(200).json({ok: true}); + } else { + res.status(404).json(undefined); + } }