verification emails and full email setup

This commit is contained in:
2026-01-29 00:43:24 +00:00
parent 14520618d1
commit d943561e89
31 changed files with 2190 additions and 53 deletions

View File

@@ -0,0 +1,54 @@
import { render } from "@react-email/render";
import type React from "react";
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
const FROM_EMAIL = process.env.EMAIL_FROM || "Sprint <noreply@sprint.app>";
export interface SendEmailOptions {
to: string;
subject: string;
template: React.ReactElement;
from?: string;
}
export async function sendEmail({ to, subject, template, from }: SendEmailOptions) {
const html = await render(template);
const { data, error } = await resend.emails.send({
from: from || FROM_EMAIL,
to,
subject,
html,
});
if (error) {
console.error("Failed to send email:", error);
throw new Error(`Email send failed: ${error.message}`);
}
return data;
}
export async function sendEmailWithRetry(
options: SendEmailOptions,
maxRetries = 3,
): Promise<ReturnType<typeof sendEmail>> {
let lastError: Error | undefined;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await sendEmail(options);
} catch (error) {
lastError = error as Error;
console.warn(`Email send attempt ${attempt} failed:`, error);
if (attempt < maxRetries) {
await new Promise((resolve) => setTimeout(resolve, 1000 * 2 ** (attempt - 1)));
}
}
}
throw lastError || new Error("Email send failed after all retries");
}