Skip to content

Commit 95c6587

Browse files
author
ajy0127
committed
feat: Add AWS SES email integration for contact form
- Created API route /api/contact for handling form submissions - Integrated AWS SES for sending emails to teamconnoisseurww@gmail.com - Added IAM user setup scripts with minimal SES permissions - Updated contact form to use new API endpoint - Added comprehensive documentation and test script - Installed @aws-sdk/client-ses package Changes: - app/api/contact/route.ts: New API endpoint for email sending - components/sections/Contact.tsx: Updated to call new API - aws-deployment-kit/scripts/: IAM setup automation scripts - docs/CONTACT_FORM_SETUP.md: Complete setup documentation - .env.local.example: Environment variable template - test-contact-form.js: Test script for form validation
1 parent 06cf57d commit 95c6587

28 files changed

Lines changed: 6167 additions & 184 deletions

.env.local.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# AWS SES Configuration
2+
# Get these from your AWS account with the 'con' profile
3+
AWS_REGION=us-east-1
4+
AWS_ACCESS_KEY_ID=your_access_key_id
5+
AWS_SECRET_ACCESS_KEY=your_secret_access_key

app/api/contact/route.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
3+
4+
// Initialize SES client with AWS profile
5+
const sesClient = new SESClient({
6+
region: process.env.AWS_REGION || 'us-east-1',
7+
credentials: {
8+
accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
9+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || '',
10+
},
11+
});
12+
13+
export async function POST(request: NextRequest) {
14+
try {
15+
const body = await request.json();
16+
const { fullName, email, company, budget, message } = body;
17+
18+
// Validate required fields
19+
if (!fullName || !email || !message) {
20+
return NextResponse.json(
21+
{ error: 'Missing required fields' },
22+
{ status: 400 }
23+
);
24+
}
25+
26+
// Prepare email content
27+
const emailSubject = `New Contact Form Submission from ${fullName}`;
28+
const emailBody = `
29+
New contact form submission:
30+
31+
Name: ${fullName}
32+
Email: ${email}
33+
Company: ${company || 'Not provided'}
34+
Budget: ${budget || 'Not provided'}
35+
36+
Message:
37+
${message}
38+
39+
---
40+
This email was sent from the Construct Design Academy contact form.
41+
`.trim();
42+
43+
// Send email via SES
44+
const command = new SendEmailCommand({
45+
Source: 'teamconnoisseurww@gmail.com', // Verified sender email
46+
Destination: {
47+
ToAddresses: ['teamconnoisseurww@gmail.com'],
48+
},
49+
Message: {
50+
Subject: {
51+
Data: emailSubject,
52+
Charset: 'UTF-8',
53+
},
54+
Body: {
55+
Text: {
56+
Data: emailBody,
57+
Charset: 'UTF-8',
58+
},
59+
Html: {
60+
Data: `
61+
<html>
62+
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
63+
<h2 style="color: #C2A376;">New Contact Form Submission</h2>
64+
<table style="width: 100%; max-width: 600px; border-collapse: collapse;">
65+
<tr>
66+
<td style="padding: 10px; font-weight: bold; width: 120px;">Name:</td>
67+
<td style="padding: 10px;">${fullName}</td>
68+
</tr>
69+
<tr style="background-color: #f9f9f9;">
70+
<td style="padding: 10px; font-weight: bold;">Email:</td>
71+
<td style="padding: 10px;"><a href="mailto:${email}">${email}</a></td>
72+
</tr>
73+
<tr>
74+
<td style="padding: 10px; font-weight: bold;">Company:</td>
75+
<td style="padding: 10px;">${company || 'Not provided'}</td>
76+
</tr>
77+
<tr style="background-color: #f9f9f9;">
78+
<td style="padding: 10px; font-weight: bold;">Budget:</td>
79+
<td style="padding: 10px;">${budget || 'Not provided'}</td>
80+
</tr>
81+
</table>
82+
<div style="margin-top: 20px; padding: 15px; background-color: #f5f5f5; border-left: 4px solid #C2A376;">
83+
<h3 style="margin-top: 0; color: #C2A376;">Message:</h3>
84+
<p style="white-space: pre-wrap;">${message}</p>
85+
</div>
86+
<hr style="margin-top: 30px; border: none; border-top: 1px solid #ddd;">
87+
<p style="font-size: 12px; color: #666;">This email was sent from the Construct Design Academy contact form.</p>
88+
</body>
89+
</html>
90+
`,
91+
Charset: 'UTF-8',
92+
},
93+
},
94+
},
95+
});
96+
97+
await sesClient.send(command);
98+
99+
return NextResponse.json(
100+
{ success: true, message: 'Email sent successfully' },
101+
{ status: 200 }
102+
);
103+
} catch (error) {
104+
console.error('Error sending email:', error);
105+
return NextResponse.json(
106+
{ error: 'Failed to send email', details: error instanceof Error ? error.message : 'Unknown error' },
107+
{ status: 500 }
108+
);
109+
}
110+
}

aws-deployment-kit/.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Environment variables
2+
.env
3+
.env.local
4+
.env.production
5+
6+
# AWS credentials (never commit these!)
7+
.aws/
8+
credentials
9+
10+
# Node modules
11+
node_modules/
12+
13+
# Build outputs
14+
dist/
15+
build/
16+
17+
# Logs
18+
*.log
19+
npm-debug.log*
20+
21+
# OS files
22+
.DS_Store
23+
Thumbs.db
24+
25+
# IDE
26+
.vscode/
27+
.idea/
28+
*.swp
29+
*.swo
30+
31+
# Temporary files
32+
*.tmp
33+
.cache/

0 commit comments

Comments
 (0)