This repository has been archived by the owner on Jul 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## QA Steps - [ ] `pnpm i` - [ ] `pnpm dev` - [ ] visit any product page with reviews, and test it ## Note Leave empty when you have nothing to say
- Loading branch information
1 parent
e414e4c
commit 7f303f4
Showing
3 changed files
with
124 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,130 @@ | ||
(async () => { | ||
/** | ||
* Converts date from yyyy-mm-dd to dd.mm.yyyy | ||
*/ | ||
function convertDate() { | ||
const createdAtDate = document.querySelectorAll('.created-at-date'); | ||
|
||
createdAtDate.forEach(date => { | ||
const originalDateString = date.textContent; | ||
const originalDate = new Date(originalDateString); | ||
const day = originalDate.getDate().toString().padStart(2, '0'); | ||
const month = (originalDate.getMonth() + 1).toString().padStart(2, '0'); | ||
const year = originalDate.getFullYear().toString(); | ||
const formattedDate = `${day}.${month}.${year}`; | ||
date.textContent = formattedDate; | ||
}); | ||
} | ||
|
||
/** | ||
* Creates a review template | ||
* | ||
* @param {Object} review - Review object. | ||
* @returns {String} - Review template. | ||
*/ | ||
function reviewTemplate(review) { | ||
return ` | ||
<div class='header'> | ||
<div class="profil"> | ||
<img loading='lazy' class='image' src='${review.images_urls[0] || defaultAvatar}' /> | ||
<div class='info'> | ||
<span class='name'>${review.first_name || ''} ${review.last_name || ''}</span> | ||
<span class='created-at-date'>${review.created_at}</span> | ||
</div> | ||
</div> | ||
<div class='yc-reviews-stars' | ||
style='--rating: ${review.ratings}' | ||
aria-label="Rating of this product is ${review.ratings} out of 5" | ||
></div> | ||
</div> | ||
<div class='content'> | ||
${review.content === null ? '' : review.content} | ||
</div> | ||
`; | ||
} | ||
|
||
const setupReviews = async () => { | ||
const reviewsContainer = $('.yc-product-reviews'); | ||
const reviewsWrapper = $('.yc-reviews-wrapper'); | ||
const showMoreButton = $('#show-more'); | ||
let reviews = []; | ||
|
||
const noDataSetter = (element) => { | ||
if (reviewsContainer) { | ||
reviewsContainer.remove(); | ||
} | ||
}; | ||
/** | ||
* This function is used to remove the reviews container if there is no data. | ||
* | ||
* @param {HTMLElement} element - The element you want to target | ||
*/ | ||
const removeReviewsIfNone = () => { | ||
if (reviewsContainer) { | ||
reviewsContainer.remove(); | ||
} | ||
}; | ||
|
||
/** | ||
* Creates a review item. | ||
* | ||
* @param {Object} review - Review object. | ||
* @returns {HTMLElement} - Review item. | ||
*/ | ||
const createReviewItem = (review) => { | ||
const reviewItem = document.createElement('li'); | ||
|
||
const reviewItem = document.createElement('li') | ||
reviewItem.classList.add('review-item'); | ||
createElement(reviewItem, review); | ||
reviewItem.innerHTML = reviewTemplate(review); | ||
|
||
return reviewsWrapper.appendChild(reviewItem); | ||
} | ||
|
||
try { | ||
const res = youcanjs.product.fetchReviews(productId, { limit: 3 }); | ||
|
||
reviews = await res.data(); | ||
|
||
reviewsWrapper.append(...reviews.map(review => createReviewItem(review))); | ||
const pagination = res.pagination(); | ||
/** | ||
* Handling pagination by showing the show more button if there is more than one page. | ||
* | ||
* @param {Array} reviews - Array of reviews | ||
*/ | ||
const handelPagination = (data) => { | ||
const pagination = data.pagination(); | ||
|
||
if (pagination.totalPages > 1) { | ||
showMoreButton.style.display = 'block'; | ||
showMoreButton?.addEventListener('click', async () => { | ||
const response = res.next(); | ||
|
||
reviews = await response.data(); | ||
reviewsWrapper.append(...reviews.map(review => createReviewItem(review))); | ||
if (showMoreButton) { | ||
showMoreButton.addEventListener('click', async () => { | ||
const response = data.next(); | ||
|
||
reviews = await response.data(); | ||
addReviews(reviewsWrapper, reviews); | ||
|
||
if (pagination.totalPages >= pagination.currentPage) { | ||
showMoreButton.style.display = 'none'; | ||
} | ||
}); | ||
}; | ||
|
||
if (pagination.totalPages >= pagination.currentPage) { | ||
showMoreButton.style.display = 'none'; | ||
} | ||
}); | ||
} | ||
} | ||
|
||
if(reviews) { | ||
convertDate(); | ||
} | ||
/** | ||
* Append reviews to the reviewsWrapper. | ||
*/ | ||
const addReviews = (reviewsWrapper, reviews) => { | ||
reviewsWrapper.append(...reviews.map(review => createReviewItem(review))); | ||
} | ||
|
||
try { | ||
const res = youcanjs.product.fetchReviews(productId, { limit: 3 }); | ||
reviews = await res.data(); | ||
|
||
if (reviews.length === 0) { | ||
noDataSetter(); | ||
addReviews(reviewsWrapper, reviews); | ||
handelPagination(res); | ||
|
||
if(reviews && reviews.length) { | ||
return convertDate(); | ||
} | ||
|
||
return removeReviewsIfNone(); | ||
|
||
} catch (error) { | ||
noDataSetter(); | ||
removeReviewsIfNone(); | ||
} | ||
})(); | ||
|
||
function createElement(element, index) { | ||
element.innerHTML = ` | ||
<div class='header'> | ||
<div class="profil"> | ||
<img loading='lazy' class='image' src=${index.images_urls[0] || defaultAvatar} /> | ||
<div class='info'> | ||
<span class='name'>${index.first_name || ''} ${index.last_name || ''}</span> | ||
<span class='created-at-date'>${index.created_at}</span> | ||
</div> | ||
</div> | ||
<div class='yc-reviews-stars' | ||
style="--rating: ${index.ratings};" | ||
aria-label="Rating of this product is ${index.ratings} out of 5" | ||
> | ||
</div> | ||
</div> | ||
<div class='content'> | ||
${index.content === null ? '' : index.content} | ||
</div> | ||
`; | ||
} | ||
}; | ||
|
||
function convertDate() { | ||
const createdAtDate = document.querySelectorAll('.created-at-date'); | ||
|
||
createdAtDate?.forEach(date => { | ||
const originalDateString = date.textContent; | ||
const originalDate = new Date(originalDateString); | ||
const day = originalDate.getDate().toString().padStart(2, '0'); | ||
const month = (originalDate.getMonth() + 1).toString().padStart(2, '0'); | ||
const year = originalDate.getFullYear().toString(); | ||
const formattedDate = `${day}.${month}.${year}`; | ||
date.textContent = formattedDate; | ||
}); | ||
} | ||
document.addEventListener('DOMContentLoaded', () => { | ||
setupReviews(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters