Files
sst_site/.history/routes/contact_20251021213250.js
2025-10-22 21:22:44 +09:00

244 lines
7.2 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const nodemailer = require('nodemailer');
const { Contact } = require('../models');
const telegramService = require('../services/telegram');
// Contact form validation
const contactValidation = [
body('name').trim().isLength({ min: 2, max: 100 }),
body('email').isEmail().normalizeEmail(),
body('subject').trim().isLength({ min: 5, max: 200 }),
body('message').trim().isLength({ min: 10, max: 2000 }),
body('phone').optional().isMobilePhone(),
body('company').optional().trim().isLength({ max: 100 })
];
// Submit contact form
router.post('/submit', contactValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: 'Invalid input data',
errors: errors.array()
});
}
const contactData = {
...req.body,
ipAddress: req.ip,
userAgent: req.get('User-Agent'),
source: 'website'
};
// Save to database
const contact = new Contact(contactData);
await contact.save();
// Send email notification
await sendEmailNotification(contact);
// Send Telegram notification
await telegramService.sendNewContactAlert(contact);
res.json({
success: true,
message: 'Your message has been sent successfully. We will get back to you soon!',
contactId: contact._id
});
} catch (error) {
console.error('Contact form error:', error);
res.status(500).json({
success: false,
message: 'Sorry, there was an error sending your message. Please try again.'
});
}
});
// Get project estimate
router.post('/estimate', [
body('services').isArray().notEmpty(),
body('projectType').notEmpty(),
body('timeline').notEmpty(),
body('budget').notEmpty(),
body('description').trim().isLength({ min: 10, max: 1000 })
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: 'Invalid input data',
errors: errors.array()
});
}
const { services, projectType, timeline, budget, description, contactInfo } = req.body;
// Calculate estimate (simplified)
const estimate = calculateProjectEstimate(services, projectType, timeline);
// Save inquiry to database
const contactData = {
name: contactInfo.name,
email: contactInfo.email,
phone: contactInfo.phone,
company: contactInfo.company,
subject: `Project Estimate Request - ${projectType}`,
message: `Project Description: ${description}\n\nServices: ${services.join(', ')}\nTimeline: ${timeline}\nBudget: ${budget}\n\nCalculated Estimate: ${estimate.formatted}`,
serviceInterest: projectType,
budget: budget,
timeline: timeline,
source: 'calculator',
ipAddress: req.ip,
userAgent: req.get('User-Agent')
};
const contact = new Contact(contactData);
await contact.save();
// Send notifications
await sendEmailNotification(contact);
await sendTelegramNotification(contact);
res.json({
success: true,
message: 'Your project estimate request has been submitted successfully!',
estimate: estimate,
contactId: contact._id
});
} catch (error) {
console.error('Estimate request error:', error);
res.status(500).json({
success: false,
message: 'Sorry, there was an error processing your request. Please try again.'
});
}
});
// Helper function to send email notification
async function sendEmailNotification(contact) {
if (!process.env.EMAIL_HOST || !process.env.EMAIL_USER) {
console.log('Email configuration not provided, skipping email notification');
return;
}
try {
const transporter = nodemailer.createTransporter({
host: process.env.EMAIL_HOST,
port: process.env.EMAIL_PORT || 587,
secure: false,
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS
}
});
const mailOptions = {
from: process.env.EMAIL_USER,
to: process.env.ADMIN_EMAIL || process.env.EMAIL_USER,
subject: `New Contact Form Submission: ${contact.subject}`,
html: `
<h2>New Contact Form Submission</h2>
<p><strong>Name:</strong> ${contact.name}</p>
<p><strong>Email:</strong> ${contact.email}</p>
<p><strong>Phone:</strong> ${contact.phone || 'Not provided'}</p>
<p><strong>Company:</strong> ${contact.company || 'Not provided'}</p>
<p><strong>Subject:</strong> ${contact.subject}</p>
<p><strong>Message:</strong></p>
<p>${contact.message.replace(/\n/g, '<br>')}</p>
<p><strong>Source:</strong> ${contact.source}</p>
<p><strong>Submitted:</strong> ${contact.createdAt}</p>
<hr>
<p><a href="${process.env.SITE_URL}/admin/contacts/${contact._id}">View in Admin Panel</a></p>
`
};
await transporter.sendMail(mailOptions);
console.log('Email notification sent successfully');
} catch (error) {
console.error('Email notification error:', error);
}
}
// Helper function to send Telegram notification
async function sendTelegramNotification(contact) {
if (!bot || !process.env.TELEGRAM_CHAT_ID) {
console.log('Telegram configuration not provided, skipping Telegram notification');
return;
}
try {
const message = `
🔔 *New Contact Form Submission*
👤 *Name:* ${contact.name}
📧 *Email:* ${contact.email}
📱 *Phone:* ${contact.phone || 'Not provided'}
🏢 *Company:* ${contact.company || 'Not provided'}
📝 *Subject:* ${contact.subject}
💬 *Message:*
${contact.message}
📍 *Source:* ${contact.source}
🕐 *Time:* ${contact.createdAt.toLocaleString()}
[View in Admin Panel](${process.env.SITE_URL}/admin/contacts/${contact._id})
`;
await bot.sendMessage(process.env.TELEGRAM_CHAT_ID, message, {
parse_mode: 'Markdown',
disable_web_page_preview: true
});
console.log('Telegram notification sent successfully');
} catch (error) {
console.error('Telegram notification error:', error);
}
}
// Helper function to calculate project estimate
function calculateProjectEstimate(services, projectType, timeline) {
const baseRates = {
'web-development': 50000,
'mobile-app': 80000,
'ui-ux-design': 30000,
'branding': 20000,
'e-commerce': 70000,
'consulting': 40000
};
const timelineMultipliers = {
'asap': 1.5,
'1-month': 1.2,
'1-3-months': 1.0,
'3-6-months': 0.9,
'flexible': 0.8
};
let basePrice = baseRates[projectType] || 50000;
let multiplier = timelineMultipliers[timeline] || 1.0;
// Add service modifiers
let serviceModifier = 1.0;
if (services.length > 3) serviceModifier += 0.3;
if (services.length > 5) serviceModifier += 0.5;
const totalEstimate = Math.round(basePrice * multiplier * serviceModifier);
const rangeMin = Math.round(totalEstimate * 0.8);
const rangeMax = Math.round(totalEstimate * 1.3);
return {
base: totalEstimate,
min: rangeMin,
max: rangeMax,
formatted: `${rangeMin.toLocaleString()} - ₩${rangeMax.toLocaleString()}`,
currency: 'KRW'
};
}
module.exports = router;