diff --git a/src/email/templates/assignment.handlebars b/src/email/templates/assignment.handlebars
index d4a0752e..4774de28 100644
--- a/src/email/templates/assignment.handlebars
+++ b/src/email/templates/assignment.handlebars
@@ -19,7 +19,7 @@
Don't forget to do it before its end date!
- Click here to open the EnCoach Platform!
+ Click here to open the EnCoach Platform!
Thanks,
Your EnCoach team
diff --git a/src/email/templates/main.handlebars b/src/email/templates/main.handlebars
index c7ac02a1..77a0f501 100644
--- a/src/email/templates/main.handlebars
+++ b/src/email/templates/main.handlebars
@@ -11,7 +11,8 @@
Hello future {{type}} of EnCoach ,
-
You have been invited to register at EnCoach
+ You have been invited to register at EnCoach
to
become a
{{type}}!
@@ -19,7 +20,7 @@
-
+
{{code}}
diff --git a/src/email/templates/verification.handlebars b/src/email/templates/verification.handlebars
index ebf387db..03a35498 100644
--- a/src/email/templates/verification.handlebars
+++ b/src/email/templates/verification.handlebars
@@ -10,7 +10,8 @@
Hello {{name}},
Follow this link to verify your email address.
- Verify account
+ Verify
+ account
If you didn’t ask to verify this address, you can ignore this email.
diff --git a/src/email/templates/verification.handlebars.json b/src/email/templates/verification.handlebars.json
index 2fbb1fad..c415aa8f 100644
--- a/src/email/templates/verification.handlebars.json
+++ b/src/email/templates/verification.handlebars.json
@@ -1,5 +1,6 @@
{
"name": "Tiago Ribeiro",
"email": "tiago.ribeiro@ecrop.dev",
- "code": "123"
+ "code": "123",
+ "environment": "platform"
}
\ No newline at end of file
diff --git a/src/pages/action.tsx b/src/pages/action.tsx
index f7564cd5..bee4552a 100644
--- a/src/pages/action.tsx
+++ b/src/pages/action.tsx
@@ -1,227 +1,170 @@
/* eslint-disable @next/next/no-img-element */
-import { toast, ToastContainer } from "react-toastify";
+import {toast, ToastContainer} from "react-toastify";
import axios from "axios";
-import { FormEvent, useEffect, useState } from "react";
+import {FormEvent, useEffect, useState} from "react";
import Head from "next/head";
import useUser from "@/hooks/useUser";
-import { Divider } from "primereact/divider";
+import {Divider} from "primereact/divider";
import Button from "@/components/Low/Button";
-import { BsArrowRepeat } from "react-icons/bs";
+import {BsArrowRepeat} from "react-icons/bs";
import Link from "next/link";
import Input from "@/components/Low/Input";
-import { useRouter } from "next/router";
+import {useRouter} from "next/router";
export function getServerSideProps({
- query,
- res,
+ query,
+ res,
}: {
- query: {
- oobCode: string;
- mode: string;
- continueUrl?: string;
- };
- res: any;
+ query: {
+ oobCode: string;
+ mode: string;
+ continueUrl?: string;
+ };
+ res: any;
}) {
- if (!query || !query.oobCode || !query.mode) {
- res.setHeader("location", "/login");
- res.statusCode = 302;
- res.end();
- return {
- props: {},
- };
- }
+ if (!query || !query.oobCode || !query.mode) {
+ res.setHeader("location", "/login");
+ res.statusCode = 302;
+ res.end();
+ return {
+ props: {},
+ };
+ }
- return {
- props: {
- code: query.oobCode,
- mode: query.mode,
- ...(query.continueUrl ? { continueUrl: query.continueUrl } : {}),
- },
- };
+ return {
+ props: {
+ code: query.oobCode,
+ mode: query.mode,
+ ...(query.continueUrl ? {continueUrl: query.continueUrl} : {}),
+ },
+ };
}
-export default function Reset({
- code,
- mode,
- continueUrl,
-}: {
- code: string;
- mode: string;
- continueUrl?: string;
-}) {
- const [password, setPassword] = useState("");
- const [isLoading, setIsLoading] = useState(false);
+export default function Reset({code, mode, continueUrl}: {code: string; mode: string; continueUrl?: string}) {
+ const [password, setPassword] = useState("");
+ const [isLoading, setIsLoading] = useState(false);
- const router = useRouter();
+ const router = useRouter();
- useUser({
- redirectTo: "/",
- redirectIfFound: true,
- });
+ useUser({
+ redirectTo: "/",
+ redirectIfFound: true,
+ });
- useEffect(() => {
- if (mode === "signIn") {
- axios
- .post<{ ok: boolean }>("/api/reset/verify", {
- email: continueUrl?.replace("https://platform.encoach.com/", ""),
- })
- .then((response) => {
- if (response.data.ok) {
- toast.success("Your account has been verified!", {
- toastId: "verify-successful",
- });
- setTimeout(() => {
- router.push("/");
- }, 1000);
- return;
- }
+ useEffect(() => {
+ if (mode === "signIn") {
+ axios
+ .post<{ok: boolean}>("/api/reset/verify", {
+ email: continueUrl?.replace("https://platform.encoach.com/", "").replace("https://staging.encoach.com/", ""),
+ })
+ .then((response) => {
+ if (response.data.ok) {
+ toast.success("Your account has been verified!", {
+ toastId: "verify-successful",
+ });
+ setTimeout(() => {
+ router.push("/");
+ }, 1000);
+ return;
+ }
- toast.error(
- "Something went wrong! Please make sure to click the link in your e-mail again and input the correct e-mail!",
- {
- toastId: "verify-error",
- },
- );
- })
- .catch(() => {
- toast.error(
- "Something went wrong! Please make sure to click the link in your e-mail again and input the correct e-mail!",
- {
- toastId: "verify-error",
- },
- );
- setIsLoading(false);
- });
- }
- });
+ toast.error("Something went wrong! Please make sure to click the link in your e-mail again and input the correct e-mail!", {
+ toastId: "verify-error",
+ });
+ })
+ .catch(() => {
+ toast.error("Something went wrong! Please make sure to click the link in your e-mail again and input the correct e-mail!", {
+ toastId: "verify-error",
+ });
+ setIsLoading(false);
+ });
+ }
+ });
- const login = (e: FormEvent) => {
- e.preventDefault();
+ const login = (e: FormEvent) => {
+ e.preventDefault();
- setIsLoading(true);
- axios
- .post<{ ok: boolean }>("/api/reset/confirm", { code, password })
- .then((response) => {
- if (response.data.ok) {
- toast.success("Your password has been reset!", {
- toastId: "reset-successful",
- });
- setTimeout(() => {
- router.push("/login");
- }, 1000);
- return;
- }
+ setIsLoading(true);
+ axios
+ .post<{ok: boolean}>("/api/reset/confirm", {code, password})
+ .then((response) => {
+ if (response.data.ok) {
+ toast.success("Your password has been reset!", {
+ toastId: "reset-successful",
+ });
+ setTimeout(() => {
+ router.push("/login");
+ }, 1000);
+ return;
+ }
- toast.error(
- "Something went wrong! Please make sure to click the link in your e-mail again!",
- { toastId: "reset-error" },
- );
- })
- .catch(() => {
- toast.error(
- "Something went wrong! Please make sure to click the link in your e-mail again!",
- { toastId: "reset-error" },
- );
- })
- .finally(() => setIsLoading(false));
- };
+ toast.error("Something went wrong! Please make sure to click the link in your e-mail again!", {toastId: "reset-error"});
+ })
+ .catch(() => {
+ toast.error("Something went wrong! Please make sure to click the link in your e-mail again!", {toastId: "reset-error"});
+ })
+ .finally(() => setIsLoading(false));
+ };
- return (
- <>
-
- Reset | EnCoach
-
-
-
-
-
-
-
-
-
-
- {mode === "resetPassword" && (
-
-
-
-
- Reset your password
-
-
- to your registered Email Address
-
-
-
-
+
+ Don't have an account?{" "}
+
+ Sign up
+
+
+
+ )}
+ {mode === "signIn" && (
+
+
+
+
Confirm your account
+
to your registered Email Address
+
+
+
+
+ Your e-mail is currently being verified, please wait a second.
+ Once it has been verified, you will be redirected to the home page.
+
+
+
+ )}
+
+ >
+ );
}
diff --git a/src/pages/api/assignments/index.ts b/src/pages/api/assignments/index.ts
index 471b8376..4d0cc11a 100644
--- a/src/pages/api/assignments/index.ts
+++ b/src/pages/api/assignments/index.ts
@@ -163,6 +163,7 @@ async function POST(req: NextApiRequest, res: NextApiResponse) {
modules: examModulesLabel,
assigner: teacher.name,
},
+ environment: process.env.ENVIRONMENT,
},
[assignee.email],
"EnCoach - New Assignment!",
diff --git a/src/pages/api/invites/accept/[id].ts b/src/pages/api/invites/accept/[id].ts
index b12db506..20e8445e 100644
--- a/src/pages/api/invites/accept/[id].ts
+++ b/src/pages/api/invites/accept/[id].ts
@@ -113,6 +113,7 @@ async function get(req: NextApiRequest, res: NextApiResponse) {
corporateName: invitedBy.name,
name: req.session.user.name,
decision: "accept",
+ environment: process.env.ENVIRONMENT,
},
[invitedBy.email],
`${req.session.user.name} has accepted your invite!`,
diff --git a/src/pages/api/invites/decline/[id].ts b/src/pages/api/invites/decline/[id].ts
index e8ab55a9..4110e70b 100644
--- a/src/pages/api/invites/decline/[id].ts
+++ b/src/pages/api/invites/decline/[id].ts
@@ -1,72 +1,62 @@
// 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 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";
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 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});
- const invitedBy = { ...invitedByRef.data(), id: invitedByRef.id } as User;
+ const invitedBy = {...invitedByRef.data(), id: invitedByRef.id} as User;
- try {
- await sendEmail(
- "respondedInvite",
- {
- corporateName: invitedBy.name,
- name: req.session.user.name,
- decision: "decline",
- },
- [invitedBy.email],
- `${req.session.user.name} has declined your invite!`,
- );
- } catch (e) {
- console.log(e);
- }
+ try {
+ await sendEmail(
+ "respondedInvite",
+ {
+ corporateName: invitedBy.name,
+ name: req.session.user.name,
+ decision: "decline",
+ environment: process.env.ENVIRONMENT,
+ },
+ [invitedBy.email],
+ `${req.session.user.name} has declined 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);
+ }
}
diff --git a/src/pages/api/invites/index.ts b/src/pages/api/invites/index.ts
index 023e6e2d..efc88d72 100644
--- a/src/pages/api/invites/index.ts
+++ b/src/pages/api/invites/index.ts
@@ -1,20 +1,13 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
-import { sendEmail } from "@/email";
-import { app } from "@/firebase";
-import { Invite } from "@/interfaces/invite";
-import { Ticket } from "@/interfaces/ticket";
-import { User } from "@/interfaces/user";
-import { sessionOptions } from "@/lib/session";
-import {
- collection,
- doc,
- getDoc,
- getDocs,
- getFirestore,
- setDoc,
-} from "firebase/firestore";
-import { withIronSessionApiRoute } from "iron-session/next";
-import type { NextApiRequest, NextApiResponse } from "next";
+import {sendEmail} from "@/email";
+import {app} from "@/firebase";
+import {Invite} from "@/interfaces/invite";
+import {Ticket} from "@/interfaces/ticket";
+import {User} from "@/interfaces/user";
+import {sessionOptions} from "@/lib/session";
+import {collection, doc, getDoc, getDocs, getFirestore, setDoc} from "firebase/firestore";
+import {withIronSessionApiRoute} from "iron-session/next";
+import type {NextApiRequest, NextApiResponse} from "next";
import ShortUniqueId from "short-unique-id";
const db = getFirestore(app);
@@ -22,67 +15,60 @@ const db = getFirestore(app);
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(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;
+ }
- if (req.method === "GET") await get(req, res);
- if (req.method === "POST") await post(req, res);
+ if (req.method === "GET") await get(req, res);
+ if (req.method === "POST") await post(req, res);
}
async function get(req: NextApiRequest, res: NextApiResponse) {
- const snapshot = await getDocs(collection(db, "invites"));
+ const snapshot = await getDocs(collection(db, "invites"));
- res.status(200).json(
- snapshot.docs.map((doc) => ({
- id: doc.id,
- ...doc.data(),
- })),
- );
+ res.status(200).json(
+ snapshot.docs.map((doc) => ({
+ id: doc.id,
+ ...doc.data(),
+ })),
+ );
}
async function post(req: NextApiRequest, res: NextApiResponse) {
- const body = req.body as Invite;
+ const body = req.body as Invite;
- const existingInvites = (await getDocs(collection(db, "invites"))).docs.map(
- (x) => ({ ...x.data(), id: x.id }),
- ) as Invite[];
+ const existingInvites = (await getDocs(collection(db, "invites"))).docs.map((x) => ({...x.data(), id: x.id})) as Invite[];
- const invitedRef = await getDoc(doc(db, "users", body.to));
- if (!invitedRef.exists()) return res.status(404).json({ ok: false });
+ const invitedRef = await getDoc(doc(db, "users", body.to));
+ if (!invitedRef.exists()) return res.status(404).json({ok: false});
- const invitedByRef = await getDoc(doc(db, "users", body.from));
- if (!invitedByRef.exists()) return res.status(404).json({ ok: false });
+ const invitedByRef = await getDoc(doc(db, "users", body.from));
+ if (!invitedByRef.exists()) return res.status(404).json({ok: false});
- const invited = { ...invitedRef.data(), id: invitedRef.id } as User;
- const invitedBy = { ...invitedByRef.data(), id: invitedByRef.id } as User;
+ const invited = {...invitedRef.data(), id: invitedRef.id} as User;
+ const invitedBy = {...invitedByRef.data(), id: invitedByRef.id} as User;
- try {
- await sendEmail(
- "receivedInvite",
- {
- name: invited.name,
- corporateName:
- invitedBy.type === "corporate"
- ? invitedBy.corporateInformation?.companyInformation?.name ||
- invitedBy.name
- : invitedBy.name,
- },
- [invited.email],
- "You have been invited to a group!",
- );
- } catch (e) {
- console.log(e);
- }
+ try {
+ await sendEmail(
+ "receivedInvite",
+ {
+ name: invited.name,
+ corporateName:
+ invitedBy.type === "corporate" ? invitedBy.corporateInformation?.companyInformation?.name || invitedBy.name : invitedBy.name,
+ environment: process.env.ENVIRONMENT,
+ },
+ [invited.email],
+ "You have been invited to a group!",
+ );
+ } catch (e) {
+ console.log(e);
+ }
- if (
- existingInvites.filter((i) => i.to === body.to && i.from === body.from)
- .length == 0
- ) {
- const shortUID = new ShortUniqueId();
- await setDoc(doc(db, "invites", body.id || shortUID.randomUUID(8)), body);
- }
+ if (existingInvites.filter((i) => i.to === body.to && i.from === body.from).length == 0) {
+ const shortUID = new ShortUniqueId();
+ await setDoc(doc(db, "invites", body.id || shortUID.randomUUID(8)), body);
+ }
- res.status(200).json({ ok: true });
+ res.status(200).json({ok: true});
}
diff --git a/src/pages/api/reset/sendVerification.ts b/src/pages/api/reset/sendVerification.ts
index cb582cb1..1116cc2d 100644
--- a/src/pages/api/reset/sendVerification.ts
+++ b/src/pages/api/reset/sendVerification.ts
@@ -19,6 +19,7 @@ async function sendVerification(req: NextApiRequest, res: NextApiResponse) {
name: req.session.user.name,
code: short.randomUUID(6),
email: req.session.user.email,
+ environment: process.env.ENVIRONMENT,
},
[req.session.user.email],
"EnCoach Verification",
diff --git a/src/pages/api/tickets/[id].ts b/src/pages/api/tickets/[id].ts
index 29e35e45..f55ca518 100644
--- a/src/pages/api/tickets/[id].ts
+++ b/src/pages/api/tickets/[id].ts
@@ -1,109 +1,104 @@
// 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,
-} from "firebase/firestore";
-import { withIronSessionApiRoute } from "iron-session/next";
-import { sessionOptions } from "@/lib/session";
-import { Ticket, TicketTypeLabel, TicketStatusLabel } from "@/interfaces/ticket";
+import type {NextApiRequest, NextApiResponse} from "next";
+import {app} from "@/firebase";
+import {getFirestore, getDoc, doc, deleteDoc, setDoc} from "firebase/firestore";
+import {withIronSessionApiRoute} from "iron-session/next";
+import {sessionOptions} from "@/lib/session";
+import {Ticket, TicketTypeLabel, TicketStatusLabel} from "@/interfaces/ticket";
import moment from "moment";
-import { sendEmail } from "@/email";
+import {sendEmail} from "@/email";
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 === "DELETE") return await del(req, res);
- if (req.method === "PATCH") return await patch(req, res);
+ if (req.method === "GET") return await get(req, res);
+ if (req.method === "DELETE") return await del(req, res);
+ if (req.method === "PATCH") return await patch(req, res);
- res.status(404).json(undefined);
+ res.status(404).json(undefined);
}
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 {id} = req.query as {id: string};
- const snapshot = await getDoc(doc(db, "tickets", id));
+ const snapshot = await getDoc(doc(db, "tickets", id));
- if (snapshot.exists()) {
- res.status(200).json({ ...snapshot.data(), id: snapshot.id });
- } else {
- res.status(404).json(undefined);
- }
+ if (snapshot.exists()) {
+ res.status(200).json({...snapshot.data(), id: snapshot.id});
+ } else {
+ res.status(404).json(undefined);
+ }
}
async function del(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 {id} = req.query as {id: string};
- const snapshot = await getDoc(doc(db, "tickets", id));
- const data = snapshot.data() as Ticket;
+ const snapshot = await getDoc(doc(db, "tickets", id));
+ const data = snapshot.data() as Ticket;
- const user = req.session.user;
- if (user.type === "admin" || user.type === "developer") {
- await deleteDoc(snapshot.ref);
- res.status(200).json({ ok: true });
- return;
- }
+ const user = req.session.user;
+ if (user.type === "admin" || user.type === "developer") {
+ await deleteDoc(snapshot.ref);
+ res.status(200).json({ok: true});
+ return;
+ }
- res.status(403).json({ ok: false });
+ res.status(403).json({ok: false});
}
async function patch(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 body = req.body as Ticket;
+ const {id} = req.query as {id: string};
+ const body = req.body as Ticket;
- const snapshot = await getDoc(doc(db, "tickets", id));
+ const snapshot = await getDoc(doc(db, "tickets", id));
- const user = req.session.user;
- if (user.type === "admin" || user.type === "developer") {
- const data = snapshot.data() as Ticket;
- await setDoc(snapshot.ref, body, { merge: true });
- try {
- // send email if the status actually changed to completed
- if(data.status !== req.body.status && req.body.status === 'completed') {
- await sendEmail(
- "ticketStatusCompleted",
- {
- id,
- subject: body.subject,
- reporter: body.reporter,
- date: moment(body.date).format("DD/MM/YYYY - HH:mm"),
- type: TicketTypeLabel[body.type],
- reportedFrom: body.reportedFrom,
- description: body.description,
- },
- [data.reporter.email],
- `Ticket ${id}: ${data.subject}`,
- );
- }
- } catch(err) {
- console.error(err);
- // doesnt matter if the email fails
- }
- res.status(200).json({ ok: true });
- return;
- }
+ const user = req.session.user;
+ if (user.type === "admin" || user.type === "developer") {
+ const data = snapshot.data() as Ticket;
+ await setDoc(snapshot.ref, body, {merge: true});
+ try {
+ // send email if the status actually changed to completed
+ if (data.status !== req.body.status && req.body.status === "completed") {
+ await sendEmail(
+ "ticketStatusCompleted",
+ {
+ id,
+ subject: body.subject,
+ reporter: body.reporter,
+ date: moment(body.date).format("DD/MM/YYYY - HH:mm"),
+ type: TicketTypeLabel[body.type],
+ reportedFrom: body.reportedFrom,
+ description: body.description,
+ environment: process.env.ENVIRONMENT,
+ },
+ [data.reporter.email],
+ `Ticket ${id}: ${data.subject}`,
+ );
+ }
+ } catch (err) {
+ console.error(err);
+ // doesnt matter if the email fails
+ }
+ res.status(200).json({ok: true});
+ return;
+ }
- res.status(403).json({ ok: false });
+ res.status(403).json({ok: false});
}
diff --git a/src/pages/api/tickets/index.ts b/src/pages/api/tickets/index.ts
index d7daa365..d99b9fee 100644
--- a/src/pages/api/tickets/index.ts
+++ b/src/pages/api/tickets/index.ts
@@ -1,110 +1,103 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
-import { sendEmail } from "@/email";
-import { app } from "@/firebase";
-import { Ticket, TicketTypeLabel, TicketWithCorporate } from "@/interfaces/ticket";
-import { sessionOptions } from "@/lib/session";
-import {
- collection,
- doc,
- getDocs,
- getFirestore,
- setDoc,
- where,
- query,
-} from "firebase/firestore";
-import { withIronSessionApiRoute } from "iron-session/next";
+import {sendEmail} from "@/email";
+import {app} from "@/firebase";
+import {Ticket, TicketTypeLabel, TicketWithCorporate} from "@/interfaces/ticket";
+import {sessionOptions} from "@/lib/session";
+import {collection, doc, getDocs, getFirestore, setDoc, where, query} from "firebase/firestore";
+import {withIronSessionApiRoute} from "iron-session/next";
import moment from "moment";
-import type { NextApiRequest, NextApiResponse } from "next";
+import type {NextApiRequest, NextApiResponse} from "next";
import ShortUniqueId from "short-unique-id";
-import { Group, CorporateUser } from "@/interfaces/user";
+import {Group, CorporateUser} from "@/interfaces/user";
const db = getFirestore(app);
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
- // due to integration with the homepage the POST request should be public
- if (req.method === "POST") {
- await post(req, res);
- return;
- }
+ // due to integration with the homepage the POST request should be public
+ if (req.method === "POST") {
+ await post(req, res);
+ return;
+ }
- // specific logic for the preflight request
- if (req.method === "OPTIONS") {
- res.status(200).end();
- return;
- }
- if (!req.session.user) {
- res.status(401).json({ ok: false });
- return;
- }
+ // specific logic for the preflight request
+ if (req.method === "OPTIONS") {
+ res.status(200).end();
+ return;
+ }
+ if (!req.session.user) {
+ res.status(401).json({ok: false});
+ return;
+ }
- if (req.method === "GET") {
- await get(req, res);
- }
+ if (req.method === "GET") {
+ await get(req, res);
+ }
}
async function get(req: NextApiRequest, res: NextApiResponse) {
- const snapshot = await getDocs(collection(db, "tickets"));
+ const snapshot = await getDocs(collection(db, "tickets"));
- const docs = snapshot.docs.map((doc) => ({
- id: doc.id,
- ...doc.data(),
- })) as Ticket[];
+ const docs = snapshot.docs.map((doc) => ({
+ id: doc.id,
+ ...doc.data(),
+ })) as Ticket[];
- // fetch all groups for these users
+ // fetch all groups for these users
- const reporters = [...new Set(docs.map((d) => d.reporter.id).filter((id) => id))];
+ const reporters = [...new Set(docs.map((d) => d.reporter.id).filter((id) => id))];
- const groupsSnapshot = await getDocs(query(collection(db, "groups"), where("participants", "array-contains-any", reporters)));
- const groups = groupsSnapshot.docs.map((doc) => doc.data()) as Group[];
+ const groupsSnapshot = await getDocs(query(collection(db, "groups"), where("participants", "array-contains-any", reporters)));
+ const groups = groupsSnapshot.docs.map((doc) => doc.data()) as Group[];
- // based on the admin of each group, verify if it exists and it's of type corporate
- const groupsAdmins = [...new Set(groups.map((g) => g.admin).filter((id) => id))];
- const adminsSnapshot = await getDocs(query(collection(db, "users"), where("id", "in", groupsAdmins), where("type", "==", "corporate")));
- const admins = adminsSnapshot.docs.map((doc) => doc.data());
+ // based on the admin of each group, verify if it exists and it's of type corporate
+ const groupsAdmins = [...new Set(groups.map((g) => g.admin).filter((id) => id))];
+ const adminsSnapshot = await getDocs(query(collection(db, "users"), where("id", "in", groupsAdmins), where("type", "==", "corporate")));
+ const admins = adminsSnapshot.docs.map((doc) => doc.data());
- const docsWithAdmins = docs.map((d) => {
- const group = groups.find((g) => g.participants.includes(d.reporter.id));
- const admin = admins.find((a) => a.id === group?.admin) as CorporateUser;
+ const docsWithAdmins = docs.map((d) => {
+ const group = groups.find((g) => g.participants.includes(d.reporter.id));
+ const admin = admins.find((a) => a.id === group?.admin) as CorporateUser;
- if(admin) {
- return {
- ...d,
- corporate: admin.corporateInformation?.companyInformation?.name,
- };
- }
+ if (admin) {
+ return {
+ ...d,
+ corporate: admin.corporateInformation?.companyInformation?.name,
+ };
+ }
- return d;
- }) as TicketWithCorporate[];
+ return d;
+ }) as TicketWithCorporate[];
- res.status(200).json(docsWithAdmins);
+ res.status(200).json(docsWithAdmins);
}
async function post(req: NextApiRequest, res: NextApiResponse) {
- const body = req.body as Ticket;
+ const body = req.body as Ticket;
- const shortUID = new ShortUniqueId();
- const id = body.id || shortUID.randomUUID(8);
- await setDoc(doc(db, "tickets", id), body);
- res.status(200).json({ ok: true });
+ const shortUID = new ShortUniqueId();
+ const id = body.id || shortUID.randomUUID(8);
+ await setDoc(doc(db, "tickets", id), body);
+ res.status(200).json({ok: true});
- try {
- await sendEmail(
- "submittedFeedback",
- {
- id,
- subject: body.subject,
- reporter: body.reporter,
- date: moment(body.date).format("DD/MM/YYYY - HH:mm"),
- type: TicketTypeLabel[body.type],
- reportedFrom: body.reportedFrom,
- description: body.description,
- },
- [body.reporter.email],
- `Ticket ${id}: ${body.subject}`
- );
- } catch (e) {
- console.log(e);
- }
+ try {
+ await sendEmail(
+ "submittedFeedback",
+ {
+ id,
+ subject: body.subject,
+ reporter: body.reporter,
+ date: moment(body.date).format("DD/MM/YYYY - HH:mm"),
+ type: TicketTypeLabel[body.type],
+ reportedFrom: body.reportedFrom,
+ description: body.description,
+ environment: process.env.ENVIRONMENT,
+ },
+ [body.reporter.email],
+ `Ticket ${id}: ${body.subject}`,
+ );
+ } catch (e) {
+ console.log(e);
+ }
}