PageSourceSearch

https://decathlon.qa/cdn/shop/t/15/assets/product-reviews.js?v=145458594512170527551774245877

js decathlon.qa collected 2026-10-04 13:25:58 UTC 6,790 bytes, 30 lines download raw bytes

1class ProductReviews{constructor(){this.currentPage=0,this.itemsPerPage=3,this.totalReviews=0,this.modelId=null,this.isLoading=!1,this.init()}init(){this.modelId=this.extractModelId(),this.modelId&&(this.setupPaginationControls(),this.loadReviews())}extractModelId(){return window.reviewsTranslations&&window.reviewsTranslations.modelCode?window.reviewsTranslations.modelCode:null}setupPaginationControls(){const commentsSections=document.querySelectorAll(".ReviewSummary-comments");if(!commentsSections.length)return;commentsSections.forEach((commentsSection,index)=>{const paginationId=index===0?"mobile":"desktop",paginationHtml=`
2        <div class="review-pagination review-pagination--${paginationId}" style="display: none;">
3          <button class="review-pagination__btn review-pagination__prev review-pagination__prev--${paginationId}" disabled>
4            <span>${window.reviewsTranslations?.previous||"\u2190 Pr\xE9c\xE9dent"}</span>
5          </button>
6          <span class="review-pagination__info review-pagination__info--${paginationId}"></span>
7          <button class="review-pagination__btn review-pagination__next review-pagination__next--${paginationId}">
8            <span>${window.reviewsTranslations?.next||"Suivant \u2192"}</span>
9          </button>
10        </div>
11      `;commentsSection.insertAdjacentHTML("beforeend",paginationHtml)});const prevBtns=document.querySelectorAll(".review-pagination__prev"),nextBtns=document.querySelectorAll(".review-pagination__next");prevBtns.forEach(btn=>{btn.addEventListener("click",()=>this.previousPage())}),nextBtns.forEach(btn=>{btn.addEventListener("click",()=>this.nextPage())})}async loadReviews(){if(!(this.isLoading||!this.modelId)){this.isLoading=!0,this.showLoadingState();try{const rangeStart=this.currentPage*this.itemsPerPage,rangeEnd=rangeStart+this.itemsPerPage-1,apiUrl=window.reviewsApiUrl;if(!apiUrl)throw new Error("Reviews API URL is not defined.");const url=`${apiUrl}/reviews/model/${this.modelId}/only_reviews?range=${rangeStart}-${rangeEnd}`,response=await fetch(url);if(!response.ok)throw new Error(`HTTP error! status: ${response.status}`);const reviews=await response.json(),translatedReviews=await this.translateReviews(reviews);this.renderReviews(translatedReviews),this.updatePaginationControls(reviews.length)}catch{this.showError()}finally{this.isLoading=!1}}}async translateReviews(reviews){const locale=window.reviewsTranslations?.locale;if(!locale||!reviews||reviews.length===0)return reviews;const apiUrl=window.reviewsApiUrl,translationPromises=reviews.map(async review=>{try{const translateUrl=`${apiUrl}/reviews/review/${review.id}/${locale}/translate`,response=await fetch(translateUrl);if(response.ok){const translatedData=await response.json();return{...review,title:translatedData.title||review.title,message:translatedData.message||review.comment}}}catch(error){console.error(`Failed to translate review ${review.id}:`,error)}return review});return await Promise.all(translationPromises)}renderReviews(reviews){const reviewLists=document.querySelectorAll(".ReviewList");if(!reviewLists.length)return;if(!reviews||reviews.length===0){reviewLists.forEach(reviewList=>{reviewList.innerHTML=`<p class="no-reviews">${window.reviewsTranslations?.noReviews||"Aucun avis disponible pour cette page."}</p>`,reviewList.style.minHeight=""});return}const reviewsHtml=reviews.map(review=>this.createReviewHTML(review)).join("");reviewLists.forEach(reviewList=>{reviewList.innerHTML=reviewsHtml,reviewList.style.minHeight=""})}createReviewHTML(review){const rating=review.rating?review.rating.code:0,title=this.escapeHtml(review.title||""),comment=this.escapeHtml(review.message||review.comment||""),username=this.escapeHtml(review.author?.username||window.reviewsTranslations?.anonymous||"Anonyme"),date=review.publisherDate?new Date(review.publisherDate).toLocaleDateString("fr-FR"):"",starsHtml=this.generateStarsHTML(rating);return`
12      <div class="ReviewItem">
13        ${title?`<h3>${title}</h3>`:""}
14        <p>${comment}</p>
15        <div class="ReviewMeta">
16          <span>${username}</span>
17          <span>|</span>
18          <span>${date}</span>
19          <span>|</span>
20          <span class="StarRating rating__stars">
21            ${starsHtml}
22          </span>
23        </div>
24      </div>
25    `}generateStarsHTML(rating){let starsHtml="";for(let i=1;i<=5;i++)i<=rating?starsHtml+=`<svg fill="none" focusable="false" width="14" height="14" class="icon icon--rating-star rating__star rating__star--full" viewBox="0 0 14 13">
26          <path d="M7 0L8.6458 4.73475L13.6574 4.83688L9.66296 7.86525L11.1145 12.6631L7 9.8L2.8855 12.6631L4.33704 7.86525L0.342604 4.83688L5.3542 4.73475L7 0Z" fill="currentColor"></path>
27        </svg>`:starsHtml+=`<svg fill="none" focusable="false" width="14" height="14" class="icon icon--rating-star rating__star rating__star--empty" viewBox="0 0 14 13">
28          <path d="M7 0L8.6458 4.73475L13.6574 4.83688L9.66296 7.86525L11.1145 12.6631L7 9.8L2.8855 12.6631L4.33704 7.86525L0.342604 4.83688L5.3542 4.73475L7 0Z" fill="currentColor"></path>
29        </svg>`;return starsHtml}updatePaginationControls(currentPageCount){const paginations=document.querySelectorAll(".review-pagination"),prevBtns=document.querySelectorAll(".review-pagination__prev"),nextBtns=document.querySelectorAll(".review-pagination__next"),infos=document.querySelectorAll(".review-pagination__info");paginations.length&&(currentPageCount>0&&paginations.forEach(pagination=>{pagination.style.display="flex"}),prevBtns.forEach(btn=>{btn.disabled=this.currentPage===0}),nextBtns.forEach(btn=>{btn.disabled=currentPageCount<this.itemsPerPage}),infos.forEach(info=>{const pageText=window.reviewsTranslations?.pageInfo?.replace("{{ page }}",this.currentPage+1)||`Page ${this.currentPage+1}`;info.textContent=pageText}))}previousPage(){this.currentPage>0&&(this.currentPage--,this.loadReviews())}nextPage(){this.currentPage++,this.loadReviews()}showLoadingState(){document.querySelectorAll(".ReviewList").forEach(reviewList=>{reviewList.offsetHeight>0&&(reviewList.style.minHeight=`${reviewList.offsetHeight}px`),reviewList.innerHTML=`<div class="review-loading">${window.reviewsTranslations?.loading||"Loading reviews..."}</div>`})}hideLoadingState(){}showError(){document.querySelectorAll(".ReviewList").forEach(reviewList=>{reviewList.innerHTML=`<div class="review-error">${window.reviewsTranslations?.error||"Erreur lors du chargement des avis."}</div>`})}escapeHtml(text){const div=document.createElement("div");return div.textContent=text,div.innerHTML}}
29document.addEventListener("DOMContentLoaded",function(){document.querySelector(".ReviewsContainer")&&new ProductReviews});
30//# sourceMappingURL=/cdn/shop/t/15/assets/product-reviews.js.map?v=145458594512170527551774245877

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.