Skip to content

Commit

Permalink
First pass, working email template
Browse files Browse the repository at this point in the history
  • Loading branch information
francisli committed Nov 13, 2024
1 parent 24e1a5b commit 166575c
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ EMAIL_AUTH_PASS=
EMAIL_FROM=no-reply@compassiep.org
EMAIL_HOST=localhost
EMAIL_PORT=1025

BASE_URL=http://localhost:3000
15 changes: 15 additions & 0 deletions src/backend/emails/_button.html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%; min-width: 100%;" width="100%">
<tbody>
<tr>
<td align="left" style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 16px;" valign="top">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
<tbody>
<tr>
<td style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; border-radius: 4px; text-align: center; background-color: #0867ec;" valign="top" align="center" bgcolor="#0867ec"> <a href="<%= url %>" target="_blank" style="border: solid 2px #0867ec; border-radius: 4px; box-sizing: border-box; cursor: pointer; display: inline-block; font-size: 16px; font-weight: bold; margin: 0; padding: 12px 24px; text-decoration: none; text-transform: capitalize; background-color: #0867ec; border-color: #0867ec; color: #ffffff;"><%= label %></a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
31 changes: 31 additions & 0 deletions src/backend/emails/_footer.html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
</td>
</tr>

<!-- END MAIN CONTENT AREA -->
</table>

<!-- START FOOTER -->
<div class="footer" style="clear: both; padding-top: 24px; text-align: center; width: 100%;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
<tr>
<td class="content-block" style="font-family: Helvetica, sans-serif; vertical-align: top; color: #9a9ea6; font-size: 16px; text-align: center;" valign="top" align="center">
<span class="apple-link" style="color: #9a9ea6; font-size: 16px; text-align: center;">Copyright &copy; <%= new Date().getFullYear() %> Compass</span>
</td>
</tr>
<tr>
<td class="content-block powered-by" style="font-family: Helvetica, sans-serif; vertical-align: top; color: #9a9ea6; font-size: 16px; text-align: center;" valign="top" align="center">
<a href="<%= env.BASE_URL %>" style="color: #9a9ea6; font-size: 16px; text-align: center; text-decoration: none;"><%= env.BASE_URL %></a>
</td>
</tr>
</table>
</div>

<!-- END FOOTER -->

<!-- END CENTERED WHITE CONTAINER --></div>
</td>
<td style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top;" valign="top">&nbsp;</td>
</tr>
</table>
</body>
</html>
3 changes: 3 additions & 0 deletions src/backend/emails/_footer.text.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
----
Copyright (C) <%= new Date().getFullYear() %> Compass
<%= env.BASE_URL %>
77 changes: 77 additions & 0 deletions src/backend/emails/_header.html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!doctype html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style media="all" type="text/css">
@media only screen and (max-width: 640px) {
.main p,
.main td,
.main span {
font-size: 16px !important;
}
.wrapper {
padding: 8px !important;
}
.content {
padding: 0 !important;
}
.container {
padding: 0 !important;
padding-top: 8px !important;
width: 100% !important;
}
.main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
.btn table {
max-width: 100% !important;
width: 100% !important;
}
.btn a {
font-size: 16px !important;
max-width: 100% !important;
width: 100% !important;
}
}
@media all {
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
}
</style>
</head>
<body style="font-family: Helvetica, sans-serif; -webkit-font-smoothing: antialiased; font-size: 16px; line-height: 1.3; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; background-color: #f4f5f6; margin: 0; padding: 0;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: #f4f5f6; width: 100%;" width="100%" bgcolor="#f4f5f6">
<tr>
<td style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top;" valign="top">&nbsp;</td>
<td class="container" style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; max-width: 600px; padding: 0; padding-top: 24px; width: 600px; margin: 0 auto;" width="600" valign="top">
<div class="content" style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 600px; padding: 0;">

<!-- START CENTERED WHITE CONTAINER -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background: #ffffff; border: 1px solid #eaebed; border-radius: 16px; width: 100%;" width="100%">
<!-- START BRAND HEADER AREA -->
<tr>
<td style="background-color: rgb(208, 235, 255); height: 80px; display: flex; justify-content: center; align-items: center; border-top-left-radius: 16px; border-top-right-radius: 16px;">
<img src="<%= env.BASE_URL %>" width="34" height="34" alt="Compass logo"/>
<h1 style="margin-left: 4px; position: relative; top: 1px; font-size: 22px; line-height: 1;">
Compass
</h1>
</td>
</tr>
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper" style="font-family: Helvetica, sans-serif; font-size: 16px; vertical-align: top; box-sizing: border-box; padding: 24px;" valign="top">
22 changes: 22 additions & 0 deletions src/backend/emails/invite_para/html.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<%- include('../_header.html.ejs') %>

