p 1 and 2 compeleted
This commit is contained in:
1 parent
6adb541967
commit
3573709d99
28 files changed
+2533
-240
No files matched your search
@@ -0,0 +1,148 @@
|
||||
import { Resend } from "resend";
|
||||
import { render } from "@react-email/render";
|
||||
import log from "./logger";
|
||||
|
||||
/**
|
||||
* Email service using Resend
|
||||
*
|
||||
* Environment variables required:
|
||||
* - RESEND_API_KEY: API key from Resend dashboard
|
||||
* - EMAIL_FROM: Sender email address (e.g., "FitAI <noreply@fitai.com>")
|
||||
* - EMAIL_REPLY_TO: Reply-to email address (optional)
|
||||
*/
|
||||
|
||||
const resend = new Resend(process.env.RESEND_API_KEY);
|
||||
|
||||
const DEFAULT_FROM = process.env.EMAIL_FROM || "FitAI <noreply@fitai.com>";
|
||||
const DEFAULT_REPLY_TO = process.env.EMAIL_REPLY_TO;
|
||||
|
||||
export interface SendEmailOptions {
|
||||
to: string | string[];
|
||||
subject: string;
|
||||
react: React.ReactElement;
|
||||
from?: string;
|
||||
replyTo?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email using Resend
|
||||
*
|
||||
* @param options - Email options including recipient, subject, and React component
|
||||
* @returns Response from Resend API
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* import { WelcomeEmail } from '@/emails/welcome-email';
|
||||
*
|
||||
* await sendEmail({
|
||||
* to: 'user@example.com',
|
||||
* subject: 'Welcome to FitAI',
|
||||
* react: <WelcomeEmail name="John" />
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export async function sendEmail({
|
||||
to,
|
||||
subject,
|
||||
react,
|
||||
from = DEFAULT_FROM,
|
||||
replyTo = DEFAULT_REPLY_TO,
|
||||
}: SendEmailOptions) {
|
||||
try {
|
||||
// Check if email is configured
|
||||
if (!process.env.RESEND_API_KEY) {
|
||||
log.warn("RESEND_API_KEY not configured. Email not sent.", {
|
||||
to,
|
||||
subject,
|
||||
});
|
||||
return { success: false, error: "Email not configured" };
|
||||
}
|
||||
|
||||
const { data, error } = await resend.emails.send({
|
||||
from,
|
||||
to,
|
||||
subject,
|
||||
react,
|
||||
...(replyTo && { replyTo }),
|
||||
});
|
||||
|
||||
if (error) {
|
||||
log.error("Failed to send email", error, { to, subject });
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
|
||||
log.info("Email sent successfully", { to, subject, emailId: data?.id });
|
||||
return { success: true, data };
|
||||
} catch (error) {
|
||||
log.error("Email service error", error, { to, subject });
|
||||
return { success: false, error: "Email service error" };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a welcome email to a new user
|
||||
*/
|
||||
export async function sendWelcomeEmail(email: string, name: string) {
|
||||
const { WelcomeEmail } = await import("@/emails/welcome-email");
|
||||
|
||||
return sendEmail({
|
||||
to: email,
|
||||
subject: "Welcome to FitAI!",
|
||||
react: WelcomeEmail({ name }),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an invitation email to a new user
|
||||
*/
|
||||
export async function sendInvitationEmail(
|
||||
email: string,
|
||||
role: string,
|
||||
inviteUrl: string,
|
||||
) {
|
||||
const { UserInvitationEmail } = await import(
|
||||
"@/emails/user-invitation-email"
|
||||
);
|
||||
|
||||
return sendEmail({
|
||||
to: email,
|
||||
subject: "You've been invited to join FitAI",
|
||||
react: UserInvitationEmail({ email, role, inviteUrl }),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a trainer assignment notification email
|
||||
*/
|
||||
export async function sendTrainerAssignmentEmail(
|
||||
clientEmail: string,
|
||||
clientName: string,
|
||||
trainerName: string,
|
||||
) {
|
||||
const { TrainerAssignmentEmail } = await import(
|
||||
"@/emails/trainer-assignment-email"
|
||||
);
|
||||
|
||||
return sendEmail({
|
||||
to: clientEmail,
|
||||
subject: "You've been assigned a trainer",
|
||||
react: TrainerAssignmentEmail({ clientName, trainerName }),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a recommendation notification email to a client
|
||||
*/
|
||||
export async function sendRecommendationEmail(
|
||||
clientEmail: string,
|
||||
clientName: string,
|
||||
recommendationText: string,
|
||||
) {
|
||||
const { RecommendationEmail } = await import("@/emails/recommendation-email");
|
||||
|
||||
return sendEmail({
|
||||
to: clientEmail,
|
||||
subject: "New fitness recommendation from your trainer",
|
||||
react: RecommendationEmail({ clientName, recommendationText }),
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user