145 lines
5.4 KiB
JavaScript
145 lines
5.4 KiB
JavaScript
const data = window.REPORT_DATA;
|
||
const cards = document.querySelector("#cards");
|
||
const rows = document.querySelector("#summaryRows");
|
||
const rate = document.querySelector("#rate");
|
||
const criteria = document.querySelector("#criteria");
|
||
const notes = document.querySelector("#notes");
|
||
const lightbox = document.querySelector("#lightbox");
|
||
const lightboxImage = document.querySelector("#lightboxImage");
|
||
const lightboxSource = document.querySelector("#lightboxSource");
|
||
|
||
rate.textContent = `${data.generated}. ${data.rate}`;
|
||
criteria.textContent = data.criteria;
|
||
notes.innerHTML = data.notes.map((note) => `<li>${note}</li>`).join("");
|
||
|
||
const labelByKind = {
|
||
hotel: "отель",
|
||
review: "отзыв",
|
||
"traveler-video": "видео"
|
||
};
|
||
|
||
function formatRub(value) {
|
||
return new Intl.NumberFormat("ru-RU").format(value);
|
||
}
|
||
|
||
function formatByn(value) {
|
||
return new Intl.NumberFormat("ru-RU").format(value);
|
||
}
|
||
|
||
function renderSummary(filter = "all") {
|
||
const visible = data.hotels.filter((hotel) => filter === "all" || hotel.segment === filter);
|
||
rows.innerHTML = visible.map((hotel) => `
|
||
<tr>
|
||
<td><strong>${hotel.name}</strong><br><span class="badge ${hotel.segment === "8-9" ? "" : "warn"}">${hotel.rank}</span></td>
|
||
<td>${hotel.dates}</td>
|
||
<td>${hotel.nights}</td>
|
||
<td class="price">${formatByn(hotel.price_byn)} BYN<br><span>${formatRub(hotel.price_rub)} RUB</span></td>
|
||
<td>${hotel.transfer}</td>
|
||
<td>${hotel.verdict}</td>
|
||
</tr>
|
||
`).join("");
|
||
}
|
||
|
||
function renderCards(filter = "all") {
|
||
const visible = data.hotels.filter((hotel) => filter === "all" || hotel.segment === filter);
|
||
cards.innerHTML = visible.map((hotel) => `
|
||
<article class="hotel-card" data-segment="${hotel.segment}">
|
||
<div class="gallery" aria-label="Фото ${hotel.name}">
|
||
${hotel.images.map((image, index) => `
|
||
<button class="shot" data-full="${image.file}" data-source="${image.source}" type="button">
|
||
<img src="${image.file}" loading="${index < 2 ? "eager" : "lazy"}" alt="${hotel.name}: ${labelByKind[image.kind] || "фото"}" />
|
||
<span class="tag">${labelByKind[image.kind] || image.kind}</span>
|
||
</button>
|
||
`).join("")}
|
||
</div>
|
||
|
||
<div class="hotel-info">
|
||
<div class="hotel-head">
|
||
<div class="hotel-title">
|
||
<h3>${hotel.name} ${hotel.stars}</h3>
|
||
<p>${hotel.rank}</p>
|
||
</div>
|
||
<div class="hotel-price">
|
||
<strong>${formatByn(hotel.price_byn)} BYN</strong>
|
||
<span>${formatRub(hotel.price_rub)} RUB. ${hotel.alt_price}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="facts">
|
||
<div class="fact"><span>Даты</span><strong>${hotel.dates}</strong></div>
|
||
<div class="fact"><span>Ночи</span><strong>${hotel.nights}</strong></div>
|
||
<div class="fact"><span>Питание</span><strong>${hotel.meal}</strong></div>
|
||
<div class="fact"><span>Трансфер</span><strong>${hotel.transfer}</strong></div>
|
||
<div class="fact"><span>Рейс</span><strong>${hotel.flight}</strong></div>
|
||
<div class="fact"><span>Пляж</span><strong>${hotel.line}, ${hotel.beach}</strong></div>
|
||
<div class="fact"><span>Рейтинг</span><strong>${hotel.rating}</strong></div>
|
||
<div class="fact"><span>Сегмент</span><strong>${hotel.segment === "near-9" ? "рядом с 9" : hotel.segment + " тыс."}</strong></div>
|
||
</div>
|
||
|
||
<p class="verdict">${hotel.verdict}</p>
|
||
|
||
<div class="columns">
|
||
<div>
|
||
<h4>Плюсы</h4>
|
||
<ul class="pros">${hotel.pros.map((item) => `<li>${item}</li>`).join("")}</ul>
|
||
</div>
|
||
<div>
|
||
<h4>Риски</h4>
|
||
<ul class="cons">${hotel.cons.map((item) => `<li>${item}</li>`).join("")}</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="review">
|
||
<h4>По фото и отзывам</h4>
|
||
<p>${hotel.review}</p>
|
||
</div>
|
||
|
||
<div class="links">
|
||
<h4>Источники</h4>
|
||
<a href="${hotel.top_source}" target="_blank" rel="noreferrer">TopHotels media</a>
|
||
<a href="${hotel.trip}" target="_blank" rel="noreferrer">Tripadvisor</a>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
`).join("");
|
||
}
|
||
|
||
function setFilter(filter) {
|
||
document.querySelectorAll(".filter").forEach((button) => {
|
||
button.classList.toggle("active", button.dataset.filter === filter);
|
||
});
|
||
renderSummary(filter);
|
||
renderCards(filter);
|
||
}
|
||
|
||
document.querySelectorAll(".filter").forEach((button) => {
|
||
button.addEventListener("click", () => setFilter(button.dataset.filter));
|
||
});
|
||
|
||
cards.addEventListener("click", (event) => {
|
||
const shot = event.target.closest(".shot");
|
||
if (!shot) return;
|
||
lightboxImage.src = shot.dataset.full;
|
||
lightboxSource.href = shot.dataset.source;
|
||
lightbox.classList.add("open");
|
||
lightbox.setAttribute("aria-hidden", "false");
|
||
document.body.classList.add("lightbox-open");
|
||
});
|
||
|
||
document.querySelector("#closeLightbox").addEventListener("click", closeLightbox);
|
||
lightbox.addEventListener("click", (event) => {
|
||
if (event.target === lightbox) closeLightbox();
|
||
});
|
||
window.addEventListener("keydown", (event) => {
|
||
if (event.key === "Escape") closeLightbox();
|
||
});
|
||
|
||
function closeLightbox() {
|
||
lightbox.classList.remove("open");
|
||
lightbox.setAttribute("aria-hidden", "true");
|
||
document.body.classList.remove("lightbox-open");
|
||
lightboxImage.src = "";
|
||
}
|
||
|
||
setFilter("all");
|