1document.addEventListener("DOMContentLoaded", function () { 2const utils = { 3lockScroll: () => (document.body.style.overflow = "hidden"),unlockScroll: () => (document.body.style.overflow = ""), 4findTextNode: (element) => 5Array.from(element.childNodes).find( 6(node) => node.nodeType === Node.TEXT_NODE && node.textContent.trim(),), 7parseNumber: (str) => { 8const cleaned = str.replace(/\s/g, "").replace(",", "."); 9const number = parseFloat(cleaned); 10return isNaN(number) ? 0 : number;},formatPrice: (price) => { 11return new Intl.NumberFormat("ru-RU").format(price);},};const cookieUtils = { 12set: function (name, value, days){let expires = ""; 13if(days){const date = new Date(); 14date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); 15expires = "; expires=" + date.toUTCString();} 16document.cookie = name + "=" + (value || "") + expires + "; path=/"; 17},get: function (name){const nameEQ = name + "="; 18const ca = document.cookie.split(";"); 19for (let i = 0; i < ca.length; i++){let c = ca[i]; 20while (c.charAt(0) === " ") c = c.substring(1, c.length); 21if(c.indexOf(nameEQ) === 0) 22return c.substring(nameEQ.length, c.length);} 23return null;},remove: function (name){document.cookie = name + "=; Max-Age=-99999999; path=/"; 24},};function safeJQuery(callback){if(typeof jQuery !== "undefined") { 25callback(jQuery);}else{console.warn("jQuery не доÑÑÑпен, пÑопÑÑкаем вÑполнение");} 26} 27function updateBasketCounter(basketData){if(!basketData) return; 28const cartSpan = document.querySelector(".top_header_cart span"); 29if(cartSpan){cartSpan.textContent = " â " + (basketData.total_quantity || 0);} 30// У Ð½Ð°Ñ Ð½ÐµÑ items в basketData, поÑÑÐ¾Ð¼Ñ Ð´ÐµÐ»Ð°ÐµÐ¼ оÑделÑнÑй запÑÐ¾Ñ 31loadBasketState(); 32if(typeof BX !== "undefined"){BX.onCustomEvent("OnBasketChange");} 33} 34function updateFavoritesLine(){fetch("/ajax/get_favorites.php") 35.then((response) => response.json()) 36.then((data) => { 37if(data.success){const favSpan = document.querySelector(".favor-list-wrap span"); 38if(favSpan){favSpan.textContent = " â " + (data.count || 0);} 39safeJQuery(function ($){$.ajax("?AJAX_CALL_FAVORITES_LINE=Y", { 40type: "POST",success: function (data){var obj = $("<div />").html(data); 41$(".favor-list-wrap").html(obj.find(".favor-list-wrap").html());},dataType: "html", 42});}); 43} 44});} 45const modals = [ 46{ 47buttons: ".product-card__btn, .product-detail__btn-basket",modal: ".pp-modal-basket", 48close: ".pp-modal-basket__btn-close, .pp-modal-basket__btn",onOpen: function (btn, modal){fillBasketModal(btn, modal);}, 49addToCart: true,checkInBasket: true, 50},{ 51buttons: ".product-detail__buy-one-click",modal: ".pp-quick-order", 52close: ".pp-quick-order__btn-close",onOpen: function (btn, modal){fillQuickOrderModal(btn, modal);}, 53addToCart: false,}, 54]; 55modals.forEach( 56({ 57buttons: btnSel,modal: modalSel, 58close: closeSel,onOpen, 59addToCart,}) => { 60const modal = document.querySelector(modalSel); 61if(!modal) return; 62const openButtons = document.querySelectorAll(btnSel); 63openButtons.forEach((btn) => { 64const newBtn = btn.cloneNode(true); 65btn.parentNode.replaceChild(newBtn, btn); 66newBtn.addEventListener("click", (e) => { 67e.preventDefault(); 68const productId = newBtn.dataset.id; 69if(!productId){console.error("ID ÑоваÑа не найден"); 70return;} 71if(newBtn.classList.contains("in-basket")){window.location.href = "/personal/cart/"; 72return;} 73const originalText = newBtn.innerHTML; 74if(onOpen){onOpen(newBtn, modal);} 75if(addToCart){newBtn.classList.add("loading"); 76const textSpan = newBtn.querySelector( 77".product-card__btn-text, .product-detail__btn-basket-text",); 78if(textSpan){textSpan.textContent = "Ðобавление...";} 79let quantity = 1; 80if(document.querySelector(".product-detail__counter-input")){quantity = getCurrentQuantity();} 81fetch("/ajax/addToBasket.php", { 82method: "POST",headers: { 83"Content-Type": "application/x-www-form-urlencoded", 84},body: "product_id=" + productId + "&quantity=" + quantity, 85}) 86.then((response) => response.json()) 87.then((data) => { 88if(data.success){if(typeof updateBasketCounter === "function") { 89updateBasketCounter(data.basket);} 90updateButtonToInBasket(newBtn); 91modal.classList.add("open"); 92utils.lockScroll(); 93newBtn.classList.remove("loading");}else{console.error("ÐÑибка:", data.error); 94alert( 95"ÐÑибка пÑи добавлении ÑоваÑа: " + 96(data.error || "ÐеизвеÑÑÐ½Ð°Ñ Ð¾Ñибка"),); 97newBtn.classList.remove("loading"); 98newBtn.innerHTML = originalText;} 99}) 100.catch((error) => { 101console.error("ÐÑибка запÑоÑа:", error); 102alert("ÐÑибка пÑи добавлении ÑоваÑа"); 103newBtn.classList.remove("loading"); 104newBtn.innerHTML = originalText;});}else{modal.classList.add("open"); 105utils.lockScroll();} 106});}); 107const closeButtons = closeSel ? modal.querySelectorAll(closeSel) : []; 108closeButtons.forEach((btn) => { 109btn.addEventListener("click", () => { 110modal.classList.remove("open"); 111utils.unlockScroll();}); 112}); 113modal.addEventListener("click", (e) => { 114if(e.target === modal){modal.classList.remove("open"); 115utils.unlockScroll();} 116});},); 117function fillBasketModal(btn, modal){if(!modal) return; 118let productName = "ТоваÑ"; 119let productPrice = "0 â½"; 120let productId = btn.dataset.id; 121const isDetailPage =
122document.querySelector(".product-detail__counter-input") !== null; 123const currentQty = isDetailPage ? getCurrentQuantity() : 1; 124const productCard = btn.closest('[data-entity="item"], .product-card'); 125if(productCard){const titleEl = productCard.querySelector(".product-card__title"); 126const priceEl = productCard.querySelector(".product-card__price"); 127if(titleEl) productName = titleEl.textContent || productName; 128if(priceEl) productPrice = priceEl.textContent?.trim() || productPrice;}else{const titleEl = document.querySelector(".product-detail__info-title"); 129const priceEl = document.querySelector(".product-detail__info-price"); 130if(titleEl) productName = titleEl.textContent || productName; 131if(priceEl) productPrice = priceEl.textContent?.trim() || productPrice;} 132const priceNumber = utils.parseNumber(productPrice); 133const totalPrice = priceNumber * currentQty; 134const titleElement = modal.querySelector(".js-modal-product-title"); 135if(titleElement) titleElement.textContent = productName; 136const priceElement = modal.querySelector(".js-modal-product-price"); 137if(priceElement) priceElement.textContent = productPrice; 138const priceMobileElement = modal.querySelector( 139".js-modal-product-price-mobile",); 140if(priceMobileElement) 141priceMobileElement.textContent = productPrice + "/ÑÑ."; 142const totalElement = modal.querySelector(".js-modal-product-total"); 143if(totalElement) 144totalElement.textContent = utils.formatPrice(totalPrice) + " â½"; 145const quantityElement = modal.querySelector(".js-modal-product-quantity"); 146if(quantityElement) quantityElement.textContent = currentQty;} 147function fillQuickOrderModal(btn, modal){if(!modal) return; 148const isDetailPage = 149document.querySelector(".product-detail__counter-input") !== null; 150const productName = 151document.querySelector(".product-detail__info-title")?.textContent || 152btn.closest(".product-card")?.querySelector(".product-card__title") 153?.textContent || 154"ТоваÑ"; 155const productPrice = 156document 157.querySelector(".product-detail__info-price") 158?.textContent?.trim() || 159btn 160.closest(".product-card") 161?.querySelector(".product-card__price") 162?.textContent?.trim() || 163"0 â½"; 164const priceNumber = utils.parseNumber(productPrice); 165const productId = btn.dataset.id; 166const productUrl = window.location.href; 167const currentQty = isDetailPage ? getCurrentQuantity() : 1; 168const totalPrice = priceNumber * currentQty; 169const titleElement = modal.querySelector(".js-quick-product-title"); 170if(titleElement) titleElement.textContent = productName; 171const priceElement = modal.querySelector(".js-quick-product-price"); 172if(priceElement) 173priceElement.textContent = utils.formatPrice(priceNumber) + " â½"; 174const priceMobileElement = modal.querySelector( 175".js-quick-product-price-mobile",); 176if(priceMobileElement){priceMobileElement.textContent = 177utils.formatPrice(priceNumber) + " â½/ÑÑ."; 178} 179const totalElement = modal.querySelector(".js-quick-product-total"); 180if(totalElement) totalElement.textContent = utils.formatPrice(totalPrice); 181const quantityElement = modal.querySelector(".js-quick-product-quantity"); 182if(quantityElement) quantityElement.textContent = currentQty; 183const commentInput = modal.querySelector(".js-quick-product-comment"); 184if(commentInput){commentInput.value = 185productUrl + (isDetailPage ? " | ÐолиÑеÑÑво: " + currentQty + " ÑÑ." : "");} 186modal.dataset.productId = productId; 187modal.dataset.productPrice = priceNumber; 188modal.dataset.productName = productName; 189modal.dataset.productQuantity = currentQty; 190modal.dataset.productUrl = productUrl;} 191function initQuickOrderForm(){const quickForm = document.querySelector(".pp-quick-order__form"); 192if(!quickForm){console.log("ФоÑма бÑÑÑÑого заказа не найдена"); 193return;} 194const submitBtn = quickForm.querySelector( 195".js-quick-order-submit, .pp-quick-order__form-btn-submit",); 196if(!submitBtn){console.log("Ðнопка оÑпÑавки не найдена"); 197return;} 198const newSubmitBtn = submitBtn.cloneNode(true); 199submitBtn.parentNode.replaceChild(newSubmitBtn, submitBtn); 200newSubmitBtn.addEventListener("click", function (e){e.preventDefault(); 201const modalElement = this.closest(".pp-quick-order"); 202const formBlock = modalElement.querySelector( 203".pp-quick-order__form-block",); 204const successBlock = modalElement.querySelector( 205".pp-quick-order__success-block",); 206const nameInput = quickForm.querySelector('input[name="fio"]'); 207const phoneInput = quickForm.querySelector('input[name="phone"]'); 208const commentInput = quickForm.querySelector('input[name="comment"]'); 209const agreeCheckbox = quickForm.querySelector('input[name="agree"]'); 210if(!nameInput){console.error("Ðоле fio не найдено"); 211alert("ÐÑибка: поле имени не найдено"); 212return;} 213if(!phoneInput){console.error("Ðоле phone не найдено"); 214alert("ÐÑибка: поле ÑелеÑона не найдено"); 215return;} 216if(!nameInput.value.trim()){alert("ÐведиÑе имÑ"); 217nameInput.focus(); 218return;} 219const phone = phoneInput.value.replace(/\D/g, "") || ""; 220if(phone.length < 11){alert("ÐведиÑе коÑÑекÑнÑй Ð½Ð¾Ð¼ÐµÑ ÑелеÑона"); 221phoneInput.focus(); 222return;} 223if(agreeCheckbox && !agreeCheckbox.checked){alert("ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ ÑоглаÑие на обÑабоÑÐºÑ Ð´Ð°Ð½Ð½ÑÑ "); 224agreeCheckbox.focus(); 225return;} 226const formData = new URLSearchParams(); 227formData.append("fio", nameInput.value.trim()); 228formData.append("phone", phoneInput.value); 229formData.append("comment", commentInput?.value || window.location.href); 230formData.append("source", "ÐÑÑÑÑÐ°Ñ Ð¿Ð¾ÐºÑпка"); 231const quickOrderModal = document.querySelector(".pp-quick-order"); 232formData.append("page_url", quickOrderModal?.dataset.productUrl || window.location.href); 233if(quickOrderModal && quickOrderModal.dataset.productQuantity){formData.append("quantity", quickOrderModal.dataset.productQuantity);} 234const originalText = this.textContent; 235this.disabled = true; 236this.textContent = "ÐÑпÑавка..."; 237fetch("/ajax/quick_order.php", { 238method: "POST",headers: { 239"Content-Type": "application/x-www-form-urlencoded", 240},body: formData.toString(), 241}) 242.then((response) => response.text()) 243.then((data) => { 244if( 245data.indexOf("success-form") !== -1 || 246data.indexOf("ÑÑпеÑно оÑпÑавлена") !== -1 247){if(formBlock) formBlock.style.display = "none"; 248if(successBlock) successBlock.style.display = "block";}else{alert("ÐÑибка пÑи оÑпÑавке: " + data);} 249}) 250.catch((error) => { 251console.error("ÐÑибка:", error); 252alert("ÐÑоизоÑла оÑибка пÑи оÑпÑавке. ÐопÑобÑйÑе позже.");}) 253.finally(() => { 254this.disabled = false;
255this.textContent = originalText;}); 256}); 257const quickOrderModal = document.querySelector(".pp-quick-order"); 258if(quickOrderModal){const continueBtn = quickOrderModal.querySelector( 259".pp-quick-order__success-btn",); 260if(continueBtn){continueBtn.addEventListener("click", function () { 261quickOrderModal.classList.remove("open"); 262utils.unlockScroll(); 263setTimeout(() => { 264const formBlock = quickOrderModal.querySelector( 265".pp-quick-order__form-block",); 266const successBlock = quickOrderModal.querySelector( 267".pp-quick-order__success-block",); 268if(formBlock) formBlock.style.display = "block"; 269if(successBlock) successBlock.style.display = "none"; 270quickForm.reset(); 271if(agreeCheckbox) agreeCheckbox.checked = true;}, 300); 272});} 273} 274} 275initQuickOrderForm(); 276const goToCartBtn = document.querySelector( 277".pp-modal-basket__btn-basket, .js-go-to-cart",); 278if(goToCartBtn){goToCartBtn.addEventListener("click", function () { 279window.location.href = "/personal/cart/"; 280});} 281document 282.querySelectorAll(".pp-modal-basket__btn, .js-close-modal") 283.forEach((btn) => { 284btn.addEventListener("click", function (){const modal = this.closest(".pp-modal-section"); 285if(modal){modal.classList.remove("open"); 286utils.unlockScroll();} 287});}); 288const thumbsEl = document.querySelector(".product-detail__slider-thumbs"); 289if(thumbsEl && typeof Swiper !== "undefined"){const thumbsSwiper = new Swiper(thumbsEl, { 290spaceBetween: 0,slidesPerView: "auto", 291freeMode: true,updateOnWindowResize: true, 292speed: 500,}); 293const mainSliderEl = document.querySelector(".product-detail__slider"); 294if(mainSliderEl){new Swiper(mainSliderEl, { 295spaceBetween: 10,slidesPerView: 1, 296thumbs: { swiper: thumbsSwiper },});} 297} 298const reviewsSlider = document.querySelector( 299".product-detail__reviews-slider",); 300if(reviewsSlider && typeof Swiper !== "undefined"){new Swiper(reviewsSlider, { 301slidesPerView: 3,spaceBetween: 16, 302speed: 600,grabCursor: true, 303loop: reviewsSlider.querySelectorAll('.swiper-slide').length > 3,navigation: { 304nextEl: ".reviews-btn-next",prevEl: ".reviews-btn-prev", 305},breakpoints: { 3060: { slidesPerView: 1, spaceBetween: 10 },768: { slidesPerView: 2, spaceBetween: 16 }, 307992: { slidesPerView: 2.5, spaceBetween: 16 },1340: { slidesPerView: 3, spaceBetween: 16 }, 308},});} 309const ppReviewsSlider = document.querySelector(".pp-modal-review__slider"); 310if(ppReviewsSlider && typeof Swiper !== "undefined"){new Swiper(ppReviewsSlider, { 311slidesPerView: 1,spaceBetween: 10, 312speed: 600,loop: ppReviewsSlider.querySelectorAll('.swiper-slide').length > 1, 313grabCursor: true,navigation: { 314nextEl: ".pp-modal-review__slider-btn-next",prevEl: ".pp-modal-review__slider-btn-prev", 315},});} 316if(typeof Fancybox !== "undefined"){Fancybox.bind("[data-fancybox='product-gallery']", { 317caption: (fancybox, slide) => 318slide.triggerEl?.getAttribute("data-caption") || "",});} 319const copyContainer = document.querySelector(".product-detail__info-sku"); 320if(copyContainer){const textElem = copyContainer.querySelector( 321".product-detail__info-sku-text",); 322const iconElem = copyContainer.querySelector( 323".product-detail__info-sku-icon",); 324if(textElem){const originalFullText = textElem.textContent; 325let isCopying = false; 326copyContainer.addEventListener("click", async () => { 327if(isCopying) return; 328const skuToCopy = textElem.textContent 329.replace(/ÐÑÑикÑл:\s*/i, "") 330.trim(); 331try { 332await navigator.clipboard.writeText(skuToCopy); 333isCopying = true; 334copyContainer.classList.add("is-copied"); 335textElem.textContent = "СкопиÑовано!"; 336setTimeout(() => { 337textElem.textContent = originalFullText; 338copyContainer.classList.remove("is-copied"); 339isCopying = false;}, 2000); 340} catch (err){console.error("ÐÑибка пÑи копиÑовании:", err);} 341});} 342} 343document.querySelectorAll(".review-card__block").forEach((block) => { 344const pics = block.querySelectorAll(".review-card__pic"); 345if(pics.length <= 3) return; 346pics.forEach((pic, i) => { 347if(i >= 3) pic.style.display = "none";}); 348const indicator = document.createElement("div"); 349indicator.className = "review-card__more-indicator"; 350indicator.innerHTML = `<span>+${pics.length - 3}</span>`; 351block.appendChild(indicator);}); 352document.addEventListener("click", (e) => { 353const cardBtn = e.target.closest(".product-card__btn-fav"); 354if(cardBtn){e.preventDefault(); 355handleFavoriteClick(cardBtn); 356return;} 357const detailBtn = e.target.closest(".product-detail__info-fav-btn"); 358if(detailBtn){e.preventDefault(); 359handleFavoriteClick(detailBtn); 360return;} 361}); 362function handleFavoriteClick(btn){const productId = btn.dataset.id; 363if(!productId){console.error("ID ÑоваÑа не найден"); 364return;} 365const isActive = btn.classList.contains("active"); 366const action = isActive ? "remove" : "add"; 367fetch("/ajax/favorite_handler.php", { 368method: "POST",headers: { 369"Content-Type": "application/x-www-form-urlencoded", 370},body: "product_id=" + productId + "&action=" + action, 371}) 372.then((response) => response.json()) 373.then((data) => { 374if(data.success){btn.classList.toggle("active"); 375if(btn.classList.contains("product-detail__info-fav-btn")){const textSpan = btn.querySelector( 376".product-detail__info-benefit-text",); 377if(textSpan){textSpan.textContent = btn.classList.contains("active") 378? "РизбÑанном" 379: "РизбÑанное";} 380} 381updateFavoritesLine();} else if(data.error === "ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð° авÑоÑизаÑиÑ"){alert("ÐÐ»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² избÑанное Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ авÑоÑизоваÑÑÑÑ"); 382window.location.href = "/auth/"; 383} else { 384console.error("ÐÑибка:", data.error); 385alert("ÐÑибка: " + data.error);} 386}) 387.catch((error) => { 388console.error("ÐÑибка запÑоÑа:", error);}); 389} 390function loadFavoritesStatus(){fetch("/ajax/get_favorites.php") 391.then((response) => response.json()) 392.then((data) => { 393if(data.success && data.favorites){const favoritesIds = data.favorites.map((id) => parseInt(id)); 394document.querySelectorAll(".product-card__btn-fav").forEach((btn) => { 395const productId = parseInt(btn.dataset.id); 396if(favoritesIds.includes(productId)){btn.classList.add("active");} 397}); 398document 399.querySelectorAll(".product-detail__info-fav-btn") 400.forEach((btn) => { 401const productId = parseInt(btn.dataset.id); 402if(favoritesIds.includes(productId)){btn.classList.add("active"); 403const textSpan = btn.querySelector( 404".product-detail__info-benefit-text",); 405if(textSpan){textSpan.textContent = "РизбÑанном";}}else{btn.classList.remove("active"); 406const textSpan = btn.querySelector( 407".product-detail__info-benefit-text",); 408if(textSpan){textSpan.textContent = "РизбÑанное";} 409} 410}); 411const favSpan = document.querySelector(".favor-list-wrap span"); 412if(favSpan && data.count !== undefined){favSpan.textContent = " â " + data.count;} 413} 414}) 415.catch((error) => console.error("ÐÑибка загÑÑзки избÑанного:", error));} 416loadFavoritesStatus(); 417const navLinks = document.querySelectorAll(".product-detail__nav-link"); 418if(navLinks.length){const menuItems = Array.from(navLinks) 419.map((link) => ({ 420link,section: document.querySelector(link.getAttribute("href")), 421})) 422.filter((item) => item.section); 423const getOffsetTop = (el) => { 424let top = 0; 425while (el){top += el.offsetTop; 426el = el.offsetParent;} 427return top;};const updateActiveNav = () => { 428const scrollPos = window.scrollY + 180; 429let activeItem = menuItems[0];
430menuItems.forEach((item) => { 431if(scrollPos >= getOffsetTop(item.section)) activeItem = item;}); 432const isBottom = 433window.innerHeight + window.scrollY >= 434document.documentElement.scrollHeight - 50; 435if(isBottom) activeItem = menuItems[menuItems.length - 1]; 436menuItems.forEach((item) => { 437item.link.classList.toggle("active", item === activeItem);}); 438};let ticking = false; 439window.addEventListener("scroll", () => { 440if(!ticking){requestAnimationFrame(() => { 441updateActiveNav(); 442ticking = false;}); 443ticking = true;} 444}); 445setTimeout(updateActiveNav, 100); 446navLinks.forEach((link) => { 447link.addEventListener("click", (e) => { 448const targetId = link.getAttribute("href"); 449if(!targetId?.startsWith("#")) return; 450const target = document.querySelector(targetId); 451if(target){e.preventDefault(); 452window.scrollTo({ 453top: getOffsetTop(target) - 150,behavior: "smooth", 454});} 455});}); 456} 457function initPriceCalculator(){const priceEl = document.querySelector(".product-detail__info-price"); 458const qtyInput = document.querySelector(".product-detail__counter-input"); 459const totalEl = document.querySelector(".product-detail__total-price"); 460const minusBtn = document.querySelector( 461".product-detail__counter-btn--minus",); 462const plusBtn = document.querySelector( 463".product-detail__counter-btn--plus",); 464if(!priceEl || !qtyInput || !totalEl) return; 465const pricePerUnit = utils.parseNumber(priceEl.textContent); 466if(pricePerUnit === 0) return; 467function updateTotal(){let qty = parseInt(qtyInput.value) || 1; 468if(qty < 1) qty = 1; 469qtyInput.value = qty; 470const total = qty * pricePerUnit; 471totalEl.textContent = `на ÑÑÐ¼Ð¼Ñ ${total.toLocaleString("ru-RU", { 472minimumFractionDigits: 2,maximumFractionDigits: 2, 473})} â½`;} 474if(minusBtn){const newMinusBtn = minusBtn.cloneNode(true); 475minusBtn.parentNode.replaceChild(newMinusBtn, minusBtn); 476newMinusBtn.addEventListener("click", function (e){e.preventDefault(); 477let qty = parseInt(qtyInput.value) || 1; 478if(qty > 1){qtyInput.value = qty - 1; 479updateTotal(); 480if(typeof BX !== "undefined"){BX.onCustomEvent("onQuantityChange", [{ quantity: qty - 1 }]);} 481} 482});} 483if(plusBtn){const newPlusBtn = plusBtn.cloneNode(true); 484plusBtn.parentNode.replaceChild(newPlusBtn, plusBtn); 485newPlusBtn.addEventListener("click", function (e){e.preventDefault(); 486let qty = parseInt(qtyInput.value) || 1; 487qtyInput.value = qty + 1; 488updateTotal(); 489if(typeof BX !== "undefined"){BX.onCustomEvent("onQuantityChange", [{ quantity: qty + 1 }]);} 490});} 491qtyInput.addEventListener("input", function (e){this.value = this.value.replace(/[^\d]/g, ""); 492if(this.value === "" || this.value === "0"){this.value = "1";} 493updateTotal();}); 494qtyInput.addEventListener("blur", function (){if(!this.value || parseInt(this.value) < 1) { 495this.value = "1";} 496updateTotal();}); 497updateTotal();} 498if(document.readyState === "loading"){document.addEventListener("DOMContentLoaded", initPriceCalculator);}else{initPriceCalculator();} 499const quickForm = document.querySelector(".pp-quick-order__form"); 500if(quickForm){const formRules = { 501phone: { 502validate: (v) => 503/^[\d\s+()-]+$/.test(v) && v.replace(/\D/g, "").length >= 11, 504msg: "ÐведиÑе коÑÑекÑнÑй номеÑ",}, 505name: { validate: (v) => v.trim().length >= 2, msg: "ÐведиÑе имÑ" },agree: { validate: (c) => c, msg: "ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ ÑоглаÑие" }, 506};const addError = (field, msg) => { 507const errorDiv = document.createElement("div"); 508errorDiv.className = "form-error-msg"; 509errorDiv.textContent = msg; 510errorDiv.style.display = "none"; 511field.parentNode.insertBefore(errorDiv, field.nextSibling);};["name", "phone"].forEach((name) => { 512const field = quickForm.querySelector(`[name="${name}"]`); 513if(field && !field.parentNode.querySelector(".form-error-msg")){addError(field, formRules[name].msg);} 514}); 515const agree = quickForm.querySelector('[name="agree"]'); 516if(agree){const container = 517agree.closest(".pp-quick-order__form-checkbox") || agree.parentNode; 518if(!container.parentNode.querySelector(".form-error-msg")){const error = document.createElement("div"); 519error.className = "form-error-msg"; 520error.textContent = "ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ ÑоглаÑие"; 521error.style.display = "none"; 522container.parentNode.insertBefore(error, container.nextSibling);} 523} 524const validateField = (field) => { 525const rule = formRules[field.name]; 526if(!rule) return true; 527const isValid = !field.required 528? true 529: rule.validate( 530field.type === "checkbox" ? field.checked : field.value,); 531const error = 532field.type === "checkbox" 533? ( 534field.closest(".pp-quick-order__form-checkbox") || 535field.parentNode 536).parentNode.querySelector(".form-error-msg") 537: field.parentNode.querySelector(".form-error-msg"); 538if(error){error.style.display = isValid ? "none" : "block"; 539field.classList.toggle("error", !isValid);} 540return isValid;};quickForm.querySelectorAll("input, select, textarea").forEach((field) => { 541if(field.type === "submit" || field.type === "hidden") return; 542field.addEventListener("blur", () => validateField(field)); 543field.addEventListener( 544"input",() => field.classList.contains("error") && validateField(field),
545);}); 546quickForm 547.querySelector('.feedback-btn[type="button"]') 548?.addEventListener("click", function (){const isValid = [ 549...quickForm.querySelectorAll("input, select, textarea"),] 550.filter((f) => f.type !== "submit" && f.type !== "hidden") 551.every((f) => validateField(f)); 552if(isValid) console.log("ФоÑма валидна");}); 553quickForm 554.querySelectorAll(".pp-quick-order__form-input") 555.forEach((input) => { 556const original = input.placeholder; 557input.addEventListener("focus", function (){this.placeholder = ""; 558this.classList.add("focused");}); 559input.addEventListener("blur", function (){if(!this.value) { 560this.placeholder = original; 561this.classList.remove("focused");} 562});}); 563} 564function initPhoneMasks(){const phoneInputs = document.querySelectorAll( 565'input[name="phone"], .form_phone',); 566phoneInputs.forEach((input) => { 567const newInput = input.cloneNode(true); 568input.parentNode.replaceChild(newInput, input); 569newInput.addEventListener("input", function (e){let numbers = e.target.value.replace(/\D/g, ""); 570if(numbers.startsWith("7") || numbers.startsWith("8")){numbers = numbers.substring(1);} 571numbers = numbers.substring(0, 10); 572let result = "+7"; 573if(numbers.length > 0) result += ` (${numbers.substring(0, 3)}`; 574if(numbers.length > 3) result += `) ${numbers.substring(3, 6)}`; 575if(numbers.length > 6) result += `-${numbers.substring(6, 8)}`; 576if(numbers.length > 8) result += `-${numbers.substring(8, 10)}`; 577e.target.value = result;}); 578newInput.addEventListener("keydown", function (e){const allowedKeys = [ 579"Backspace","Delete", 580"Tab","ArrowLeft", 581"ArrowRight",]; 582if(!/\d/.test(e.key) && !allowedKeys.includes(e.key)) { 583e.preventDefault();} 584});}); 585} 586if(document.readyState === "loading"){document.addEventListener("DOMContentLoaded", initPhoneMasks);}else{initPhoneMasks();} 587document.addEventListener("click", function (e){if(e.target.closest(".product-detail__buy-one-click")) { 588setTimeout(initPhoneMasks, 100);} 589}); 590// window.updateLike = function (reviewId, type, button) { 591// method: "POST", 592// "Content-Type": "application/x-www-form-urlencoded", 593// body: 594// reviewId + 595// type + 596// (isActive ? "0" : "1"), 597// .then((response) => response.json()) 598// if(data.success) { 599// if(counter) { 600// } 601// if(container) { 602// ? container.querySelector(".review-card__btn-disl") 603// otherBtn.classList.remove("active"); 604// ".review-card__counter", 605// if(otherCounter) { 606// } 607// } 608// saveVoteToCookie(reviewId, type); 609// saveVoteToCookie(reviewId, null); 610// } else { 611// } 612// .catch((error) => { 613// }); 614window.updateLike = function (reviewId, type, button){if(event) event.stopPropagation(); 615if(button.disabled) return; 616button.disabled = true; 617const isActive = button.classList.contains("active"); 618fetch("/ajax/review_handler.php", { 619method: "POST",headers: { 620"Content-Type": "application/x-www-form-urlencoded", 621},body: "action=update_like&review_id=" + reviewId + 622"&type=" + type + 623"&active=" + (isActive ? "0" : "1") 624}) 625.then((response) => response.json()) 626.then((data) => { 627if(data.success){const counter = button.querySelector(".review-card__counter"); 628if(counter){counter.textContent = data.new_value;} 629button.classList.toggle("active"); 630const container = button.closest(".review-card__actions"); 631if(container){const otherBtn = button.classList.contains("review-card__btn-like") 632? container.querySelector(".review-card__btn-disl") 633: container.querySelector(".review-card__btn-like"); 634if(otherBtn && data.other_value !== undefined){otherBtn.classList.remove("active"); 635const otherCounter = otherBtn.querySelector(".review-card__counter"); 636if(otherCounter){otherCounter.textContent = data.other_value;} 637} 638} 639const modal = document.getElementById("review-modal"); 640if(modal && modal.classList.contains("open") && modal.dataset.reviewId == reviewId){const likeCounter = document.getElementById("modal-like-count"); 641const dislCounter = document.getElementById("modal-disl-count"); 642if(likeCounter && dislCounter){if(type === "like") { 643likeCounter.textContent = data.new_value; 644if(data.other_value !== undefined){dislCounter.textContent = data.other_value;}}else{dislCounter.textContent = data.new_value; 645if(data.other_value !== undefined){likeCounter.textContent = data.other_value;} 646} 647} 648const modalLikeBtn = document.getElementById("modal-like-btn"); 649const modalDislBtn = document.getElementById("modal-disl-btn"); 650if(modalLikeBtn && modalDislBtn){if(type === "like") { 651modalLikeBtn.classList.toggle("active"); 652if(modalDislBtn.classList.contains("active")){modalDislBtn.classList.remove("active");}}else{modalDislBtn.classList.toggle("active"); 653if(modalLikeBtn.classList.contains("active")){modalLikeBtn.classList.remove("active");} 654} 655} 656} 657if(!isActive){saveVoteToCookie(reviewId, type);}else{saveVoteToCookie(reviewId, null);} 658} else { 659console.error("ÐÑибка:", data.error); 660if(data.error === "ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð° авÑоÑизаÑиÑ"){alert("ÐÐ»Ñ Ð¾Ñенки оÑзÑва Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ авÑоÑизоваÑÑÑÑ");}else{alert("ÐÑибка: " + data.error);} 661} 662}) 663.catch((error) => { 664console.error("ÐÑибка запÑоÑа:", error); 665alert("ÐÑоизоÑла оÑибка пÑи оÑпÑавке");}) 666.finally(() => { 667button.disabled = false;}); 668};// console.log(review); 669// if(!modal) return; 670// if(userNameEl) userNameEl.textContent = review.USER_NAME || "Ðноним"; 671// if(dateEl) dateEl.textContent = review.DATE ? formatDate(review.DATE) : ""; 672// if(textEl) textEl.textContent = review.TEXT || ""; 673// if(likeEl) likeEl.textContent = review.LIKE_COUNT || 0; 674// if(dislEl) dislEl.textContent = review.DISLIKE_COUNT || 0; 675// if(starsContainer) { 676// if(isNaN(rating) || rating < 1 || rating > 5) { 677// } 678// const star = document.createElement("div"); 679// i < rating ? "pp-modal-review__star active" : "pp-modal-review__star";
680// } 681// if(imagesContainer) { 682// review.FILES.forEach((file) => { 683// slide.className = "swiper-slide pp-modal-review__slider-card"; 684// file.SRC || file.src || file.THUMBNAIL || file.thumbnail || ""; 685// <picture class="pp-modal-review__slider-pic"> 686// </picture> 687// imagesContainer.appendChild(slide); 688// } else { 689// slide.className = "swiper-slide pp-modal-review__slider-card"; 690// <picture class="pp-modal-review__slider-pic"> 691// </picture> 692// imagesContainer.appendChild(slide); 693// } 694// const responseText = document.getElementById("modal-response-text"); 695// if(review.RESPONSE) { 696// responseBlock.style.display = "block"; 697// responseBlock.style.display = "none"; 698// } 699// const dislBtn = document.getElementById("modal-disl-btn"); 700// const newLikeBtn = likeBtn.cloneNode(true); 701// likeBtn.parentNode.replaceChild(newLikeBtn, likeBtn); 702// const voteType = window.userReviewVotes[review.ID]; 703// newLikeBtn.classList.add("active"); 704// newDislBtn.classList.add("active"); 705// } 706// e.stopPropagation(); 707// }); 708// e.stopPropagation(); 709// }); 710// if(window.reviewModalSlider) { 711// } 712// window.reviewModalSlider = new Swiper(".pp-modal-review__slider", { 713// spaceBetween: 10, 714// loop: imagesContainer.children.length > 1, 715// navigation: { 716// prevEl: ".pp-modal-review__slider-btn-prev", 717// }); 718// }, 100); 719// utils.lockScroll(); 720window.openReviewModal = function (review){console.log('Opening review modal for:', review); 721const modal = document.getElementById("review-modal"); 722if(!modal) return; 723modal.classList.add("open"); 724utils.lockScroll(); 725const userNameEl = document.getElementById("modal-user-name"); 726if(userNameEl) userNameEl.textContent = review.USER_NAME || "Ðноним"; 727const dateEl = document.getElementById("modal-review-date"); 728if(dateEl) dateEl.textContent = review.DATE ? formatDate(review.DATE) : ""; 729const textEl = document.getElementById("modal-review-text"); 730if(textEl) textEl.textContent = review.TEXT || ""; 731const likeEl = document.getElementById("modal-like-count"); 732if(likeEl) likeEl.textContent = review.LIKE_COUNT || 0; 733const dislEl = document.getElementById("modal-disl-count"); 734if(dislEl) dislEl.textContent = review.DISLIKE_COUNT || 0; 735const starsContainer = document.getElementById("modal-review-stars"); 736if(starsContainer){starsContainer.innerHTML = ""; 737let rating = parseInt(review.RATING); 738if(isNaN(rating) || rating < 1 || rating > 5){rating = 5;} 739for (let i = 0; i < 5; i++){const star = document.createElement("div"); 740star.className = i < rating ? "pp-modal-review__star active" : "pp-modal-review__star"; 741starsContainer.appendChild(star);} 742} 743const imagesContainer = document.getElementById("modal-images-container"); 744if(imagesContainer){imagesContainer.innerHTML = ""; 745if(review.FILES && review.FILES.length > 0){review.FILES.forEach((file) => { 746const slide = document.createElement("div"); 747slide.className = "swiper-slide pp-modal-review__slider-card"; 748const imageUrl = file.SRC || file.src || file.THUMBNAIL || file.thumbnail || ""; 749slide.innerHTML = ` 750<picture class="pp-modal-review__slider-pic"> 751<img src="${imageUrl}" alt="" loading="lazy" /> 752</picture> 753`; 754imagesContainer.appendChild(slide);});}else{const slide = document.createElement("div"); 755slide.className = "swiper-slide pp-modal-review__slider-card"; 756slide.innerHTML = ` 757<picture class="pp-modal-review__slider-pic"> 758<img src="/local/img/nf.jpg" alt="" /> 759</picture> 760`; 761imagesContainer.appendChild(slide);} 762} 763const responseBlock = document.getElementById("modal-shop-response"); 764const responseText = document.getElementById("modal-response-text"); 765if(responseBlock && responseText){if(review.RESPONSE) { 766responseText.textContent = review.RESPONSE; 767responseBlock.style.display = "block";}else{responseBlock.style.display = "none";} 768} 769modal.dataset.reviewId = review.ID || review.id; 770const likeBtn = document.getElementById("modal-like-btn"); 771const dislBtn = document.getElementById("modal-disl-btn"); 772if(likeBtn && dislBtn){const newLikeBtn = likeBtn.cloneNode(true); 773const newDislBtn = dislBtn.cloneNode(true); 774likeBtn.parentNode.replaceChild(newLikeBtn, likeBtn); 775dislBtn.parentNode.replaceChild(newDislBtn, dislBtn); 776newLikeBtn.addEventListener("click", function (e){e.stopPropagation(); 777window.updateLike(review.ID || review.id, "like", this);}); 778newDislBtn.addEventListener("click", function (e){e.stopPropagation(); 779window.updateLike(review.ID || review.id, "dislike", this);}); 780} 781fetch("/ajax/get_review_data.php?review_id=" + (review.ID || review.id)) 782.then(response => response.json()) 783.then(actualData => { 784if(actualData.success){console.log('Actual review data received:', actualData); 785const likeCounter = document.getElementById("modal-like-count"); 786if(likeCounter){likeCounter.textContent = actualData.like_count;} 787const dislCounter = document.getElementById("modal-disl-count"); 788if(dislCounter){dislCounter.textContent = actualData.dislike_count;} 789const currentLikeBtn = document.getElementById("modal-like-btn"); 790const currentDislBtn = document.getElementById("modal-disl-btn"); 791if(currentLikeBtn && currentDislBtn){currentLikeBtn.classList.remove("active"); 792currentDislBtn.classList.remove("active"); 793if(actualData.user_vote === "like"){currentLikeBtn.classList.add("active");} else if(actualData.user_vote === "dislike"){currentDislBtn.classList.add("active"); 794} 795}}else{console.error('Error fetching actual review data:', actualData.error);} 796}) 797.catch(error => { 798console.error('Error fetching actual review data:', error);}); 799setTimeout(() => { 800if(window.reviewModalSlider){window.reviewModalSlider.destroy();} 801if(typeof Swiper !== "undefined" && imagesContainer){window.reviewModalSlider = new Swiper(".pp-modal-review__slider", { 802slidesPerView: 1,spaceBetween: 10, 803speed: 600,loop: imagesContainer.children.length > 1, 804grabCursor: true,navigation: { 805nextEl: ".pp-modal-review__slider-btn-next",prevEl: ".pp-modal-review__slider-btn-prev", 806},});} 807}, 100);};window.closeReviewModal = function (){const modal = document.getElementById("review-modal"); 808if(modal){modal.classList.remove("open"); 809utils.unlockScroll();} 810};window.openAddReviewModal = function (productId){const modal = document.getElementById("add-review-modal"); 811if(!modal) return; 812document.getElementById("review-product-id").value = productId; 813const form = document.getElementById("review-form"); 814form.reset(); 815document.getElementById("rating-value").value = "5"; 816document.querySelectorAll(".rating-star").forEach((star, index) => { 817if(index < 5){star.classList.add("active");}else{star.classList.remove("active");} 818}); 819document.getElementById("file-preview").innerHTML = ""; 820document.querySelector(".pp-modal-add-review__form").style.display = 821"block"; 822document.querySelector(".pp-modal-add-review__success").style.display = 823"none"; 824modal.classList.add("open"); 825utils.lockScroll();};window.closeAddReviewModal = function (){const modal = document.getElementById("add-review-modal"); 826if(modal){modal.classList.remove("open"); 827utils.unlockScroll();} 828};function formatDate(dateString){// return date.toLocaleDateString("ru-RU"); 829if(!dateString) return ''; 830return dateString.split(' ')[0];} 831function saveVoteToCookie(reviewId, type){let votes = window.userReviewVotes || {};if(type){votes[reviewId] = type;}else{delete votes[reviewId];} 832cookieUtils.set( 833"review_votes",encodeURIComponent(JSON.stringify(votes)), 834365,); 835window.userReviewVotes = votes;} 836function loadUserVotesFromCookie(){const votesCookie = cookieUtils.get("review_votes"); 837let votes = {};if(votesCookie){try { 838votes = JSON.parse(decodeURIComponent(votesCookie));} catch (e){console.error("ÐÑибка паÑÑинга кÑки:", e); 839} 840} 841window.userReviewVotes = votes; 842document.querySelectorAll(".review-card").forEach((card) => { 843const reviewId = card.dataset.reviewId; 844if(reviewId && votes[reviewId]){const likeBtn = card.querySelector(".review-card__btn-like"); 845const dislBtn = card.querySelector(".review-card__btn-disl"); 846if(likeBtn && votes[reviewId] === "like"){likeBtn.classList.add("active");} 847if(dislBtn && votes[reviewId] === "dislike"){dislBtn.classList.add("active");} 848} 849}); 850return votes;} 851function initReviewForm(){const form = document.getElementById("review-form"); 852if(!form) return; 853const stars = document.querySelectorAll(".rating-star"); 854const ratingInput = document.getElementById("rating-value");
855stars.forEach((star, index) => { 856star.addEventListener("mouseover", function (){stars.forEach((s, i) => { 857if(i <= index){s.classList.add("active");}else{s.classList.remove("active");} 858});}); 859star.addEventListener("mouseout", function (){const currentRating = parseInt(ratingInput.value) || 5; 860stars.forEach((s, i) => { 861if(i < currentRating){s.classList.add("active");}else{s.classList.remove("active");} 862});}); 863star.addEventListener("click", function (){const value = index + 1; 864ratingInput.value = value; 865stars.forEach((s, i) => { 866if(i < value){s.classList.add("active");}else{s.classList.remove("active");} 867});}); 868}); 869const fileInput = document.getElementById("review-files"); 870const preview = document.getElementById("file-preview"); 871fileInput.addEventListener("change", function (){preview.innerHTML = ""; 872Array.from(this.files).forEach((file, index) => { 873if(index >= 5) return; 874const reader = new FileReader(); 875reader.onload = function (e){const item = document.createElement("div"); 876item.className = "file-preview-item"; 877item.innerHTML = ` 878<img src="${e.target.result}" alt=""> 879<div class="file-preview-remove" data-index="${index}">Ã</div> 880`; 881item 882.querySelector(".file-preview-remove") 883.addEventListener("click", function (){item.remove();}); 884preview.appendChild(item);};reader.readAsDataURL(file);}); 885}); 886form.addEventListener("submit", function (e){e.preventDefault(); 887const formData = new FormData(this); 888const submitBtn = this.querySelector(".pp-modal-add-review__submit"); 889const originalText = submitBtn.textContent; 890submitBtn.disabled = true; 891submitBtn.textContent = "ÐÑпÑавка..."; 892fetch("/ajax/review_handler.php", { 893method: "POST",body: formData, 894}) 895.then((response) => response.json()) 896.then((data) => { 897if(data.success){document.querySelector(".pp-modal-add-review__form").style.display = 898"none"; 899document.querySelector( 900".pp-modal-add-review__success",).style.display = "block"; 901setTimeout(() => { 902location.reload();}, 2000);}else{alert("ÐÑибка: " + data.error);} 903}) 904.catch((error) => { 905console.error("ÐÑибка:", error); 906alert("ÐÑоизоÑла оÑибка пÑи оÑпÑавке");}) 907.finally(() => { 908submitBtn.disabled = false; 909submitBtn.textContent = originalText;}); 910});} 911initReviewForm(); 912function getCurrentQuantity(){const qtyInput = document.querySelector(".product-detail__counter-input"); 913if(qtyInput){let qty = parseInt(qtyInput.value); 914return !isNaN(qty) && qty > 0 ? qty : 1;} 915return 1;} 916const tabCont = document.querySelector(".tab_cont"); 917if(tabCont){const row = tabCont.querySelector(".row"); 918if(row){const rowContent = row.innerHTML.replace(/<br\s*\/?>/gi, "").trim(); 919if(!rowContent){tabCont.style.display = "none";}}else{tabCont.style.display = "none";} 920} 921loadUserVotesFromCookie(); 922function updateButtonsFromBasket(basketData){let basketItemsIds = new Set(); 923if(basketData.items){if( 924Array.isArray(basketData.items) && 925typeof basketData.items[0] === "number" 926){basketItemsIds = new Set(basketData.items);} 927else if( 928Array.isArray(basketData.items) && 929basketData.items[0] && 930basketData.items[0].id 931){basketItemsIds = new Set( 932basketData.items.map((item) => parseInt(item.id)),);} 933} 934else if(Array.isArray(basketData)){basketItemsIds = new Set(basketData);} 935// ÐÐÐÐÐ: ÐÑем кнопки по клаÑÑÑ .product-card__btn и data-id 936document.querySelectorAll(".product-card__btn").forEach((btn) => { 937const productId = parseInt(btn.dataset.id); 938if(basketItemsIds.has(productId)){updateButtonToInBasket(btn);}else{resetButtonToAddToCart(btn);} 939}); 940const detailBtn = document.querySelector(".product-detail__btn-basket"); 941if(detailBtn){const productId = parseInt(detailBtn.dataset.id); 942if(basketItemsIds.has(productId)){updateButtonToInBasket(detailBtn);}else{resetButtonToAddToCart(detailBtn);} 943} 944} 945function loadBasketState(){fetch("/ajax/get_basket_items.php") 946.then((response) => response.json()) 947.then((data) => { 948if(data.success){updateButtonsFromBasket(data); 949const cartSpan = document.querySelector(".top_header_cart span"); 950if(cartSpan){cartSpan.textContent = " â " + (data.total_quantity || 0);} 951} 952}) 953.catch((error) =>
953 console.error("ÐÑибка загÑÑзки коÑзинÑ:", error));} 954function updateButtonToInBasket(btn){if(!btn) return; 955if(btn.classList.contains("in-basket")) return; 956btn.classList.add("in-basket"); 957btn.dataset.inBasket = "true"; 958if(btn.classList.contains("product-card__btn")){const textSpan = btn.querySelector(".product-card__btn-text"); 959if(textSpan){textSpan.textContent = "Уже в коÑзине";}else{const icon = btn.querySelector(".product-card__btn-icon"); 960if(icon){btn.innerHTML = ""; 961btn.appendChild(icon); 962const newSpan = document.createElement("span"); 963newSpan.className = "product-card__btn-text"; 964newSpan.textContent = "Уже в коÑзине"; 965btn.appendChild(newSpan);}else{btn.innerHTML = "Уже в коÑзине";} 966} 967btn.disabled = false;} 968else if(btn.classList.contains("product-detail__btn-basket")){const textSpan = btn.querySelector(".product-detail__btn-basket-text"); 969if(textSpan){textSpan.textContent = "Уже в коÑзине";} 970const oneClickBtn = document.querySelector( 971".product-detail__buy-one-click",); 972if(oneClickBtn){oneClickBtn.disabled = false;} 973} 974} 975function resetButtonToAddToCart(btn){if(!btn) return; 976if(!btn.classList.contains("in-basket")) return; 977btn.classList.remove("in-basket"); 978btn.dataset.inBasket = "false"; 979if(btn.classList.contains("product-card__btn")){const textSpan = btn.querySelector(".product-card__btn-text"); 980if(textSpan){textSpan.textContent = "РкоÑзинÑ";}else{const icon = btn.querySelector(".product-card__btn-icon"); 981if(icon){btn.innerHTML = ""; 982btn.appendChild(icon); 983const newSpan = document.createElement("span"); 984newSpan.className = "product-card__btn-text"; 985newSpan.textContent = "РкоÑзинÑ"; 986btn.appendChild(newSpan);}else{btn.innerHTML = "РкоÑзинÑ";} 987} 988btn.disabled = false;} 989else if(btn.classList.contains("product-detail__btn-basket")){const textSpan = btn.querySelector(".product-detail__btn-basket-text"); 990if(textSpan){textSpan.textContent = "РкоÑзинÑ";} 991} 992} 993setTimeout(() => { 994loadBasketState();}, 500); 995if(typeof BX !== "undefined"){BX.addCustomEvent("OnBasketChange", function () { 996loadBasketState();}); 997} 998function refreshAllLikeCounters(){const productId = getCurrentProductId(); 999if(!productId) return; 1000fetch("/ajax/get_reviews_actual.php?product_id=" + productId + "&_=" + Date.now()) 1001.then(response => response.json()) 1002.then(data => { 1003if(data.success && data.reviews){const actualCounts = {};data.reviews.forEach(review => { 1004actualCounts[review.ID] = { 1005likes: review.LIKE_COUNT,dislikes: review.DISLIKE_COUNT 1006};}); 1007document.querySelectorAll('.review-card').forEach(card => { 1008const reviewId = card.dataset.reviewId; 1009if(reviewId && actualCounts[reviewId]){const likeSpan = card.querySelector('.review-card__btn-like .review-card__counter'); 1010const dislSpan = card.querySelector('.review-card__btn-disl .review-card__counter'); 1011if(likeSpan) likeSpan.textContent = actualCounts[reviewId].likes; 1012if(dislSpan) dislSpan.textContent = actualCounts[reviewId].dislikes;} 1013});} 1014}) 1015.catch(error => console.error('Error refreshing like counters:', error));} 1016function getCurrentProductId(){const urlMatch = window.location.pathname.match(/\/catalog\/[^/]+\/(\d+)\//); 1017if(urlMatch) return urlMatch[1]; 1018const metaTag = document.querySelector('meta[name="product-id"]'); 1019if(metaTag) return metaTag.content; 1020const basketBtn = document.querySelector('.product-detail__btn-basket'); 1021if(basketBtn && basketBtn.dataset.id) return basketBtn.dataset.id; 1022return null;} 1023setTimeout(() => { 1024refreshAllLikeCounters();}, 500); 1025window.addEventListener('pageshow', function (event){if(event.persisted) { 1026setTimeout(refreshAllLikeCounters, 100);} 1027}); 1028document.addEventListener('visibilitychange', function (){if(!document.hidden) { 1029refreshAllLikeCounters();} 1030});}); 1031window.addEventListener("pageshow", function (event){if(event.persisted) { 1032setTimeout(() => { 1033loadBasketState();}, 100); 1034} 1035});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.