mirror of
https://github.com/lukevella/rallly.git
synced 2025-07-23 11:17:26 +02:00
♻️ Refactor code for generating absolute url (#904)
This commit is contained in:
parent
eaa8f5813d
commit
703d551aac
25 changed files with 108 additions and 61 deletions
|
@ -7,6 +7,7 @@ import previewEmail from "preview-email";
|
|||
import React from "react";
|
||||
|
||||
import * as templates from "./templates";
|
||||
import { EmailContext } from "./templates/components/email-context";
|
||||
|
||||
type Templates = typeof templates;
|
||||
|
||||
|
@ -15,7 +16,6 @@ type TemplateName = keyof typeof templates;
|
|||
type TemplateProps<T extends TemplateName> = React.ComponentProps<
|
||||
TemplateComponent<T>
|
||||
>;
|
||||
|
||||
type TemplateComponent<T extends TemplateName> = Templates[T];
|
||||
|
||||
type SendEmailOptions<T extends TemplateName> = {
|
||||
|
@ -59,6 +59,10 @@ type EmailClientConfig = {
|
|||
address: string;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Context to pass to each email
|
||||
*/
|
||||
context: EmailContext;
|
||||
};
|
||||
|
||||
export class EmailClient {
|
||||
|
@ -79,8 +83,14 @@ export class EmailClient {
|
|||
}
|
||||
|
||||
const Template = templates[templateName] as TemplateComponent<T>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const html = render(<Template {...(options.props as any)} />);
|
||||
const html = render(
|
||||
<EmailContext.Provider value={this.config.context}>
|
||||
<Template
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
{...(options.props as any)}
|
||||
/>
|
||||
</EmailContext.Provider>,
|
||||
);
|
||||
|
||||
try {
|
||||
await this.sendEmail({
|
||||
|
|
19
packages/emails/src/templates/components/email-context.tsx
Normal file
19
packages/emails/src/templates/components/email-context.tsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
|
||||
export type EmailContext = {
|
||||
logoUrl: string;
|
||||
baseUrl: string;
|
||||
};
|
||||
|
||||
export const EmailContext = React.createContext<EmailContext>({
|
||||
logoUrl: "",
|
||||
baseUrl: "",
|
||||
});
|
||||
|
||||
export const useEmailContext = () => {
|
||||
const context = React.useContext(EmailContext);
|
||||
return {
|
||||
...context,
|
||||
domain: context.baseUrl.replace(/(^\w+:|^)\/\//, ""),
|
||||
};
|
||||
};
|
|
@ -1,4 +1,3 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
import {
|
||||
Body,
|
||||
Container,
|
||||
|
@ -9,6 +8,7 @@ import {
|
|||
Preview,
|
||||
} from "@react-email/components";
|
||||
|
||||
import { useEmailContext } from "./email-context";
|
||||
import { fontFamily, Section, Text } from "./styled-components";
|
||||
|
||||
export interface EmailLayoutProps {
|
||||
|
@ -43,13 +43,14 @@ export const EmailLayout = ({
|
|||
children,
|
||||
footNote,
|
||||
}: React.PropsWithChildren<EmailLayoutProps>) => {
|
||||
const { logoUrl, baseUrl } = useEmailContext();
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<Preview>{preview}</Preview>
|
||||
<Body style={{ backgroundColor: "#F3F4F6", padding: "16px" }}>
|
||||
<Container style={containerStyles}>
|
||||
<Img src={absoluteUrl("/logo.png")} alt="Rallly" width={128} />
|
||||
<Img src={logoUrl} alt="Rallly" width={128} />
|
||||
<Section style={sectionStyles}>
|
||||
<Text>Hi {recipientName},</Text>
|
||||
{children}
|
||||
|
@ -68,7 +69,7 @@ export const EmailLayout = ({
|
|||
) : null}
|
||||
</Section>
|
||||
<Section style={{ ...sectionStyles, fontSize: 14, marginBottom: 0 }}>
|
||||
<Link style={linkStyles} href={absoluteUrl()}>
|
||||
<Link style={linkStyles} href={baseUrl}>
|
||||
Home
|
||||
</Link>
|
||||
<span> • </span>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useEmailContext } from "./email-context";
|
||||
import { EmailLayout } from "./email-layout";
|
||||
import { Button, Link, Text } from "./styled-components";
|
||||
import { getDomain } from "./utils";
|
||||
|
||||
export interface NotificationBaseProps {
|
||||
name: string;
|
||||
|
@ -20,6 +20,7 @@ export const NotificationEmail = ({
|
|||
preview,
|
||||
children,
|
||||
}: React.PropsWithChildren<NotificationEmailProps>) => {
|
||||
const { domain } = useEmailContext();
|
||||
return (
|
||||
<EmailLayout
|
||||
recipientName={name}
|
||||
|
@ -36,7 +37,7 @@ export const NotificationEmail = ({
|
|||
>
|
||||
{children}
|
||||
<Text>
|
||||
<Button href={pollUrl}>View on {getDomain()}</Button>
|
||||
<Button href={pollUrl}>View on {domain}</Button>
|
||||
</Text>
|
||||
</EmailLayout>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
import {
|
||||
Button as UnstyledButton,
|
||||
ButtonProps,
|
||||
|
@ -11,7 +10,7 @@ import {
|
|||
TextProps,
|
||||
} from "@react-email/components";
|
||||
|
||||
import { getDomain } from "./utils";
|
||||
import { useEmailContext } from "./email-context";
|
||||
|
||||
export const borderColor = "#E2E8F0";
|
||||
export const Text = (
|
||||
|
@ -34,7 +33,8 @@ export const Text = (
|
|||
};
|
||||
|
||||
export const Domain = () => {
|
||||
return <Link href={absoluteUrl()}>{getDomain()}</Link>;
|
||||
const { baseUrl, domain } = useEmailContext();
|
||||
return <Link href={baseUrl}>{domain}</Link>;
|
||||
};
|
||||
|
||||
export const Button = (props: ButtonProps) => {
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
|
||||
export const removeProtocalFromUrl = (url: string) => {
|
||||
return url.replace(/(^\w+:|^)\/\//, "");
|
||||
};
|
||||
|
||||
export const getDomain = () => removeProtocalFromUrl(absoluteUrl());
|
|
@ -1,3 +1,4 @@
|
|||
import { useEmailContext } from "./components/email-context";
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import {
|
||||
Button,
|
||||
|
@ -7,7 +8,6 @@ import {
|
|||
Text,
|
||||
trackingWide,
|
||||
} from "./components/styled-components";
|
||||
import { getDomain } from "./components/utils";
|
||||
|
||||
interface LoginEmailProps {
|
||||
name: string;
|
||||
|
@ -20,6 +20,7 @@ export const LoginEmail = ({
|
|||
code = "123456",
|
||||
magicLink = "https://rallly.co",
|
||||
}: LoginEmailProps) => {
|
||||
const { domain } = useEmailContext();
|
||||
return (
|
||||
<EmailLayout
|
||||
footNote={
|
||||
|
@ -39,7 +40,7 @@ export const LoginEmail = ({
|
|||
<Heading>Option 1: Magic Link</Heading>
|
||||
<Text>Click this magic link to log in on this device.</Text>
|
||||
<Button href={magicLink} id="magicLink">
|
||||
Log in to {getDomain()}
|
||||
Log in to {domain}
|
||||
</Button>
|
||||
<Text light={true}>This link will expire in 15 minutes.</Text>
|
||||
</Card>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useEmailContext } from "./components/email-context";
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Button, Domain, Section, Text } from "./components/styled-components";
|
||||
import { getDomain } from "./components/utils";
|
||||
|
||||
interface NewParticipantConfirmationEmailProps {
|
||||
name: string;
|
||||
|
@ -12,6 +12,7 @@ export const NewParticipantConfirmationEmail = ({
|
|||
name = "John",
|
||||
editSubmissionUrl = "https://rallly.co",
|
||||
}: NewParticipantConfirmationEmailProps) => {
|
||||
const { domain } = useEmailContext();
|
||||
return (
|
||||
<EmailLayout
|
||||
footNote={
|
||||
|
@ -32,7 +33,7 @@ export const NewParticipantConfirmationEmail = ({
|
|||
</Text>
|
||||
<Section>
|
||||
<Button id="editSubmissionUrl" href={editSubmissionUrl}>
|
||||
Review response on {getDomain()}
|
||||
Review response on {domain}
|
||||
</Button>
|
||||
</Section>
|
||||
</EmailLayout>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
|
||||
import { useEmailContext } from "./components/email-context";
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Button, Card, Link, Text } from "./components/styled-components";
|
||||
import { getDomain } from "./components/utils";
|
||||
|
||||
export interface NewPollEmailProps {
|
||||
title: string;
|
||||
|
@ -40,13 +38,14 @@ export const NewPollEmail = ({
|
|||
adminLink = "https://rallly.co/admin/abcdefg123",
|
||||
participantLink = "https://rallly.co/invite/wxyz9876",
|
||||
}: NewPollEmailProps) => {
|
||||
const { baseUrl, domain } = useEmailContext();
|
||||
return (
|
||||
<EmailLayout
|
||||
footNote={
|
||||
<>
|
||||
You are receiving this email because a new poll was created with this
|
||||
email address on <Link href={absoluteUrl()}>{getDomain()}</Link>. If
|
||||
this wasn't you, please ignore this email.
|
||||
email address on <Link href={baseUrl}>{domain}</Link>. If this
|
||||
wasn't you, please ignore this email.
|
||||
</>
|
||||
}
|
||||
recipientName={name}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue