This commit is contained in:
Owen
2025-10-04 18:36:44 -07:00
parent 3123f858bb
commit c2c907852d
320 changed files with 35785 additions and 2984 deletions

View File

@@ -11,7 +11,7 @@ export async function sendEmail(
from: string | undefined;
to: string | undefined;
subject: string;
},
}
) {
if (!emailClient) {
logger.warn("Email client not configured, skipping email send");
@@ -25,16 +25,16 @@ export async function sendEmail(
const emailHtml = await render(template);
const appName = "Pangolin";
const appName = config.getRawPrivateConfig().branding?.app_name || "Pangolin";
await emailClient.sendMail({
from: {
name: opts.name || appName,
address: opts.from,
address: opts.from
},
to: opts.to,
subject: opts.subject,
html: emailHtml,
html: emailHtml
});
}

View File

@@ -0,0 +1,82 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import React from "react";
import { Body, Head, Html, Preview, Tailwind } from "@react-email/components";
import { themeColors } from "./lib/theme";
import {
EmailContainer,
EmailFooter,
EmailGreeting,
EmailHeading,
EmailLetterHead,
EmailSignature,
EmailText
} from "./components/Email";
interface Props {
email: string;
limitName: string;
currentUsage: number;
usageLimit: number;
billingLink: string; // Link to billing page
}
export const NotifyUsageLimitApproaching = ({ email, limitName, currentUsage, usageLimit, billingLink }: Props) => {
const previewText = `Your usage for ${limitName} is approaching the limit.`;
const usagePercentage = Math.round((currentUsage / usageLimit) * 100);
return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind config={themeColors}>
<Body className="font-sans bg-gray-50">
<EmailContainer>
<EmailLetterHead />
<EmailHeading>Usage Limit Warning</EmailHeading>
<EmailGreeting>Hi there,</EmailGreeting>
<EmailText>
We wanted to let you know that your usage for <strong>{limitName}</strong> is approaching your plan limit.
</EmailText>
<EmailText>
<strong>Current Usage:</strong> {currentUsage} of {usageLimit} ({usagePercentage}%)
</EmailText>
<EmailText>
Once you reach your limit, some functionality may be restricted or your sites may disconnect until you upgrade your plan or your usage resets.
</EmailText>
<EmailText>
To avoid any interruption to your service, we recommend upgrading your plan or monitoring your usage closely. You can <a href={billingLink}>upgrade your plan here</a>.
</EmailText>
<EmailText>
If you have any questions or need assistance, please don't hesitate to reach out to our support team.
</EmailText>
<EmailFooter>
<EmailSignature />
</EmailFooter>
</EmailContainer>
</Body>
</Tailwind>
</Html>
);
};
export default NotifyUsageLimitApproaching;

View File

@@ -0,0 +1,84 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import React from "react";
import { Body, Head, Html, Preview, Tailwind } from "@react-email/components";
import { themeColors } from "./lib/theme";
import {
EmailContainer,
EmailFooter,
EmailGreeting,
EmailHeading,
EmailLetterHead,
EmailSignature,
EmailText
} from "./components/Email";
interface Props {
email: string;
limitName: string;
currentUsage: number;
usageLimit: number;
billingLink: string; // Link to billing page
}
export const NotifyUsageLimitReached = ({ email, limitName, currentUsage, usageLimit, billingLink }: Props) => {
const previewText = `You've reached your ${limitName} usage limit - Action required`;
const usagePercentage = Math.round((currentUsage / usageLimit) * 100);
return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind config={themeColors}>
<Body className="font-sans bg-gray-50">
<EmailContainer>
<EmailLetterHead />
<EmailHeading>Usage Limit Reached - Action Required</EmailHeading>
<EmailGreeting>Hi there,</EmailGreeting>
<EmailText>
You have reached your usage limit for <strong>{limitName}</strong>.
</EmailText>
<EmailText>
<strong>Current Usage:</strong> {currentUsage} of {usageLimit} ({usagePercentage}%)
</EmailText>
<EmailText>
<strong>Important:</strong> Your functionality may now be restricted and your sites may disconnect until you either upgrade your plan or your usage resets. To prevent any service interruption, immediate action is recommended.
</EmailText>
<EmailText>
<strong>What you can do:</strong>
<br /> <a href={billingLink} style={{ color: '#2563eb', fontWeight: 'bold' }}>Upgrade your plan immediately</a> to restore full functionality
<br /> Monitor your usage to stay within limits in the future
</EmailText>
<EmailText>
If you have any questions or need immediate assistance, please contact our support team right away.
</EmailText>
<EmailFooter>
<EmailSignature />
</EmailFooter>
</EmailContainer>
</Body>
</Tailwind>
</Html>
);
};
export default NotifyUsageLimitReached;

View File

@@ -17,7 +17,7 @@ export function EmailLetterHead() {
<div className="px-6 pt-8 pb-2 text-center">
<Img
src="https://fossorial-public-assets.s3.us-east-1.amazonaws.com/word_mark_black.png"
alt="Fossorial"
alt="Pangolin Logo"
width="120"
height="auto"
className="mx-auto"
@@ -107,7 +107,7 @@ export function EmailSignature() {
<p className="mb-2">
Best regards,
<br />
<strong>The Fossorial Team</strong>
<strong>The Pangolin Team</strong>
</p>
</div>
);