diff --git a/teressa-copeland-homes/src/emails/SigningRequestEmail.tsx b/teressa-copeland-homes/src/emails/SigningRequestEmail.tsx new file mode 100644 index 0000000..fc3b200 --- /dev/null +++ b/teressa-copeland-homes/src/emails/SigningRequestEmail.tsx @@ -0,0 +1,78 @@ +import { + Html, + Head, + Body, + Container, + Heading, + Text, + Button, + Hr, + Preview, +} from '@react-email/components'; + +interface SigningRequestEmailProps { + documentName: string; + signingUrl: string; + expiryDate: string; // e.g. "March 25, 2026" + clientName?: string; +} + +export function SigningRequestEmail({ + documentName, + signingUrl, + expiryDate, + clientName, +}: SigningRequestEmailProps) { + return ( + + + Please review and sign: {documentName} + + + + Teressa Copeland Homes + +
+ {clientName && ( + Hello {clientName}, + )} + + You have a document ready for your review and signature: + + + {documentName} + + + No account needed — just click the button below. + + + + This link expires on {expiryDate}. If you did not expect this document, you can safely + ignore this email. + +
+ + Teressa Copeland Homes · Utah Licensed Real Estate Agent + +
+ + + ); +} diff --git a/teressa-copeland-homes/src/lib/signing/signing-mailer.tsx b/teressa-copeland-homes/src/lib/signing/signing-mailer.tsx new file mode 100644 index 0000000..42ec712 --- /dev/null +++ b/teressa-copeland-homes/src/lib/signing/signing-mailer.tsx @@ -0,0 +1,67 @@ +import { render } from '@react-email/render'; +import nodemailer from 'nodemailer'; +import { SigningRequestEmail } from '@/emails/SigningRequestEmail'; +import React from 'react'; + +function createTransporter() { + return nodemailer.createTransport({ + host: process.env.CONTACT_SMTP_HOST!, + port: Number(process.env.CONTACT_SMTP_PORT ?? 587), + secure: false, + auth: { + user: process.env.CONTACT_EMAIL_USER!, + pass: process.env.CONTACT_EMAIL_PASS!, + }, + }); +} + +export async function sendSigningRequestEmail(opts: { + to: string; + clientName?: string; + documentName: string; + signingUrl: string; + expiresAt: Date; +}): Promise { + const expiryDate = opts.expiresAt.toLocaleDateString('en-US', { + month: 'long', + day: 'numeric', + year: 'numeric', + }); + const html = await render( + React.createElement(SigningRequestEmail, { + documentName: opts.documentName, + signingUrl: opts.signingUrl, + expiryDate, + clientName: opts.clientName, + }) + ); + const transporter = createTransporter(); + await transporter.sendMail({ + from: '"Teressa Copeland" ', + to: opts.to, + subject: `Please sign: ${opts.documentName}`, + html, + }); +} + +export async function sendAgentNotificationEmail(opts: { + clientName: string; + documentName: string; + signedAt: Date; +}): Promise { + const formattedTime = opts.signedAt.toLocaleString('en-US', { + month: 'long', + day: 'numeric', + year: 'numeric', + hour: 'numeric', + minute: '2-digit', + timeZoneName: 'short', + }); + const transporter = createTransporter(); + await transporter.sendMail({ + from: '"Teressa Copeland Homes" ', + to: 'teressa@teressacopelandhomes.com', + subject: `Signed: ${opts.documentName}`, + text: `${opts.clientName} has signed "${opts.documentName}" on ${formattedTime}.`, + }); +}