Some checks failed
Build and Deploy / build (push) Has been cancelled
- Add Resend email integration with @react-email/render - Create email templates: OrderConfirmation, OrderShipped, OrderCancelled, OrderPaid - Implement webhook handler for ORDER_CREATED and other events - Add multi-language support for customer emails - Admin emails in English with order details - Update checkout page with auto-scroll on order completion - Configure DASHBOARD_URL environment variable
107 lines
2.0 KiB
TypeScript
107 lines
2.0 KiB
TypeScript
import { Resend } from "resend";
|
|
import { render } from "@react-email/render";
|
|
|
|
let resendClient: Resend | null = null;
|
|
|
|
function getResendClient(): Resend {
|
|
if (!resendClient) {
|
|
if (!process.env.RESEND_API_KEY) {
|
|
throw new Error("RESEND_API_KEY environment variable is not set");
|
|
}
|
|
resendClient = new Resend(process.env.RESEND_API_KEY);
|
|
}
|
|
return resendClient;
|
|
}
|
|
|
|
export const ADMIN_EMAILS = ["me@hytham.me", "tamara@hytham.me"];
|
|
|
|
export async function sendEmail({
|
|
to,
|
|
subject,
|
|
react,
|
|
text,
|
|
tags,
|
|
idempotencyKey,
|
|
}: {
|
|
to: string | string[];
|
|
subject: string;
|
|
react: React.ReactNode;
|
|
text?: string;
|
|
tags?: { name: string; value: string }[];
|
|
idempotencyKey?: string;
|
|
}) {
|
|
const resend = getResendClient();
|
|
|
|
// Render React component to HTML
|
|
const html = await render(react, {
|
|
pretty: true,
|
|
});
|
|
|
|
const { data, error } = await resend.emails.send({
|
|
from: "ManoonOils <support@mail.manoonoils.com>",
|
|
replyTo: "support@manoonoils.com",
|
|
to: Array.isArray(to) ? to : [to],
|
|
subject,
|
|
html,
|
|
text,
|
|
tags,
|
|
...(idempotencyKey && { idempotencyKey }),
|
|
});
|
|
|
|
if (error) {
|
|
console.error("Failed to send email:", error);
|
|
throw error;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
export async function sendEmailToCustomer({
|
|
to,
|
|
subject,
|
|
react,
|
|
text,
|
|
language,
|
|
idempotencyKey,
|
|
}: {
|
|
to: string;
|
|
subject: string;
|
|
react: React.ReactNode;
|
|
text?: string;
|
|
language: string;
|
|
idempotencyKey?: string;
|
|
}) {
|
|
const tag = `customer-${language}`;
|
|
return sendEmail({
|
|
to,
|
|
subject,
|
|
react,
|
|
text,
|
|
tags: [{ name: "type", value: tag }],
|
|
idempotencyKey,
|
|
});
|
|
}
|
|
|
|
export async function sendEmailToAdmin({
|
|
subject,
|
|
react,
|
|
text,
|
|
eventType,
|
|
orderId,
|
|
}: {
|
|
subject: string;
|
|
react: React.ReactNode;
|
|
text?: string;
|
|
eventType: string;
|
|
orderId: string;
|
|
}) {
|
|
return sendEmail({
|
|
to: ADMIN_EMAILS,
|
|
subject: `[Admin] ${subject}`,
|
|
react,
|
|
text,
|
|
tags: [{ name: "type", value: "admin-notification" }],
|
|
idempotencyKey: `admin-${eventType}/${orderId}`,
|
|
});
|
|
}
|