1import { Controller } from '@hotwired/stimulus'; 2 3export default class extends Controller { 4 static targets = [ 5 'reviewsWrapper', 6 'paginator', 7 'raterReviewsWrapper', 8 'reviewsForItemToggle', 9 'reviewsForLenderToggle', 10 'reviewsForAllReviewsToggle', 11 'reviewsAsARenterToggle', 12 'reviewsAsALenderToggle', 13 'commentModalContentWrapper', 14 'sortByDropdown', 15 'sortByDropdownMenu', 16 ]; 17 18 connect() { 19 this.fetchReviews(); 20 } 21 22 fetchReviews() { 23 const thisController = this; 24 fetch(`${this.data.get('url')}?${this.setParams()}`) 25 .then((response) => response.json()) 26 .then((data) => { 27 thisController.reviewsWrapperTarget.innerHTML = data.index_page; 28 thisController.raterReviewsWrapperTarget.innerHTML = data.reviews; 29 thisController.paginatorTarget.innerHTML = data.paginator; 30 thisController.toggleBtnState(); 31 thisController.sortDropdownActiveState(); 32 }) 33 .catch((error) => { 34 return error; 35 }); 36 } 37 38 fetchToggles(event) { 39 event.preventDefault(); 40 this.data.set('reviewPage', '1'); 41 this.data.set('toggleStateFor', event.currentTarget.dataset.toggleStateFor); 42 this.raterReviewsWrapperTarget.style.opacity = '0.3'; 43 this.toggleBtnState(); 44 this.sortDropdownActiveState(); 45 this.fetchReviews(); 46 this.scrollToReviewSection(); 47 } 48 49 setParams() { 50 return [ 51 `listing_id=${encodeURIComponent(`${this.data.get('listingId')}`)}`, 52 `member_id=${encodeURIComponent(`${this.data.get('memberId')}`)}`, 53 `brand_id=${encodeURIComponent(`${this.data.get('brandId')}`)}`, 54 `page=${encodeURIComponent(`${this.data.get('reviewPage')}`)}`, 55 `toggle_state_for=${encodeURIComponent(`${this.data.get('toggleStateFor')}`)}`, 56 `sort_by=${encodeURIComponent(`${this.data.get('sortBy')}`)}`, 57 ].join('&'); 58 } 59 60 paginate(event) { 61 event.preventDefault(); 62 this.data.set('reviewPage', event.currentTarget.dataset.page); 63 this.raterReviewsWrapperTarget.style.opacity = '0.3'; 64 this.fetchReviews(); 65 this.scrollToReviewSection(); 66 } 67 68 scrollToReviewSection(event) { 69 if (event) event.preventDefault(); 70 71 $('html, body').animate( 72 { 73 scrollTop: $('#reviews-section').offset().top, 74 }, 75 250, 76 ); 77 } 78 79 toggleBtnState() { 80 this.removeAllActiveToggles(); 81 const activateToggle = (target) => { 82 target.classList.add('toggle-btn-active'); 83 }; 84 switch (this.data.get('toggleStateFor')) { 85 case 'reviews_for_item': 86 activateToggle(this.reviewsForItemToggleTarget); 87 break; 88 case 'reviews_for_lender': 89 activateToggle(this.reviewsForLenderToggleTarget); 90 break; 91 case 'all_reviews': 92 activateToggle(this.reviewsForAllReviewsToggleTarget); 93 break; 94 case 'reviews_as_a_renter': 95 activateToggle(this.reviewsAsARenterToggleTarget); 96 break; 97 case 'reviews_as_a_lender': 98 activateToggle(this.reviewsAsALenderToggleTarget); 99 break; 100 } 101 } 102 103 sortDropdownActiveState() { 104 if (this.data.get('sortBy') !== '') { 105 const selectedDropdownItem = document.querySelector(`[data-sort-reviews-value="${this.data.get('sortBy')}"]`); 106 const activeDropdownItems = selectedDropdownItem 107 .closest('.dropdown-menu') 108 .getElementsByClassName('dropdown-item active'); 109 const activateDropdownItem = (textContent) => { 110 this.sortByDropdownTarget.innerHTML = textContent; 111 activeDropdownItems[0].classList.remove('active'); 112 selectedDropdownItem.classList.add('active'); 113 }; 114 switch (this.data.get('sortBy')) { 115 case 'newest': 116 activateDropdownItem('Newest'); 117 break; 118 case 'highest_rated': 119 activateDropdownItem('Highest Rated'); 120 break; 121 case 'lowest_rated': 122 activateDropdownItem('Lowest Rated'); 123 break; 124 } 125 } 126 } 127 128 removeAllActiveToggles() { 129 const activeButtonsElement = document.getElementsByClassName('toggle-btn-active'); 130 Array.from(activeButtonsElement).forEach((activeElement) => { 131 activeElement.classList.remove('toggle-btn-active'); 132 }); 133 } 134 135 fetchModalCommentContent(event) { 136 event.preventDefault(); 137 const currentTarget = event.currentTarget; 138 fetch(`${currentTarget.dataset.reviewUrl}?review_of=${currentTarget.dataset.reviewOf}`) 139 .then((response) => response.json()) 140 .then((data) => {
141 this.commentModalContentWrapperTarget.innerHTML = data.content; 142 window.$(`#${currentTarget.dataset.modalFor}_modal`).modal('show'); 143 }) 144 .catch((error) => { 145 return error; 146 }); 147 } 148 149 sortByFilter(event) { 150 event.preventDefault(); 151 let current = event.currentTarget.closest('.dropdown-menu').getElementsByClassName('dropdown-item active'); 152 current[0].classList.remove('active'); 153 event.currentTarget.classList.add('active'); 154 this.raterReviewsWrapperTarget.style.opacity = '0.3'; 155 this.sortByDropdownTarget.innerHTML = event.currentTarget.innerHTML; 156 this.data.set('sortBy', event.currentTarget.dataset.sortReviewsValue); 157 this.fetchReviews(); 158 this.scrollToReviewSection(); 159 } 160};
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.