feat: Оптимизация навигации AdminJS в логические группы

- Объединены ресурсы в 5 логических групп: Контент сайта, Бронирования, Отзывы и рейтинги, Персонал и гиды, Администрирование
- Удалены дублирующие настройки navigation для чистой группировки
- Добавлены CSS стили для визуального отображения иерархии с отступами
- Добавлены эмодзи-иконки для каждого типа ресурсов через CSS
- Улучшена навигация с правильной вложенностью элементов
This commit is contained in:
2025-11-30 21:57:58 +09:00
parent 1e7d7c06eb
commit 13c752b93a
47 changed files with 14148 additions and 61 deletions

View File

@@ -1,8 +1,18 @@
import express from 'express';
import SiteSettingsHelper from '../helpers/site-settings.js';
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const router = express.Router();
const STYLES_CONFIG_PATH = path.join(__dirname, '../../config/styles.json');
const CUSTOM_CSS_PATH = path.join(__dirname, '../../public/css/custom-styles.css');
/**
* Динамический CSS на основе настроек сайта
*/
@@ -19,6 +29,86 @@ router.get('/dynamic-styles.css', async (req, res) => {
}
});
// Загрузка настроек стилей для продвинутого редактора
router.get('/api/settings/styles', async (req, res) => {
try {
let styles = {};
try {
const data = await fs.readFile(STYLES_CONFIG_PATH, 'utf8');
styles = JSON.parse(data);
} catch (error) {
// Файл не существует, создаем дефолтные настройки
styles = {
'primary-color': '#ff6b6b',
'secondary-color': '#38C172',
'background-color': '#f8f9fa',
'text-color': '#333333',
'primary-font': "'Inter', sans-serif",
'base-font-size': '16px',
'line-height': '1.6',
'max-width': '1200px',
'section-padding': '60px',
'border-radius': '8px',
'transition-speed': '0.3s',
'hover-effect': 'lift'
};
}
res.json({ success: true, styles });
} catch (error) {
console.error('Ошибка загрузки стилей:', error);
res.status(500).json({ success: false, error: 'Ошибка загрузки стилей' });
}
});
// Сохранение настроек стилей
router.post('/api/settings/styles', async (req, res) => {
try {
const { styles, css } = req.body;
if (!styles || !css) {
return res.status(400).json({ success: false, error: 'Отсутствуют данные стилей' });
}
// Создаем директории если не существуют
await fs.mkdir(path.dirname(STYLES_CONFIG_PATH), { recursive: true });
await fs.mkdir(path.dirname(CUSTOM_CSS_PATH), { recursive: true });
// Сохраняем конфигурацию стилей
await fs.writeFile(STYLES_CONFIG_PATH, JSON.stringify(styles, null, 2));
// Сохраняем CSS файл
const cssContent = `/* Автоматически сгенерированные стили - ${new Date().toISOString()} */\n\n${css}`;
await fs.writeFile(CUSTOM_CSS_PATH, cssContent);
res.json({ success: true, message: 'Стили успешно сохранены' });
} catch (error) {
console.error('Ошибка сохранения стилей:', error);
res.status(500).json({ success: false, error: 'Ошибка сохранения стилей' });
}
});
// Получение текущего CSS
router.get('/api/settings/styles/css', async (req, res) => {
try {
let css = '';
try {
css = await fs.readFile(CUSTOM_CSS_PATH, 'utf8');
} catch (error) {
// Файл не существует, возвращаем пустой CSS
css = '/* Пользовательские стили не найдены */';
}
res.setHeader('Content-Type', 'text/css');
res.send(css);
} catch (error) {
console.error('Ошибка загрузки CSS:', error);
res.status(500).send('/* Ошибка загрузки стилей */');
}
});
/**
* API для получения настроек сайта
*/