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 (
+
+
+
+
+ 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}.`,
+ });
+}