212 lines
6.4 KiB
JavaScript
212 lines
6.4 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 telegramService.sendCalculatorQuote({
|
|
...contactData,
|
|
services: services.map(s => ({ name: s, price: 0 })) // Simplified for now
|
|
});
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
// Telegram notifications now handled by telegramService
|
|
|
|
// 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; |