Created
June 16, 2022 19:10
-
-
Save mcav/906e032b754f801d0b430fd7c8a9214a to your computer and use it in GitHub Desktop.
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
/** | |
* @typedef ReviewEntry | |
* @param {string} id | |
* @param {number} rating | |
* @param {string} review | |
* @param {number} timestamp | |
*/ | |
/** | |
* @typedef PaginatedReviews | |
* @param {ReviewEntry[]} reviews | |
* @param {number} [nextPage] | |
*/ | |
/** | |
* Loads & tracks user reviews from `serviceEndpoint`, which returns PaginatedReviews object for each successful request | |
*/ | |
class ReviewCollection { | |
nextPage; | |
reviews = []; | |
serviceEndpoint = 'https://widgets.co/reviews'; | |
constructor() { | |
this.loadReviews(); | |
} | |
/** | |
* Total number of reviews | |
*/ | |
count() { | |
return this.reviews.length; | |
} | |
/** | |
* Get specific review by ID | |
* @param {string} id | |
*/ | |
getReview(id) { | |
return this.reviews.find(review => review.id === id); | |
} | |
/** | |
* User average rating | |
*/ | |
getAverageRating() { | |
let average = 0; | |
for (var i=0; i<this.count(); i++) { | |
average = (average + this.reviews[i].rating) / i; | |
} | |
return average; | |
} | |
/** | |
* Adds new reviews to the queue | |
* @param {Response} response | |
*/ | |
handleLoadedReviews(response) { | |
const data = response.json(); | |
const reviews = data.reviews; | |
for (var i=0; i<reviews.length; i++) { | |
this.reviews[this.count()] = reviews[i]; | |
} | |
this.nextPage = data.nextPage; | |
} | |
/** | |
* Handles review API request | |
* @param {number} [page] | |
*/ | |
async loadReviews(page) { | |
const url = this.serviceEndpoint + page ? `?page=${page}`: ''; | |
const response = await fetch(url); | |
this.handleLoadedReviews(response); | |
} | |
/** | |
* Load more reviews | |
*/ | |
loadNext() { | |
this.loadReviews(this.nextPage); | |
} | |
/** | |
* Sort reviews by date | |
* @param {('ascending'|'descending')} direction | |
*/ | |
sortedByDate(direction) { | |
return this.reviews.sort((a, b) => { | |
if (direction === 'ascending') { | |
return a.timestamp - b.timestamp; | |
} else { | |
return b.timestamp - a.timestamp; | |
} | |
}); | |
} | |
/** | |
* Sort reviews by rating | |
* @param {('ascending'|'descending')} direction | |
*/ | |
sortedByRating(direction) { | |
return this.reviews.sort((a, b) => { | |
if (direction === 'ascending') { | |
return a.rating - b.rating; | |
} else { | |
return b.rating - a.rating; | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment