✨ Features: - Modern tourism website with responsive design - AdminJS admin panel with image editor integration - PostgreSQL database with comprehensive schema - Docker containerization - Image upload and gallery management 🛠 Tech Stack: - Backend: Node.js + Express.js - Database: PostgreSQL 13+ - Frontend: HTML/CSS/JS with responsive design - Admin: AdminJS with custom components - Deployment: Docker + Docker Compose - Image Processing: Sharp with optimization 📱 Admin Features: - Routes/Tours management (city, mountain, fishing) - Guides profiles with specializations - Articles and blog system - Image editor with upload/gallery/URL options - User management and authentication - Responsive admin interface 🎨 Design: - Korean tourism focused branding - Mobile-first responsive design - Custom CSS with modern aesthetics - Image optimization and gallery - SEO-friendly structure 🔒 Security: - Helmet.js security headers - bcrypt password hashing - Input validation and sanitization - CORS protection - Environment variables
103 lines
3.6 KiB
HTML
103 lines
3.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Тест редактора изображений</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
}
|
|
.test-container {
|
|
border: 1px solid #ddd;
|
|
padding: 20px;
|
|
margin: 20px 0;
|
|
border-radius: 8px;
|
|
}
|
|
.result-image {
|
|
max-width: 300px;
|
|
max-height: 200px;
|
|
border: 1px solid #ddd;
|
|
margin: 10px 0;
|
|
}
|
|
.btn {
|
|
background: #007bff;
|
|
color: white;
|
|
padding: 10px 20px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
margin: 5px;
|
|
}
|
|
.btn:hover {
|
|
background: #0056b3;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Тестирование редактора изображений</h1>
|
|
|
|
<div class="test-container">
|
|
<h3>Тест для туров (routes)</h3>
|
|
<button class="btn" onclick="testImageEditor('routes')">Открыть редактор для туров</button>
|
|
<div id="routes-result"></div>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h3>Тест для гидов (guides)</h3>
|
|
<button class="btn" onclick="testImageEditor('guides')">Открыть редактор для гидов</button>
|
|
<div id="guides-result"></div>
|
|
</div>
|
|
|
|
<div class="test-container">
|
|
<h3>Тест для статей (articles)</h3>
|
|
<button class="btn" onclick="testImageEditor('articles')">Открыть редактор для статей</button>
|
|
<div id="articles-result"></div>
|
|
</div>
|
|
|
|
<!-- Подключаем редактор изображений -->
|
|
<script src="/js/image-editor.js"></script>
|
|
|
|
<script>
|
|
function testImageEditor(targetFolder) {
|
|
if (typeof window.openImageEditor === 'function') {
|
|
window.openImageEditor({
|
|
targetFolder: targetFolder,
|
|
onSave: (url) => {
|
|
console.log('Saved image:', url);
|
|
const resultDiv = document.getElementById(targetFolder + '-result');
|
|
resultDiv.innerHTML = `
|
|
<p>Изображение сохранено: <strong>${url}</strong></p>
|
|
<img src="${url}" alt="Result" class="result-image">
|
|
`;
|
|
}
|
|
}).catch((error) => {
|
|
if (error.message !== 'Canceled') {
|
|
console.error('Editor error:', error);
|
|
alert('Ошибка редактора: ' + error.message);
|
|
}
|
|
});
|
|
} else {
|
|
alert('Редактор изображений не загружен!');
|
|
}
|
|
}
|
|
|
|
// Проверяем доступность API
|
|
async function checkAPI() {
|
|
try {
|
|
const response = await fetch('/api/images/images/routes');
|
|
const result = await response.json();
|
|
console.log('API check:', result);
|
|
} catch (error) {
|
|
console.error('API not available:', error);
|
|
}
|
|
}
|
|
|
|
// Проверяем при загрузке страницы
|
|
checkAPI();
|
|
</script>
|
|
</body>
|
|
</html> |