Skip to content

Commit

Permalink
translate email templates
Browse files Browse the repository at this point in the history
  • Loading branch information
cmintey committed Dec 21, 2024
1 parent b7ae852 commit 5e20c8c
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 66 deletions.
16 changes: 15 additions & 1 deletion src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"toggle-manager": "{isManager, select, true {remove} other {add}} {user} as manager",
"toggle-password-visibility": "toggle password visibility",
"two-people-looking-in-an-empty-box": "Two people looking in an empty box",
"upload-profile-image": "upload profile image"
"upload-profile-image": "upload profile image",
"wishlist-logo": "Wishlist Logo"
},
"admin": {
"about": "About",
Expand Down Expand Up @@ -111,6 +112,19 @@
"username": "Username",
"your-password-was-reset": "Your password was reset."
},
"email": {
"invite-body": "You've been invited to join Wishlist! To accept the invitation, click on the link below.",
"invite-button": "Join Wishlist",
"invite-fallback-text": "Somebody has invited you to join their Wishlist! Follow the link to signup: {url}",
"invite-footer": "If you do not wish to join or believe this email to be sent in error, then you can ignore this email.",
"invite-subject": "Wishlist Invite",
"invite-title": "Welcome to Wishlist!",
"pw-reset-body": "If you requested a password reset, click the link below to complete the process. If you didn't make this request, then you can safely ignore this email.",
"pw-reset-fallback-text": "Follow the link to reset your password {resetUrl}",
"pw-reset-title": "Reset Password",
"test-body": "If you're reading this, then congratulations! Email configuration seems to have been set up properly!",
"test-subject": "Test from Wishlist"
},
"errors": {
"asset-not-found": "Asset not found",
"cannot-delete-default-group": "Cannot Delete Default Group",
Expand Down
55 changes: 42 additions & 13 deletions src/lib/server/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ import { readFile } from "fs";
import type Mail from "nodemailer/lib/mailer";
import { getConfig } from "$lib/server/config";
import { env } from "$env/dynamic/private";
import { getFormatter } from "$lib/i18n";

type TemplateData = {
type InviteTemplateData = {
url: string;
baseUrl: string;
wishlistLogoText: string;
previewText: string;
titleText: string;
bodyText: string;
buttonText: string;
footerText: string;
};

let passResetTempl: HandlebarsTemplateDelegate<TemplateData>;
let inviteTempl: HandlebarsTemplateDelegate<TemplateData>;
type PasswordResetTemplateData = Omit<InviteTemplateData, "footerText">;

let passResetTempl: HandlebarsTemplateDelegate<PasswordResetTemplateData>;
let inviteTempl: HandlebarsTemplateDelegate<InviteTemplateData>;

readFile("templates/password-reset.html", "utf-8", (err, data) => {
if (err) {
Expand Down Expand Up @@ -79,30 +88,50 @@ const sendEmail = async (options: Mail.Options) => {
});
};

export const sendSignupLink = async (to: string, url: string) => {
const html = inviteTempl({ url, baseUrl: env.ORIGIN || "http://localhost:5173" });
export const sendSignupLink = async (to: string, inviteUrl: string) => {
const $t = await getFormatter();
const html = inviteTempl({
url: inviteUrl,
baseUrl: env.ORIGIN || "http://localhost:5173",
wishlistLogoText: $t("a11y.wishlist-logo"),
previewText: $t("email.invite-title"),
titleText: $t("email.invite-title"),
bodyText: $t("email.invite-body"),
buttonText: $t("email.invite-button"),
footerText: $t("email.invite-footer")
});
return await sendEmail({
to,
subject: "Wishlist Invite",
subject: $t("email.invite-subject"),
html,
text: `Somebody has invited you to join their Wishlist! Follow the link to signup: ${url}`
text: $t("email.invite-fallback-text", { values: { url: inviteUrl } })
});
};

export const sendPasswordReset = async (to: string, url: string) => {
const html = passResetTempl({ url, baseUrl: env.ORIGIN || "http://localhost:5173" });
export const sendPasswordReset = async (to: string, resetUrl: string) => {
const $t = await getFormatter();
const html = passResetTempl({
url: resetUrl,
baseUrl: env.ORIGIN || "http://localhost:5173",
wishlistLogoText: $t("a11y.wishlist-logo"),
previewText: $t("email.pw-reset-title"),
titleText: $t("email.pw-reset-title"),
bodyText: $t("email.pw-reset-body"),
buttonText: $t("email.pw-reset-title")
});
return await sendEmail({
to,
subject: "Password Reset",
subject: "Wishlist | " + $t("email.pw-reset-title"),
html,
text: `Follow the link to reset your password ${url}`
text: $t("email.pw-reset-fallback-text", { values: { url: resetUrl } })
});
};

export const sendTest = async (to: string) => {
const $t = await getFormatter();
return await sendEmail({
to,
subject: "Test from Wishlist",
text: "If you're reading this, then congratulations! Email configuration seems to have been set up properly!"
subject: $t("email.test-subject"),
text: $t("email.test-body")
});
};
6 changes: 3 additions & 3 deletions templates/invite.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
}</style><style media="screen and (min-width:480px)">.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }</style><style type="text/css">@media only screen and (max-width:480px) {
table.mj-full-width-mobile { width: 100% !important; }
td.mj-full-width-mobile { width: auto !important; }
}</style></head><body style="word-spacing:normal;background-color:#e3e1e5;"><div style="display:none;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">Welcome to Wishlist!</div><div style="background-color:#e3e1e5;"><!-- Logo Headaer --><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:10px 25px;padding-bottom:0px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;"><tbody><tr><td style="width:120px;"><img alt="Wishlist Logo" height="auto" src="{{baseUrl}}/android-chrome-512x512.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" width="120"></td></tr></tbody></table></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;padding-top:0px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:32px;line-height:1;text-align:center;color:#531f5e;">Wishlist</div></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 2px #000000;font-size:1px;margin:0px auto;width:45%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 2px #000000;font-size:1px;margin:0px auto;width:247.5px;" role="presentation" width="247.5px" ><tr><td style="height:0;line-height:0;"> &nbsp;
</td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--><!-- Main Body --><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;padding-top:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:28px;line-height:1;text-align:center;color:#201a29;">Welcome to Wishlist!</div></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:16px;line-height:1;text-align:center;color:#201a29;">You've been invited to join Wishlist! To accept the invitation, click on the link below.</div></td></tr><tr><td align="center" vertical-align="middle" style="font-size:0px;padding:10px 25px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;"><tr><td align="center" bgcolor="#a940bf" role="presentation" style="border:none;border-radius:12px;cursor:auto;mso-padding-alt:9px 20px;background:#a940bf;" valign="middle"><a href="{{url}}" rel="noreferrer" style="display:inline-block;background:#a940bf;color:#ffffff;font-family:Lato, ui-sans-serif, system-ui;font-size:16px;font-weight:normal;line-height:120%;margin:0;text-decoration:none;text-transform:none;padding:9px 20px;mso-padding-alt:0px;border-radius:12px;" target="_blank">Join Wishlist</a></td></tr></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 1px #000000;font-size:1px;margin:0px auto;width:100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #000000;font-size:1px;margin:0px auto;width:550px;" role="presentation" width="550px" ><tr><td style="height:0;line-height:0;"> &nbsp;
</td></tr></table><![endif]--></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:13px;line-height:1;text-align:center;color:#201a29;">If you do not wish to join or believe this email to be sent in error, then you can ignore this email.</div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
}</style></head><body style="word-spacing:normal;background-color:#e3e1e5;"><div style="display:none;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">{{previewText}}</div><div style="background-color:#e3e1e5;"><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:10px 25px;padding-bottom:0px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;"><tbody><tr><td style="width:120px;"><img alt="{{wishlistLogoText}}" height="auto" src="{{baseUrl}}/android-chrome-512x512.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:13px;" width="120"></td></tr></tbody></table></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;padding-top:0px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:32px;line-height:1;text-align:center;color:#531f5e;">Wishlist</div></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 2px #000000;font-size:1px;margin:0px auto;width:45%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 2px #000000;font-size:1px;margin:0px auto;width:247.5px;" role="presentation" width="247.5px" ><tr><td style="height:0;line-height:0;"> &nbsp;
</td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;padding-top:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:28px;line-height:1;text-align:center;color:#201a29;">{{titleText}}</div></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:16px;line-height:1;text-align:center;color:#201a29;">{{bodyText}}</div></td></tr><tr><td align="center" vertical-align="middle" style="font-size:0px;padding:10px 25px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;"><tr><td align="center" bgcolor="#a940bf" role="presentation" style="border:none;border-radius:12px;cursor:auto;mso-padding-alt:9px 20px;background:#a940bf;" valign="middle"><a href="{{inviteUrl}}" rel="noreferrer" style="display:inline-block;background:#a940bf;color:#ffffff;font-family:Lato, ui-sans-serif, system-ui;font-size:16px;font-weight:normal;line-height:120%;margin:0;text-decoration:none;text-transform:none;padding:9px 20px;mso-padding-alt:0px;border-radius:12px;" target="_blank">{{buttonText}}</a></td></tr></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 1px #000000;font-size:1px;margin:0px auto;width:100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #000000;font-size:1px;margin:0px auto;width:550px;" role="presentation" width="550px" ><tr><td style="height:0;line-height:0;"> &nbsp;
</td></tr></table><![endif]--></td></tr><tr><td align="center" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Lato, ui-sans-serif, system-ui;font-size:13px;line-height:1;text-align:center;color:#201a29;">{{footerText}}</div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
Loading

0 comments on commit 5e20c8c

Please sign in to comment.