Files
hotell777_260507/public/js/rooms-public.js
2026-05-11 23:44:01 +05:00

145 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const AMENITY_ICONS = {
has_ac: { icon: 'fa-snowflake', label: 'Кондиционер' },
has_tv: { icon: 'fa-tv', label: 'ТВ' },
has_fridge: { icon: 'fa-sink', label: 'Холодильник' },
has_wifi: { icon: 'fa-wifi', label: 'WiFi' },
has_kettle: { icon: 'fa-mug-hot', label: 'Чайник' },
has_hairdryer: { icon: 'fa-wind', label: 'Фен' },
has_shower: { icon: 'fa-shower', label: 'Душ в номере' },
has_sea_view: { icon: 'fa-water', label: 'Вид на море' }
};
let cachedRooms = [];
async function loadRoomsPublic() {
try {
const res = await fetch('/api/rooms');
if (!res.ok) throw new Error('Failed to load rooms');
cachedRooms = await res.json();
renderRoomsPublic(cachedRooms);
updateRoomPrices(cachedRooms);
} catch (err) {
console.error('Error loading rooms:', err);
document.getElementById('roomsEmpty').style.display = 'block';
}
}
function renderRoomsPublic(rooms) {
const grid = document.getElementById('roomsGrid');
const empty = document.getElementById('roomsEmpty');
if (!rooms || rooms.length === 0) {
grid.innerHTML = '';
empty.style.display = 'block';
return;
}
empty.style.display = 'none';
grid.innerHTML = rooms.map((room, index) => {
const amenities = Array.isArray(room.amenities) ? room.amenities : [];
const floors = Array.isArray(room.floors) ? room.floors : [];
const imageSrc = room.image_path || 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 250"%3E%3Crect fill="%23274151" width="400" height="250"/%3E%3Ctext fill="%2364748b" font-family="sans-serif" font-size="16" x="50%25" y="50%25" text-anchor="middle" dy=".3em"%3EФото%3C/text%3E%3C/svg%3E';
const fullImageSrc = imageSrc.startsWith('uploads') ? '/' + imageSrc : imageSrc;
const amenitiesHtml = amenities.map(a => {
const info = AMENITY_ICONS[a];
if (!info) return '';
return `<span class="room-feature-tag"><i class="fas ${info.icon}"></i> ${info.label}</span>`;
}).join('');
const floorsStr = floors.length > 0 ? 'Этажи ' + floors.join(', ') : '';
const extraBedsHtml = room.extra_beds > 0
? `<div class="room-extra-hint">Возможно +${room.extra_beds} доп. мест (${room.extra_bed_price} ₽)</div>`
: '';
const featuredClass = room.type === 'Семейный' ? ' featured' : '';
return `
<div class="col-lg-4">
<div class="room-card${featuredClass}">
<div class="room-image">
<img src="${fullImageSrc}" alt="${room.name}"
onerror="this.src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 400 250%22%3E%3Crect fill=%22%23274151%22 width=%22400%22 height=%22250%22/%3E%3Ctext fill=%22%2364748b%22 font-family=%22sans-serif%22 font-size=%2216%22 x=%2250%25%22 y=%2250%25%22 text-anchor=%22middle%22 dy=%22.3em%22%3EФото%3C/text%3E%3C/svg%3E'">
<div class="room-category">${room.type}</div>
</div>
<div class="room-body">
<h3 class="room-name">${escapeHtml(room.name)}</h3>
<p class="room-desc">${escapeHtml(room.description || '')}</p>
<div class="room-meta">
<span><i class="fas fa-door-open"></i> ${room.area_sqm || 20} м²</span>
${floorsStr ? `<span><i class="fas fa-layer-group"></i> ${floorsStr}</span>` : ''}
${amenities.includes('has_shower') ? '<span><i class="fas fa-shower"></i> Душ в номере</span>' : ''}
</div>
<div class="room-features">
${amenitiesHtml}
</div>
${extraBedsHtml}
<div class="room-footer">
<div class="room-price">
<span class="amount">от ${room.price_per_night || 0} ₽</span>
<span class="period"> / ночь</span>
</div>
<button class="btn-book" data-bs-toggle="modal" data-bs-target="#bookingModal" data-room-id="${room.id}" data-room-type="${room.type}" data-room-name="${escapeHtml(room.name)}" data-max-guests="${room.max_guests}">Забронировать</button>
</div>
</div>
</div>
</div>
`;
}).join('');
initRoomBookingHandlers();
}
function updateRoomPrices(rooms) {
const prices = {};
const maxGuests = {};
rooms.forEach(room => {
prices[room.type] = room.price_per_night;
maxGuests[room.type] = room.max_guests;
});
if (window.updateRoomPricesData) {
window.updateRoomPricesData(prices, maxGuests);
}
}
function initRoomBookingHandlers() {
document.querySelectorAll('.btn-book').forEach(btn => {
btn.addEventListener('click', function() {
const roomId = this.getAttribute('data-room-id');
const roomType = this.getAttribute('data-room-type');
const roomName = this.getAttribute('data-room-name');
const maxGuests = parseInt(this.getAttribute('data-max-guests')) || 4;
document.getElementById('selectedRoom').value = roomType;
document.getElementById('selectedRoomId').value = roomId;
updateGuestOptionsDynamic(roomType, maxGuests);
hidePriceInfo();
});
});
}
function updateGuestOptionsDynamic(roomType, maxGuests) {
const guestsSelect = document.querySelector('[name="guests"]');
if (!guestsSelect) return;
let options = [];
for (let i = 1; i <= maxGuests; i++) {
let text = i === 1 ? '1 гость' : (i < 5 ? `${i} гостя` : `${i} гостей`);
options.push(`<option value="${i}">${text}</option>`);
}
guestsSelect.innerHTML = options.join('');
}
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
document.addEventListener('DOMContentLoaded', () => {
loadRoomsPublic();
});