268 lines
9.0 KiB
JavaScript
268 lines
9.0 KiB
JavaScript
// app/api/contact/route.js
|
|
// ❌ REMOVE "use client" from here - API routes must NOT have this directive
|
|
|
|
import { NextResponse } from 'next/server';
|
|
import nodemailer from 'nodemailer';
|
|
|
|
// Create transporter with Zoho configuration
|
|
const createTransport = () => {
|
|
return nodemailer.createTransport({
|
|
host: 'smtp.zoho.com',
|
|
port: 587,
|
|
secure: false,
|
|
auth: {
|
|
user: process.env.ZOHO_EMAIL,
|
|
pass: process.env.ZOHO_PASSWORD,
|
|
},
|
|
debug: true,
|
|
logger: true,
|
|
});
|
|
};
|
|
|
|
// Handle Newsletter Subscription
|
|
async function handleNewsletter(data) {
|
|
console.log('Processing newsletter subscription for:', data.email);
|
|
|
|
const transporter = createTransport();
|
|
|
|
const mailOptions = {
|
|
from: process.env.ZOHO_EMAIL,
|
|
to: process.env.RECIPIENT_EMAIL,
|
|
subject: 'New Newsletter Subscription - Keystone Solutions',
|
|
html: `
|
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<h2 style="color: #ff3a2d;">New Newsletter Subscription</h2>
|
|
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
|
<p><strong>Email:</strong> ${data.email}</p>
|
|
<p><strong>Subscribed at:</strong> ${new Date().toLocaleString()}</p>
|
|
</div>
|
|
<hr style="margin: 20px 0;">
|
|
<p style="color: #666; font-size: 14px;">
|
|
This email was sent from your website's newsletter subscription form.
|
|
</p>
|
|
</div>
|
|
`,
|
|
};
|
|
|
|
const result = await transporter.sendMail(mailOptions);
|
|
console.log('Newsletter email sent successfully:', result.messageId);
|
|
return result;
|
|
}
|
|
|
|
// Handle Contact Form
|
|
async function handleContact(data) {
|
|
console.log('Processing contact form for:', data.fullName, data.email);
|
|
|
|
const transporter = createTransport();
|
|
|
|
const mailOptions = {
|
|
from: process.env.ZOHO_EMAIL,
|
|
to: process.env.RECIPIENT_EMAIL,
|
|
subject: 'New Contact Form Submission - Keystone Solutions',
|
|
html: `
|
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<h2 style="color: #ff3a2d;">New Contact Form Submission</h2>
|
|
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
|
<p><strong>Full Name:</strong> ${data.fullName}</p>
|
|
<p><strong>Email:</strong> ${data.email}</p>
|
|
<p><strong>Phone:</strong> ${data.phone || 'Not provided'}</p>
|
|
<p><strong>Message:</strong></p>
|
|
<div style="background: white; padding: 15px; border-left: 4px solid #ff3a2d; margin: 10px 0;">
|
|
${data.message || 'No message provided'}
|
|
</div>
|
|
<p><strong>Submitted at:</strong> ${new Date().toLocaleString()}</p>
|
|
</div>
|
|
<hr style="margin: 20px 0;">
|
|
<p style="color: #666; font-size: 14px;">
|
|
This email was sent from your website's contact form.
|
|
</p>
|
|
</div>
|
|
`,
|
|
};
|
|
|
|
const result = await transporter.sendMail(mailOptions);
|
|
console.log('Contact email sent successfully:', result.messageId);
|
|
return result;
|
|
}
|
|
|
|
// Handle Career Form
|
|
async function handleCareer(data) {
|
|
console.log('Processing career form for:', data.fullName, data.email);
|
|
|
|
const transporter = createTransport();
|
|
|
|
const attachments = [];
|
|
|
|
// Handle file attachment if present
|
|
if (data.resume) {
|
|
console.log('Resume file attached:', data.resume.name);
|
|
attachments.push({
|
|
filename: data.resume.name,
|
|
content: Buffer.from(data.resume.data, 'base64'),
|
|
contentType: data.resume.type,
|
|
});
|
|
}
|
|
|
|
const mailOptions = {
|
|
from: process.env.ZOHO_EMAIL,
|
|
to: process.env.RECIPIENT_EMAIL,
|
|
subject: 'New Career Application - Keystone Solutions',
|
|
html: `
|
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<h2 style="color: #ff3a2d;">New Career Application</h2>
|
|
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
|
<p><strong>Full Name:</strong> ${data.fullName}</p>
|
|
<p><strong>Email:</strong> ${data.email}</p>
|
|
<p><strong>Phone:</strong> ${data.phone}</p>
|
|
<p><strong>Roles of Interest:</strong> ${data.roles}</p>
|
|
<p><strong>Resume:</strong> ${data.resume ? 'Attached' : 'Not provided'}</p>
|
|
<p><strong>Applied at:</strong> ${new Date().toLocaleString()}</p>
|
|
</div>
|
|
<hr style="margin: 20px 0;">
|
|
<p style="color: #666; font-size: 14px;">
|
|
This email was sent from your website's career application form.
|
|
</p>
|
|
</div>
|
|
`,
|
|
attachments: attachments,
|
|
};
|
|
|
|
const result = await transporter.sendMail(mailOptions);
|
|
console.log('Career email sent successfully:', result.messageId);
|
|
return result;
|
|
}
|
|
|
|
// POST handler for all form submissions
|
|
export async function POST(request) {
|
|
console.log('\n🚀 === EMAIL API ROUTE STARTED ===');
|
|
|
|
try {
|
|
// Check environment variables first
|
|
const requiredEnvVars = {
|
|
ZOHO_EMAIL: process.env.ZOHO_EMAIL,
|
|
ZOHO_PASSWORD: process.env.ZOHO_PASSWORD,
|
|
RECIPIENT_EMAIL: process.env.RECIPIENT_EMAIL,
|
|
};
|
|
|
|
console.log('Environment variables check:');
|
|
Object.entries(requiredEnvVars).forEach(([key, value]) => {
|
|
console.log(`${key}: ${value ? '✅ Set' : '❌ Missing'}`);
|
|
});
|
|
console.log(
|
|
'Loaded password (first 3 chars):',
|
|
process.env.ZOHO_PASSWORD?.slice(0, 3)
|
|
);
|
|
|
|
if (!requiredEnvVars.ZOHO_EMAIL || !requiredEnvVars.ZOHO_PASSWORD || !requiredEnvVars.RECIPIENT_EMAIL) {
|
|
console.error('❌ Missing required environment variables');
|
|
return NextResponse.json(
|
|
{ error: 'Email configuration missing' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
// Parse request body
|
|
let body;
|
|
try {
|
|
body = await request.json();
|
|
console.log('✅ Request body parsed successfully');
|
|
} catch (parseError) {
|
|
console.error('❌ Failed to parse request body:', parseError);
|
|
return NextResponse.json(
|
|
{ error: 'Invalid JSON in request body' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const { type, ...data } = body;
|
|
console.log(`📝 Form type: ${type}`);
|
|
console.log(`📋 Form data keys: ${Object.keys(data).join(', ')}`);
|
|
|
|
if (!type) {
|
|
console.error('❌ No form type specified');
|
|
return NextResponse.json(
|
|
{ error: 'Form type is required' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Route to appropriate handler based on form type
|
|
let result;
|
|
switch (type) {
|
|
case 'newsletter':
|
|
if (!data.email) {
|
|
console.error('❌ Newsletter: Email is required');
|
|
return NextResponse.json({ error: 'Email is required' }, { status: 400 });
|
|
}
|
|
result = await handleNewsletter(data);
|
|
break;
|
|
|
|
case 'contact':
|
|
if (!data.fullName || !data.email) {
|
|
console.error('❌ Contact: Full name and email are required');
|
|
return NextResponse.json({ error: 'Full name and email are required' }, { status: 400 });
|
|
}
|
|
result = await handleContact(data);
|
|
break;
|
|
|
|
case 'career':
|
|
if (!data.fullName || !data.email || !data.phone) {
|
|
console.error('❌ Career: Full name, email, and phone are required');
|
|
return NextResponse.json({ error: 'Full name, email, and phone are required' }, { status: 400 });
|
|
}
|
|
result = await handleCareer(data);
|
|
break;
|
|
|
|
default:
|
|
console.error('❌ Invalid form type:', type);
|
|
return NextResponse.json({ error: 'Invalid form type' }, { status: 400 });
|
|
}
|
|
|
|
console.log('✅ Email sent successfully!');
|
|
console.log('📧 Message ID:', result.messageId);
|
|
console.log('🎉 === EMAIL API ROUTE SUCCESS ===\n');
|
|
|
|
return NextResponse.json(
|
|
{
|
|
message: 'Email sent successfully',
|
|
messageId: result.messageId,
|
|
type: type
|
|
},
|
|
{ status: 200 }
|
|
);
|
|
|
|
} catch (error) {
|
|
console.error('\n💥 === EMAIL API ROUTE ERROR ===');
|
|
console.error('Error name:', error.name);
|
|
console.error('Error message:', error.message);
|
|
console.error('Error code:', error.code);
|
|
console.error('Error stack:', error.stack);
|
|
|
|
// Provide more specific error messages
|
|
let errorMessage = 'Failed to send email';
|
|
let statusCode = 500;
|
|
|
|
if (error.code === 'EAUTH') {
|
|
errorMessage = 'Authentication failed. Please check your Zoho email and app password.';
|
|
console.error('🔐 Authentication issue - check ZOHO_EMAIL and ZOHO_PASSWORD');
|
|
} else if (error.code === 'ECONNECTION' || error.code === 'ETIMEDOUT') {
|
|
errorMessage = 'Connection to email server failed. Please try again.';
|
|
console.error('🌐 Network connection issue');
|
|
} else if (error.code === 'EMESSAGE') {
|
|
errorMessage = 'Invalid email message format.';
|
|
statusCode = 400;
|
|
console.error('📧 Email format issue');
|
|
}
|
|
|
|
console.error('💥 === END ERROR DETAILS ===\n');
|
|
|
|
return NextResponse.json(
|
|
{
|
|
error: errorMessage,
|
|
details: error.message,
|
|
code: error.code
|
|
},
|
|
{ status: statusCode }
|
|
);
|
|
}
|
|
} |