Initial commit: Korea Tourism Agency website with AdminJS

- Full-stack Node.js/Express application with PostgreSQL
- Modern ES modules architecture
- AdminJS admin panel with Sequelize ORM
- Tourism routes, guides, articles, bookings management
- Responsive Bootstrap 5 frontend
- Docker containerization with docker-compose
- Complete database schema with migrations
- Authentication system for admin panel
- Dynamic placeholder images for tour categories
This commit is contained in:
2025-11-29 18:13:17 +09:00
commit 409e6c146b
53 changed files with 16195 additions and 0 deletions

191
views/contact.ejs Normal file
View File

@@ -0,0 +1,191 @@
<!-- Hero Section -->
<section class="hero-section bg-primary text-white text-center py-5">
<div class="container">
<div class="row">
<div class="col-lg-8 mx-auto">
<h1 class="display-4 fw-bold mb-4">Свяжитесь с нами</h1>
<p class="lead">Мы готовы ответить на все ваши вопросы о турах по Корее</p>
</div>
</div>
</div>
</section>
<!-- Contact Form and Info -->
<section class="py-5">
<div class="container">
<div class="row">
<div class="col-lg-8 mb-4">
<div class="card">
<div class="card-body">
<h3 class="card-title mb-4">Напишите нам</h3>
<form id="contactForm">
<div class="row">
<div class="col-md-6 mb-3">
<label for="name" class="form-label">Ваше имя *</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="col-md-6 mb-3">
<label for="email" class="form-label">Email *</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
</div>
<div class="mb-3">
<label for="phone" class="form-label">Телефон</label>
<input type="tel" class="form-control" id="phone" name="phone">
</div>
<div class="mb-3">
<label for="subject" class="form-label">Тема сообщения</label>
<select class="form-select" id="subject" name="subject">
<option value="">Выберите тему...</option>
<option value="booking">Бронирование тура</option>
<option value="info">Информация о турах</option>
<option value="custom">Индивидуальный тур</option>
<option value="feedback">Отзыв</option>
<option value="other">Другое</option>
</select>
</div>
<div class="mb-3">
<label for="message" class="form-label">Сообщение *</label>
<textarea class="form-control" id="message" name="message" rows="5" required></textarea>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-paper-plane me-1"></i>Отправить сообщение
</button>
</form>
</div>
</div>
</div>
<div class="col-lg-4">
<!-- Contact Info -->
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Контактная информация</h5>
<div class="mb-3">
<i class="fas fa-map-marker-alt text-primary me-2"></i>
<strong>Адрес:</strong><br>
<small class="text-muted">Москва, ул. Примерная, д. 123</small>
</div>
<div class="mb-3">
<i class="fas fa-phone text-primary me-2"></i>
<strong>Телефон:</strong><br>
<small class="text-muted">+7 (495) 123-45-67</small>
</div>
<div class="mb-3">
<i class="fas fa-envelope text-primary me-2"></i>
<strong>Email:</strong><br>
<small class="text-muted">info@koreatour.ru</small>
</div>
<div class="mb-3">
<i class="fas fa-clock text-primary me-2"></i>
<strong>Время работы:</strong><br>
<small class="text-muted">Пн-Пт: 9:00-18:00<br>Сб: 10:00-16:00<br>Вс: выходной</small>
</div>
</div>
</div>
<!-- Social Media -->
<div class="card">
<div class="card-body">
<h5 class="card-title">Мы в соцсетях</h5>
<div class="d-flex gap-2">
<a href="#" class="btn btn-outline-primary btn-sm">
<i class="fab fa-facebook-f"></i>
</a>
<a href="#" class="btn btn-outline-primary btn-sm">
<i class="fab fa-instagram"></i>
</a>
<a href="#" class="btn btn-outline-primary btn-sm">
<i class="fab fa-youtube"></i>
</a>
<a href="#" class="btn btn-outline-primary btn-sm">
<i class="fab fa-telegram"></i>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- FAQ Section -->
<section class="bg-light py-5">
<div class="container">
<h2 class="text-center mb-5">Часто задаваемые вопросы</h2>
<div class="row">
<div class="col-lg-8 mx-auto">
<div class="accordion" id="faqAccordion">
<div class="accordion-item">
<h2 class="accordion-header" id="faq1">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse1">
Нужна ли виза для поездки в Корею?
</button>
</h2>
<div id="collapse1" class="accordion-collapse collapse show" data-bs-parent="#faqAccordion">
<div class="accordion-body">
Граждане России могут находиться в Южной Корее без визы до 60 дней для туристических целей. Необходим загранпаспорт, действующий минимум 6 месяцев.
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="faq2">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse2">
Какая валюта используется в Корее?
</button>
</h2>
<div id="collapse2" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
<div class="accordion-body">
В Корее используется корейская вона (KRW или ₩). Обменять деньги можно в банках, обменных пунктах или снять в банкоматах.
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="faq3">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse3">
Включена ли страховка в стоимость тура?
</button>
</h2>
<div id="collapse3" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
<div class="accordion-body">
Да, все наши туры включают базовую туристическую страховку. По желанию можно оформить расширенную страховку.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<script>
document.getElementById('contactForm').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData.entries());
try {
const response = await fetch('/contact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
alert('Спасибо! Ваше сообщение отправлено. Мы свяжемся с вами в ближайшее время.');
e.target.reset();
} else {
alert('Произошла ошибка при отправке сообщения. Попробуйте еще раз.');
}
} catch (error) {
alert('Произошла ошибка при отправке сообщения. Попробуйте еще раз.');
}
});
</script>