Skip to content

Commit

Permalink
Working example
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Dec 28, 2024
1 parent 4f0a863 commit 8bf7e66
Show file tree
Hide file tree
Showing 15 changed files with 319 additions and 154 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ yarn-error.log*
# turbo
.turbo

dist
dist

.react-email
Binary file modified bun.lockb
Binary file not shown.
230 changes: 110 additions & 120 deletions examples/email/emails/vercel-invite-user.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { withI18n } from "@languine/react-email";
import { setupI18n } from "@languine/react-email";
import {
Body,
Button,
Expand All @@ -19,6 +19,7 @@ import {
import * as React from "react";

interface VercelInviteUserEmailProps {
locale: string;
username?: string;
userImage?: string;
invitedByUsername?: string;
Expand All @@ -34,125 +35,114 @@ const baseUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: "";

export const VercelInviteUserEmail = withI18n(
({
username,
userImage,
invitedByUsername,
invitedByEmail,
teamName,
teamImage,
inviteLink,
inviteFromIp,
inviteFromLocation,
}: VercelInviteUserEmailProps) => {
const previewText = `Join ${invitedByUsername} on Vercel`;
export const VercelInviteUserEmail = ({
locale = "es",
username = "alanturing",
userImage = `${baseUrl}/static/vercel-user.png`,
invitedByUsername = "Alan",
invitedByEmail = "[email protected]",
teamName = "Enigma",
teamImage = `${baseUrl}/static/vercel-team.png`,
inviteLink = "https://vercel.com/teams/invite/foo",
inviteFromIp = "204.13.186.218",
inviteFromLocation = "São Paulo, Brazil",
}: VercelInviteUserEmailProps) => {
const i18n = setupI18n(locale);

return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind>
<Body className="bg-white my-auto mx-auto font-sans px-2">
<Container className="border border-solid border-[#eaeaea] rounded my-[40px] mx-auto p-[20px] max-w-[465px]">
<Section className="mt-[32px]">
<Img
src={`${baseUrl}/static/vercel-logo.png`}
width="40"
height="37"
alt="Vercel"
className="my-0 mx-auto"
/>
</Section>
<Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0">
Join <strong>{teamName}</strong> on <strong>Vercel</strong>
</Heading>
<Text className="text-black text-[14px] leading-[24px]">
Hello {username},
</Text>
<Text className="text-black text-[14px] leading-[24px]">
<strong>{invitedByUsername}</strong> (
<Link
href={`mailto:${invitedByEmail}`}
className="text-blue-600 no-underline"
>
{invitedByEmail}
</Link>
) has invited you to the <strong>{teamName}</strong> team on{" "}
<strong>Vercel</strong>.
</Text>
<Section>
<Row>
<Column align="right">
<Img
className="rounded-full"
src={userImage}
width="64"
height="64"
/>
</Column>
<Column align="center">
<Img
src={`${baseUrl}/static/vercel-arrow.png`}
width="12"
height="9"
alt="invited you to"
/>
</Column>
<Column align="left">
<Img
className="rounded-full"
src={teamImage}
width="64"
height="64"
/>
</Column>
</Row>
</Section>
<Section className="text-center mt-[32px] mb-[32px]">
<Button
className="bg-[#000000] rounded text-white text-[12px] font-semibold no-underline text-center px-5 py-3"
href={inviteLink}
>
Join the team
</Button>
</Section>
<Text className="text-black text-[14px] leading-[24px]">
or copy and paste this URL into your browser:{" "}
<Link href={inviteLink} className="text-blue-600 no-underline">
{inviteLink}
</Link>
</Text>
<Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" />
<Text className="text-[#666666] text-[12px] leading-[24px]">
This invitation was intended for{" "}
<span className="text-black">{username}</span>. This invite was
sent from <span className="text-black">{inviteFromIp}</span>{" "}
located in{" "}
<span className="text-black">{inviteFromLocation}</span>. If you
were not expecting this invitation, you can ignore this email.
If you are concerned about your account's safety, please reply
to this email to get in touch with us.
</Text>
</Container>
</Body>
</Tailwind>
</Html>
);
},
"en",
);

VercelInviteUserEmail.PreviewProps = {
username: "alanturing",
userImage: `${baseUrl}/static/vercel-user.png`,
invitedByUsername: "Alan",
invitedByEmail: "[email protected]",
teamName: "Enigma",
teamImage: `${baseUrl}/static/vercel-team.png`,
inviteLink: "https://vercel.com/teams/invite/foo",
inviteFromIp: "204.13.186.218",
inviteFromLocation: "São Paulo, Brazil",
} as VercelInviteUserEmailProps;
return (
<Html>
<Head />
<Preview>{i18n.t("previewText", { invitedByUsername })}</Preview>
<Tailwind>
<Body className="bg-white my-auto mx-auto font-sans px-2">
<Container className="border border-solid border-[#eaeaea] rounded my-[40px] mx-auto p-[20px] max-w-[465px]">
<Section className="mt-[32px]">
<Img
src={`${baseUrl}/static/vercel-logo.png`}
width="40"
height="37"
alt={i18n.t("logoAlt")}
className="my-0 mx-auto"
/>
</Section>
<Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0">
{i18n.t("joinTeamHeading", {
teamName: teamName,
company: "Vercel",
})}
</Heading>
<Text className="text-black text-[14px] leading-[24px]">
{i18n.t("greeting", { username })}
</Text>
<Text className="text-black text-[14px] leading-[24px]">
{i18n.t("invitationText", {
invitedByUsername: <strong>{invitedByUsername}</strong>,
email: (
<Link href={`mailto:${invitedByEmail}`}>
{invitedByEmail}
</Link>
),
teamName: <strong>{teamName}</strong>,
company: "Vercel",
})}
</Text>
<Section>
<Row>
<Column align="right">
<Img
className="rounded-full"
src={userImage}
width="64"
height="64"
/>
</Column>
<Column align="center">
<Img
src={`${baseUrl}/static/vercel-arrow.png`}
width="12"
height="9"
alt={i18n.t("invitedToAlt")}
/>
</Column>
<Column align="left">
<Img
className="rounded-full"
src={teamImage}
width="64"
height="64"
/>
</Column>
</Row>
</Section>
<Section className="text-center mt-[32px] mb-[32px]">
<Button
className="bg-[#000000] rounded text-white text-[12px] font-semibold no-underline text-center px-5 py-3"
href={inviteLink}
>
{i18n.t("joinTeamButton")}
</Button>
</Section>
<Text className="text-black text-[14px] leading-[24px]">
{i18n.t("copyUrlText")}{" "}
<Link href={inviteLink} className="text-blue-600 no-underline">
{inviteLink}
</Link>
</Text>
<Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" />
<Text className="text-[#666666] text-[12px] leading-[24px]">
{i18n.t("footerText", {
username: <span className="text-black">{username}</span>,
ip: <span className="text-black">{inviteFromIp}</span>,
location: (
<span className="text-black">{inviteFromLocation}</span>
),
})}
</Text>
</Container>
</Body>
</Tailwind>
</Html>
);
};

export default VercelInviteUserEmail;
18 changes: 18 additions & 0 deletions examples/email/languine.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineConfig } from "languine";

export default defineConfig({
version: "7.0.0",
locale: {
source: "en",
targets: ["es", "sv", "pt"],
},
files: {
json: {
include: ["locales/[locale].json"],
},
},
llm: {
provider: "openai",
model: "gpt-4-turbo",
},
});
15 changes: 15 additions & 0 deletions examples/email/locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"previewText": "Join %{invitedByUsername} on %{company}",
"company": "%{company}",
"logoAlt": "Vercel Logo",
"joinTeamHeading": "Join %{teamName} on %{company}",
"greeting": "Hi %{username},",
"invitationText":
"%{invitedByUsername} (%{email}) has invited you to join the %{teamName} team on %{company}.",
"invitedToAlt": "Invited to",
"joinTeamButton": "Join the team",
"copyUrlText": "Or copy and paste this URL into your browser:",
"footerText":
"This invitation was intended for %{username} (%{ip} from %{location}). If you were not expecting this invitation, you can ignore this email. If you are concerned about your account's safety, please reply to this email to get in touch with us."
}

