💄 Updated transactional email templates (#1285)

This commit is contained in:
Luke Vella 2024-08-30 17:18:36 +01:00 committed by GitHub
parent 4078618afd
commit 2f00dac998
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 186 additions and 234 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

View file

@ -49,6 +49,12 @@ export const env = createEnv({
* Example: "user@example.com, *@example.com, *@*.example.com" * Example: "user@example.com, *@example.com, *@*.example.com"
*/ */
ALLOWED_EMAILS: z.string().optional(), ALLOWED_EMAILS: z.string().optional(),
/**
* Email addresses for support and no-reply emails.
*/
SUPPORT_EMAIL: z.string().email(),
NOREPLY_EMAIL: z.string().email().optional(),
NOREPLY_EMAIL_NAME: z.string().default("Rallly"),
}, },
/* /*
* Environment variables available on the client (and server). * Environment variables available on the client (and server).
@ -90,6 +96,9 @@ export const env = createEnv({
NEXT_PUBLIC_POSTHOG_API_KEY: process.env.NEXT_PUBLIC_POSTHOG_API_KEY, NEXT_PUBLIC_POSTHOG_API_KEY: process.env.NEXT_PUBLIC_POSTHOG_API_KEY,
NEXT_PUBLIC_POSTHOG_API_HOST: process.env.NEXT_PUBLIC_POSTHOG_API_HOST, NEXT_PUBLIC_POSTHOG_API_HOST: process.env.NEXT_PUBLIC_POSTHOG_API_HOST,
NEXT_PUBLIC_SELF_HOSTED: process.env.NEXT_PUBLIC_SELF_HOSTED, NEXT_PUBLIC_SELF_HOSTED: process.env.NEXT_PUBLIC_SELF_HOSTED,
SUPPORT_EMAIL: process.env.SUPPORT_EMAIL,
NOREPLY_EMAIL: process.env.NOREPLY_EMAIL,
NOREPLY_EMAIL_NAME: process.env.NOREPLY_EMAIL_NAME,
}, },
skipValidation: !!process.env.SKIP_ENV_VALIDATION, skipValidation: !!process.env.SKIP_ENV_VALIDATION,
}); });

View file

@ -1,25 +1,26 @@
import { EmailClient, SupportedEmailProviders } from "@rallly/emails"; import { EmailClient, SupportedEmailProviders } from "@rallly/emails";
import { env } from "@/env";
import { absoluteUrl } from "@/utils/absolute-url"; import { absoluteUrl } from "@/utils/absolute-url";
import { isSelfHosted } from "@/utils/constants";
const env = process.env["NODE" + "_ENV"];
export const emailClient = new EmailClient({ export const emailClient = new EmailClient({
openPreviews: env === "development", openPreviews: env.NODE_ENV === "development",
provider: { provider: {
name: (process.env.EMAIL_PROVIDER as SupportedEmailProviders) ?? "smtp", name: (process.env.EMAIL_PROVIDER as SupportedEmailProviders) ?? "smtp",
}, },
mail: { mail: {
from: { from: {
name: (process.env.NOREPLY_EMAIL_NAME as string) || "Rallly", name: env.NOREPLY_EMAIL_NAME,
address: address: env.NOREPLY_EMAIL || env.SUPPORT_EMAIL,
(process.env.NOREPLY_EMAIL as string) ||
(process.env.SUPPORT_EMAIL as string),
}, },
}, },
context: { context: {
logoUrl: absoluteUrl("/logo.png"), logoUrl: isSelfHosted
? absoluteUrl("/images/rallly-logo-mark.png")
: "https://rallly-public.s3.amazonaws.com/images/rallly-logo-mark.png",
baseUrl: absoluteUrl(""), baseUrl: absoluteUrl(""),
domain: absoluteUrl("").replace(/(^\w+:|^)\/\//, ""), domain: absoluteUrl("").replace(/(^\w+:|^)\/\//, ""),
supportEmail: env.SUPPORT_EMAIL,
}, },
}); });

View file

@ -2,10 +2,12 @@ export type EmailContext = {
logoUrl: string; logoUrl: string;
baseUrl: string; baseUrl: string;
domain: string; domain: string;
supportEmail: string;
}; };
export const defaultEmailContext = { export const defaultEmailContext = {
logoUrl: "https://rallly.co/logo.png", logoUrl: "https://rallly-public.s3.amazonaws.com/images/rallly-logo-mark.png",
baseUrl: "https://rallly.co", baseUrl: "https://rallly.co",
domain: "rallly.co", domain: "rallly.co",
supportEmail: "support@rallly.co",
}; };

View file

@ -4,97 +4,56 @@ import {
Head, Head,
Html, Html,
Img, Img,
Link,
Preview, Preview,
Section,
} from "@react-email/components"; } from "@react-email/components";
import { EmailContext } from "./email-context"; import { EmailContext } from "./email-context";
import { fontFamily, Section, Text } from "./styled-components"; import { darkTextColor, fontFamily, Link, Text } from "./styled-components";
export interface EmailLayoutProps { export interface EmailLayoutProps {
preview: string; preview: string;
recipientName?: string;
footNote?: React.ReactNode;
ctx: EmailContext; ctx: EmailContext;
} }
const containerStyles = { const containerStyles = {
maxWidth: "600px", maxWidth: "480px",
margin: "0 auto", margin: "0 auto",
background: "white", background: "white",
fontFamily, fontFamily,
padding: 16, padding: "32px 8px",
border: "1px solid #E2E8F0", color: darkTextColor,
borderRadius: 5,
};
const sectionStyles = {
marginTop: "16px",
marginBottom: "16px",
};
const linkStyles = {
color: "#64748B",
marginRight: "8px",
}; };
export const EmailLayout = ({ export const EmailLayout = ({
preview, preview,
recipientName,
children, children,
footNote,
ctx, ctx,
}: React.PropsWithChildren<EmailLayoutProps>) => { }: React.PropsWithChildren<EmailLayoutProps>) => {
const { logoUrl, baseUrl } = ctx; const { logoUrl } = ctx;
return ( return (
<Html> <Html>
<Head /> <Head />
<Preview>{preview}</Preview> <Preview>{preview}</Preview>
<Body <Body style={{ backgroundColor: "#FFFFFF" }}>
style={{
backgroundColor: "#F3F4F6",
paddingTop: 20,
paddingBottom: 20,
}}
>
<Container style={containerStyles}> <Container style={containerStyles}>
<Img src={logoUrl} alt="Rallly" width={128} /> <Img
<Section style={sectionStyles}> src={logoUrl}
{recipientName ? <Text>Hi {recipientName},</Text> : null} width="32"
{children} height="32"
{footNote ? (
<Text
style={{ style={{
color: "#64748B", marginBottom: 32,
fontFamily,
paddingTop: 16,
marginTop: 32,
borderTop: "1px solid #e2e8f0",
}} }}
> alt="Rallly Logo"
{footNote} />
{children}
<Section style={{ marginTop: 32, textAlign: "center" }}>
<Text light={true}>
Powered by{" "}
<Link href="https://rallly.co?utm_source=email&utm_medium=transactional">
rallly.co
</Link>
</Text> </Text>
) : null}
</Section>
<Section style={{ ...sectionStyles, fontSize: 14, marginBottom: 0 }}>
<Link style={linkStyles} href={baseUrl}>
Home
</Link>
<span>&nbsp;&bull;&nbsp;</span>
<Link style={linkStyles} href="https://twitter.com/ralllyco">
Twitter
</Link>
<span>&nbsp;&bull;&nbsp;</span>
<Link style={linkStyles} href="https://github.com/lukevella/rallly">
Github
</Link>
<span>&nbsp;&bull;&nbsp;</span>
<Link
style={linkStyles}
href={`mailto:${process.env["SUPPORT_EMAIL"]}`}
>
Contact
</Link>
</Section> </Section>
</Container> </Container>
</Body> </Body>

View file

@ -1,3 +1,5 @@
import { Section } from "@react-email/section";
import { EmailContext } from "./email-context"; import { EmailContext } from "./email-context";
import { EmailLayout } from "./email-layout"; import { EmailLayout } from "./email-layout";
import { Button, Link, Text } from "./styled-components"; import { Button, Link, Text } from "./styled-components";
@ -15,7 +17,6 @@ export interface NotificationEmailProps extends NotificationBaseProps {
} }
export const NotificationEmail = ({ export const NotificationEmail = ({
name,
pollUrl, pollUrl,
disableNotificationsUrl, disableNotificationsUrl,
preview, preview,
@ -24,23 +25,17 @@ export const NotificationEmail = ({
}: React.PropsWithChildren<NotificationEmailProps>) => { }: React.PropsWithChildren<NotificationEmailProps>) => {
const { domain } = ctx; const { domain } = ctx;
return ( return (
<EmailLayout <EmailLayout ctx={ctx} preview={preview}>
ctx={ctx} {children}
recipientName={name} <Section style={{ marginTop: 32, marginBottom: 32 }}>
footNote={ <Button href={pollUrl}>View on {domain}</Button>
<> </Section>
<Text light={true}>
If you would like to stop receiving updates you can{" "} If you would like to stop receiving updates you can{" "}
<Link className="whitespace-nowrap" href={disableNotificationsUrl}> <Link className="whitespace-nowrap" href={disableNotificationsUrl}>
turn notifications off turn notifications off
</Link> </Link>
. .
</>
}
preview={preview}
>
{children}
<Text>
<Button href={pollUrl}>View on {domain}</Button>
</Text> </Text>
</EmailLayout> </EmailLayout>
); );

View file

@ -11,6 +11,8 @@ import {
import { EmailContext } from "./email-context"; import { EmailContext } from "./email-context";
export const lightTextColor = "#4B5563";
export const darkTextColor = "#1F2937";
export const borderColor = "#E2E8F0"; export const borderColor = "#E2E8F0";
export const Text = ( export const Text = (
props: TextProps & { light?: boolean; small?: boolean }, props: TextProps & { light?: boolean; small?: boolean },
@ -23,7 +25,7 @@ export const Text = (
margin: "16px 0", margin: "16px 0",
fontFamily, fontFamily,
fontSize: small ? "14px" : "16px", fontSize: small ? "14px" : "16px",
color: light ? "#64748B" : "#334155", color: light ? lightTextColor : darkTextColor,
lineHeight: "1.5", lineHeight: "1.5",
...props.style, ...props.style,
}} }}
@ -46,6 +48,11 @@ export const Button = (props: React.ComponentProps<typeof UnstyledButton>) => {
borderRadius: "4px", borderRadius: "4px",
padding: "12px 14px", padding: "12px 14px",
fontFamily, fontFamily,
boxSizing: "border-box",
display: "block",
width: "100%",
maxWidth: "100%",
textAlign: "center",
fontSize: "16px", fontSize: "16px",
color: "white", color: "white",
}} }}
@ -62,23 +69,24 @@ export const Link = (props: LinkProps) => {
); );
}; };
export const Heading = (
props: React.ComponentProps<typeof UnstyledHeading>,
) => {
const { as = "h3" } = props;
const fontSize = { const fontSize = {
h1: "32px", h1: "20px",
h2: "24px", h2: "18px",
h3: "20px", h3: "16px",
h4: "16px", h4: "16px",
h5: "14px", h5: "14px",
h6: "12px", h6: "12px",
}; };
export const Heading = (
props: React.ComponentProps<typeof UnstyledHeading>,
) => {
const { as = "h1" } = props;
return ( return (
<UnstyledHeading <UnstyledHeading
{...props} {...props}
as={as} as={as}
className="font-sans font-bold text-gray-900"
style={{ style={{
fontSize: fontSize[as], fontSize: fontSize[as],
...props.style, ...props.style,
@ -146,3 +154,5 @@ export const trackingWide = {
export const fontFamily = export const fontFamily =
"'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif"; "'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
export const primaryColor = "#4F46E5";

View file

@ -2,7 +2,12 @@ import { Column, Row, Section } from "@react-email/components";
import { defaultEmailContext, EmailContext } from "./_components/email-context"; import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout"; import { EmailLayout } from "./_components/email-layout";
import { borderColor, Button, Text } from "./_components/styled-components"; import {
borderColor,
Button,
Heading,
Text,
} from "./_components/styled-components";
export interface FinalizeHostEmailProps { export interface FinalizeHostEmailProps {
date: string; date: string;
@ -18,7 +23,6 @@ export interface FinalizeHostEmailProps {
} }
export const FinalizeHostEmail = ({ export const FinalizeHostEmail = ({
name = "Guest",
title = "Untitled Poll", title = "Untitled Poll",
pollUrl = "https://rallly.co", pollUrl = "https://rallly.co",
day = "12", day = "12",
@ -28,7 +32,8 @@ export const FinalizeHostEmail = ({
ctx = defaultEmailContext, ctx = defaultEmailContext,
}: FinalizeHostEmailProps) => { }: FinalizeHostEmailProps) => {
return ( return (
<EmailLayout ctx={ctx} recipientName={name} preview="Final date booked!"> <EmailLayout ctx={ctx} preview="Final date booked!">
<Heading>Final date booked!</Heading>
<Text> <Text>
<strong>{title}</strong> has been booked for: <strong>{title}</strong> has been booked for:
</Text> </Text>
@ -73,9 +78,9 @@ export const FinalizeHostEmail = ({
<Text> <Text>
We&apos;ve notified participants and sent them calendar invites. We&apos;ve notified participants and sent them calendar invites.
</Text> </Text>
<Text> <Section style={{ marginTop: 32 }}>
<Button href={pollUrl}>View Event</Button> <Button href={pollUrl}>View Event</Button>
</Text> </Section>
</EmailLayout> </EmailLayout>
); );
}; };

View file

@ -2,7 +2,12 @@ import { Column, Row, Section } from "@react-email/components";
import { defaultEmailContext, EmailContext } from "./_components/email-context"; import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout"; import { EmailLayout } from "./_components/email-layout";
import { borderColor, Button, Text } from "./_components/styled-components"; import {
borderColor,
Button,
Heading,
Text,
} from "./_components/styled-components";
export interface FinalizeParticipantEmailProps { export interface FinalizeParticipantEmailProps {
date: string; date: string;
@ -19,7 +24,6 @@ export interface FinalizeParticipantEmailProps {
} }
export const FinalizeParticipantEmail = ({ export const FinalizeParticipantEmail = ({
name = "Guest",
title = "Untitled Poll", title = "Untitled Poll",
hostName = "Host", hostName = "Host",
pollUrl = "https://rallly.co", pollUrl = "https://rallly.co",
@ -30,12 +34,13 @@ export const FinalizeParticipantEmail = ({
ctx = defaultEmailContext, ctx = defaultEmailContext,
}: FinalizeParticipantEmailProps) => { }: FinalizeParticipantEmailProps) => {
return ( return (
<EmailLayout ctx={ctx} recipientName={name} preview="Final date booked!"> <EmailLayout ctx={ctx} preview="Final date booked!">
<Heading>Final date booked!</Heading>
<Text> <Text>
<strong>{hostName}</strong> has booked <strong>{title}</strong> for the <strong>{hostName}</strong> has booked <strong>{title}</strong> for the
following date: following date:
</Text> </Text>
<Section> <Section data-testid="date-section">
<Row> <Row>
<Column style={{ width: 48 }}> <Column style={{ width: 48 }}>
<Section <Section
@ -74,9 +79,9 @@ export const FinalizeParticipantEmail = ({
</Row> </Row>
</Section> </Section>
<Text>Please find attached a calendar invite for this event.</Text> <Text>Please find attached a calendar invite for this event.</Text>
<Text> <Section style={{ marginTop: 32 }}>
<Button href={pollUrl}>View Event</Button> <Button href={pollUrl}>View Event</Button>
</Text> </Section>
</EmailLayout> </EmailLayout>
); );
}; };

View file

@ -1,3 +1,5 @@
import { Section } from "@react-email/components";
import { defaultEmailContext, EmailContext } from "./_components/email-context"; import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout"; import { EmailLayout } from "./_components/email-layout";
import { import {
@ -17,43 +19,40 @@ interface LoginEmailProps {
} }
export const LoginEmail = ({ export const LoginEmail = ({
name = "Guest",
code = "123456", code = "123456",
magicLink = "https://rallly.co", magicLink = "https://rallly.co",
ctx = defaultEmailContext, ctx = defaultEmailContext,
}: LoginEmailProps) => { }: LoginEmailProps) => {
return ( return (
<EmailLayout <EmailLayout ctx={ctx} preview="Use this link to log in on this device.">
ctx={ctx} <Heading>Login</Heading>
footNote={ <Text>Enter this one-time 6-digit verification code:</Text>
<> <Card style={{ textAlign: "center" }}>
You&apos;re receiving this email because a request was made to login <Text
to <Domain ctx={ctx} />. If this wasn&apos;t you, let us know by style={{
replying to this email. ...trackingWide,
</> textAlign: "center",
} fontSize: "32px",
recipientName={name} fontWeight: "bold",
preview="Use this link to log in on this device." }}
id="code"
> >
<Text> {code}
To log in to your account, please choose one of the following options:
</Text> </Text>
<Card> <Text style={{ textAlign: "center" }} light={true}>
<Heading>Option 1: Magic Link</Heading> This code is valid for 15 minutes
<Text>Click this magic link to log in on this device.</Text> </Text>
</Card>
<Section style={{ marginBottom: 32 }}>
<Button href={magicLink} id="magicLink"> <Button href={magicLink} id="magicLink">
Log in to {ctx.domain} Log in to {ctx.domain}
</Button> </Button>
<Text light={true}>This link will expire in 15 minutes.</Text> </Section>
</Card> <Text light>
<Card> You&apos;re receiving this email because a request was made to login to{" "}
<Heading>Option 2: Verification Code</Heading> <Domain ctx={ctx} />. If this wasn&apos;t you contact{" "}
<Text>Enter this one-time 6-digit verification code.</Text> <a href={`mailto:${ctx.supportEmail}`}>{ctx.supportEmail}</a>.
<Heading as="h1" style={trackingWide} id="code"> </Text>
{code}
</Heading>
<Text light={true}>This code will expire in 15 minutes.</Text>
</Card>
</EmailLayout> </EmailLayout>
); );
}; };

View file

@ -2,7 +2,7 @@ import { defaultEmailContext } from "./_components/email-context";
import NotificationEmail, { import NotificationEmail, {
NotificationBaseProps, NotificationBaseProps,
} from "./_components/notification-email"; } from "./_components/notification-email";
import { Text } from "./_components/styled-components"; import { Heading, Text } from "./_components/styled-components";
export interface NewCommentEmailProps extends NotificationBaseProps { export interface NewCommentEmailProps extends NotificationBaseProps {
authorName: string; authorName: string;
@ -25,6 +25,7 @@ export const NewCommentEmail = ({
disableNotificationsUrl={disableNotificationsUrl} disableNotificationsUrl={disableNotificationsUrl}
preview="Go to your poll to see what they said." preview="Go to your poll to see what they said."
> >
<Heading>New Comment</Heading>
<Text> <Text>
<strong>{authorName}</strong> has commented on <strong>{title}</strong>. <strong>{authorName}</strong> has commented on <strong>{title}</strong>.
</Text> </Text>

View file

@ -1,6 +1,12 @@
import { defaultEmailContext, EmailContext } from "./_components/email-context"; import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout"; import { EmailLayout } from "./_components/email-layout";
import { Button, Domain, Section, Text } from "./_components/styled-components"; import {
Button,
Domain,
Heading,
Section,
Text,
} from "./_components/styled-components";
interface NewParticipantConfirmationEmailProps { interface NewParticipantConfirmationEmailProps {
name: string; name: string;
@ -10,24 +16,13 @@ interface NewParticipantConfirmationEmailProps {
} }
export const NewParticipantConfirmationEmail = ({ export const NewParticipantConfirmationEmail = ({
title = "Untitled Poll", title = "Untitled Poll",
name = "John",
editSubmissionUrl = "https://rallly.co", editSubmissionUrl = "https://rallly.co",
ctx = defaultEmailContext, ctx = defaultEmailContext,
}: NewParticipantConfirmationEmailProps) => { }: NewParticipantConfirmationEmailProps) => {
const { domain } = ctx; const { domain } = ctx;
return ( return (
<EmailLayout <EmailLayout ctx={ctx} preview="To edit your response use the link below">
ctx={ctx} <Heading>Poll Response Confirmation</Heading>
footNote={
<>
You are receiving this email because a response was submitted on{" "}
<Domain ctx={ctx} />. If this wasn&apos;t you, please ignore this
email.
</>
}
recipientName={name}
preview="To edit your response use the link below"
>
<Text> <Text>
Your response to <strong>{title}</strong> has been submitted. Your response to <strong>{title}</strong> has been submitted.
</Text> </Text>
@ -35,11 +30,15 @@ export const NewParticipantConfirmationEmail = ({
While the poll is still open you can change your response using the link While the poll is still open you can change your response using the link
below. below.
</Text> </Text>
<Section> <Section style={{ marginTop: 32 }}>
<Button id="editSubmissionUrl" href={editSubmissionUrl}> <Button id="editSubmissionUrl" href={editSubmissionUrl}>
Review response on {domain} Review response on {domain}
</Button> </Button>
</Section> </Section>
<Text light>
You are receiving this email because a response was submitted on{" "}
<Domain ctx={ctx} />. If this wasn&apos;t you, please ignore this email.
</Text>
</EmailLayout> </EmailLayout>
); );
}; };

View file

@ -2,7 +2,7 @@ import { defaultEmailContext } from "./_components/email-context";
import NotificationEmail, { import NotificationEmail, {
NotificationBaseProps, NotificationBaseProps,
} from "./_components/notification-email"; } from "./_components/notification-email";
import { Text } from "./_components/styled-components"; import { Heading, Text } from "./_components/styled-components";
export interface NewParticipantEmailProps extends NotificationBaseProps { export interface NewParticipantEmailProps extends NotificationBaseProps {
participantName: string; participantName: string;
@ -25,10 +25,12 @@ export const NewParticipantEmail = ({
disableNotificationsUrl={disableNotificationsUrl} disableNotificationsUrl={disableNotificationsUrl}
preview="Go to your poll to see the new response." preview="Go to your poll to see the new response."
> >
<Heading>New Response</Heading>
<Text> <Text>
<strong>{participantName}</strong> has responded to{" "} <strong>{participantName}</strong> has responded to{" "}
<strong>{title}</strong>. <strong>{title}</strong>.
</Text> </Text>
<Text>Go to your poll to see the new response.</Text>
</NotificationEmail> </NotificationEmail>
); );
}; };

View file

@ -1,6 +1,12 @@
import { defaultEmailContext, EmailContext } from "./_components/email-context"; import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout"; import { EmailLayout } from "./_components/email-layout";
import { Button, Card, Link, Text } from "./_components/styled-components"; import {
Button,
Card,
Heading,
Link,
Text,
} from "./_components/styled-components";
export interface NewPollEmailProps { export interface NewPollEmailProps {
title: string; title: string;
@ -10,82 +16,28 @@ export interface NewPollEmailProps {
ctx: EmailContext; ctx: EmailContext;
} }
const ShareLink = ({
title,
participantLink,
name,
children,
}: React.PropsWithChildren<{
name: string;
title: string;
participantLink: string;
}>) => {
return (
<Link
href={`mailto:?subject=${encodeURIComponent(
`Availability for ${title}`,
)}&body=${encodeURIComponent(
`Hi all,\nI'm trying to find the best date for ${title}.\nCan you please use the link below to choose your preferred dates:\n${participantLink}\nThank you.\n${name}`,
)}`}
>
{children}
</Link>
);
};
export const NewPollEmail = ({ export const NewPollEmail = ({
title = "Untitled Poll", title = "Untitled Poll",
name = "John",
adminLink = "https://rallly.co/admin/abcdefg123", adminLink = "https://rallly.co/admin/abcdefg123",
participantLink = "https://rallly.co/invite/wxyz9876", participantLink = "https://rallly.co/invite/wxyz9876",
ctx = defaultEmailContext, ctx = defaultEmailContext,
}: NewPollEmailProps) => { }: NewPollEmailProps) => {
const { baseUrl, domain } = ctx;
return ( return (
<EmailLayout <EmailLayout
ctx={ctx} ctx={ctx}
footNote={
<>
You are receiving this email because a new poll was created with this
email address on <Link href={baseUrl}>{domain}</Link>. If this
wasn&apos;t you, please ignore this email.
</>
}
recipientName={name}
preview="Share your participant link to start collecting responses." preview="Share your participant link to start collecting responses."
> >
<Heading>New Poll Created</Heading>
<Text> <Text>
Your poll has been successfully created! Here are the details: Your meeting poll titled <strong>{`"${title}"`}</strong> is ready! Share
it using the link below:
</Text> </Text>
<Card> <Card style={{ textAlign: "center" }}>
<Text> <Text style={{ textAlign: "center" }}>
<strong>Title:</strong> {title}
<br />
<strong>Invite Link:</strong>{" "}
<Link href={participantLink}>{participantLink}</Link> <Link href={participantLink}>{participantLink}</Link>
</Text> </Text>
<Text>
<ShareLink
title={title}
name={name}
participantLink={participantLink}
>
Share via email
</ShareLink>
</Text>
</Card> </Card>
<Text>
To invite participants to your poll, simply share the{" "}
<strong>Invite Link</strong> above with them. They&apos;ll be able to
vote on their preferred meeting times and dates.
</Text>
<Text>
If you need to make any changes to your poll, or if you want to see the
results so far, just click on the button below:
</Text>
<Text>
<Button href={adminLink}>Manage Poll &rarr;</Button> <Button href={adminLink}>Manage Poll &rarr;</Button>
</Text>
</EmailLayout> </EmailLayout>
); );
}; };

View file

@ -1,6 +1,9 @@
import { Section } from "@react-email/section";
import { defaultEmailContext, EmailContext } from "./_components/email-context"; import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout"; import { EmailLayout } from "./_components/email-layout";
import { import {
Card,
Domain, Domain,
Heading, Heading,
Text, Text,
@ -17,24 +20,34 @@ export const RegisterEmail = ({
ctx = defaultEmailContext, ctx = defaultEmailContext,
}: RegisterEmailProps) => { }: RegisterEmailProps) => {
return ( return (
<EmailLayout <EmailLayout ctx={ctx} preview={`Your 6-digit code is: ${code}`}>
ctx={ctx} <Heading>Verify your email address</Heading>
footNote={
<>
You&apos;re receiving this email because a request was made to
register an account on <Domain ctx={ctx} />. If this wasn&apos;t you,
please ignore this email.
</>
}
preview={`Your 6-digit code is: ${code}`}
>
<Text> <Text>
Please use the following 6-digit verification code to verify your email: Please use the following 6-digit verification code to verify your email:
</Text> </Text>
<Heading as="h1" style={{ ...trackingWide }} id="code"> <Card style={{ textAlign: "center" }}>
<Text
style={{
...trackingWide,
textAlign: "center",
fontSize: "32px",
fontWeight: "bold",
}}
id="code"
>
{code} {code}
</Heading> </Text>
<Text>This code is valid for 15 minutes</Text> <Text style={{ textAlign: "center" }} light={true}>
This code is valid for 15 minutes
</Text>
</Card>
<Section>
<Text light={true}>
You&apos;re receiving this email because a request was made to
register an account on <Domain ctx={ctx} />. If this wasn&apos;t you,
please ignore this email.
</Text>
</Section>
</EmailLayout> </EmailLayout>
); );
}; };