126 أسطر
3.7 KiB
JavaScript
126 أسطر
3.7 KiB
JavaScript
import express from 'express';
|
|
import nodemailer from 'nodemailer';
|
|
import bodyParser from 'body-parser';
|
|
import cors from 'cors';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import dotenv from 'dotenv';
|
|
|
|
// Load environment variables
|
|
dotenv.config();
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3001; // Changed to 3001 to avoid conflict
|
|
|
|
// Middleware
|
|
app.use(bodyParser.urlencoded({ extended: true }));
|
|
app.use(bodyParser.json());
|
|
app.use(cors());
|
|
|
|
// Serve static files from the React app build directory
|
|
// Only serve static files if the dist directory exists
|
|
const distPath = path.join(__dirname, 'dist');
|
|
app.use(express.static(distPath, {
|
|
maxAge: '1d',
|
|
etag: false
|
|
}));
|
|
|
|
// Contact form endpoint
|
|
app.post('/api/contact', async (req, res) => {
|
|
const { name, email, phone, message } = req.body;
|
|
|
|
// Validation
|
|
if (!name || !email || !message) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Please fill in all required fields.'
|
|
});
|
|
}
|
|
|
|
// Validate email format
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(email)) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Please provide a valid email address.'
|
|
});
|
|
}
|
|
|
|
try {
|
|
// Create transporter object using SMTP transport
|
|
const transporter = nodemailer.createTransport({ // Fixed: createTransporter -> createTransport
|
|
host: 'smtp.gmail.com',
|
|
port: 465,
|
|
secure: true,
|
|
auth: {
|
|
user: process.env.EMAIL_USER, // Your Gmail address from environment variables
|
|
pass: process.env.EMAIL_PASS // Your Gmail App Password from environment variables
|
|
}
|
|
});
|
|
|
|
// Verify transporter configuration
|
|
await transporter.verify();
|
|
console.log('SMTP transporter verified successfully');
|
|
|
|
// Email content
|
|
const mailOptions = {
|
|
from: `"Website Contact Form" <${process.env.EMAIL_USER}>`,
|
|
to: 'bayan10kh@gmail.com',
|
|
subject: 'New message from contact form',
|
|
html: `
|
|
<h2>You have received a new message from your website:</h2>
|
|
<p><strong>Name:</strong> ${name}</p>
|
|
<p><strong>Email:</strong> ${email}</p>
|
|
<p><strong>Phone:</strong> ${phone || 'Not provided'}</p>
|
|
<p><strong>Message:</strong><br/>${message.replace(/\n/g, '<br/>')}</p>
|
|
`,
|
|
text: `
|
|
You have received a new message from your website:
|
|
|
|
Name: ${name}
|
|
Email: ${email}
|
|
Phone: ${phone || 'Not provided'}
|
|
Message:
|
|
${message}
|
|
`
|
|
};
|
|
|
|
// Send email
|
|
const info = await transporter.sendMail(mailOptions);
|
|
console.log('Email sent successfully:', info.messageId);
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Your message has been sent successfully!'
|
|
});
|
|
} catch (error) {
|
|
console.error('Error sending email:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Sorry, there was an error sending your message. Please try again later.'
|
|
});
|
|
}
|
|
});
|
|
|
|
// Handle React routing, return all requests to React app
|
|
// Only serve index.html if the dist directory exists
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(path.join(distPath, 'index.html'), (err) => {
|
|
if (err) {
|
|
res.status(200).send(`
|
|
<h1>Drone Build Showcase Backend Server</h1>
|
|
<p>Server is running on port ${PORT}</p>
|
|
<p>API endpoint: <a href="/api/contact">/api/contact</a></p>
|
|
<p>Email user: ${process.env.EMAIL_USER || 'Not set'}</p>
|
|
`);
|
|
}
|
|
});
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`Server is running on port ${PORT}`);
|
|
console.log(`Email user: ${process.env.EMAIL_USER || 'Not set'}`);
|
|
}); |