This commit is contained in:
yotakii
2026-01-14 14:57:04 +03:00
parent 13a004fa40
commit fb2bec5c62

View File

@@ -1,25 +1,45 @@
// cms/routes/settings.js
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const SiteSettings = require('../models/SiteSettings'); const SiteSettings = require('../models/SiteSettings');
const adminAuth = require('../middleware/adminAuth'); const adminAuth = require('../middleware/adminAuth');
const normalizeAddress = (val) => {
if (!val) return '';
if (typeof val === 'string') return val;
if (typeof val === 'number') return String(val);
if (Array.isArray(val)) return val.join(', ');
if (typeof val === 'object') {
if (typeof val.text === 'string') return val.text;
if (typeof val.label === 'string') return val.label;
if (typeof val.address === 'string') return val.address;
// {coordinates:[lng,lat]}
if (Array.isArray(val.coordinates) && val.coordinates.length >= 2) {
const [lng, lat] = val.coordinates;
if (lat != null && lng != null) return `${lat}, ${lng}`;
}
// {coordinates:{lat,lng}}
if (val.coordinates && typeof val.coordinates === 'object') {
const lat = val.coordinates.lat ?? val.coordinates.latitude;
const lng = val.coordinates.lng ?? val.coordinates.lon ?? val.coordinates.longitude;
if (lat != null && lng != null) return `${lat}, ${lng}`;
}
}
return '';
};
// @route GET /api/settings // @route GET /api/settings
// @desc Get site settings // @desc Get site settings
// @access Public // @access Public
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
try { try {
const settings = await SiteSettings.getSiteSettings(); const settings = await SiteSettings.getSiteSettings();
res.json({ success: true, data: { settings } });
res.json({
success: true,
data: { settings }
});
} catch (error) { } catch (error) {
console.error('Get settings error:', error); console.error('Get settings error:', error);
res.status(500).json({ res.status(500).json({ success: false, message: 'Error fetching settings' });
success: false,
message: 'Error fetching settings'
});
} }
}); });
@@ -33,11 +53,9 @@ router.put('/', adminAuth, async (req, res) => {
if (!settings) { if (!settings) {
settings = new SiteSettings(req.body); settings = new SiteSettings(req.body);
} else { } else {
// Update all provided fields Object.keys(req.body).forEach((key) => {
Object.keys(req.body).forEach(key => {
if (key !== '_id' && key !== '__v') { if (key !== '_id' && key !== '__v') {
if (typeof req.body[key] === 'object' && !Array.isArray(req.body[key]) && req.body[key] !== null) { if (typeof req.body[key] === 'object' && !Array.isArray(req.body[key]) && req.body[key] !== null) {
// Deep merge for nested objects
settings[key] = { ...settings[key], ...req.body[key] }; settings[key] = { ...settings[key], ...req.body[key] };
} else { } else {
settings[key] = req.body[key]; settings[key] = req.body[key];
@@ -46,22 +64,18 @@ router.put('/', adminAuth, async (req, res) => {
}); });
} }
if (req.admin && req.admin.id) { if (req.admin && req.admin.id) settings.lastModifiedBy = req.admin.id;
settings.lastModifiedBy = req.admin.id;
}
await settings.save(); await settings.save();
res.json({ res.json({
success: true, success: true,
message: 'Settings updated successfully', message: 'Settings updated successfully',
data: { settings } data: { settings },
}); });
} catch (error) { } catch (error) {
console.error('Update settings error:', error); console.error('Update settings error:', error);
res.status(500).json({ res.status(500).json({ success: false, message: 'Error updating settings' });
success: false,
message: 'Error updating settings'
});
} }
}); });
@@ -72,7 +86,8 @@ router.get('/public', async (req, res) => {
try { try {
const settings = await SiteSettings.getSiteSettings(); const settings = await SiteSettings.getSiteSettings();
// Return only public-facing settings const addressText = normalizeAddress(settings.hotel.address || settings.hotel.location);
const publicSettings = { const publicSettings = {
hotel: { hotel: {
name: settings.hotel.name, name: settings.hotel.name,
@@ -80,9 +95,9 @@ router.get('/public', async (req, res) => {
phone: settings.hotel.phone, phone: settings.hotel.phone,
email: settings.hotel.email, email: settings.hotel.email,
whatsapp: settings.hotel.whatsapp, whatsapp: settings.hotel.whatsapp,
address: settings.hotel.address, address: addressText,
socialMedia: settings.hotel.socialMedia, socialMedia: settings.hotel.socialMedia,
businessHours: settings.hotel.businessHours businessHours: settings.hotel.businessHours,
}, },
theme: settings.theme, theme: settings.theme,
features: settings.features, features: settings.features,
@@ -92,30 +107,20 @@ router.get('/public', async (req, res) => {
minNights: settings.booking.minNights, minNights: settings.booking.minNights,
maxNights: settings.booking.maxNights, maxNights: settings.booking.maxNights,
currency: settings.booking.currency, currency: settings.booking.currency,
currencySymbol: settings.booking.currencySymbol currencySymbol: settings.booking.currencySymbol,
} },
}; };
res.json({ res.json({ success: true, data: { settings: publicSettings } });
success: true,
data: { settings: publicSettings }
});
} catch (error) { } catch (error) {
console.error('Get public settings error:', error); console.error('Get public settings error:', error);
res.status(500).json({ res.status(500).json({ success: false, message: 'Error fetching settings' });
success: false,
message: 'Error fetching settings'
});
} }
}); });
// @route PUT /api/settings/hotel
// @desc Update hotel information
// @access Private (Admin)
router.put('/hotel', adminAuth, async (req, res) => { router.put('/hotel', adminAuth, async (req, res) => {
try { try {
const settings = await SiteSettings.getSiteSettings(); const settings = await SiteSettings.getSiteSettings();
settings.hotel = { ...settings.hotel, ...req.body }; settings.hotel = { ...settings.hotel, ...req.body };
settings.lastModifiedBy = req.admin.id; settings.lastModifiedBy = req.admin.id;
await settings.save(); await settings.save();
@@ -123,34 +128,22 @@ router.put('/hotel', adminAuth, async (req, res) => {
res.json({ res.json({
success: true, success: true,
message: 'Hotel information updated successfully', message: 'Hotel information updated successfully',
data: { hotel: settings.hotel } data: { hotel: settings.hotel },
}); });
} catch (error) { } catch (error) {
console.error('Update hotel info error:', error); console.error('Update hotel info error:', error);
res.status(500).json({ res.status(500).json({ success: false, message: 'Error updating hotel information' });
success: false,
message: 'Error updating hotel information'
});
} }
}); });
// @route PUT /api/settings/theme
// @desc Update theme settings
// @access Private (Admin)
router.put('/theme', adminAuth, async (req, res) => { router.put('/theme', adminAuth, async (req, res) => {
try { try {
const settings = await SiteSettings.getSiteSettings(); const settings = await SiteSettings.getSiteSettings();
settings.theme = { ...settings.theme, ...req.body }; settings.theme = { ...settings.theme, ...req.body };
if (req.body.colors) { if (req.body.colors) settings.theme.colors = { ...settings.theme.colors, ...req.body.colors };
settings.theme.colors = { ...settings.theme.colors, ...req.body.colors }; if (req.body.fonts) settings.theme.fonts = { ...settings.theme.fonts, ...req.body.fonts };
} if (req.body.layout) settings.theme.layout = { ...settings.theme.layout, ...req.body.layout };
if (req.body.fonts) {
settings.theme.fonts = { ...settings.theme.fonts, ...req.body.fonts };
}
if (req.body.layout) {
settings.theme.layout = { ...settings.theme.layout, ...req.body.layout };
}
settings.lastModifiedBy = req.admin.id; settings.lastModifiedBy = req.admin.id;
await settings.save(); await settings.save();
@@ -158,34 +151,22 @@ router.put('/theme', adminAuth, async (req, res) => {
res.json({ res.json({
success: true, success: true,
message: 'Theme updated successfully', message: 'Theme updated successfully',
data: { theme: settings.theme } data: { theme: settings.theme },
}); });
} catch (error) { } catch (error) {
console.error('Update theme error:', error); console.error('Update theme error:', error);
res.status(500).json({ res.status(500).json({ success: false, message: 'Error updating theme' });
success: false,
message: 'Error updating theme'
});
} }
}); });
// @route PUT /api/settings/maintenance
// @desc Toggle maintenance mode
// @access Private (Admin)
router.put('/maintenance', adminAuth, async (req, res) => { router.put('/maintenance', adminAuth, async (req, res) => {
try { try {
const settings = await SiteSettings.getSiteSettings(); const settings = await SiteSettings.getSiteSettings();
const { enabled, message, allowedIPs } = req.body; const { enabled, message, allowedIPs } = req.body;
if (typeof enabled !== 'undefined') { if (typeof enabled !== 'undefined') settings.maintenance.enabled = enabled;
settings.maintenance.enabled = enabled; if (message) settings.maintenance.message = message;
} if (allowedIPs) settings.maintenance.allowedIPs = allowedIPs;
if (message) {
settings.maintenance.message = message;
}
if (allowedIPs) {
settings.maintenance.allowedIPs = allowedIPs;
}
settings.lastModifiedBy = req.admin.id; settings.lastModifiedBy = req.admin.id;
await settings.save(); await settings.save();
@@ -193,16 +174,12 @@ router.put('/maintenance', adminAuth, async (req, res) => {
res.json({ res.json({
success: true, success: true,
message: 'Maintenance mode updated successfully', message: 'Maintenance mode updated successfully',
data: { maintenance: settings.maintenance } data: { maintenance: settings.maintenance },
}); });
} catch (error) { } catch (error) {
console.error('Update maintenance mode error:', error); console.error('Update maintenance mode error:', error);
res.status(500).json({ res.status(500).json({ success: false, message: 'Error updating maintenance mode' });
success: false,
message: 'Error updating maintenance mode'
});
} }
}); });
module.exports = router; module.exports = router;