improve email formatting and invite flow for new users

This commit is contained in:
Milo Schwartz
2024-12-31 18:25:11 -05:00
parent d244d6003b
commit d447de9e8a
15 changed files with 107 additions and 89 deletions

View File

@@ -6,6 +6,7 @@ import logger from "@server/logger";
export async function sendEmail(
template: ReactElement,
opts: {
name: string | undefined;
from: string | undefined;
to: string | undefined;
subject: string;
@@ -23,14 +24,15 @@ export async function sendEmail(
const emailHtml = await render(template);
const options = {
from: opts.from,
await emailClient.sendMail({
from: {
name: opts.name || "Pangolin Proxy",
address: opts.from,
},
to: opts.to,
subject: opts.subject,
html: emailHtml,
};
await emailClient.sendMail(options);
});
}
export default sendEmail;

View File

@@ -10,6 +10,7 @@ import {
Tailwind
} from "@react-email/components";
import * as React from "react";
import LetterHead from "./components/LetterHead";
interface Props {
email: string;
@@ -35,15 +36,7 @@ export const ConfirmPasswordReset = ({ email }: Props) => {
>
<Body className="font-sans relative">
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
<div className="flex items-center justify-between">
<div className="text-sm font-bold text-orange-500">
Pangolin
</div>
<div className="text-sm text-gray-500">
{new Date().toLocaleDateString()}
</div>
</div>
<LetterHead />
<Heading className="text-2xl font-semibold text-gray-800 text-center">
Password Reset Confirmation
@@ -56,10 +49,6 @@ export const ConfirmPasswordReset = ({ email }: Props) => {
reset. If you made this change, no further action is
required.
</Text>
<Text className="text-base text-gray-700">
If you did not request this change, please contact
our support team immediately.
</Text>
<Text className="text-base text-gray-700 mt-2">
Thank you for keeping your account secure.
</Text>

View File

@@ -10,6 +10,7 @@ import {
Tailwind
} from "@react-email/components";
import * as React from "react";
import LetterHead from "./components/LetterHead";
interface Props {
email: string;
@@ -18,7 +19,7 @@ interface Props {
}
export const ResetPasswordCode = ({ email, code, link }: Props) => {
const previewText = `Reset your password, ${email}`;
const previewText = `Your password reset code is ${code}`;
return (
<Html>
@@ -37,15 +38,7 @@ export const ResetPasswordCode = ({ email, code, link }: Props) => {
>
<Body className="font-sans">
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
<div className="flex items-center justify-between">
<div className="text-sm font-bold text-orange-500">
Pangolin
</div>
<div className="text-sm text-gray-500">
{new Date().toLocaleDateString()}
</div>
</div>
<LetterHead />
<Heading className="text-2xl font-semibold text-gray-800 text-center">
Password Reset Request

View File

@@ -10,6 +10,7 @@ import {
Tailwind
} from "@react-email/components";
import * as React from "react";
import LetterHead from "./components/LetterHead";
interface ResourceOTPCodeProps {
email?: string;
@@ -24,7 +25,7 @@ export const ResourceOTPCode = ({
orgName: organizationName,
otp
}: ResourceOTPCodeProps) => {
const previewText = `Your one-time password for ${resourceName} is ready!`;
const previewText = `Your one-time password for ${resourceName} is ${otp}`;
return (
<Html>
@@ -43,27 +44,18 @@ export const ResourceOTPCode = ({
>
<Body className="font-sans">
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
<div className="flex items-center justify-between">
<div className="text-sm font-bold text-orange-500">
Pangolin
</div>
<div className="text-sm text-gray-500">
{new Date().toLocaleDateString()}
</div>
</div>
<LetterHead />
<Heading className="text-2xl font-semibold text-gray-800 text-center">
Your One-Time Password
Your One-Time Password for {resourceName}
</Heading>
<Text className="text-base text-gray-700 mt-4">
Hi {email || "there"},
</Text>
<Text className="text-base text-gray-700 mt-2">
Youve requested a one-time password (OTP) to
authenticate with the resource{" "}
Youve requested a one-time password to access{" "}
<strong>{resourceName}</strong> in{" "}
<strong>{organizationName}</strong>. Use the OTP
<strong>{organizationName}</strong>. Use the code
below to complete your authentication:
</Text>
<Section className="text-center">

View File

@@ -11,6 +11,7 @@ import {
Button
} from "@react-email/components";
import * as React from "react";
import LetterHead from "./components/LetterHead";
interface SendInviteLinkProps {
email: string;
@@ -27,7 +28,7 @@ export const SendInviteLink = ({
inviterName,
expiresInDays
}: SendInviteLinkProps) => {
const previewText = `${inviterName} invited to join ${orgName}`;
const previewText = `${inviterName} invited you to join ${orgName}`;
return (
<Html>
@@ -46,18 +47,10 @@ export const SendInviteLink = ({
>
<Body className="font-sans">
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
<div className="flex items-center justify-between">
<div className="text-sm font-bold text-orange-500">
Pangolin
</div>
<div className="text-sm text-gray-500">
{new Date().toLocaleDateString()}
</div>
</div>
<LetterHead />
<Heading className="text-2xl font-semibold text-gray-800 text-center">
You're Invite to Join {orgName}
Invited to Join {orgName}
</Heading>
<Text className="text-base text-gray-700 mt-4">
Hi {email || "there"},

View File

@@ -10,6 +10,7 @@ import {
Tailwind
} from "@react-email/components";
import * as React from "react";
import LetterHead from "./components/LetterHead";
interface Props {
email: string;
@@ -36,15 +37,7 @@ export const TwoFactorAuthNotification = ({ email, enabled }: Props) => {
>
<Body className="font-sans">
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
<div className="flex items-center justify-between">
<div className="text-sm font-bold text-orange-500">
Pangolin
</div>
<div className="text-sm text-gray-500">
{new Date().toLocaleDateString()}
</div>
</div>
<LetterHead />
<Heading className="text-2xl font-semibold text-gray-800 text-center">
Two-Factor Authentication{" "}
@@ -71,10 +64,6 @@ export const TwoFactorAuthNotification = ({ email, enabled }: Props) => {
enabling it to protect your account.
</Text>
)}
<Text className="text-base text-gray-700 mt-2">
If you did not make this change, please contact our
support team immediately.
</Text>
<Text className="text-sm text-gray-500 mt-6">
Best regards,
<br />

View File

@@ -10,6 +10,7 @@ import {
Tailwind
} from "@react-email/components";
import * as React from "react";
import LetterHead from "./components/LetterHead";
interface VerifyEmailProps {
username?: string;
@@ -22,7 +23,7 @@ export const VerifyEmail = ({
verificationCode,
verifyLink
}: VerifyEmailProps) => {
const previewText = `Verify your email, ${username}`;
const previewText = `Your verification code is ${verificationCode}`;
return (
<Html>
@@ -41,15 +42,7 @@ export const VerifyEmail = ({
>
<Body className="font-sans">
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
<div className="flex items-center justify-between">
<div className="text-sm font-bold text-orange-500">
Pangolin
</div>
<div className="text-sm text-gray-500">
{new Date().toLocaleDateString()}
</div>
</div>
<LetterHead />
<Heading className="text-2xl font-semibold text-gray-800 text-center">
Please Verify Your Email

View File

@@ -0,0 +1,36 @@
import React from "react";
export function LetterHead() {
return (
<table
role="presentation"
width="100%"
style={{
marginBottom: "24px"
}}
>
<tr>
<td
style={{
fontSize: "14px",
fontWeight: "bold",
color: "#F97317"
}}
>
Pangolin
</td>
<td
style={{
fontSize: "14px",
textAlign: "right",
color: "#6B7280"
}}
>
{new Date().getFullYear()}
</td>
</tr>
</table>
);
}
export default LetterHead;