mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-02-15 13:25:04 +00:00
refactor: use react email for email templates (#734)
Co-authored-by: Alessandro (Ale) Segala <43508+ItalyPaleAle@users.noreply.github.com> Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
55
email-templates/emails/api-key-expiring-soon.tsx
Normal file
55
email-templates/emails/api-key-expiring-soon.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Text } from "@react-email/components";
|
||||
import { BaseTemplate } from "../components/base-template";
|
||||
import CardHeader from "../components/card-header";
|
||||
import { sharedPreviewProps, sharedTemplateProps } from "../props";
|
||||
|
||||
interface ApiKeyExpiringData {
|
||||
name: string;
|
||||
apiKeyName: string;
|
||||
expiresAt: string;
|
||||
}
|
||||
|
||||
interface ApiKeyExpiringEmailProps {
|
||||
logoURL: string;
|
||||
appName: string;
|
||||
data: ApiKeyExpiringData;
|
||||
}
|
||||
|
||||
export const ApiKeyExpiringEmail = ({
|
||||
logoURL,
|
||||
appName,
|
||||
data,
|
||||
}: ApiKeyExpiringEmailProps) => (
|
||||
<BaseTemplate logoURL={logoURL} appName={appName}>
|
||||
<CardHeader title="API Key Expiring Soon" warning />
|
||||
<Text>
|
||||
Hello {data.name}, <br />
|
||||
This is a reminder that your API key <strong>
|
||||
{data.apiKeyName}
|
||||
</strong>{" "}
|
||||
will expire on <strong>{data.expiresAt}</strong>.
|
||||
</Text>
|
||||
|
||||
<Text>Please generate a new API key if you need continued access.</Text>
|
||||
</BaseTemplate>
|
||||
);
|
||||
|
||||
export default ApiKeyExpiringEmail;
|
||||
|
||||
ApiKeyExpiringEmail.TemplateProps = {
|
||||
...sharedTemplateProps,
|
||||
data: {
|
||||
name: "{{.Data.Name}}",
|
||||
apiKeyName: "{{.Data.APIKeyName}}",
|
||||
expiresAt: '{{.Data.ExpiresAt.Format "2006-01-02 15:04:05 MST"}}',
|
||||
},
|
||||
};
|
||||
|
||||
ApiKeyExpiringEmail.PreviewProps = {
|
||||
...sharedPreviewProps,
|
||||
data: {
|
||||
name: "Elias Schneider",
|
||||
apiKeyName: "My API Key",
|
||||
expiresAt: "September 30, 2024",
|
||||
},
|
||||
};
|
||||
104
email-templates/emails/login-with-new-device.tsx
Normal file
104
email-templates/emails/login-with-new-device.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Column, Heading, Row, Text } from "@react-email/components";
|
||||
import { BaseTemplate } from "../components/base-template";
|
||||
import CardHeader from "../components/card-header";
|
||||
import { sharedPreviewProps, sharedTemplateProps } from "../props";
|
||||
|
||||
interface SignInData {
|
||||
city?: string;
|
||||
country?: string;
|
||||
ipAddress: string;
|
||||
device: string;
|
||||
dateTime: string;
|
||||
}
|
||||
|
||||
interface NewSignInEmailProps {
|
||||
logoURL: string;
|
||||
appName: string;
|
||||
data: SignInData;
|
||||
}
|
||||
|
||||
export const NewSignInEmail = ({
|
||||
logoURL,
|
||||
appName,
|
||||
data,
|
||||
}: NewSignInEmailProps) => (
|
||||
<BaseTemplate logoURL={logoURL} appName={appName}>
|
||||
<CardHeader title="New Sign-In Detected" warning />
|
||||
<Text>
|
||||
Your {appName} account was recently accessed from a new IP address or
|
||||
browser. If you recognize this activity, no further action is required.
|
||||
</Text>
|
||||
<Heading
|
||||
style={{
|
||||
fontSize: "1rem",
|
||||
fontWeight: "bold",
|
||||
margin: "30px 0 10px 0",
|
||||
}}
|
||||
as="h4"
|
||||
>
|
||||
Details
|
||||
</Heading>
|
||||
|
||||
<Row>
|
||||
<Column style={detailsBoxStyle}>
|
||||
<Text style={detailsLabelStyle}>Approximate Location</Text>
|
||||
<Text style={detailsBoxValueStyle}>
|
||||
{data.city}, {data.country}
|
||||
</Text>
|
||||
</Column>
|
||||
<Column style={detailsBoxStyle}>
|
||||
<Text style={detailsLabelStyle}>IP Address</Text>
|
||||
<Text style={detailsBoxValueStyle}>{data.ipAddress}</Text>
|
||||
</Column>
|
||||
</Row>
|
||||
|
||||
<Row style={{ marginTop: "10px" }}>
|
||||
<Column style={detailsBoxStyle}>
|
||||
<Text style={detailsLabelStyle}>Device</Text>
|
||||
<Text style={detailsBoxValueStyle}>{data.device}</Text>
|
||||
</Column>
|
||||
<Column style={detailsBoxStyle}>
|
||||
<Text style={detailsLabelStyle}>Sign-In Time</Text>
|
||||
<Text style={detailsBoxValueStyle}>{data.dateTime}</Text>
|
||||
</Column>
|
||||
</Row>
|
||||
</BaseTemplate>
|
||||
);
|
||||
|
||||
export default NewSignInEmail;
|
||||
|
||||
const detailsBoxStyle = {
|
||||
width: "225px",
|
||||
};
|
||||
|
||||
const detailsLabelStyle = {
|
||||
margin: 0,
|
||||
fontSize: "12px",
|
||||
color: "gray",
|
||||
};
|
||||
|
||||
const detailsBoxValueStyle = {
|
||||
margin: 0,
|
||||
};
|
||||
|
||||
NewSignInEmail.TemplateProps = {
|
||||
...sharedTemplateProps,
|
||||
data: {
|
||||
city: "{{.Data.City}}",
|
||||
country: "{{.Data.Country}}",
|
||||
ipAddress: "{{.Data.IPAddress}}",
|
||||
device: "{{.Data.Device}}",
|
||||
dateTime: '{{.Data.DateTime.Format "January 2, 2006 at 3:04 PM MST"}}',
|
||||
},
|
||||
};
|
||||
|
||||
NewSignInEmail.PreviewProps = {
|
||||
...sharedPreviewProps,
|
||||
data: {
|
||||
city: "San Francisco",
|
||||
country: "USA",
|
||||
ipAddress: "127.0.0.1",
|
||||
device: "Chrome on macOS",
|
||||
dateTime: "2024-01-01 12:00 PM UTC",
|
||||
},
|
||||
};
|
||||
71
email-templates/emails/one-time-access.tsx
Normal file
71
email-templates/emails/one-time-access.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Link, Text } from "@react-email/components";
|
||||
import { BaseTemplate } from "../components/base-template";
|
||||
import { Button } from "../components/button";
|
||||
import CardHeader from "../components/card-header";
|
||||
import { sharedPreviewProps, sharedTemplateProps } from "../props";
|
||||
|
||||
interface OneTimeAccessData {
|
||||
code: string;
|
||||
loginLink: string;
|
||||
buttonCodeLink: string;
|
||||
expirationString: string;
|
||||
}
|
||||
|
||||
interface OneTimeAccessEmailProps {
|
||||
logoURL: string;
|
||||
appName: string;
|
||||
data: OneTimeAccessData;
|
||||
}
|
||||
|
||||
export const OneTimeAccessEmail = ({
|
||||
logoURL,
|
||||
appName,
|
||||
data,
|
||||
}: OneTimeAccessEmailProps) => (
|
||||
<BaseTemplate logoURL={logoURL} appName={appName}>
|
||||
<CardHeader title="Your Login Code" />
|
||||
|
||||
<Text>
|
||||
Click the button below to sign in to {appName} with a login code.
|
||||
<br />
|
||||
Or visit{" "}
|
||||
<Link href={data.loginLink} style={linkStyle}>
|
||||
{data.loginLink}
|
||||
</Link>{" "}
|
||||
and enter the code <strong>{data.code}</strong>.
|
||||
<br />
|
||||
<br />
|
||||
This code expires in {data.expirationString}.
|
||||
</Text>
|
||||
|
||||
<Button href={data.buttonCodeLink}>Sign In</Button>
|
||||
</BaseTemplate>
|
||||
);
|
||||
|
||||
export default OneTimeAccessEmail;
|
||||
|
||||
const linkStyle = {
|
||||
color: "#000",
|
||||
textDecoration: "underline",
|
||||
fontFamily: "Arial, sans-serif",
|
||||
};
|
||||
|
||||
OneTimeAccessEmail.TemplateProps = {
|
||||
...sharedTemplateProps,
|
||||
data: {
|
||||
code: "{{.Data.Code}}",
|
||||
loginLink: "{{.Data.LoginLink}}",
|
||||
buttonCodeLink: "{{.Data.LoginLinkWithCode}}",
|
||||
expirationString: "{{.Data.ExpirationString}}",
|
||||
},
|
||||
};
|
||||
|
||||
OneTimeAccessEmail.PreviewProps = {
|
||||
...sharedPreviewProps,
|
||||
data: {
|
||||
code: "123456",
|
||||
loginLink: "https://example.com/login",
|
||||
buttonCodeLink: "https://example.com/login?code=123456",
|
||||
expirationString: "15 minutes",
|
||||
},
|
||||
};
|
||||
26
email-templates/emails/test.tsx
Normal file
26
email-templates/emails/test.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Text } from "@react-email/components";
|
||||
import { BaseTemplate } from "../components/base-template";
|
||||
import CardHeader from "../components/card-header";
|
||||
import { sharedPreviewProps, sharedTemplateProps } from "../props";
|
||||
|
||||
interface TestEmailProps {
|
||||
logoURL: string;
|
||||
appName: string;
|
||||
}
|
||||
|
||||
export const TestEmail = ({ logoURL, appName }: TestEmailProps) => (
|
||||
<BaseTemplate logoURL={logoURL} appName={appName}>
|
||||
<CardHeader title="Test Email" />
|
||||
<Text>Your email setup is working correctly!</Text>
|
||||
</BaseTemplate>
|
||||
);
|
||||
|
||||
export default TestEmail;
|
||||
|
||||
TestEmail.TemplateProps = {
|
||||
...sharedTemplateProps,
|
||||
};
|
||||
|
||||
TestEmail.PreviewProps = {
|
||||
...sharedPreviewProps,
|
||||
};
|
||||
Reference in New Issue
Block a user