<p>Hi <%= first_name %>!</p>

<p><%= case_manager_name %> has added you as a staff member for their classroom in Compass.<br/>
Compass is an all in one tool for collecting data for students’ IEP goals and empowering your classroom team to better assist students.</p>

<p>How does Compass work?<br/>
Compass will help you organize data collection for the students you work with and securely store the data you collect.<br/>
<%= case_manager_name %> will add you to data collection tasks for specific student goals. Upon logging in, you’ll see which students you’re expected to collect data for.
Instructions from <%= case_manager_name %> will be available with each assignment. When you’re ready to begin, you’ll be able to collect and submit data and notes directly in the app.</p>

<p>Getting started<br/>
To get set up with Compass, use the link below and log in with the email address you received this message at.<br/>
Thank you for the key role you play in improving student outcomes!</p>

<%- include('../_button.html.ejs', { label: 'Accept Invite', url: env.BASE_URL }) %>

<p>Sincerely,<br />
The Compass Team</p>

<%- include('../_footer.html.ejs') %>
1 change: 1 addition & 0 deletions src/backend/emails/invite_para/subject.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Welcome to <%= case_manager_name %>'s classroom
20 changes: 20 additions & 0 deletions src/backend/emails/invite_para/text.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Hi <%= first_name %>!

<%= case_manager_name %> has added you as a staff member for their classroom in Compass.
Compass is an all in one tool for collecting data for students' IEP goals and empowering your classroom team to better assist students.

How does Compass work?
Compass will help you organize data collection for the students you work with and securely store the data you collect.
<%= case_manager_name %> will add you to data collection tasks for specific student goals. Upon logging in, you'll see which students you're expected to collect data for.
Instructions from <%= case_manager_name %> will be available with each assignment. When you're ready to begin, you'll be able to collect and submit data and notes directly in the app.

Getting started
To get set up with Compass, use the link below and log in with the email address you received this message at.
Thank you for the key role you play in improving student outcomes!

<%= env.BASE_URL %>

Sincerely,
The Compass Team

<%- include('../_footer.text.ejs') %>
26 changes: 11 additions & 15 deletions src/backend/lib/db_helpers/case_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,17 @@ export async function sendInviteEmail(
case_manager_name: string,
env: Env
): Promise<void> {
await getTransporter(env).sendMail({
from: fromEmail,
to: toEmail,
subject: `Welcome to ${case_manager_name}'s classroom`,
text: `${first_name}, get set up for data collection with Compass`,
html: `Hi ${first_name}! <br/>
${case_manager_name} has added you as a staff member for their classroom in Compass. <br/>
Compass is an all in one tool for collecting data for students’ IEP goals and empowering your classroom team to better assist students. <br/> <br/>
How does Compass work? <br/>
Compass will help you organize data collection for the students you work with and securely store the data you collect. <br/>
${case_manager_name} will add you to data collection tasks for specific student goals. Upon logging in, you’ll see which students you’re expected to collect data for.
Instructions from ${case_manager_name} will be available with each assignment. When you’re ready to begin, you’ll be able to collect and submit data and notes directly in the app. <br/><br/>
Getting started <br/>
To get set up with Compass, use the link below and log in with the email address you received this message at. <br/>
Thank you for the key role you play in improving student outcomes!`,
await getTransporter(env).send({
message: {
from: fromEmail,
to: toEmail,
},
template: "invite_para",
locals: {
case_manager_name,
first_name,
env,
},
});
return;
}
Expand Down
19 changes: 18 additions & 1 deletion src/backend/lib/nodemailer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { createTransport } from "nodemailer";
import SMTPTransport from "nodemailer/lib/smtp-transport";
import Email from "email-templates";
import { Env } from "./types";
import path from "path";
import { dirname } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));

export const getTransporter = (env: Env) => {
const options: SMTPTransport.Options = {
Expand All @@ -14,5 +20,16 @@ export const getTransporter = (env: Env) => {
options.host = env.EMAIL_HOST;
options.port = parseInt(env.EMAIL_PORT, 10);
}
return createTransport(options);
const transport = createTransport(options);
return new Email({
send: true,
transport,
views: {
root: path.resolve(__dirname, "../emails"),
options: {
extension: "ejs",
},
},
juice: false,
});
};
1 change: 1 addition & 0 deletions src/backend/lib/types/env.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface Env {
BASE_URL: string;
DATABASE_URL: string;
S3_USER_UPLOADS_ENDPOINT: string;
S3_USER_UPLOADS_REGION: string;
Expand Down

0 comments on commit 166575c

Please sign in to comment.