Add i18n support to email-templates

The email-templates package now uses the i18n (internationalization) library to translate email content based on user language preferences. This update involves changes to the email structure, the addition of translation JSON files, and modifications to the files referencing the emails. Email file locations were also restructured for better organization.
This commit is contained in:
giancarlo
2024-05-01 17:35:48 +07:00
parent 3220526a30
commit 15f6c72c6e
10 changed files with 152 additions and 37 deletions

View File

@@ -0,0 +1,84 @@
import {
Body,
Container,
Head,
Heading,
Html,
Preview,
Tailwind,
Text,
render,
} from '@react-email/components';
import { initializeEmailI18n } from '../lib/i18n';
interface Props {
productName: string;
userDisplayName: string;
language?: string;
}
export async function renderAccountDeleteEmail(props: Props) {
const namespace = 'account-delete-email';
const { t } = await initializeEmailI18n({
language: props.language,
namespace,
});
const previewText = t(`${namespace}:previewText`, {
productName: props.productName,
});
const subject = t(`${namespace}:subject`);
const html = render(
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind>
<Body className="mx-auto my-auto bg-[#ffffff] font-sans">
<Container className="mx-auto my-[40px] w-[465px] rounded-lg border border-solid border-[#eaeaea] bg-white p-[20px]">
<Heading className="mx-0 my-[30px] p-0 text-center text-[24px] font-bold text-black">
{previewText}
</Heading>
<Text className="text-[14px] leading-[24px] text-black">
{t(`${namespace}:hello`, {
displayName: props.userDisplayName,
})}
</Text>
<Text className="text-[14px] leading-[24px] text-black">
{t(`${namespace}:paragraph1`, {
productName: props.productName,
})}
</Text>
<Text className="text-[14px] leading-[24px] text-black">
{t(`${namespace}:paragraph2`)}
</Text>
<Text className="text-[14px] leading-[24px] text-black">
{t(`${namespace}:paragraph3`, {
productName: props.productName,
})}
</Text>
<Text className="text-[14px] leading-[24px] text-black">
{t(`${namespace}:paragraph4`, {
productName: props.productName,
})}
</Text>
</Container>
</Body>
</Tailwind>
</Html>,
);
return {
html,
subject,
};
}

View File

@@ -0,0 +1,131 @@
import {
Body,
Button,
Column,
Container,
Head,
Heading,
Hr,
Html,
Img,
Link,
Preview,
Row,
Section,
Tailwind,
Text,
render,
} from '@react-email/components';
import { initializeEmailI18n } from '../lib/i18n';
interface Props {
teamName: string;
teamLogo?: string;
inviter: string | undefined;
invitedUserEmail: string;
link: string;
productName: string;
language?: string;
}
export async function renderInviteEmail(props: Props) {
const namespace = 'invite-email';
const { t } = await initializeEmailI18n({
language: props.language,
namespace,
});
const previewText = `Join ${props.invitedUserEmail} on ${props.productName}`;
const subject = t(`${namespace}:subject`);
const heading = t(`${namespace}:heading`, {
teamName: props.teamName,
productName: props.productName,
});
const hello = t(`${namespace}:hello`, {
invitedUserEmail: props.invitedUserEmail,
});
const mainText = t(`${namespace}:mainText`, {
inviter: props.inviter,
teamName: props.teamName,
productName: props.productName,
});
const joinTeam = t(`${namespace}:joinTeam`, {
teamName: props.teamName,
});
const html = render(
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind>
<Body className="mx-auto my-auto bg-[#ffffff] font-sans">
<Container className="mx-auto my-[40px] w-[465px] rounded-lg border border-solid border-[#eaeaea] bg-white p-[20px]">
<Heading className="mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black">
{heading}
</Heading>
<Text className="text-[14px] leading-[24px] text-black">
{hello}
</Text>
<Text
className="text-[14px] leading-[24px] text-black"
dangerouslySetInnerHTML={{ __html: mainText }}
/>
{props.teamLogo && (
<Section>
<Row>
<Column align="center">
<Img
className="rounded-full"
src={props.teamLogo}
width="64"
height="64"
/>
</Column>
</Row>
</Section>
)}
<Section className="mb-[32px] mt-[32px] text-center">
<Button
className="rounded bg-[#000000] px-[20px] py-[12px] text-center text-[12px] font-semibold text-white no-underline"
href={props.link}
>
{joinTeam}
</Button>
</Section>
<Text className="text-[14px] leading-[24px] text-black">
{t(`${namespace}:copyPasteLink`)}{' '}
<Link href={props.link} className="text-blue-600 no-underline">
{props.link}
</Link>
</Text>
<Hr className="mx-0 my-[26px] w-full border border-solid border-[#eaeaea]" />
<Text className="text-[12px] leading-[24px] text-[#666666]">
{t(`${namespace}:invitationIntendedFor`, {
invitedUserEmail: props.invitedUserEmail,
})}
</Text>
</Container>
</Body>
</Tailwind>
</Html>,
);
return {
html,
subject,
};
}