Skip to content

Commit

Permalink
add admin emailing and mark placeholders
Browse files Browse the repository at this point in the history
  • Loading branch information
bowenzhu1 committed Dec 27, 2022
1 parent 6c6ef22 commit d547626
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 28 deletions.
21 changes: 8 additions & 13 deletions backend/typescript/rest/camperRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import CamperService from "../services/implementations/camperService";
import ICamperService from "../services/interfaces/camperService";
import { getErrorMessage } from "../utilities/errorUtils";
import { sendResponseByMimeType } from "../utilities/responseUtil";
import { CamperDTO, CreateCampersDTO, WaitlistedCamperDTO } from "../types";
import {
CamperDTO,
CreateCampersDTO,
EmailDTO,
WaitlistedCamperDTO,
} from "../types";
import { createWaitlistedCamperDtoValidator } from "../middlewares/validators/waitlistedCamperValidators";
import IEmailService from "../services/interfaces/emailService";
import EmailService from "../services/implementations/emailService";
Expand All @@ -22,17 +27,17 @@ const camperRouter: Router = Router();

const camperService: ICamperService = new CamperService();

const emailService: IEmailService = new EmailService(nodemailerConfig);

// ROLES: Leaving unprotected as the registration flow probs needs this endpoint to register @dhruv
/* Create a camper */
camperRouter.post("/register", createCampersDtoValidator, async (req, res) => {
try {
const campers = req.body.campers as CreateCampersDTO;
const campSessions = req.body.campSessions as string[];
const waiverContent = req.body.waiverContent as EmailDTO;
const newCampers = await camperService.createCampers(
campers,
campSessions,
waiverContent,
req.query?.wId as string,
);
res.status(201).json(newCampers);
Expand All @@ -41,16 +46,6 @@ camperRouter.post("/register", createCampersDtoValidator, async (req, res) => {
}
});

camperRouter.post("/email", async (req, res) => {
try {
const waiverContent = req.body;
emailService.sendWaiverEmail(waiverContent);
res.status(201);
} catch (error: unknown) {
res.status(500).json({ error: getErrorMessage(error) });
}
});

// ROLES: Admin + CC
/* Get all campers, optionally filter by camp ID */
camperRouter.get(
Expand Down
11 changes: 8 additions & 3 deletions backend/typescript/services/implementations/camperService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
WaitlistedCamperDTO,
UpdateCamperDTO,
CamperCharges,
EmailDTO,
} from "../../types";
import { getErrorMessage } from "../../utilities/errorUtils";
import logger from "../../utilities/logger";
Expand Down Expand Up @@ -80,7 +81,7 @@ class CamperService implements ICamperService {
async createCampers(
campers: CreateCampersDTO,
campSessions: string[],
waiverContent: string,
waiverContent: EmailDTO,
waitlistedCamperId?: string,
): Promise<CamperDTO[]> {
const session = await mongoose.startSession();
Expand Down Expand Up @@ -246,10 +247,11 @@ class CamperService implements ICamperService {
);

// Email the parent about all the campers and sessions they have signed up for
await emailService.sendRegistrationEmails(
await emailService.sendConfirmationEmails(
camp,
registeredCampers,
sessionsToRegister,
waiverContent,
);

// Send admin an email for all the sessions that are now full
Expand Down Expand Up @@ -449,7 +451,10 @@ class CamperService implements ICamperService {
): Promise<CamperDTO[]> {
try {
// eslint-disable-next-line prettier/prettier
const campers: Camper[] = await MgCamper.find({ chargeId, campSession: sessionId });
const campers: Camper[] = await MgCamper.find({
chargeId,
campSession: sessionId,
});

if (!campers || campers.length === 0) {
throw new Error(
Expand Down
58 changes: 52 additions & 6 deletions backend/typescript/services/implementations/emailService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { CampSession } from "../../models/campSession.model";
import { WaitlistedCamper } from "../../models/waitlistedCamper.model";

// TODO: swap out this email for the focus on nature admin email
const ADMIN_EMAIL = "[email protected]";
const ADMIN_EMAIL = "[email protected]";

const Logger = logger(__filename);

Expand Down Expand Up @@ -48,26 +48,71 @@ class EmailService implements IEmailService {
}
}

async sendWaiverEmail(waiverContent: EmailDTO): Promise<void> {
async sendConfirmationEmails(
camp: Camp,
campers: Camper[],
campSessions: CampSession[],
waiverContent: EmailDTO,
): Promise<void> {
const pdfAttachment: Attachment = {
filename: "waiver.pdf",
content: Buffer.from(waiverContent.pdf),
contentType: "application/pdf",
encoding: "base64",
};

await this.sendAdminConfirmationEmail(camp, campers, campSessions, [
pdfAttachment,
]);

await this.sendParentConfirmationEmail(camp, campers, campSessions, [
pdfAttachment,
]);
}

async sendAdminConfirmationEmail(
camp: Camp,
campers: Camper[],
campSessions: CampSession[],
attachments: Attachment[],
): Promise<void> {
const sessionDatesListItems: string[] = getSessionDatesListItems(
campSessions,
);

await this.sendEmail(
"[email protected]",
"Focus on Nature Camp Registration - Waiver",
"A copy of your Focus on Nature Camp Registration is attached.",
[pdfAttachment],
ADMIN_EMAIL,
`Waiver Responses for
${campers.map((camper) => {
return `${camper.firstName} ${camper.lastName},`;
})}
for ${camp.name}`,
`<ul>
<li><b>Campers:</b></li>
${campers
.map((camper) => {
return `<ul>
<li><b>Name:</b> ${camper.firstName} ${camper.lastName}</li>
<ul><li><b>Age:</b> ${camper.age}</li></ul>
</ul>`;
})
.join("")}
<li><b>Camp name:</b> ${camp.name}</li>
<li><b>Session dates:</b></li>
<ol>
${sessionDatesListItems.join("")}
</ol>
<li><b>Responses Received on:</b> </li>
</ul>`,
attachments,
);
}

async sendParentConfirmationEmail(
camp: Camp,
campers: Camper[],
campSessions: CampSession[],
attachments: Attachment[],
): Promise<void> {
const contact = campers[0].contacts[0];
const link = "DUMMY LINK"; // TODO: Update link
Expand Down Expand Up @@ -147,6 +192,7 @@ class EmailService implements IEmailService {
if we have another camper on our waitlist.
<br><br>Thanks, <br><br>
Focus on Nature`,
attachments,
);
}

Expand Down
3 changes: 2 additions & 1 deletion backend/typescript/services/interfaces/camperService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
CreateWaitlistedCamperDTO,
WaitlistedCamperDTO,
UpdateCamperDTO,
EmailDTO,
} from "../../types";

interface ICamperService {
Expand All @@ -19,7 +20,7 @@ interface ICamperService {
createCampers(
campers: CreateCampersDTO,
campSessions: string[],
waiverContent: string,
waiverContent: EmailDTO,
waitlistedCamperId?: string,
): Promise<CamperDTO[]>;

Expand Down
14 changes: 9 additions & 5 deletions backend/typescript/services/interfaces/emailService.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
import { Attachment } from "nodemailer/lib/mailer";
import { Camp } from "../../models/camp.model";
import { Camper } from "../../models/camper.model";
import { CampSession } from "../../models/campSession.model";
import { WaitlistedCamper } from "../../models/waitlistedCamper.model";
import { EmailDTO } from "../../types";

interface IEmailService {
/**
* Send camp registration confirmation email.
* Wrapper to send camp registration confirmation emails
* to admin and parents with waiver pdf attached.
* @throws Error if email was not sent successfully
*/
sendConfirmationEmails(
camp: Camp,
campers: Camper[],
campSessions: CampSession[],
waiverContent: string,
waiverContent: EmailDTO,
): Promise<void>;

/**
* Send camp registration confirmation email.
* Send camp registration confirmation email to admin.
* @throws Error if email was not sent successfully
*/
sendAdminConfirmationEmail(
camp: Camp,
campers: Camper[],
campSessions: CampSession[],
waiverContent: string,
attachments: Attachment[],
): Promise<void>;

/**
* Send camp registration confirmation email.
* Send camp registration confirmation email to parent.
* @throws Error if email was not sent successfully
*/
sendParentConfirmationEmail(
camp: Camp,
campers: Camper[],
campSessions: CampSession[],
attachments: Attachment[],
): Promise<void>;

/**
Expand Down

0 comments on commit d547626

Please sign in to comment.