mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-04 10:05:53 +02:00
major ui tweaks and refactoring
This commit is contained in:
parent
51bf5c1408
commit
64158a823b
91 changed files with 1791 additions and 1246 deletions
|
@ -26,7 +26,7 @@ export async function sendEmail(
|
|||
|
||||
await emailClient.sendMail({
|
||||
from: {
|
||||
name: opts.name || "Pangolin Proxy",
|
||||
name: opts.name || "Pangolin",
|
||||
address: opts.from,
|
||||
},
|
||||
to: opts.to,
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
Text,
|
||||
Tailwind
|
||||
} from "@react-email/components";
|
||||
import * as React from "react";
|
||||
import LetterHead from "./components/LetterHead";
|
||||
import { themeColors } from "./lib/theme";
|
||||
import {
|
||||
EmailContainer,
|
||||
EmailFooter,
|
||||
EmailGreeting,
|
||||
EmailHeading,
|
||||
EmailLetterHead,
|
||||
EmailText
|
||||
} from "./components/Email";
|
||||
|
||||
interface Props {
|
||||
email: string;
|
||||
|
@ -23,41 +27,31 @@ export const ConfirmPasswordReset = ({ email }: Props) => {
|
|||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#16A34A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tailwind config={themeColors}>
|
||||
<Body className="font-sans relative">
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
<LetterHead />
|
||||
<EmailContainer>
|
||||
<EmailLetterHead />
|
||||
|
||||
<Heading className="text-2xl font-semibold text-gray-800 text-center">
|
||||
Password Reset Confirmation
|
||||
</Heading>
|
||||
<Text className="text-base text-gray-700 mt-4">
|
||||
Hi {email || "there"},
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
<EmailHeading>Password Reset Confirmation</EmailHeading>
|
||||
|
||||
<EmailGreeting>Hi {email || "there"},</EmailGreeting>
|
||||
|
||||
<EmailText>
|
||||
This email confirms that your password has just been
|
||||
reset. If you made this change, no further action is
|
||||
required.
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
</EmailText>
|
||||
|
||||
<EmailText>
|
||||
Thank you for keeping your account secure.
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500 mt-6">
|
||||
</EmailText>
|
||||
|
||||
<EmailFooter>
|
||||
Best regards,
|
||||
<br />
|
||||
Fossorial
|
||||
</Text>
|
||||
</Container>
|
||||
</EmailFooter>
|
||||
</EmailContainer>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
Text,
|
||||
Tailwind
|
||||
} from "@react-email/components";
|
||||
import * as React from "react";
|
||||
import LetterHead from "./components/LetterHead";
|
||||
import { themeColors } from "./lib/theme";
|
||||
import {
|
||||
EmailContainer,
|
||||
EmailFooter,
|
||||
EmailGreeting,
|
||||
EmailHeading,
|
||||
EmailLetterHead,
|
||||
EmailSection,
|
||||
EmailText
|
||||
} from "./components/Email";
|
||||
import CopyCodeBox from "./components/CopyCodeBox";
|
||||
|
||||
interface Props {
|
||||
email: string;
|
||||
|
@ -25,50 +31,39 @@ export const ResetPasswordCode = ({ email, code, link }: Props) => {
|
|||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#F97317"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tailwind config={themeColors}>
|
||||
<Body className="font-sans">
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
<LetterHead />
|
||||
<EmailContainer>
|
||||
<EmailLetterHead />
|
||||
|
||||
<Heading className="text-2xl font-semibold text-gray-800 text-center">
|
||||
Password Reset Request
|
||||
</Heading>
|
||||
<Text className="text-base text-gray-700 mt-4">
|
||||
Hi {email || "there"},
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
<EmailHeading>Password Reset Request</EmailHeading>
|
||||
|
||||
<EmailGreeting>Hi {email || "there"},</EmailGreeting>
|
||||
|
||||
<EmailText>
|
||||
You’ve requested to reset your password. Please{" "}
|
||||
<a href={link} className="text-primary">
|
||||
click here
|
||||
</a>{" "}
|
||||
and follow the instructions to reset your password,
|
||||
or manually enter the following code:
|
||||
</Text>
|
||||
<Section className="text-center">
|
||||
<Text className="inline-block bg-primary text-xl font-bold text-white py-2 px-4 border border-gray-300 rounded-xl">
|
||||
{code}
|
||||
</Text>
|
||||
</Section>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
</EmailText>
|
||||
|
||||
<EmailSection>
|
||||
<CopyCodeBox text={code} />
|
||||
</EmailSection>
|
||||
|
||||
<EmailText>
|
||||
If you didn’t request this, you can safely ignore
|
||||
this email.
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500 mt-6">
|
||||
</EmailText>
|
||||
|
||||
<EmailFooter>
|
||||
Best regards,
|
||||
<br />
|
||||
Fossorial
|
||||
</Text>
|
||||
</Container>
|
||||
</EmailFooter>
|
||||
</EmailContainer>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
Text,
|
||||
Tailwind
|
||||
} from "@react-email/components";
|
||||
import * as React from "react";
|
||||
import LetterHead from "./components/LetterHead";
|
||||
import {
|
||||
EmailContainer,
|
||||
EmailLetterHead,
|
||||
EmailHeading,
|
||||
EmailText,
|
||||
EmailFooter,
|
||||
EmailSection,
|
||||
EmailGreeting
|
||||
} from "./components/Email";
|
||||
import { themeColors } from "./lib/theme";
|
||||
import CopyCodeBox from "./components/CopyCodeBox";
|
||||
|
||||
interface ResourceOTPCodeProps {
|
||||
email?: string;
|
||||
|
@ -31,44 +37,34 @@ export const ResourceOTPCode = ({
|
|||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#F97317"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tailwind config={themeColors}>
|
||||
<Body className="font-sans">
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
<LetterHead />
|
||||
<EmailContainer>
|
||||
<EmailLetterHead />
|
||||
|
||||
<Heading className="text-2xl font-semibold text-gray-800 text-center">
|
||||
<EmailHeading>
|
||||
Your One-Time Password for {resourceName}
|
||||
</Heading>
|
||||
<Text className="text-base text-gray-700 mt-4">
|
||||
Hi {email || "there"},
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
</EmailHeading>
|
||||
|
||||
<EmailGreeting>Hi {email || "there"},</EmailGreeting>
|
||||
|
||||
<EmailText>
|
||||
You’ve requested a one-time password to access{" "}
|
||||
<strong>{resourceName}</strong> in{" "}
|
||||
<strong>{organizationName}</strong>. Use the code
|
||||
below to complete your authentication:
|
||||
</Text>
|
||||
<Section className="text-center">
|
||||
<Text className="inline-block bg-primary text-xl font-bold text-white py-2 px-4 border border-gray-300 rounded-xl">
|
||||
{otp}
|
||||
</Text>
|
||||
</Section>
|
||||
<Text className="text-sm text-gray-500 mt-6">
|
||||
</EmailText>
|
||||
|
||||
<EmailSection>
|
||||
<CopyCodeBox text={otp} />
|
||||
</EmailSection>
|
||||
|
||||
<EmailFooter>
|
||||
Best regards,
|
||||
<br />
|
||||
Fossorial
|
||||
</Text>
|
||||
</Container>
|
||||
</EmailFooter>
|
||||
</EmailContainer>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
Text,
|
||||
Tailwind,
|
||||
Button
|
||||
} from "@react-email/components";
|
||||
import * as React from "react";
|
||||
import LetterHead from "./components/LetterHead";
|
||||
import { themeColors } from "./lib/theme";
|
||||
import {
|
||||
EmailContainer,
|
||||
EmailFooter,
|
||||
EmailGreeting,
|
||||
EmailHeading,
|
||||
EmailLetterHead,
|
||||
EmailSection,
|
||||
EmailText
|
||||
} from "./components/Email";
|
||||
import ButtonLink from "./components/ButtonLink";
|
||||
|
||||
interface SendInviteLinkProps {
|
||||
email: string;
|
||||
|
@ -34,55 +39,42 @@ export const SendInviteLink = ({
|
|||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#F97317"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tailwind config={themeColors}>
|
||||
<Body className="font-sans">
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
<LetterHead />
|
||||
<EmailContainer>
|
||||
<EmailLetterHead />
|
||||
|
||||
<Heading className="text-2xl font-semibold text-gray-800 text-center">
|
||||
Invited to Join {orgName}
|
||||
</Heading>
|
||||
<Text className="text-base text-gray-700 mt-4">
|
||||
Hi {email || "there"},
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
<EmailHeading>Invited to Join {orgName}</EmailHeading>
|
||||
|
||||
<EmailGreeting>Hi {email || "there"},</EmailGreeting>
|
||||
|
||||
<EmailText>
|
||||
You’ve been invited to join the organization{" "}
|
||||
{orgName}
|
||||
<strong>{orgName}</strong>
|
||||
{inviterName ? ` by ${inviterName}.` : "."} Please
|
||||
access the link below to accept the invite.
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
</EmailText>
|
||||
|
||||
<EmailText>
|
||||
This invite will expire in{" "}
|
||||
<b>
|
||||
<strong>
|
||||
{expiresInDays}{" "}
|
||||
{expiresInDays === "1" ? "day" : "days"}.
|
||||
</b>
|
||||
</Text>
|
||||
<Section className="text-center">
|
||||
<Button
|
||||
href={inviteLink}
|
||||
className="rounded-lg bg-primary px-[12px] py-[9px] text-center font-semibold text-white cursor-pointer text-xl"
|
||||
>
|
||||
Accept Invite to {orgName}
|
||||
</Button>
|
||||
</Section>
|
||||
</strong>
|
||||
</EmailText>
|
||||
|
||||
<Text className="text-sm text-gray-500 mt-6">
|
||||
<EmailSection>
|
||||
<ButtonLink href={inviteLink}>
|
||||
Accept Invite to {orgName}
|
||||
</ButtonLink>
|
||||
</EmailSection>
|
||||
|
||||
<EmailFooter>
|
||||
Best regards,
|
||||
<br />
|
||||
Fossorial
|
||||
</Text>
|
||||
</Container>
|
||||
</EmailFooter>
|
||||
</EmailContainer>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
Text,
|
||||
Tailwind
|
||||
} from "@react-email/components";
|
||||
import * as React from "react";
|
||||
import LetterHead from "./components/LetterHead";
|
||||
import { themeColors } from "./lib/theme";
|
||||
import {
|
||||
EmailContainer,
|
||||
EmailFooter,
|
||||
EmailGreeting,
|
||||
EmailHeading,
|
||||
EmailLetterHead,
|
||||
EmailText
|
||||
} from "./components/Email";
|
||||
|
||||
interface Props {
|
||||
email: string;
|
||||
|
@ -24,52 +28,44 @@ export const TwoFactorAuthNotification = ({ email, enabled }: Props) => {
|
|||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#16A34A"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tailwind config={themeColors}>
|
||||
<Body className="font-sans">
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
<LetterHead />
|
||||
<EmailContainer>
|
||||
<EmailLetterHead />
|
||||
|
||||
<Heading className="text-2xl font-semibold text-gray-800 text-center">
|
||||
<EmailHeading>
|
||||
Two-Factor Authentication{" "}
|
||||
{enabled ? "Enabled" : "Disabled"}
|
||||
</Heading>
|
||||
<Text className="text-base text-gray-700 mt-4">
|
||||
Hi {email || "there"},
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
</EmailHeading>
|
||||
|
||||
<EmailGreeting>Hi {email || "there"},</EmailGreeting>
|
||||
|
||||
<EmailText>
|
||||
This email confirms that Two-Factor Authentication
|
||||
has been successfully{" "}
|
||||
{enabled ? "enabled" : "disabled"} on your account.
|
||||
</Text>
|
||||
</EmailText>
|
||||
|
||||
{enabled ? (
|
||||
<Text className="text-base text-gray-700">
|
||||
<EmailText>
|
||||
With Two-Factor Authentication enabled, your
|
||||
account is now more secure. Please ensure you
|
||||
keep your authentication method safe.
|
||||
</Text>
|
||||
</EmailText>
|
||||
) : (
|
||||
<Text className="text-base text-gray-700">
|
||||
<EmailText>
|
||||
With Two-Factor Authentication disabled, your
|
||||
account may be less secure. We recommend
|
||||
enabling it to protect your account.
|
||||
</Text>
|
||||
</EmailText>
|
||||
)}
|
||||
<Text className="text-sm text-gray-500 mt-6">
|
||||
|
||||
<EmailFooter>
|
||||
Best regards,
|
||||
<br />
|
||||
Fossorial
|
||||
</Text>
|
||||
</Container>
|
||||
</EmailFooter>
|
||||
</EmailContainer>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
import {
|
||||
Body,
|
||||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
Text,
|
||||
Tailwind
|
||||
} from "@react-email/components";
|
||||
import * as React from "react";
|
||||
import LetterHead from "./components/LetterHead";
|
||||
import { themeColors } from "./lib/theme";
|
||||
import {
|
||||
EmailContainer,
|
||||
EmailFooter,
|
||||
EmailGreeting,
|
||||
EmailHeading,
|
||||
EmailLetterHead,
|
||||
EmailSection,
|
||||
EmailText
|
||||
} from "./components/Email";
|
||||
import CopyCodeBox from "./components/CopyCodeBox";
|
||||
|
||||
interface VerifyEmailProps {
|
||||
username?: string;
|
||||
|
@ -29,47 +35,36 @@ export const VerifyEmail = ({
|
|||
<Html>
|
||||
<Head />
|
||||
<Preview>{previewText}</Preview>
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#F97317"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tailwind config={themeColors}>
|
||||
<Body className="font-sans">
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
<LetterHead />
|
||||
<EmailContainer>
|
||||
<EmailLetterHead />
|
||||
|
||||
<Heading className="text-2xl font-semibold text-gray-800 text-center">
|
||||
Please Verify Your Email
|
||||
</Heading>
|
||||
<Text className="text-base text-gray-700 mt-4">
|
||||
Hi {username || "there"},
|
||||
</Text>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
<EmailHeading>Please Verify Your Email</EmailHeading>
|
||||
|
||||
<EmailGreeting>Hi {username || "there"},</EmailGreeting>
|
||||
|
||||
<EmailText>
|
||||
You’ve requested to verify your email. Please use
|
||||
the code below to complete the verification process
|
||||
upon logging in.
|
||||
</Text>
|
||||
<Section className="text-center">
|
||||
<Text className="inline-block bg-primary text-xl font-bold text-white py-2 px-4 border border-gray-300 rounded-xl">
|
||||
{verificationCode}
|
||||
</Text>
|
||||
</Section>
|
||||
<Text className="text-base text-gray-700 mt-2">
|
||||
</EmailText>
|
||||
|
||||
<EmailSection>
|
||||
<CopyCodeBox text={verificationCode} />
|
||||
</EmailSection>
|
||||
|
||||
<EmailText>
|
||||
If you didn’t request this, you can safely ignore
|
||||
this email.
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500 mt-6">
|
||||
</EmailText>
|
||||
|
||||
<EmailFooter>
|
||||
Best regards,
|
||||
<br />
|
||||
Fossorial
|
||||
</Text>
|
||||
</Container>
|
||||
</EmailFooter>
|
||||
</EmailContainer>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
|
|
18
server/emails/templates/components/ButtonLink.tsx
Normal file
18
server/emails/templates/components/ButtonLink.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
export default function ButtonLink({
|
||||
href,
|
||||
children,
|
||||
className = ""
|
||||
}: {
|
||||
href: string;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={`rounded-full bg-primary px-4 py-2 text-center font-semibold text-white text-xl no-underline inline-block ${className}`}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
11
server/emails/templates/components/CopyCodeBox.tsx
Normal file
11
server/emails/templates/components/CopyCodeBox.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
|
||||
export default function CopyCodeBox({ text }: { text: string }) {
|
||||
return (
|
||||
<div className="flex items-center justify-center rounded-lg bg-neutral-100 p-2">
|
||||
<span className="text-2xl font-mono text-neutral-600 tracking-wide">
|
||||
{text}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
91
server/emails/templates/components/Email.tsx
Normal file
91
server/emails/templates/components/Email.tsx
Normal file
|
@ -0,0 +1,91 @@
|
|||
import { Container } from "@react-email/components";
|
||||
import React from "react";
|
||||
|
||||
// EmailContainer: Wraps the entire email layout
|
||||
export function EmailContainer({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<Container className="bg-white border border-solid border-gray-200 p-6 max-w-lg mx-auto my-8 rounded-lg">
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
// EmailLetterHead: For branding or logo at the top
|
||||
export function EmailLetterHead() {
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<table
|
||||
role="presentation"
|
||||
width="100%"
|
||||
style={{
|
||||
marginBottom: "24px"
|
||||
}}
|
||||
>
|
||||
<tr>
|
||||
<td
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
fontWeight: "bold",
|
||||
color: "#F97317"
|
||||
}}
|
||||
>
|
||||
Pangolin
|
||||
</td>
|
||||
<td
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
textAlign: "right",
|
||||
color: "#6B7280"
|
||||
}}
|
||||
>
|
||||
{new Date().getFullYear()}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// EmailHeading: For the primary message or headline
|
||||
export function EmailHeading({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<h1 className="text-2xl font-semibold text-gray-800 text-center">
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
export function EmailGreeting({ children }: { children: React.ReactNode }) {
|
||||
return <p className="text-lg text-gray-700 my-4">{children}</p>;
|
||||
}
|
||||
|
||||
// EmailText: For general text content
|
||||
export function EmailText({
|
||||
children,
|
||||
className
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<p className={`my-2 text-base text-gray-700 ${className}`}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
// EmailSection: For visually distinct sections (like OTP)
|
||||
export function EmailSection({
|
||||
children,
|
||||
className
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return <div className={`text-center my-4 ${className}`}>{children}</div>;
|
||||
}
|
||||
|
||||
// EmailFooter: For closing or signature
|
||||
export function EmailFooter({ children }: { children: React.ReactNode }) {
|
||||
return <div className="text-sm text-gray-500 mt-6">{children}</div>;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export function LetterHead() {
|
||||
return (
|
||||
<table
|
||||
role="presentation"
|
||||
width="100%"
|
||||
style={{
|
||||
marginBottom: "24px"
|
||||
}}
|
||||
>
|
||||
<tr>
|
||||
<td
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
fontWeight: "bold",
|
||||
color: "#F97317"
|
||||
}}
|
||||
>
|
||||
Pangolin
|
||||
</td>
|
||||
<td
|
||||
style={{
|
||||
fontSize: "14px",
|
||||
textAlign: "right",
|
||||
color: "#6B7280"
|
||||
}}
|
||||
>
|
||||
{new Date().getFullYear()}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
export default LetterHead;
|
9
server/emails/templates/lib/theme.ts
Normal file
9
server/emails/templates/lib/theme.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const themeColors = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#F97317"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue