🎨 Добавлен полный редактор стилей и поле image_url для туров

 Новые функции:
- Поле image_url в модели туров для изменения изображений через админ-панель
- Расширенная модель настроек сайта с категориями: colors, typography, images, effects, layout
- Динамический CSS генератор на основе настроек (/dynamic-styles.css)
- API для управления настройками сайта (/api/site-settings)

🎯 Редактор стилей:
- Управление цветами (основные, акцентные, текст, фон)
- Настройка типографики (шрифты, размеры, межстрочный интервал)
- Управление изображениями (фоны, логотипы, фавикон)
- Эффекты (прозрачность, тени, размытие, скругления)
- Макет (высота секций, размеры контейнеров)
- Пользовательский CSS код

🛠️ Техническая реализация:
- SiteSettingsHelper с кешированием для производительности
- CSS переменные для динамического изменения стилей
- Автоматическая миграция базы данных
- Интеграция с AdminJS для удобного управления
- Загрузка настроек в шаблоны для доступности

📊 База данных:
- Расширена таблица site_settings (добавлено поле category)
- Новые типы настроек: color, file
- 27 предустановленных настроек для полного контроля над дизайном
- Автоматическое применение миграций при старте приложения
This commit is contained in:
2025-11-29 22:03:00 +09:00
parent a461fea9d9
commit ed871fc4d1
8 changed files with 528 additions and 28 deletions

View File

@@ -7,6 +7,7 @@ import compression from 'compression';
import morgan from 'morgan';
import methodOverride from 'method-override';
import formatters from './helpers/formatters.js';
import SiteSettingsHelper from './helpers/site-settings.js';
import { adminJs, router as adminRouter } from './config/adminjs-simple.js';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
@@ -76,8 +77,8 @@ app.use(session({
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '../views'));
// Global template variables
app.use((req, res, next) => {
// Global template variables with site settings
app.use(async (req, res, next) => {
res.locals.siteName = process.env.SITE_NAME || 'Корея Тур Агентство';
res.locals.siteDescription = process.env.SITE_DESCRIPTION || 'Откройте для себя красоту Кореи';
res.locals.user = req.session.user || null;
@@ -85,6 +86,14 @@ app.use((req, res, next) => {
res.locals.currentPath = req.path;
res.locals.page = 'home'; // default page
// Load site settings for templates
try {
res.locals.siteSettings = await SiteSettingsHelper.getAllSettings();
} catch (error) {
console.error('Error loading site settings for templates:', error);
res.locals.siteSettings = {};
}
// Add all helper functions to template globals
Object.assign(res.locals, formatters);
@@ -148,6 +157,7 @@ const toursRouter = (await import('./routes/tours.js')).default;
const guidesRouter = (await import('./routes/guides.js')).default;
const articlesRouter = (await import('./routes/articles.js')).default;
const apiRouter = (await import('./routes/api.js')).default;
const settingsRouter = (await import('./routes/settings.js')).default;
const ratingsRouter = (await import('./routes/ratings.js')).default;
app.use('/', indexRouter);
@@ -156,6 +166,7 @@ app.use('/guides', guidesRouter);
app.use('/articles', articlesRouter);
app.use('/api', apiRouter);
app.use('/api', ratingsRouter);
app.use('/', settingsRouter); // Settings routes (CSS and API)
// Health check endpoint
app.get('/health', (req, res) => {