mirror of
https://github.com/lukevella/rallly.git
synced 2025-05-21 04:46:22 +02:00
✨ Update notification flow (#548)
This commit is contained in:
parent
cb1fb23b19
commit
39a07558ee
41 changed files with 930 additions and 520 deletions
|
@ -46,12 +46,19 @@ export const sendEmail = async <T extends TemplateName>(
|
|||
templateName: T,
|
||||
options: SendEmailOptions<T>,
|
||||
) => {
|
||||
if (!process.env.SUPPORT_EMAIL) {
|
||||
console.info("SUPPORT_EMAIL not configured - skipping email send");
|
||||
return;
|
||||
}
|
||||
const transport = getTransport();
|
||||
const Template = templates[templateName] as TemplateComponent<T>;
|
||||
|
||||
try {
|
||||
return await transport.sendMail({
|
||||
from: process.env.SUPPORT_EMAIL,
|
||||
from: {
|
||||
name: "Rallly",
|
||||
address: process.env.SUPPORT_EMAIL,
|
||||
},
|
||||
to: options.to,
|
||||
subject: options.subject,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export * from "./templates/guest-verify-email";
|
||||
export * from "./templates/login";
|
||||
export * from "./templates/new-comment";
|
||||
export * from "./templates/new-participant";
|
||||
export * from "./templates/new-participant-confirmation";
|
||||
export * from "./templates/new-poll";
|
||||
export * from "./templates/new-poll-verification";
|
||||
export * from "./templates/verification-code";
|
||||
export * from "./templates/register";
|
||||
export * from "./templates/turn-on-notifications";
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Hr,
|
||||
Html,
|
||||
Img,
|
||||
Link,
|
||||
|
@ -12,14 +13,24 @@ import {
|
|||
} from "@react-email/components";
|
||||
import { Tailwind } from "@react-email/tailwind";
|
||||
|
||||
export const EmailLayout = (props: {
|
||||
children: React.ReactNode;
|
||||
import { SmallText, Text } from "./styled-components";
|
||||
|
||||
interface EmailLayoutProps {
|
||||
preview: string;
|
||||
}) => {
|
||||
recipientName: string;
|
||||
footNote?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const EmailLayout = ({
|
||||
preview,
|
||||
recipientName = "Guest",
|
||||
children,
|
||||
footNote,
|
||||
}: React.PropsWithChildren<EmailLayoutProps>) => {
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<Preview>{props.preview}</Preview>
|
||||
<Preview>{preview}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
|
@ -115,12 +126,21 @@ export const EmailLayout = (props: {
|
|||
},
|
||||
}}
|
||||
>
|
||||
<Body className="bg-gray-50 p-4">
|
||||
<Container className="mx-auto bg-white p-6">
|
||||
<Body className="bg-white px-3 py-6">
|
||||
<Container className="max-w-lg">
|
||||
<Section className="mb-4">
|
||||
<Img src={absoluteUrl("/logo.png")} alt="Rallly" width={128} />
|
||||
</Section>
|
||||
<Section>{props.children}</Section>
|
||||
<Section>
|
||||
<Text>Hi {recipientName},</Text>
|
||||
{children}
|
||||
{footNote ? (
|
||||
<>
|
||||
<Hr />
|
||||
<SmallText>{footNote}</SmallText>
|
||||
</>
|
||||
) : null}
|
||||
</Section>
|
||||
<Section className="mt-4 text-sm text-slate-500">
|
||||
<Link className="font-sans text-slate-500" href={absoluteUrl()}>
|
||||
Home
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
import { Hr } from "@react-email/components";
|
||||
import { Container } from "@react-email/container";
|
||||
|
||||
import { Link, Text } from "./styled-components";
|
||||
import { Link, SmallText, Text } from "./styled-components";
|
||||
import { removeProtocalFromUrl } from "./utils";
|
||||
|
||||
export interface NewPollBaseEmailProps {
|
||||
title: string;
|
||||
|
@ -29,6 +32,12 @@ export const NewPollBaseEmail = ({
|
|||
</Link>
|
||||
</Text>
|
||||
{children}
|
||||
<Hr />
|
||||
<SmallText>
|
||||
You are receiving this email because a new poll was created with this
|
||||
email address on{" "}
|
||||
<Link href={absoluteUrl()}>{removeProtocalFromUrl(absoluteUrl())}</Link>
|
||||
</SmallText>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { EmailLayout } from "./email-layout";
|
||||
import { Link, Section } from "./styled-components";
|
||||
|
||||
export interface NotificationBaseProps {
|
||||
name: string;
|
||||
title: string;
|
||||
pollUrl: string;
|
||||
unsubscribeUrl: string;
|
||||
}
|
||||
|
||||
export interface NotificationEmailProps extends NotificationBaseProps {
|
||||
preview: string;
|
||||
}
|
||||
|
||||
export const NotificationEmail = ({
|
||||
name,
|
||||
title,
|
||||
pollUrl,
|
||||
unsubscribeUrl,
|
||||
preview,
|
||||
children,
|
||||
}: React.PropsWithChildren<NotificationEmailProps>) => {
|
||||
return (
|
||||
<EmailLayout
|
||||
recipientName={name}
|
||||
footNote={
|
||||
<>
|
||||
You're receiving this email because notifications are enabled for{" "}
|
||||
<strong>{title}</strong>. If you want to stop receiving emails about
|
||||
this event you can{" "}
|
||||
<Link className="whitespace-nowrap" href={unsubscribeUrl}>
|
||||
turn notifications off
|
||||
</Link>
|
||||
.
|
||||
</>
|
||||
}
|
||||
preview={preview}
|
||||
>
|
||||
{children}
|
||||
<Section>
|
||||
<Link href={pollUrl}>Go to poll →</Link>
|
||||
</Section>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationEmail;
|
|
@ -39,7 +39,7 @@ export const Link = (props: LinkProps) => {
|
|||
return (
|
||||
<UnstyledLink
|
||||
{...props}
|
||||
className={clsx("text-primary-500 font-sans text-base", props.className)}
|
||||
className={clsx("text-primary-500", props.className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -61,3 +61,12 @@ export const Section = (props: SectionProps) => {
|
|||
<UnstyledSection {...props} className={clsx("my-4", props.className)} />
|
||||
);
|
||||
};
|
||||
|
||||
export const SmallText = (props: TextProps) => {
|
||||
return (
|
||||
<UnstyledText
|
||||
{...props}
|
||||
className={clsx("font-sans text-sm text-slate-500", props.className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
3
packages/emails/src/templates/components/utils.ts
Normal file
3
packages/emails/src/templates/components/utils.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const removeProtocalFromUrl = (url: string) => {
|
||||
return url.replace(/(^\w+:|^)\/\//, "");
|
||||
};
|
|
@ -1,41 +0,0 @@
|
|||
import { Button, Container } from "@react-email/components";
|
||||
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Section, Text } from "./components/styled-components";
|
||||
|
||||
type GuestVerifyEmailProps = {
|
||||
title: string;
|
||||
name: string;
|
||||
verificationLink: string;
|
||||
adminLink: string;
|
||||
};
|
||||
|
||||
export const GuestVerifyEmail = ({
|
||||
title = "Untitled Poll",
|
||||
name = "Guest",
|
||||
verificationLink = "https://rallly.co",
|
||||
}: GuestVerifyEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview="Click the button below to verify your email">
|
||||
<Container>
|
||||
<Text>Hi {name},</Text>
|
||||
<Text>
|
||||
To receive notifications for <strong>"{title}"</strong> you
|
||||
will need to verify your email address.
|
||||
</Text>
|
||||
<Text>To verify your email please click the button below.</Text>
|
||||
<Section>
|
||||
<Button
|
||||
className="bg-primary-500 rounded px-3 py-2 font-sans text-white"
|
||||
href={verificationLink}
|
||||
id="verifyEmailUrl"
|
||||
>
|
||||
Verify your email →
|
||||
</Button>
|
||||
</Section>
|
||||
</Container>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default GuestVerifyEmail;
|
55
packages/emails/src/templates/login.tsx
Normal file
55
packages/emails/src/templates/login.tsx
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Heading, Link, Text } from "./components/styled-components";
|
||||
import { removeProtocalFromUrl } from "./components/utils";
|
||||
|
||||
interface LoginEmailProps {
|
||||
name: string;
|
||||
code: string;
|
||||
// magicLink: string;
|
||||
}
|
||||
|
||||
export const LoginEmail = ({
|
||||
name = "Guest",
|
||||
code = "123456",
|
||||
}: // magicLink = "https://rallly.co",
|
||||
LoginEmailProps) => {
|
||||
return (
|
||||
<EmailLayout
|
||||
footNote={
|
||||
<>
|
||||
You're receiving this email because a request was made to login
|
||||
to{" "}
|
||||
<Link href={absoluteUrl()}>
|
||||
{removeProtocalFromUrl(absoluteUrl())}
|
||||
</Link>
|
||||
. If this wasn't you, let us know by replying to this email.
|
||||
</>
|
||||
}
|
||||
recipientName={name}
|
||||
preview={`Your 6-digit code: ${code}`}
|
||||
>
|
||||
<Text>Your 6-digit code is:</Text>
|
||||
<Heading as="h1" className="font-sans tracking-widest" id="code">
|
||||
{code}
|
||||
</Heading>
|
||||
<Text>
|
||||
Use this code to complete the verification process on{" "}
|
||||
<Link href={absoluteUrl()}>{removeProtocalFromUrl(absoluteUrl())}</Link>
|
||||
</Text>
|
||||
<Text>
|
||||
<span className="text-slate-500">
|
||||
This code is valid for 15 minutes
|
||||
</span>
|
||||
</Text>
|
||||
{/* <Heading>Magic link</Heading>
|
||||
<Text>
|
||||
Alternatively, you can login by using this{" "}
|
||||
<Link href={magicLink}>magic link ✨</Link>
|
||||
</Text> */}
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginEmail;
|
|
@ -1,12 +1,10 @@
|
|||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Button, Link, Section, Text } from "./components/styled-components";
|
||||
import NotificationEmail, {
|
||||
NotificationBaseProps,
|
||||
} from "./components/notification-email";
|
||||
import { Text } from "./components/styled-components";
|
||||
|
||||
export interface NewCommentEmailProps {
|
||||
name: string;
|
||||
title: string;
|
||||
export interface NewCommentEmailProps extends NotificationBaseProps {
|
||||
authorName: string;
|
||||
pollUrl: string;
|
||||
unsubscribeUrl: string;
|
||||
}
|
||||
|
||||
export const NewCommentEmail = ({
|
||||
|
@ -17,20 +15,17 @@ export const NewCommentEmail = ({
|
|||
unsubscribeUrl = "https://rallly.co",
|
||||
}: NewCommentEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview={`${authorName} has commented on ${title}`}>
|
||||
<Text>Hi {name},</Text>
|
||||
<NotificationEmail
|
||||
name={name}
|
||||
title={title}
|
||||
pollUrl={pollUrl}
|
||||
unsubscribeUrl={unsubscribeUrl}
|
||||
preview={`${authorName} has commented on ${title}`}
|
||||
>
|
||||
<Text>
|
||||
<strong>{authorName}</strong> has commented on <strong>{title}</strong>.
|
||||
</Text>
|
||||
<Section>
|
||||
<Button href={pollUrl}>Go to poll →</Button>
|
||||
</Section>
|
||||
<Text>
|
||||
<Link href={unsubscribeUrl}>
|
||||
Stop receiving notifications for this poll.
|
||||
</Link>
|
||||
</Text>
|
||||
</EmailLayout>
|
||||
</NotificationEmail>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -12,8 +12,13 @@ export const NewParticipantConfirmationEmail = ({
|
|||
editSubmissionUrl = "https://rallly.co",
|
||||
}: NewParticipantConfirmationEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview="To edit your response use the link below">
|
||||
<Text>Hi {name},</Text>
|
||||
<EmailLayout
|
||||
footNote={
|
||||
<>You are receiving this email because a response was submitting </>
|
||||
}
|
||||
recipientName={name}
|
||||
preview="To edit your response use the link below"
|
||||
>
|
||||
<Text>
|
||||
Thank you for submitting your availability for <strong>{title}</strong>.
|
||||
</Text>
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Button, Link, Section, Text } from "./components/styled-components";
|
||||
import NotificationEmail, {
|
||||
NotificationBaseProps,
|
||||
} from "./components/notification-email";
|
||||
import { Text } from "./components/styled-components";
|
||||
|
||||
export interface NewParticipantEmailProps {
|
||||
name: string;
|
||||
title: string;
|
||||
export interface NewParticipantEmailProps extends NotificationBaseProps {
|
||||
participantName: string;
|
||||
pollUrl: string;
|
||||
unsubscribeUrl: string;
|
||||
}
|
||||
|
||||
export const NewParticipantEmail = ({
|
||||
|
@ -17,21 +15,18 @@ export const NewParticipantEmail = ({
|
|||
unsubscribeUrl = "https://rallly.co",
|
||||
}: NewParticipantEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview={`${participantName} has responded`}>
|
||||
<Text>Hi {name},</Text>
|
||||
<NotificationEmail
|
||||
name={name}
|
||||
title={title}
|
||||
pollUrl={pollUrl}
|
||||
unsubscribeUrl={unsubscribeUrl}
|
||||
preview={`${participantName} has responded`}
|
||||
>
|
||||
<Text>
|
||||
<strong>{participantName}</strong> has shared their availability for{" "}
|
||||
<strong>{participantName}</strong> has responded to{" "}
|
||||
<strong>{title}</strong>.
|
||||
</Text>
|
||||
<Section>
|
||||
<Button href={pollUrl}>Go to poll →</Button>
|
||||
</Section>
|
||||
<Text>
|
||||
<Link href={unsubscribeUrl}>
|
||||
Stop receiving notifications for this poll.
|
||||
</Link>
|
||||
</Text>
|
||||
</EmailLayout>
|
||||
</NotificationEmail>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
import { EmailLayout } from "./components/email-layout";
|
||||
import {
|
||||
NewPollBaseEmail,
|
||||
NewPollBaseEmailProps,
|
||||
} from "./components/new-poll-base";
|
||||
import { Button, Heading, Section, Text } from "./components/styled-components";
|
||||
|
||||
export interface NewPollVerificationEmailProps extends NewPollBaseEmailProps {
|
||||
verificationLink: string;
|
||||
}
|
||||
|
||||
export const NewPollVerificationEmail = ({
|
||||
title = "Untitled Poll",
|
||||
name = "Guest",
|
||||
verificationLink = "https://rallly.co",
|
||||
adminLink = "https://rallly.co/admin/abcdefg123",
|
||||
}: NewPollVerificationEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview="Please verify your email address to turn on notifications">
|
||||
<NewPollBaseEmail name={name} title={title} adminLink={adminLink}>
|
||||
<Section className="mt-8 bg-gray-100 px-4 text-center">
|
||||
<Heading as="h3">
|
||||
Want to get notified when participants vote?
|
||||
</Heading>
|
||||
<Text>Verify your email address to turn on notifications.</Text>
|
||||
<Section>
|
||||
<Button id="verifyEmailUrl" href={verificationLink}>
|
||||
Verify your email →
|
||||
</Button>
|
||||
</Section>
|
||||
</Section>
|
||||
</NewPollBaseEmail>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewPollVerificationEmail;
|
|
@ -1,17 +1,93 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import {
|
||||
NewPollBaseEmail,
|
||||
NewPollBaseEmailProps,
|
||||
} from "./components/new-poll-base";
|
||||
import { Heading, Link, Section, Text } from "./components/styled-components";
|
||||
import { removeProtocalFromUrl } from "./components/utils";
|
||||
|
||||
export interface NewPollEmailProps {
|
||||
title: string;
|
||||
name: string;
|
||||
adminLink: string;
|
||||
participantLink: string;
|
||||
}
|
||||
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
const LinkContainer = (props: { link: string }) => {
|
||||
return (
|
||||
<Section className="rounded bg-gray-50 p-4">
|
||||
<Link href={props.link} className="font-mono">
|
||||
{props.link}
|
||||
</Link>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
export const NewPollEmail = ({
|
||||
title = "Untitled Poll",
|
||||
name = "Guest",
|
||||
adminLink = "https://rallly.co/admin/abcdefg123",
|
||||
}: NewPollBaseEmailProps) => {
|
||||
participantLink = "https://rallly.co/p/wxyz9876",
|
||||
}: NewPollEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview="Please verify your email address to turn on notifications">
|
||||
<NewPollBaseEmail name={name} title={title} adminLink={adminLink} />
|
||||
<EmailLayout
|
||||
footNote={
|
||||
<>
|
||||
You are receiving this email because a new poll was created with this
|
||||
email address on{" "}
|
||||
<Link href={absoluteUrl()}>
|
||||
{removeProtocalFromUrl(absoluteUrl())}
|
||||
</Link>
|
||||
. If this wasn't you, please ignore this email.
|
||||
</>
|
||||
}
|
||||
recipientName={name}
|
||||
preview="Share your participant link to start collecting responses."
|
||||
>
|
||||
<Text>
|
||||
Your new poll is ready! Now lets find a date for{" "}
|
||||
<strong>{title}</strong>.
|
||||
</Text>
|
||||
<Text>
|
||||
Copy this link and share it with your participants to start collecting
|
||||
responses.
|
||||
</Text>
|
||||
<LinkContainer link={participantLink} />
|
||||
<Text>
|
||||
<ShareLink title={title} name={name} participantLink={participantLink}>
|
||||
Share via email →
|
||||
</ShareLink>
|
||||
</Text>
|
||||
<Heading>Your secret link</Heading>
|
||||
<Text>
|
||||
Use this link to access the admin page where you can view and edit your
|
||||
poll.
|
||||
</Text>
|
||||
<LinkContainer link={adminLink} />
|
||||
<Text>
|
||||
<Link href={adminLink}>Go to admin page →</Link>
|
||||
</Text>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
|
47
packages/emails/src/templates/register.tsx
Normal file
47
packages/emails/src/templates/register.tsx
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { absoluteUrl } from "@rallly/utils";
|
||||
import { Heading } from "@react-email/heading";
|
||||
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Link, Text } from "./components/styled-components";
|
||||
import { removeProtocalFromUrl } from "./components/utils";
|
||||
|
||||
interface RegisterEmailProps {
|
||||
name: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
export const RegisterEmail = ({
|
||||
name = "Guest",
|
||||
code = "123456",
|
||||
}: RegisterEmailProps) => {
|
||||
return (
|
||||
<EmailLayout
|
||||
footNote={
|
||||
<>
|
||||
You're receiving this email because a request was made to
|
||||
register an account on{" "}
|
||||
<Link className="text-primary-500" href={absoluteUrl()}>
|
||||
{removeProtocalFromUrl(absoluteUrl())}
|
||||
</Link>
|
||||
.
|
||||
</>
|
||||
}
|
||||
recipientName={name}
|
||||
preview={`Your 6-digit code is: ${code}`}
|
||||
>
|
||||
<Text>Your 6-digit code is:</Text>
|
||||
<Heading className="font-sans tracking-widest" id="code">
|
||||
{code}
|
||||
</Heading>
|
||||
<Text>
|
||||
Use this code to complete the verification process on{" "}
|
||||
<Link href={absoluteUrl()}>{removeProtocalFromUrl(absoluteUrl())}</Link>
|
||||
</Text>
|
||||
<Text>
|
||||
<span className="text-gray-500">This code is valid for 15 minutes</span>
|
||||
</Text>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default RegisterEmail;
|
51
packages/emails/src/templates/turn-on-notifications.tsx
Normal file
51
packages/emails/src/templates/turn-on-notifications.tsx
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { EmailLayout } from "./components/email-layout";
|
||||
import {
|
||||
Button,
|
||||
Link,
|
||||
Section,
|
||||
SmallText,
|
||||
Text,
|
||||
} from "./components/styled-components";
|
||||
|
||||
type EnableNotificationsEmailProps = {
|
||||
title: string;
|
||||
name: string;
|
||||
verificationLink: string;
|
||||
adminLink: string;
|
||||
};
|
||||
|
||||
export const EnableNotificationsEmail = ({
|
||||
title = "Untitled Poll",
|
||||
name = "Guest",
|
||||
verificationLink = "https://rallly.co",
|
||||
adminLink = "https://rallly.co",
|
||||
}: EnableNotificationsEmailProps) => {
|
||||
return (
|
||||
<EmailLayout
|
||||
recipientName={name}
|
||||
preview="Before we can send you notifications we need to verify your email"
|
||||
footNote={
|
||||
<>
|
||||
You are receiving this email because a request was made to enable
|
||||
notifications for <Link href={adminLink}>{title}</Link>.
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Text>
|
||||
Before we can send you notifications we need to verify your email.
|
||||
</Text>
|
||||
<Text>
|
||||
Click the button below to complete the email verification and enable
|
||||
notifications for <strong>{title}</strong>.
|
||||
</Text>
|
||||
<Section>
|
||||
<Button href={verificationLink} id="verifyEmailUrl">
|
||||
Enable notifications →
|
||||
</Button>
|
||||
</Section>
|
||||
<SmallText>The link will expire in 15 minutes.</SmallText>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnableNotificationsEmail;
|
|
@ -1,34 +0,0 @@
|
|||
import { Heading } from "@react-email/heading";
|
||||
|
||||
import { EmailLayout } from "./components/email-layout";
|
||||
import { Section, Text } from "./components/styled-components";
|
||||
|
||||
interface VerificationCodeEmailProps {
|
||||
name: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
export const VerificationCodeEmail = ({
|
||||
name = "Guest",
|
||||
code = "123456",
|
||||
}: VerificationCodeEmailProps) => {
|
||||
return (
|
||||
<EmailLayout preview={`Your 6-digit code is ${code}`}>
|
||||
<Text>Hi {name},</Text>
|
||||
<Text>Please use the code below to verify your email address.</Text>
|
||||
<Section className="rounded bg-gray-50 text-center">
|
||||
<Text>Your 6-digit code is:</Text>
|
||||
<Heading className="font-sans tracking-widest" id="code">
|
||||
{code}
|
||||
</Heading>
|
||||
<Text>
|
||||
<span className="text-slate-500">
|
||||
This code is valid for 15 minutes
|
||||
</span>
|
||||
</Text>
|
||||
</Section>
|
||||
</EmailLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default VerificationCodeEmail;
|
Loading…
Add table
Add a link
Reference in a new issue