12 changes: 12 additions & 0 deletions examples/email/locales/es.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"previewText": "Únete a %{invitedByUsername} en %{company}",
"company": "%{company}",
"logoAlt": "Logo de Vercel",
"joinTeamHeading": "Únete al equipo %{teamName} en %{company}",
"greeting": "Hola %{username},",
"invitationText": "%{invitedByUsername} (%{email}) te ha invitado a unirte al equipo %{teamName} en %{company}.",
"invitedToAlt": "Invitado a",
"joinTeamButton": "Únete al equipo",
"copyUrlText": "O copia y pega esta URL en tu navegador:",
"footerText": "Esta invitación fue destinada para %{username} (%{ip} desde %{location}). Si no esperabas esta invitación, puedes ignorar este correo electrónico. Si te preocupa la seguridad de tu cuenta, por favor responde a este correo electrónico para ponerte en contacto con nosotros."
}
4 changes: 0 additions & 4 deletions examples/email/locales/i18n.config.ts

This file was deleted.

12 changes: 12 additions & 0 deletions examples/email/locales/pt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"previewText": "Junte-se a %{invitedByUsername} na %{company}",
"company": "%{company}",
"logoAlt": "Logotipo da Vercel",
"joinTeamHeading": "Junte-se ao time %{teamName} na %{company}",
"greeting": "Oi %{username},",
"invitationText": "%{invitedByUsername} (%{email}) convidou você para se juntar ao time %{teamName} na %{company}.",
"invitedToAlt": "Convidado para",
"joinTeamButton": "Entrar no time",
"copyUrlText": "Ou copie e cole este URL no seu navegador:",
"footerText": "Este convite foi destinado para %{username} (%{ip} de %{location}). Se você não estava esperando este convite, pode ignorar este e-mail. Se estiver preocupado com a segurança da sua conta, por favor responda a este e-mail para entrar em contato conosco."
}
12 changes: 12 additions & 0 deletions examples/email/locales/sv.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"previewText": "Gå med %{invitedByUsername} på %{company}",
"company": "%{company}",
"logoAlt": "Vercel-logotyp",
"joinTeamHeading": "Gå med i %{teamName} på %{company}",
"greeting": "Hej %{username},",
"invitationText": "%{invitedByUsername} (%{email}) har bjudit in dig att gå med i %{teamName}-teamet på %{company}.",
"invitedToAlt": "Inbjuden till",
"joinTeamButton": "Gå med i teamet",
"copyUrlText": "Eller kopiera och klistra in denna URL i din webbläsare:",
"footerText": "Denna inbjudan var avsedd för %{username} (%{ip} från %{location}). Om du inte förväntade dig denna inbjudan kan du ignorera detta e-postmeddelande. Om du är orolig för säkerheten på ditt konto, vänligen svara på detta e-postmeddelande för att komma i kontakt med oss."
}
6 changes: 3 additions & 3 deletions examples/email/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
"export": "email export"
},
"dependencies": {
"@languine/react-email": "workspace:*",
"languine": "link:languine",
"@react-email/components": "0.0.31",
"react-dom": "19.0.0",
"react": "19.0.0"
"react": "19.0.0",
"react-dom": "19.0.0"
},
"devDependencies": {
"@types/react": "19.0.1",
Expand Down
1 change: 0 additions & 1 deletion examples/next-international/languine.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ export default defineConfig({
llm: {
provider: "ollama",
model: "mistral:latest",
temperature: 0,
},
});
5 changes: 4 additions & 1 deletion packages/react-email/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@languine/react-email",
"version": "1.0.0",
"version": "0.0.1",
"files": ["dist", "README.md"],
"main": "dist/index.mjs",
"types": "dist/index.d.ts",
Expand All @@ -18,5 +18,8 @@
"devDependencies": {
"tsup": "^8.3.5",
"typescript": "^5.7.2"
},
"dependencies": {
"react-string-replace": "^1.1.1"
}
}
Loading

0 comments on commit 8bf7e66

Please sign in to comment.