Translations for Email Notifications (#1278)

Co-authored-by: Niko Heller <hellerniko@gmail.com>
This commit is contained in:
Luke Vella 2024-09-02 19:30:58 +01:00 committed by GitHub
parent aa52a0f26f
commit f4218c3115
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 1071 additions and 970 deletions

View file

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

View file

@ -1,62 +0,0 @@
import {
Body,
Container,
Head,
Html,
Img,
Preview,
Section,
} from "@react-email/components";
import { EmailContext } from "./email-context";
import { darkTextColor, fontFamily, Link, Text } from "./styled-components";
export interface EmailLayoutProps {
preview: string;
ctx: EmailContext;
}
const containerStyles = {
maxWidth: "480px",
margin: "0 auto",
background: "white",
fontFamily,
padding: "32px 8px",
color: darkTextColor,
};
export const EmailLayout = ({
preview,
children,
ctx,
}: React.PropsWithChildren<EmailLayoutProps>) => {
const { logoUrl } = ctx;
return (
<Html>
<Head />
<Preview>{preview}</Preview>
<Body style={{ backgroundColor: "#FFFFFF" }}>
<Container style={containerStyles}>
<Img
src={logoUrl}
width="32"
height="32"
style={{
marginBottom: 32,
}}
alt="Rallly Logo"
/>
{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>
</Section>
</Container>
</Body>
</Html>
);
};

View file

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

View file

@ -1,158 +0,0 @@
import {
Button as UnstyledButton,
Heading as UnstyledHeading,
Link as UnstyledLink,
LinkProps,
Section as UnstyledSection,
SectionProps,
Text as UnstyledText,
TextProps,
} from "@react-email/components";
import { EmailContext } from "./email-context";
export const lightTextColor = "#4B5563";
export const darkTextColor = "#1F2937";
export const borderColor = "#E2E8F0";
export const Text = (
props: TextProps & { light?: boolean; small?: boolean },
) => {
const { light, small, ...forwardProps } = props;
return (
<UnstyledText
{...forwardProps}
style={{
margin: "16px 0",
fontFamily,
fontSize: small ? "14px" : "16px",
color: light ? lightTextColor : darkTextColor,
lineHeight: "1.5",
...props.style,
}}
/>
);
};
export const Domain = ({ ctx }: { ctx: EmailContext }) => {
const { baseUrl, domain } = ctx;
return <Link href={baseUrl}>{domain}</Link>;
};
export const Button = (props: React.ComponentProps<typeof UnstyledButton>) => {
return (
<UnstyledButton
{...props}
className={props.className}
style={{
backgroundColor: "#4F46E5",
borderRadius: "4px",
padding: "12px 14px",
fontFamily,
boxSizing: "border-box",
display: "block",
width: "100%",
maxWidth: "100%",
textAlign: "center",
fontSize: "16px",
color: "white",
}}
/>
);
};
export const Link = (props: LinkProps) => {
return (
<UnstyledLink
{...props}
style={{ color: "#4F46E5", fontFamily, ...props.style }}
/>
);
};
const fontSize = {
h1: "20px",
h2: "18px",
h3: "16px",
h4: "16px",
h5: "14px",
h6: "12px",
};
export const Heading = (
props: React.ComponentProps<typeof UnstyledHeading>,
) => {
const { as = "h1" } = props;
return (
<UnstyledHeading
{...props}
as={as}
style={{
fontSize: fontSize[as],
...props.style,
}}
/>
);
};
export const SubHeadingText = (props: TextProps) => {
return (
<UnstyledText
{...props}
style={{
marginBottom: "16px",
marginTop: "8px",
fontSize: 16,
color: "#374151",
fontFamily,
...props.style,
}}
/>
);
};
export const Section = (props: SectionProps) => {
return (
<UnstyledSection
{...props}
style={{ marginTop: "16px", marginBottom: "16px", ...props.style }}
/>
);
};
export const SmallText = (props: TextProps) => {
return (
<UnstyledText
{...props}
style={{
fontSize: "14px",
color: "#6B7280",
...props.style,
}}
/>
);
};
export const Card = (props: SectionProps) => {
return (
<Section
{...props}
style={{
borderRadius: "4px",
backgroundColor: "#F9FAFB",
paddingRight: "16px",
paddingLeft: "16px",
border: "1px solid #E2E8F0",
}}
/>
);
};
export const trackingWide = {
letterSpacing: 2,
};
export const fontFamily =
"'Inter UI', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
export const primaryColor = "#4F46E5";

View file

@ -1,13 +1,14 @@
import { Column, Row, Section } from "@react-email/components";
import { Trans } from "react-i18next/TransWithoutContext";
import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout";
import { EmailLayout } from "../components/email-layout";
import {
borderColor,
Button,
Heading,
Text,
} from "./_components/styled-components";
} from "../components/styled-components";
import type { EmailContext } from "../types";
export interface FinalizeHostEmailProps {
date: string;
@ -22,20 +23,43 @@ export interface FinalizeHostEmailProps {
ctx: EmailContext;
}
export const FinalizeHostEmail = ({
title = "Untitled Poll",
pollUrl = "https://rallly.co",
day = "12",
dow = "Fri",
date = "Friday, 12th June 2020",
time = "6:00 PM to 11:00 PM BST",
ctx = defaultEmailContext,
const FinalizeHostEmail = ({
title,
pollUrl,
day,
dow,
date,
time,
ctx,
}: FinalizeHostEmailProps) => {
return (
<EmailLayout ctx={ctx} preview="Final date booked!">
<Heading>Final date booked!</Heading>
<EmailLayout
ctx={ctx}
preview={ctx.t("finalizeHost_preview", {
ns: "emails",
defaultValue:
"Final date booked! We've notified participants and sent them calendar invites.",
title,
})}
>
<Heading>
{ctx.t("finalizeHost_heading", {
defaultValue: "Final date booked!",
ns: "emails",
})}
</Heading>
<Text>
<strong>{title}</strong> has been booked for:
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="finalizeHost_content"
ns="emails"
values={{ title }}
components={{
b: <strong />,
}}
defaults="<b>{{title}}</b> has been booked for:"
/>
</Text>
<Section>
<Row>
@ -76,13 +100,33 @@ export const FinalizeHostEmail = ({
</Row>
</Section>
<Text>
We&apos;ve notified participants and sent them calendar invites.
{ctx.t("finalizeHost_content2", {
defaultValue:
"We've notified participants and sent them calendar invites.",
ns: "emails",
})}
</Text>
<Section style={{ marginTop: 32 }}>
<Button href={pollUrl}>View Event</Button>
<Button href={pollUrl}>
{ctx.t("finalizeHost_button", {
defaultValue: "View Event",
ns: "emails",
})}
</Button>
</Section>
</EmailLayout>
);
};
export default FinalizeHostEmail;
FinalizeHostEmail.getSubject = (
props: FinalizeHostEmailProps,
ctx: EmailContext,
) => {
return ctx.t("finalizeHost_subject", {
defaultValue: "Date booked for {{title}}",
title: props.title,
ns: "emails",
});
};
export { FinalizeHostEmail };

View file

@ -1,44 +1,62 @@
import { Column, Row, Section } from "@react-email/components";
import { Trans } from "react-i18next/TransWithoutContext";
import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout";
import { EmailLayout } from "../components/email-layout";
import {
borderColor,
Button,
Heading,
Text,
} from "./_components/styled-components";
} from "../components/styled-components";
import type { EmailContext } from "../types";
export interface FinalizeParticipantEmailProps {
date: string;
day: string;
dow: string;
time: string;
name: string;
title: string;
hostName: string;
location: string | null;
pollUrl: string;
attendees: string[];
ctx: EmailContext;
}
export const FinalizeParticipantEmail = ({
title = "Untitled Poll",
hostName = "Host",
pollUrl = "https://rallly.co",
day = "12",
dow = "Fri",
date = "Friday, 12th June 2020",
time = "6:00 PM to 11:00 PM BST",
ctx = defaultEmailContext,
const FinalizeParticipantEmail = ({
title,
hostName,
pollUrl,
day,
dow,
date,
time,
ctx,
}: FinalizeParticipantEmailProps) => {
return (
<EmailLayout ctx={ctx} preview="Final date booked!">
<Heading>Final date booked!</Heading>
<EmailLayout
ctx={ctx}
preview={ctx.t("finalizeParticipant_preview", {
defaultValue: "Final date booked!",
ns: "emails",
})}
>
<Heading>
{ctx.t("finalizeParticipant_heading", {
defaultValue: "Final date booked!",
ns: "emails",
})}
</Heading>
<Text>
<strong>{hostName}</strong> has booked <strong>{title}</strong> for the
following date:
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="finalizeParticipant_content"
ns="emails"
defaults="<b>{{hostName}}</b> has booked <b>{{title}}</b> for the following date:"
values={{ hostName, title }}
components={{
b: <strong />,
}}
/>
</Text>
<Section data-testid="date-section">
<Row>
@ -78,7 +96,12 @@ export const FinalizeParticipantEmail = ({
</Column>
</Row>
</Section>
<Text>Please find attached a calendar invite for this event.</Text>
<Text>
{ctx.t("finalizeParticipant_content2", {
defaultValue:
"Please find attached a calendar invite for this event.",
})}
</Text>
<Section style={{ marginTop: 32 }}>
<Button href={pollUrl}>View Event</Button>
</Section>
@ -86,4 +109,15 @@ export const FinalizeParticipantEmail = ({
);
};
export default FinalizeParticipantEmail;
FinalizeParticipantEmail.getSubject = (
props: FinalizeParticipantEmailProps,
ctx: EmailContext,
) => {
return ctx.t("finalizeParticipant_subject", {
defaultValue: "Date booked for {{title}}",
title: props.title,
ns: "emails",
});
};
export { FinalizeParticipantEmail };

View file

@ -1,32 +1,42 @@
import { Section } from "@react-email/components";
import { Trans } from "react-i18next/TransWithoutContext";
import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout";
import { EmailLayout } from "../components/email-layout";
import {
Button,
Card,
Domain,
Heading,
Link,
Text,
trackingWide,
} from "./_components/styled-components";
} from "../components/styled-components";
import type { EmailContext } from "../types";
interface LoginEmailProps {
name: string;
code: string;
magicLink: string;
ctx: EmailContext;
}
export const LoginEmail = ({
code = "123456",
magicLink = "https://rallly.co",
ctx = defaultEmailContext,
}: LoginEmailProps) => {
export const LoginEmail = ({ code, magicLink, ctx }: LoginEmailProps) => {
return (
<EmailLayout ctx={ctx} preview="Use this link to log in on this device.">
<Heading>Login</Heading>
<Text>Enter this one-time 6-digit verification code:</Text>
<EmailLayout
ctx={ctx}
preview={ctx.t("login_preview", {
defaultValue: "Use this link to log in on this device.",
ns: "emails",
})}
>
<Heading>
{ctx.t("login_heading", { defaultValue: "Login", ns: "emails" })}
</Heading>
<Text>
{ctx.t("login_content", {
defaultValue: "Enter this one-time 6-digit verification code:",
ns: "emails",
})}
</Text>
<Card style={{ textAlign: "center" }}>
<Text
style={{
@ -40,21 +50,48 @@ export const LoginEmail = ({
{code}
</Text>
<Text style={{ textAlign: "center" }} light={true}>
This code is valid for 15 minutes
{ctx.t("login_codeValid", {
defaultValue: "This code is valid for 15 minutes",
ns: "emails",
})}
</Text>
</Card>
<Section style={{ marginBottom: 32 }}>
<Button href={magicLink} id="magicLink">
Log in to {ctx.domain}
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="login_button"
defaults="Log in to {domain}"
values={{ domain: ctx.domain }}
ns="emails"
/>
</Button>
</Section>
<Text light>
You&apos;re receiving this email because a request was made to login to{" "}
<Domain ctx={ctx} />. If this wasn&apos;t you contact{" "}
<a href={`mailto:${ctx.supportEmail}`}>{ctx.supportEmail}</a>.
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="login_content2"
defaults="You're receiving this email because a request was made to login to <domain />. If this wasn't you contact <a>{supportEmail}</a>."
values={{ supportEmail: ctx.supportEmail }}
components={{
domain: <Domain ctx={ctx} />,
a: <Link href={`mailto:${ctx.supportEmail}`} />,
}}
ns="emails"
/>
</Text>
</EmailLayout>
);
};
LoginEmail.getSubject = (props: LoginEmailProps, ctx: EmailContext) => {
return ctx.t("login_subject", {
defaultValue: "{{code}} is your 6-digit code",
code: props.code,
ns: "emails",
});
};
export default LoginEmail;

View file

@ -1,36 +1,70 @@
import { defaultEmailContext } from "./_components/email-context";
import { Trans } from "react-i18next/TransWithoutContext";
import NotificationEmail, {
NotificationBaseProps,
} from "./_components/notification-email";
import { Heading, Text } from "./_components/styled-components";
} from "../components/notification-email";
import { Heading, Text } from "../components/styled-components";
import type { EmailContext } from "../types";
export interface NewCommentEmailProps extends NotificationBaseProps {
authorName: string;
}
export const NewCommentEmail = ({
name = "Guest",
title = "Untitled Poll",
authorName = "Someone",
pollUrl = "https://rallly.co",
disableNotificationsUrl = "https://rallly.co",
ctx = defaultEmailContext,
const NewCommentEmail = ({
title,
authorName,
pollUrl,
disableNotificationsUrl,
ctx,
}: NewCommentEmailProps) => {
return (
<NotificationEmail
ctx={ctx}
name={name}
title={title}
pollUrl={pollUrl}
disableNotificationsUrl={disableNotificationsUrl}
preview="Go to your poll to see what they said."
preview={ctx.t("newComment_preview", {
ns: "emails",
defaultValue: "Go to your poll to see what they said.",
})}
>
<Heading>New Comment</Heading>
<Heading>
<Trans
i18n={ctx.i18n}
ns="emails"
i18nKey="newComment_heading"
defaults="New Comment"
/>
</Heading>
<Text>
<strong>{authorName}</strong> has commented on <strong>{title}</strong>.
<Trans
i18n={ctx.i18n}
ns="emails"
i18nKey="newComment_content"
defaults="<b>{{authorName}}</b> has commented on <b>{{title}}</b>."
components={{
b: <strong />,
}}
values={{
authorName,
title,
}}
/>
</Text>
</NotificationEmail>
);
};
export default NewCommentEmail;
NewCommentEmail.getSubject = (
props: NewCommentEmailProps,
ctx: EmailContext,
) => {
return ctx.t("newComment_subject", {
ns: "emails",
defaultValue: "{{authorName}} has commented on {{title}}",
authorName: props.authorName,
title: props.title,
});
};
export { NewCommentEmail };

View file

@ -1,46 +1,99 @@
import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout";
import { Trans } from "react-i18next/TransWithoutContext";
import { EmailLayout } from "../components/email-layout";
import {
Button,
Domain,
Heading,
Section,
Text,
} from "./_components/styled-components";
} from "../components/styled-components";
import type { EmailContext } from "../types";
interface NewParticipantConfirmationEmailProps {
name: string;
title: string;
editSubmissionUrl: string;
ctx: EmailContext;
}
export const NewParticipantConfirmationEmail = ({
title = "Untitled Poll",
editSubmissionUrl = "https://rallly.co",
ctx = defaultEmailContext,
title,
editSubmissionUrl,
ctx,
}: NewParticipantConfirmationEmailProps) => {
const { domain } = ctx;
return (
<EmailLayout ctx={ctx} preview="To edit your response use the link below">
<Heading>Poll Response Confirmation</Heading>
<EmailLayout
ctx={ctx}
preview={ctx.t("newParticipantConfirmation_preview", {
defaultValue: "To edit your response use the link below",
ns: "emails",
})}
>
<Heading>
{ctx.t("newParticipantConfirmation_heading", {
defaultValue: "Poll Response Confirmation",
ns: "emails",
})}
</Heading>
<Text>
Your response to <strong>{title}</strong> has been submitted.
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newParticipantConfirmation_content"
defaults="Your response to <b>{{title}}</b> has been submitted."
components={{
b: <strong />,
}}
values={{ title }}
ns="emails"
/>
</Text>
<Text>
While the poll is still open you can change your response using the link
below.
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newParticipantConfirmation_content2"
defaults="While the poll is still open you can change your response using the link below."
ns="emails"
/>
</Text>
<Section style={{ marginTop: 32 }}>
<Button id="editSubmissionUrl" href={editSubmissionUrl}>
Review response on {domain}
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newParticipantConfirmation_button"
defaults="Review response on {domain}"
values={{ domain }}
ns="emails"
/>
</Button>
</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.
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newParticipantConfirmation_footnote"
defaults="You are receiving this email because a response was submitted on <domain />. If this wasn't you, please ignore this email."
components={{
domain: <Domain ctx={ctx} />,
}}
ns="emails"
/>
</Text>
</EmailLayout>
);
};
NewParticipantConfirmationEmail.getSubject = (
props: NewParticipantConfirmationEmailProps,
ctx: EmailContext,
) => {
return ctx.t("newParticipantConfirmation_subject", {
defaultValue: "Thanks for responding to {{title}}",
title: props.title,
ns: "emails",
});
};
export default NewParticipantConfirmationEmail;

View file

@ -1,38 +1,75 @@
import { defaultEmailContext } from "./_components/email-context";
import { Trans } from "react-i18next/TransWithoutContext";
import NotificationEmail, {
NotificationBaseProps,
} from "./_components/notification-email";
import { Heading, Text } from "./_components/styled-components";
} from "../components/notification-email";
import { Heading, Text } from "../components/styled-components";
import type { EmailContext } from "../types";
export interface NewParticipantEmailProps extends NotificationBaseProps {
participantName: string;
}
export const NewParticipantEmail = ({
name = "John",
title = "Untitled Poll",
participantName = "Someone",
pollUrl = "https://rallly.co",
disableNotificationsUrl = "https://rallly.co",
ctx = defaultEmailContext,
const NewParticipantEmail = ({
title,
participantName,
pollUrl,
disableNotificationsUrl,
ctx,
}: NewParticipantEmailProps) => {
return (
<NotificationEmail
ctx={ctx}
name={name}
title={title}
pollUrl={pollUrl}
disableNotificationsUrl={disableNotificationsUrl}
preview="Go to your poll to see the new response."
preview={ctx.t("newParticipant_preview", {
defaultValue: "Go to your poll to see the new response.",
ns: "emails",
})}
>
<Heading>New Response</Heading>
<Heading>
{ctx.t("newParticipant_heading", {
defaultValue: "New Response",
ns: "emails",
})}
</Heading>
<Text>
<strong>{participantName}</strong> has responded to{" "}
<strong>{title}</strong>.
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newParticipant_content"
ns="emails"
defaults="<b>{{name}}</b> has responded to <b>{{title}}</b>."
components={{
b: <strong />,
}}
values={{ name: participantName, title }}
/>
</Text>
<Text>
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newParticipant_content2"
defaults="Go to your poll to see the new response."
ns="emails"
/>
</Text>
<Text>Go to your poll to see the new response.</Text>
</NotificationEmail>
);
};
export default NewParticipantEmail;
NewParticipantEmail.getSubject = (
props: NewParticipantEmailProps,
ctx: EmailContext,
) => {
return ctx.t("newParticipant_subject", {
defaultValue: "{{name}} has responded to {{title}}",
name: props.participantName,
title: props.title,
ns: "emails",
});
};
export { NewParticipantEmail };

View file

@ -1,12 +1,14 @@
import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout";
import { Trans } from "react-i18next/TransWithoutContext";
import { EmailLayout } from "../components/email-layout";
import {
Button,
Card,
Heading,
Link,
Text,
} from "./_components/styled-components";
} from "../components/styled-components";
import type { EmailContext } from "../types";
export interface NewPollEmailProps {
title: string;
@ -17,29 +19,61 @@ export interface NewPollEmailProps {
}
export const NewPollEmail = ({
title = "Untitled Poll",
adminLink = "https://rallly.co/admin/abcdefg123",
participantLink = "https://rallly.co/invite/wxyz9876",
ctx = defaultEmailContext,
title,
adminLink,
participantLink,
ctx,
}: NewPollEmailProps) => {
return (
<EmailLayout
ctx={ctx}
preview="Share your participant link to start collecting responses."
preview={ctx.t("newPoll_preview", {
defaultValue:
"Share your participant link to start collecting responses.",
ns: "emails",
})}
>
<Heading>New Poll Created</Heading>
<Heading>
{ctx.t("newPoll_heading", {
defaultValue: "New Poll Created",
ns: "emails",
})}
</Heading>
<Text>
Your meeting poll titled <strong>{`"${title}"`}</strong> is ready! Share
it using the link below:
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="newPoll_content"
ns="emails"
values={{ title }}
components={{
b: <strong />,
}}
defaults="Your meeting poll titled <b>{{title}}</b> is ready! Share it using the link below:"
/>
</Text>
<Card style={{ textAlign: "center" }}>
<Text style={{ textAlign: "center" }}>
<Link href={participantLink}>{participantLink}</Link>
</Text>
</Card>
<Button href={adminLink}>Manage Poll &rarr;</Button>
<Button href={adminLink}>
{ctx.t("newPoll_button", {
defaultValue: "Manage Poll",
ns: "emails",
})}
&rarr;
</Button>
</EmailLayout>
);
};
NewPollEmail.getSubject = (props: NewPollEmailProps, ctx: EmailContext) => {
return ctx.t("newPoll_subject", {
defaultValue: "Let's find a date for {{title}}!",
title: props.title,
ns: "emails",
});
};
export default NewPollEmail;

View file

@ -1,29 +1,43 @@
import { Section } from "@react-email/section";
import { Trans } from "react-i18next/TransWithoutContext";
import { defaultEmailContext, EmailContext } from "./_components/email-context";
import { EmailLayout } from "./_components/email-layout";
import { EmailLayout } from "../components/email-layout";
import {
Card,
Domain,
Heading,
Text,
trackingWide,
} from "./_components/styled-components";
} from "../components/styled-components";
import type { EmailContext } from "../types";
interface RegisterEmailProps {
code: string;
ctx: EmailContext;
}
export const RegisterEmail = ({
code = "123456",
ctx = defaultEmailContext,
}: RegisterEmailProps) => {
export const RegisterEmail = ({ code, ctx }: RegisterEmailProps) => {
return (
<EmailLayout ctx={ctx} preview={`Your 6-digit code is: ${code}`}>
<Heading>Verify your email address</Heading>
<EmailLayout
ctx={ctx}
preview={ctx.t("register_preview", {
ns: "emails",
defaultValue: "Your 6-digit code is: {{code}}",
code,
})}
>
<Heading>
{ctx.t("register_heading", {
defaultValue: "Verify your email address",
ns: "emails",
})}
</Heading>
<Text>
Please use the following 6-digit verification code to verify your email:
{ctx.t("register_text", {
defaultValue:
"Please use the following 6-digit verification code to verify your email",
ns: "emails",
})}
</Text>
<Card style={{ textAlign: "center" }}>
<Text
@ -38,18 +52,36 @@ export const RegisterEmail = ({
{code}
</Text>
<Text style={{ textAlign: "center" }} light={true}>
This code is valid for 15 minutes
{ctx.t("register_codeValid", {
defaultValue: "This code is valid for 15 minutes",
ns: "emails",
})}
</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.
<Trans
i18n={ctx.i18n}
t={ctx.t}
i18nKey="register_footer"
ns="emails"
values={{ domain: ctx.domain }}
components={{
domain: <Domain ctx={ctx} />,
}}
defaults="You're receiving this email because a request was made to register an account on <domain />. If this wasn't you, please ignore this email."
/>
</Text>
</Section>
</EmailLayout>
);
};
RegisterEmail.getSubject = (_props: RegisterEmailProps, ctx: EmailContext) => {
return ctx.t("register_subject", {
defaultValue: "Please verify your email address",
ns: "emails",
});
};
export default RegisterEmail;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB