Files
oldvine_cms/routes/contact.js
Talal Sharabi a3308a26e2 Initial commit: CMS backend for Old Vine Hotel
- Complete Express.js API server
- MongoDB integration with Mongoose
- Admin authentication and authorization
- Room management (CRUD operations)
- Booking management system
- Guest management
- Payment processing (Stripe integration)
- Content management (pages, blog, gallery)
- Media upload and management
- Integration services (Booking.com, Expedia, Opera PMS, Trip.com)
- Email notifications
- Comprehensive logging and error handling
2026-01-06 12:21:56 +04:00

280 lines
9.4 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const sendEmail = require('../utils/sendEmail');
const logger = require('../utils/logger');
// @route POST /api/contact
// @desc Send contact form message
// @access Public
router.post('/', [
body('name').notEmpty().withMessage('Name is required').trim(),
body('email').isEmail().withMessage('Valid email is required').normalizeEmail(),
body('phone').optional().isMobilePhone().withMessage('Valid phone number required'),
body('subject').optional().trim(),
body('message').notEmpty().withMessage('Message is required').isLength({ min: 10, max: 1000 }).withMessage('Message must be between 10 and 1000 characters')
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: 'Validation errors',
errors: errors.array()
});
}
const { name, email, phone, subject, message } = req.body;
// Log the contact form submission
logger.info('Contact form submission received', {
name,
email,
subject: subject || 'General Inquiry',
ip: req.ip
});
// Send email to hotel management
try {
await sendEmail({
to: process.env.HOTEL_EMAIL || 'info@oldvinehotel.com',
subject: `Contact Form: ${subject || 'General Inquiry'}`,
template: 'contactForm',
context: {
name,
email,
phone,
message,
timestamp: new Date().toLocaleString()
}
});
logger.info('Contact form email sent successfully', { name, email });
} catch (emailError) {
logger.error('Failed to send contact form email:', emailError);
// Don't fail the request if email fails
}
// Send auto-reply to customer
try {
await sendEmail({
to: email,
subject: 'Thank you for contacting The Old Vine Hotel',
html: `
<div style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<div style="background: #8B4513; color: white; padding: 20px; text-align: center;">
<h1>The Old Vine Hotel</h1>
</div>
<div style="padding: 20px;">
<p>Dear ${name},</p>
<p>Thank you for contacting The Old Vine Hotel. We have received your message and will respond within 24 hours.</p>
<div style="background: #f9f9f9; padding: 15px; border-radius: 5px; margin: 20px 0;">
<h3>Your Message:</h3>
<p><strong>Subject:</strong> ${subject || 'General Inquiry'}</p>
<p><strong>Message:</strong> ${message}</p>
</div>
<p>In the meantime, feel free to:</p>
<ul>
<li>Browse our rooms and amenities on our website</li>
<li>Call us directly at +1 (555) 123-4567</li>
<li>Follow us on social media for updates and special offers</li>
</ul>
<p>We look forward to serving you!</p>
<p>Best regards,<br>
The Old Vine Hotel Team</p>
</div>
<div style="background: #f4f4f4; padding: 20px; text-align: center; font-size: 12px;">
<p>&copy; 2025 The Old Vine Hotel. All rights reserved.</p>
</div>
</div>
`
});
} catch (emailError) {
logger.error('Failed to send contact form auto-reply:', emailError);
}
res.json({
success: true,
message: 'Thank you for your message. We will get back to you within 24 hours.'
});
} catch (error) {
logger.error('Contact form processing error:', error);
res.status(500).json({
success: false,
message: 'An error occurred while processing your message. Please try again.'
});
}
});
// @route POST /api/contact/newsletter
// @desc Subscribe to newsletter
// @access Public
router.post('/newsletter', [
body('email').isEmail().withMessage('Valid email is required').normalizeEmail(),
body('name').optional().trim()
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: 'Validation errors',
errors: errors.array()
});
}
const { email, name } = req.body;
// Log newsletter subscription
logger.info('Newsletter subscription', {
email,
name: name || 'Not provided',
ip: req.ip
});
// In a real application, you would save this to a newsletter database
// For now, we'll just send a confirmation email
try {
await sendEmail({
to: email,
subject: 'Welcome to The Old Vine Hotel Newsletter',
html: `
<div style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<div style="background: #8B4513; color: white; padding: 20px; text-align: center;">
<h1>The Old Vine Hotel</h1>
<h2>Newsletter Subscription Confirmed</h2>
</div>
<div style="padding: 20px;">
<p>Dear ${name || 'Valued Guest'},</p>
<p>Thank you for subscribing to The Old Vine Hotel newsletter!</p>
<p>You'll now receive:</p>
<ul>
<li>Exclusive special offers and promotions</li>
<li>Updates on hotel amenities and services</li>
<li>Local event recommendations</li>
<li>Seasonal packages and deals</li>
</ul>
<p>We're excited to keep you informed about everything happening at The Old Vine Hotel.</p>
<div style="text-align: center; margin: 30px 0;">
<a href="https://oldvinehotel.com" style="background: #D4AF37; color: black; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold;">Visit Our Website</a>
</div>
<p>Best regards,<br>
The Old Vine Hotel Team</p>
<p style="font-size: 12px; color: #666; margin-top: 30px;">
You can unsubscribe from these emails at any time by clicking the unsubscribe link in any newsletter.
</p>
</div>
<div style="background: #f4f4f4; padding: 20px; text-align: center; font-size: 12px;">
<p>&copy; 2025 The Old Vine Hotel. All rights reserved.</p>
</div>
</div>
`
});
} catch (emailError) {
logger.error('Failed to send newsletter confirmation:', emailError);
// Don't fail the request if email fails
}
res.json({
success: true,
message: 'Thank you for subscribing! You will receive a confirmation email shortly.'
});
} catch (error) {
logger.error('Newsletter subscription error:', error);
res.status(500).json({
success: false,
message: 'An error occurred while processing your subscription. Please try again.'
});
}
});
// @route GET /api/contact/info
// @desc Get hotel contact information
// @access Public
router.get('/info', (req, res) => {
const contactInfo = {
hotel: {
name: process.env.HOTEL_NAME || 'The Old Vine Hotel',
address: {
street: 'Old Damascus City',
city: 'Damascus',
state: 'Damascus Governorate',
zipCode: '',
country: 'Syria',
formatted: process.env.HOTEL_ADDRESS || 'Old Damascus City'
},
phone: process.env.HOTEL_PHONE || '+963 986 703 070',
email: process.env.HOTEL_EMAIL || 'info@oldvinehotel.com',
website: process.env.HOTEL_WEBSITE || 'https://oldvinehotel.com',
whatsapp: process.env.WHATSAPP_PHONE_NUMBER || '+963 986 703 070'
},
departments: {
reservations: {
phone: '+963 986 703 070',
email: 'reservations@oldvinehotel.com',
hours: '24/7'
},
concierge: {
phone: '+963 986 703 070',
email: 'concierge@oldvinehotel.com',
hours: '6:00 AM - 12:00 AM'
},
restaurant: {
phone: '+963 986 703 070',
email: 'restaurant@oldvinehotel.com',
hours: '6:30 AM - 11:00 PM'
},
spa: {
phone: '+963 986 703 070',
email: 'spa@oldvinehotel.com',
hours: '8:00 AM - 9:00 PM'
},
events: {
phone: '+963 986 703 070',
email: 'events@oldvinehotel.com',
hours: '9:00 AM - 6:00 PM'
}
},
socialMedia: {
facebook: 'https://facebook.com/oldvinehotel',
instagram: 'https://instagram.com/oldvinehotel',
twitter: 'https://twitter.com/oldvinehotel',
linkedin: 'https://linkedin.com/company/oldvinehotel'
},
checkInOut: {
checkIn: '3:00 PM',
checkOut: '11:00 AM',
earlyCheckIn: 'Available upon request (additional fee may apply)',
lateCheckOut: 'Available upon request (additional fee may apply)'
},
policies: {
cancellation: '24 hours before arrival',
petPolicy: 'Pets allowed with prior arrangement',
smokingPolicy: 'Non-smoking hotel',
childrenPolicy: 'Children of all ages welcome'
}
};
res.json({
success: true,
data: contactInfo
});
});
module.exports = router;