mirror of
https://github.com/lukevella/rallly.git
synced 2025-07-18 08:47:24 +02:00
♻️ Remove use of context from email package (#981)
This commit is contained in:
parent
668a4b5798
commit
e2c4cc7ad2
14 changed files with 59 additions and 44 deletions
|
@ -21,5 +21,6 @@ export const emailClient = new EmailClient({
|
||||||
context: {
|
context: {
|
||||||
logoUrl: absoluteUrl("/logo.png"),
|
logoUrl: absoluteUrl("/logo.png"),
|
||||||
baseUrl: absoluteUrl(""),
|
baseUrl: absoluteUrl(""),
|
||||||
|
domain: absoluteUrl("").replace(/(^\w+:|^)\/\//, ""),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,8 +13,9 @@ type Templates = typeof templates;
|
||||||
|
|
||||||
type TemplateName = keyof typeof templates;
|
type TemplateName = keyof typeof templates;
|
||||||
|
|
||||||
type TemplateProps<T extends TemplateName> = React.ComponentProps<
|
type TemplateProps<T extends TemplateName> = Omit<
|
||||||
TemplateComponent<T>
|
React.ComponentProps<TemplateComponent<T>>,
|
||||||
|
"ctx"
|
||||||
>;
|
>;
|
||||||
type TemplateComponent<T extends TemplateName> = Templates[T];
|
type TemplateComponent<T extends TemplateName> = Templates[T];
|
||||||
|
|
||||||
|
@ -79,12 +80,11 @@ export class EmailClient {
|
||||||
) {
|
) {
|
||||||
const Template = templates[templateName] as TemplateComponent<T>;
|
const Template = templates[templateName] as TemplateComponent<T>;
|
||||||
const html = render(
|
const html = render(
|
||||||
<EmailContext.Provider value={this.config.context}>
|
<Template
|
||||||
<Template
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
{...(options.props as any)}
|
||||||
{...(options.props as any)}
|
ctx={this.config.context}
|
||||||
/>
|
/>,
|
||||||
</EmailContext.Provider>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export type EmailContext = {
|
export type EmailContext = {
|
||||||
logoUrl: string;
|
logoUrl: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
};
|
domain: string;
|
||||||
|
|
||||||
export const EmailContext = React.createContext<EmailContext>({
|
|
||||||
logoUrl: "/static/logo.png",
|
|
||||||
baseUrl: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
export const useEmailContext = () => {
|
|
||||||
const context = React.useContext(EmailContext);
|
|
||||||
return {
|
|
||||||
...context,
|
|
||||||
domain: context.baseUrl.replace(/(^\w+:|^)\/\//, ""),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,13 +8,14 @@ import {
|
||||||
Preview,
|
Preview,
|
||||||
} from "@react-email/components";
|
} from "@react-email/components";
|
||||||
|
|
||||||
import { useEmailContext } from "./email-context";
|
import { EmailContext } from "./email-context";
|
||||||
import { fontFamily, Section, Text } from "./styled-components";
|
import { fontFamily, Section, Text } from "./styled-components";
|
||||||
|
|
||||||
export interface EmailLayoutProps {
|
export interface EmailLayoutProps {
|
||||||
preview: string;
|
preview: string;
|
||||||
recipientName: string;
|
recipientName: string;
|
||||||
footNote?: React.ReactNode;
|
footNote?: React.ReactNode;
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
const containerStyles = {
|
const containerStyles = {
|
||||||
|
@ -42,8 +43,9 @@ export const EmailLayout = ({
|
||||||
recipientName = "Guest",
|
recipientName = "Guest",
|
||||||
children,
|
children,
|
||||||
footNote,
|
footNote,
|
||||||
|
ctx,
|
||||||
}: React.PropsWithChildren<EmailLayoutProps>) => {
|
}: React.PropsWithChildren<EmailLayoutProps>) => {
|
||||||
const { logoUrl, baseUrl } = useEmailContext();
|
const { logoUrl, baseUrl } = ctx;
|
||||||
return (
|
return (
|
||||||
<Html>
|
<Html>
|
||||||
<Head />
|
<Head />
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEmailContext } 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";
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ export interface NotificationBaseProps {
|
||||||
title: string;
|
title: string;
|
||||||
pollUrl: string;
|
pollUrl: string;
|
||||||
disableNotificationsUrl: string;
|
disableNotificationsUrl: string;
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotificationEmailProps extends NotificationBaseProps {
|
export interface NotificationEmailProps extends NotificationBaseProps {
|
||||||
|
@ -19,10 +20,12 @@ export const NotificationEmail = ({
|
||||||
disableNotificationsUrl,
|
disableNotificationsUrl,
|
||||||
preview,
|
preview,
|
||||||
children,
|
children,
|
||||||
|
ctx,
|
||||||
}: React.PropsWithChildren<NotificationEmailProps>) => {
|
}: React.PropsWithChildren<NotificationEmailProps>) => {
|
||||||
const { domain } = useEmailContext();
|
const { domain } = ctx;
|
||||||
return (
|
return (
|
||||||
<EmailLayout
|
<EmailLayout
|
||||||
|
ctx={ctx}
|
||||||
recipientName={name}
|
recipientName={name}
|
||||||
footNote={
|
footNote={
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
TextProps,
|
TextProps,
|
||||||
} from "@react-email/components";
|
} from "@react-email/components";
|
||||||
|
|
||||||
import { useEmailContext } from "./email-context";
|
import { EmailContext } from "./email-context";
|
||||||
|
|
||||||
export const borderColor = "#E2E8F0";
|
export const borderColor = "#E2E8F0";
|
||||||
export const Text = (
|
export const Text = (
|
||||||
|
@ -32,8 +32,8 @@ export const Text = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Domain = () => {
|
export const Domain = ({ ctx }: { ctx: EmailContext }) => {
|
||||||
const { baseUrl, domain } = useEmailContext();
|
const { baseUrl, domain } = ctx;
|
||||||
return <Link href={baseUrl}>{domain}</Link>;
|
return <Link href={baseUrl}>{domain}</Link>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Column, Row, Section } from "@react-email/components";
|
import { Column, Row, Section } from "@react-email/components";
|
||||||
|
|
||||||
|
import { 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, Text } from "./components/styled-components";
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ export interface FinalizeHostEmailProps {
|
||||||
location: string | null;
|
location: string | null;
|
||||||
pollUrl: string;
|
pollUrl: string;
|
||||||
attendees: string[];
|
attendees: string[];
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FinalizeHostEmail = ({
|
export const FinalizeHostEmail = ({
|
||||||
|
@ -23,9 +25,10 @@ export const FinalizeHostEmail = ({
|
||||||
dow = "Fri",
|
dow = "Fri",
|
||||||
date = "Friday, 12th June 2020",
|
date = "Friday, 12th June 2020",
|
||||||
time = "6:00 PM to 11:00 PM BST",
|
time = "6:00 PM to 11:00 PM BST",
|
||||||
|
ctx,
|
||||||
}: FinalizeHostEmailProps) => {
|
}: FinalizeHostEmailProps) => {
|
||||||
return (
|
return (
|
||||||
<EmailLayout recipientName={name} preview="Final date booked!">
|
<EmailLayout ctx={ctx} recipientName={name} preview="Final date booked!">
|
||||||
<Text>
|
<Text>
|
||||||
<strong>{title}</strong> has been booked for:
|
<strong>{title}</strong> has been booked for:
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Column, Row, Section } from "@react-email/components";
|
import { Column, Row, Section } from "@react-email/components";
|
||||||
|
|
||||||
|
import { 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, Text } from "./components/styled-components";
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ export interface FinalizeParticipantEmailProps {
|
||||||
location: string | null;
|
location: string | null;
|
||||||
pollUrl: string;
|
pollUrl: string;
|
||||||
attendees: string[];
|
attendees: string[];
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FinalizeParticipantEmail = ({
|
export const FinalizeParticipantEmail = ({
|
||||||
|
@ -25,9 +27,10 @@ export const FinalizeParticipantEmail = ({
|
||||||
dow = "Fri",
|
dow = "Fri",
|
||||||
date = "Friday, 12th June 2020",
|
date = "Friday, 12th June 2020",
|
||||||
time = "6:00 PM to 11:00 PM BST",
|
time = "6:00 PM to 11:00 PM BST",
|
||||||
|
ctx,
|
||||||
}: FinalizeParticipantEmailProps) => {
|
}: FinalizeParticipantEmailProps) => {
|
||||||
return (
|
return (
|
||||||
<EmailLayout recipientName={name} preview="Final date booked!">
|
<EmailLayout ctx={ctx} recipientName={name} preview="Final date booked!">
|
||||||
<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:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEmailContext } from "./components/email-context";
|
import { EmailContext } from "./components/email-context";
|
||||||
import { EmailLayout } from "./components/email-layout";
|
import { EmailLayout } from "./components/email-layout";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
@ -13,21 +13,23 @@ interface LoginEmailProps {
|
||||||
name: string;
|
name: string;
|
||||||
code: string;
|
code: string;
|
||||||
magicLink: string;
|
magicLink: string;
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LoginEmail = ({
|
export const LoginEmail = ({
|
||||||
name = "Guest",
|
name = "Guest",
|
||||||
code = "123456",
|
code = "123456",
|
||||||
magicLink = "https://rallly.co",
|
magicLink = "https://rallly.co",
|
||||||
|
ctx,
|
||||||
}: LoginEmailProps) => {
|
}: LoginEmailProps) => {
|
||||||
const { domain } = useEmailContext();
|
|
||||||
return (
|
return (
|
||||||
<EmailLayout
|
<EmailLayout
|
||||||
|
ctx={ctx}
|
||||||
footNote={
|
footNote={
|
||||||
<>
|
<>
|
||||||
You're receiving this email because a request was made to login
|
You're receiving this email because a request was made to login
|
||||||
to <Domain />. If this wasn't you, let us know by replying to
|
to <Domain ctx={ctx} />. If this wasn't you, let us know by
|
||||||
this email.
|
replying to this email.
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
recipientName={name}
|
recipientName={name}
|
||||||
|
@ -40,7 +42,7 @@ export const LoginEmail = ({
|
||||||
<Heading>Option 1: Magic Link</Heading>
|
<Heading>Option 1: Magic Link</Heading>
|
||||||
<Text>Click this magic link to log in on this device.</Text>
|
<Text>Click this magic link to log in on this device.</Text>
|
||||||
<Button href={magicLink} id="magicLink">
|
<Button href={magicLink} id="magicLink">
|
||||||
Log in to {domain}
|
Log in to {ctx.domain}
|
||||||
</Button>
|
</Button>
|
||||||
<Text light={true}>This link will expire in 15 minutes.</Text>
|
<Text light={true}>This link will expire in 15 minutes.</Text>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -13,9 +13,11 @@ export const NewCommentEmail = ({
|
||||||
authorName = "Someone",
|
authorName = "Someone",
|
||||||
pollUrl = "https://rallly.co",
|
pollUrl = "https://rallly.co",
|
||||||
disableNotificationsUrl = "https://rallly.co",
|
disableNotificationsUrl = "https://rallly.co",
|
||||||
|
ctx,
|
||||||
}: NewCommentEmailProps) => {
|
}: NewCommentEmailProps) => {
|
||||||
return (
|
return (
|
||||||
<NotificationEmail
|
<NotificationEmail
|
||||||
|
ctx={ctx}
|
||||||
name={name}
|
name={name}
|
||||||
title={title}
|
title={title}
|
||||||
pollUrl={pollUrl}
|
pollUrl={pollUrl}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEmailContext } from "./components/email-context";
|
import { 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, Section, Text } from "./components/styled-components";
|
||||||
|
|
||||||
|
@ -6,19 +6,23 @@ interface NewParticipantConfirmationEmailProps {
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
editSubmissionUrl: string;
|
editSubmissionUrl: string;
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
export const NewParticipantConfirmationEmail = ({
|
export const NewParticipantConfirmationEmail = ({
|
||||||
title = "Untitled Poll",
|
title = "Untitled Poll",
|
||||||
name = "John",
|
name = "John",
|
||||||
editSubmissionUrl = "https://rallly.co",
|
editSubmissionUrl = "https://rallly.co",
|
||||||
|
ctx,
|
||||||
}: NewParticipantConfirmationEmailProps) => {
|
}: NewParticipantConfirmationEmailProps) => {
|
||||||
const { domain } = useEmailContext();
|
const { domain } = ctx;
|
||||||
return (
|
return (
|
||||||
<EmailLayout
|
<EmailLayout
|
||||||
|
ctx={ctx}
|
||||||
footNote={
|
footNote={
|
||||||
<>
|
<>
|
||||||
You are receiving this email because a response was submitted on{" "}
|
You are receiving this email because a response was submitted on{" "}
|
||||||
<Domain />. If this wasn't you, please ignore this email.
|
<Domain ctx={ctx} />. If this wasn't you, please ignore this
|
||||||
|
email.
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
recipientName={name}
|
recipientName={name}
|
||||||
|
|
|
@ -13,9 +13,11 @@ export const NewParticipantEmail = ({
|
||||||
participantName = "Someone",
|
participantName = "Someone",
|
||||||
pollUrl = "https://rallly.co",
|
pollUrl = "https://rallly.co",
|
||||||
disableNotificationsUrl = "https://rallly.co",
|
disableNotificationsUrl = "https://rallly.co",
|
||||||
|
ctx,
|
||||||
}: NewParticipantEmailProps) => {
|
}: NewParticipantEmailProps) => {
|
||||||
return (
|
return (
|
||||||
<NotificationEmail
|
<NotificationEmail
|
||||||
|
ctx={ctx}
|
||||||
name={name}
|
name={name}
|
||||||
title={title}
|
title={title}
|
||||||
pollUrl={pollUrl}
|
pollUrl={pollUrl}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEmailContext } from "./components/email-context";
|
import { 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, Link, Text } from "./components/styled-components";
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ export interface NewPollEmailProps {
|
||||||
name: string;
|
name: string;
|
||||||
adminLink: string;
|
adminLink: string;
|
||||||
participantLink: string;
|
participantLink: string;
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShareLink = ({
|
const ShareLink = ({
|
||||||
|
@ -37,10 +38,12 @@ export const NewPollEmail = ({
|
||||||
name = "John",
|
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,
|
||||||
}: NewPollEmailProps) => {
|
}: NewPollEmailProps) => {
|
||||||
const { baseUrl, domain } = useEmailContext();
|
const { baseUrl, domain } = ctx;
|
||||||
return (
|
return (
|
||||||
<EmailLayout
|
<EmailLayout
|
||||||
|
ctx={ctx}
|
||||||
footNote={
|
footNote={
|
||||||
<>
|
<>
|
||||||
You are receiving this email because a new poll was created with this
|
You are receiving this email because a new poll was created with this
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { EmailContext } from "./components/email-context";
|
||||||
import { EmailLayout } from "./components/email-layout";
|
import { EmailLayout } from "./components/email-layout";
|
||||||
import {
|
import {
|
||||||
Domain,
|
Domain,
|
||||||
|
@ -9,19 +10,22 @@ import {
|
||||||
interface RegisterEmailProps {
|
interface RegisterEmailProps {
|
||||||
name: string;
|
name: string;
|
||||||
code: string;
|
code: string;
|
||||||
|
ctx: EmailContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RegisterEmail = ({
|
export const RegisterEmail = ({
|
||||||
name = "John",
|
name = "John",
|
||||||
code = "123456",
|
code = "123456",
|
||||||
|
ctx,
|
||||||
}: RegisterEmailProps) => {
|
}: RegisterEmailProps) => {
|
||||||
return (
|
return (
|
||||||
<EmailLayout
|
<EmailLayout
|
||||||
|
ctx={ctx}
|
||||||
footNote={
|
footNote={
|
||||||
<>
|
<>
|
||||||
You're receiving this email because a request was made to
|
You're receiving this email because a request was made to
|
||||||
register an account on <Domain />. If this wasn't you, please
|
register an account on <Domain ctx={ctx} />. If this wasn't you,
|
||||||
ignore this email.
|
please ignore this email.
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
recipientName={name}
|
recipientName={name}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue