@salla.sa/twilight-components
Version:
Salla Web Component
175 lines (174 loc) • 8.36 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { h } from "@stencil/core";
import ShoppingBag from "../../assets/svg/shopping-bag.svg";
import Helper from "../../Helpers/Helper";
import { MasonryLayout } from "../../Helpers/masonry-layout";
export class SallaReviewsPage {
constructor() {
this.reviews = [];
this.isLoading = false;
this.pagination = null;
this.sort = "latest";
}
getUrlParams() {
const params = new URLSearchParams(window.location.search);
return {
sort: params.get('sort') || null,
page: Number.parseInt(params.get('page')) || 1
};
}
updateUrlParams(params) {
const url = new URL(window.location.href);
for (const [key, value] of Object.entries(params)) {
if (value) {
url.searchParams.set(key, value.toString());
}
else {
url.searchParams.delete(key);
}
}
;
window.history.replaceState({}, '', url.toString());
}
fetchReviews(sort, page) {
const urlParams = this.getUrlParams();
return salla.api.request('reviews', {
params: {
type: 'products',
format: 'lite',
per_page: 8,
page: page || urlParams.page || 1,
sort: sort || urlParams.sort || null
}
});
}
async initializeMasonry() {
const grid = this.el.querySelector('.s-reviews-page-grid');
if (!grid)
return;
try {
new MasonryLayout(grid);
salla.logger.info('Masonry initialized successfully');
}
catch (error) {
salla.logger.error('Masonry initialization failed:', error);
}
}
animateReviewCards() {
const items = this.wrapper.querySelectorAll('salla-review-card:not(.animated)');
Helper.animateItems(items);
}
initiateInfiniteScroll() {
var _a, _b, _c;
if (!this.wrapper) {
salla.logger.error('Wrapper is undefined. Cannot initiate infinite scroll.');
return;
}
this.infiniteScroll = salla.infiniteScroll.initiate(this.wrapper, this.wrapper, {
path: () => { var _a, _b; return ((_b = (_a = this.pagination) === null || _a === void 0 ? void 0 : _a.links) === null || _b === void 0 ? void 0 : _b.next) || null; },
history: false,
scrollThreshold: false,
}, true);
(_a = this.infiniteScroll) === null || _a === void 0 ? void 0 : _a.on('request', () => {
this.isLoading = true;
});
(_b = this.infiniteScroll) === null || _b === void 0 ? void 0 : _b.on('load', response => {
this.pagination = response.pagination;
this.reviews = [...this.reviews, ...response.data];
this.isLoading = false;
// Update URL with the current page
this.updateUrlParams({ page: response.pagination.current_page });
});
(_c = this.infiniteScroll) === null || _c === void 0 ? void 0 : _c.on('error', (e) => {
salla.logger.error('Error loading more reviews:', e);
this.isLoading = false;
});
}
componentDidRender() {
setTimeout(() => {
requestAnimationFrame(this.animateReviewCards.bind(this));
}, 176);
}
async componentWillLoad() {
var _a;
try {
await salla.onReady();
// Initialize language variables
this.langTitlesReviews = salla.lang.get("common.titles.reviews");
this.langSorting = salla.lang.get('pages.categories.sorting');
this.placeholderText = salla.lang.choice("pages.rating.reviews", 0);
this.langLoadMore = salla.lang.get('common.elements.load_more');
this.langSortByTopRating = salla.lang.get('pages.testimonials.sort_by_rating_desc');
this.langSortByMostRecent = salla.lang.get('pages.testimonials.sort_by_date_desc');
this.langSortByLeastRated = salla.lang.get('pages.testimonials.sort_by_rating_asc');
this.langSortByLeastRecent = salla.lang.get('pages.testimonials.sort_by_date_asc');
const urlParams = this.getUrlParams();
const response = await this.fetchReviews(urlParams.sort);
this.sort = urlParams.sort;
this.reviews = response.data;
this.pagination = response.pagination;
this.langRatingReviews = salla.lang.choice("pages.rating.reviews", (_a = this.pagination) === null || _a === void 0 ? void 0 : _a.total);
}
catch (error) {
salla.logger.error('Error loading reviews:', error);
}
}
async handleSorting(e) {
const value = e.target.value;
this.sort = value;
this.updateUrlParams({ sort: value, page: 1 }); // Reset to page 1 when changing sort
const response = await this.fetchReviews(value, 1);
this.reviews = response.data;
this.pagination = response.pagination;
}
async componentDidLoad() {
await this.initializeMasonry();
this.initiateInfiniteScroll();
this.sort = this.getUrlParams().sort || "latest";
this.updateUrlParams({ sort: this.sort, page: 1 });
}
disconnectedCallback() {
if (this.infiniteScroll) {
this.infiniteScroll.destroy();
}
}
renderSortingOptions() {
const options = [
{ value: 'latest', label: this.langSortByMostRecent },
{ value: 'oldest', label: this.langSortByLeastRecent },
{ value: 'top_rating', label: this.langSortByTopRating },
{ value: 'bottom_rating', label: this.langSortByLeastRated },
];
return options.map(option => (h("option", { key: option.value, value: option.value, selected: option.value === this.sort }, option.label)));
}
render() {
var _a, _b;
return (h("host", { key: '399a4d822a8442fb0f9a906f0db52fddec92ffc4' }, h("div", { key: 'fa4fa15c19b774d7eabf56f67f5bcae6b71572ab', class: "s-reviews-page-header-wrapper" }, h("h2", { key: '169d557070590248e506718c5b9aa116a84e5634', class: "s-reviews-page-title" }, this.langTitlesReviews, h("span", { key: '2549bf0697263d25aa3f2666164705e20dc51527', class: "s-reviews-page-count" }, "(", this.langRatingReviews, ")")), h("div", { key: 'bfc9cef261a830871a9832e0f137e2f181051c95', class: "s-reviews-page-filter-wrapper" }, h("label", { key: 'e4e245499b86254383ed7fb3290d0a09ee9bc604', class: "s-reviews-page-filter-label", htmlFor: "testimonials-filter" }, this.langSorting), h("select", { key: '6fcf56fa0a74026fb568d884218c55a96cd820f1', onChange: (e) => this.handleSorting(e), disabled: !this.reviews.length, class: "s-reviews-page-filter" }, this.renderSortingOptions()))), this.reviews.length ? h("main", { class: "s-reviews-page-grid", ref: el => {
this.wrapper = el;
} }, this.reviews.map(review => (h("salla-review-card", { key: review.id, review: review }))))
: h("div", { class: "s-products-list-placeholder" }, h("span", { innerHTML: ShoppingBag }), h("p", null, this.placeholderText)), ((_b = (_a = this.pagination) === null || _a === void 0 ? void 0 : _a.links) === null || _b === void 0 ? void 0 : _b.next) && this.reviews.length ? (h("div", { class: "s-reviews-page-load-more-container" }, h("salla-button", { class: "s-reviews-page-load-more-btn", loading: this.isLoading, onClick: () => { var _a; return (_a = this.infiniteScroll) === null || _a === void 0 ? void 0 : _a.loadNextPage(); }, onKeyUp: () => { var _a; return (_a = this.infiniteScroll) === null || _a === void 0 ? void 0 : _a.loadNextPage(); } }, this.langLoadMore))) : null));
}
static get is() { return "salla-reviews-page"; }
static get originalStyleUrls() {
return {
"$": ["salla-reviews-page.css"]
};
}
static get styleUrls() {
return {
"$": ["salla-reviews-page.css"]
};
}
static get states() {
return {
"reviews": {},
"isLoading": {},
"pagination": {},
"sort": {}
};
}
static get elementRef() { return "el"; }
}
//# sourceMappingURL=salla-reviews-page.js.map