@salla.sa/twilight-components
Version:
Salla Web Component
226 lines (217 loc) • 14.8 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
'use strict';
var index = require('./index-C7gO-zm5.js');
var specialDiscount = require('./special-discount-DC2oXurL.js');
var gift = require('./gift-DbNivqYO.js');
var tagMoney = require('./tag-money-Cuohw_4j.js');
var keyboard_arrow_down = require('./keyboard_arrow_down-DHJ3FFZq.js');
var cart = require('./cart-s-x1Fshk.js');
var anime_es = require('./anime.es-BqW8JHZi.js');
var FireIcon = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>fire</title>
<path d="M21.56 3.009c-0.052-0.047-0.116-0.065-0.173-0.103-0.073-0.048-0.143-0.1-0.223-0.132-0.083-0.033-0.165-0.047-0.252-0.063-0.081-0.016-0.16-0.035-0.243-0.035-0.089 0-0.172 0.020-0.26 0.037-0.080 0.016-0.159 0.028-0.236 0.059-0.084 0.035-0.157 0.088-0.235 0.14-0.053 0.036-0.115 0.053-0.165 0.097-0.049 0.044-0.988 0.895-2.288 2.255-2.364-2.839-4.476-4.815-4.576-4.908-0.056-0.052-0.127-0.075-0.188-0.115-0.075-0.049-0.143-0.105-0.224-0.137-0.080-0.032-0.163-0.041-0.245-0.057-0.085-0.016-0.167-0.040-0.252-0.040-0.084 0-0.163 0.023-0.245 0.039-0.087 0.016-0.172 0.025-0.253 0.059-0.080 0.032-0.147 0.087-0.22 0.135-0.063 0.041-0.133 0.064-0.189 0.116-0.453 0.423-11.092 10.408-11.092 18.095 0 7.977 4.935 13.549 12 13.549h8.667c6.673 0 11.333-5.115 11.333-12.439 0-7.052-10.013-16.167-10.44-16.552zM20.667 29.333h-7.777c-2.924 0-4.889-2.044-4.889-5.084 0-2.317 2.816-6.441 4.888-8.887 0.76 0.909 2.755 3.397 3.969 5.869 0.212 0.431 0.639 0.715 1.117 0.743 0.489 0.031 0.937-0.203 1.197-0.605 0.552-0.849 1.109-1.596 1.497-2.093 1.491 1.897 3.331 4.78 3.331 6.399 0 2.188-1.34 3.659-3.333 3.659zM26.537 27.052c0.081-0.44 0.129-0.899 0.129-1.377 0-3.269-3.713-7.847-4.46-8.735l-0.523-0.617c-0.507-0.599-1.528-0.599-2.035 0l-0.531 0.627c-0.147 0.175-0.495 0.599-0.936 1.187-1.595-2.597-3.495-4.776-3.595-4.889l-0.697-0.793c-0.507-0.577-1.499-0.577-2.004 0l-0.697 0.795c-0.6 0.684-5.856 6.803-5.856 11.001 0 0.881 0.127 1.712 0.356 2.484-1.896-1.933-3.023-4.821-3.023-8.283 0-4.915 6.073-11.997 9.329-15.255 1.001 1.008 2.692 2.789 4.368 4.927 0.243 0.309 0.609 0.496 1.001 0.509h0.048c0.376 0 0.735-0.159 0.988-0.439 0.889-0.981 1.693-1.795 2.269-2.359 3.051 2.965 8.663 9.323 8.663 13.727 0 3.171-1.031 5.769-2.796 7.491z"></path>
</svg>
`;
var DiscountCouponIcon = `<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>discount-coupon</title>
<path d="M27 28h-22c-0.552 0-1-0.448-1-1v0c0-1.657-1.343-3-3-3v0c-0.552 0-1-0.448-1-1v0-12c0-0.552 0.448-1 1-1v0c1.657 0 3-1.343 3-3v0c0-0.552 0.448-1 1-1v0h22c0.552 0 1 0.448 1 1v0c0 1.657 1.343 3 3 3v0c0.552 0 1 0.448 1 1v0 12c0 0.552-0.448 1-1 1v0c-1.657 0-3 1.343-3 3v0c0 0.552-0.448 1-1 1v0zM5.9 26h20.2c0.415-1.964 1.936-3.485 3.867-3.894l0.033-0.006v-10.2c-1.964-0.415-3.485-1.936-3.894-3.867l-0.006-0.033h-20.2c-0.415 1.964-1.936 3.485-3.867 3.894l-0.033 0.006v10.2c1.964 0.415 3.485 1.936 3.894 3.867l0.006 0.033zM20 7h2v3h-2v-3zM20 12h2v4h-2v-4zM20 18h2v4h-2v-4zM20 24h2v3h-2v-3zM9 16c-1.657 0-3-1.343-3-3s1.343-3 3-3c1.657 0 3 1.343 3 3v0c0 1.657-1.343 3-3 3v0zM9 12c-0.552 0-1 0.448-1 1s0.448 1 1 1c0.552 0 1-0.448 1-1v0c0-0.552-0.448-1-1-1v0zM15 24c-1.657 0-3-1.343-3-3s1.343-3 3-3c1.657 0 3 1.343 3 3v0c0 1.657-1.343 3-3 3v0zM15 20c-0.552 0-1 0.448-1 1s0.448 1 1 1c0.552 0 1-0.448 1-1v0c0-0.552-0.448-1-1-1v0zM7 24c-0.552-0-1-0.448-1-1 0-0.244 0.088-0.468 0.233-0.642l-0.001 0.002 10-12c0.185-0.221 0.461-0.36 0.769-0.36 0.553 0 1.001 0.448 1.001 1.001 0 0.245-0.088 0.469-0.233 0.643l0.001-0.002-10 12c-0.185 0.22-0.46 0.358-0.767 0.358-0.001 0-0.002 0-0.003 0h0z"></path>
</svg>
`;
const sallaCartItemOffersCss = ":host{display:block}";
const SallaCartItemOffers = class {
constructor(hostRef) {
index.registerInstance(this, hostRef);
this.internalOffers = [];
this.showAll = false;
// Translations
this.freeLabel = '';
this.receivedOffer = '';
this.discountAmountLabel = '';
this.showMoreOffers = '';
this.icons = {
DiscountCouponIcon,
GiftIcon: gift.SIGift,
FireIcon,
SpecialDiscountIcon: specialDiscount.SpecialDiscountIcon,
TagMoneyIcon: tagMoney.TagMoneyIcon,
};
this.visibleOffersCount = 3;
this.handleCartItemUpdated = (response) => {
const updatedItem = response.data?.cart?.items?.find((item) => String(item.id) === String(this.itemId));
if (updatedItem) {
this.internalQuantity = updatedItem.quantity;
this.internalOffers = updatedItem.detailed_offers || [];
this.internalProductPrice = updatedItem.product_price;
}
};
this.toggleShowAll = () => {
this.showAll = !this.showAll;
};
}
async componentWillLoad() {
await Salla.onReady();
await salla.lang.onLoaded(() => {
this.freeLabel = salla.lang.get('common.elements.freeExclam');
this.receivedOffer = salla.lang.get('pages.cart.received_offer');
this.discountAmountLabel = salla.lang.get('pages.cart.discount_amount');
this.showMoreOffers = salla.lang.get('pages.cart.show_more_offers');
});
this.internalQuantity = this.quantity;
this.internalOffers = this.parseOffers(this.offers);
this.internalProductPrice = this.productPrice;
}
componentDidLoad() {
Salla.cart.event.onLatestFetched(this.handleCartItemUpdated);
Salla.cart.event.onItemUpdated(this.handleCartItemUpdated);
Salla.cart.event.onCouponAdded(this.handleCartItemUpdated);
Salla.cart.event.onCouponDeleted(this.handleCartItemUpdated);
}
parseOffers(offers) {
try {
if (typeof offers !== 'string') {
console.warn('Offers is not a string. Returning as-is.', offers);
return Array.isArray(offers) ? offers : [];
}
const parsed = JSON.parse(offers || '[]');
return Array.isArray(parsed) ? parsed : [];
}
catch (e) {
console.error('Failed to parse offers', e);
return [];
}
}
get visibleOffers() {
return this.internalOffers.slice(0, this.visibleOffersCount);
}
get hiddenOffers() {
return this.internalOffers.slice(this.visibleOffersCount);
}
getPaidQty(quantity, offer) {
return quantity - offer.free_quantity;
}
renderOffer(quantity, offer) {
const paidQty = this.getPaidQty(quantity, offer);
return (index.h("div", { class: "s-cart-item-offers-box" }, offer.free_quantity > 0 && paidQty > 0 && (index.h("div", { class: "s-cart-item-offers-paid-free" }, index.h("div", { class: "s-cart-item-offers-line" }, salla.helpers.number(paidQty), " \u00D7 ", index.h("span", { innerHTML: salla.money(this.internalProductPrice) })), index.h("div", { class: "s-cart-item-offers-line" }, salla.helpers.number(offer.free_quantity), " \u00D7", index.h("span", { class: "s-cart-item-offers-regular-price", innerHTML: salla.money(this.internalProductPrice) }), index.h("span", { class: "s-cart-item-offers-free-label" }, this.freeLabel)))), index.h("div", { class: "s-cart-item-offers-details" }, index.h("span", { class: `s-cart-item-offers-icon`, innerHTML: this.icons[offer.discount_icon] || '' }), index.h("div", null, index.h("p", { class: "s-cart-item-offers-title" }, this.receivedOffer.replace(':offer', offer.offer_name)), index.h("p", { class: "s-cart-item-offers-discount" }, index.h("span", { innerHTML: this.discountAmountLabel.replace(':amount', salla.money(offer.discount_amount.toFixed(2))) }))))));
}
render() {
if (!this.internalOffers?.length) {
return null;
}
return (index.h("div", { class: "s-cart-item-offers-container", id: `offers_list_${this.itemId}` }, this.visibleOffers.map((offer) => this.renderOffer(this.internalQuantity, offer)), this.internalOffers?.length > this.visibleOffersCount && (index.h("div", { class: "s-cart-item-offers-show-more" }, index.h("button", { class: "s-cart-item-offers-show-more-btn", onClick: this.toggleShowAll, type: "button" }, index.h("span", { class: "s-cart-item-offers-show-more-label" }, "+", this.hiddenOffers.length, " ", this.showMoreOffers, index.h("span", { innerHTML: keyboard_arrow_down.ArrowDown, class: {
's-cart-item-offers-arrow-icon': true,
's-cart-item-offers-arrow-open': this.showAll,
} }))))), this.showAll && (index.h("div", { class: "s-cart-item-offers-collapsed", id: `offers_${this.itemId}` }, this.hiddenOffers.map((offer) => this.renderOffer(this.internalQuantity, offer))))));
}
};
SallaCartItemOffers.style = sallaCartItemOffersCss;
const sallaCartSummaryCss = "";
const SallaCartSummary = class {
constructor(hostRef) {
index.registerInstance(this, hostRef);
this.cartSummaryCount = salla.storage.get('cart.summary.count') || 0;
this.cartSummaryTotal = salla.storage.get('cart.summary.total') || 0;
this.cartLabel = salla.config.get('user.language_code') === 'ar' ? 'السلة' : 'Cart';
salla.cart.event.onUpdated((response) => {
this.cartSummaryCount = response.count || 0;
this.cartSummaryTotal = response.total || 0;
});
}
/**
* Animate product Image to cart summary
* @param image the image element to animate
*/
async animateToCart(image) {
document.querySelectorAll('.s-cart-thumb').forEach(el => el.remove());
if (!image?.src) {
salla.log('Failed to get the img element');
return;
}
let cartBtn = this.host.querySelector('#s-cart-icon'), btnOffset = cartBtn.getBoundingClientRect(), btnTop = btnOffset.top + window.scrollY, btnLeft = btnOffset.left + window.scrollX;
// get thumb position ---
let position = image.getBoundingClientRect(), width = image.offsetWidth + 'px', height = image.offsetHeight + 'px', top = position.top, left = position.left;
// create thumb img element ---
let img = document.createElement("img");
img.src = image.getAttribute('src');
img.className = "s-cart-thumb";
img.setAttribute("style", "object-fit:cover; width:" + width + '; height:' + height + '; top:' + top + 'px; left:' + left + 'px;z-index:99999999; ');
document.body.append(img);
let cartThumb = document.querySelector('.s-cart-thumb');
cartBtn.classList.remove('animated', 'rubberBand');
// start timeline ---
let cartThumbAnime = new anime_es.anime.timeline();
cartThumbAnime.add({
targets: cartThumb,
width: [150, 30],
height: [150, 30],
top: [top, window.scrollY > 0 ? btnTop - window.scrollY - 40 : btnTop - 40],
left: [left, btnLeft],
borderRadius: ['20%', '50%'],
easing: 'easeOutExpo',
duration: 1200,
}, '+=200')
.add({
targets: cartThumb,
width: [30, 0],
height: [30, 0],
opacity: [1, 0],
easing: 'easeOutExpo',
top: [window.scrollY > 0 ? btnTop - window.scrollY - 40 : btnTop - 40, window.scrollY > 0 ? btnTop - window.scrollY + 10 : btnTop + 10],
left: [btnLeft, btnLeft + 10],
}, '-=500')
.add({
complete: function () {
cartBtn.classList.add('animated', 'rubberBand');
cartThumb.remove();
},
}, '-=1700');
}
/**
* Some times it renderes with main domain, something like `https://salla.sa/cart`, because salla is not loaded,
* here, we are sure it will not be rendred unless salla is ready
*/
componentWillLoad() {
return new Promise(resolve => salla.onReady(resolve));
}
/**
* Compute cart href with scope + allocation parameters.
* Uses storage (not config) so allocation_type/allocation_id set by bullet-delivery are included.
*/
getCartLink() {
let cartUrl = salla.url.get('cart');
// Prefer storage over config: storage holds allocation_type/allocation_id, config only has type+id
const scope = salla.storage.get('scope') || salla.config.get('store.scope');
if (scope && scope.id) {
try {
const url = new URL(cartUrl);
url.searchParams.set('scope', scope.id);
if (scope.allocation_type)
url.searchParams.set('allocation_type', scope.allocation_type);
if (scope.allocation_id)
url.searchParams.set('allocation_id', scope.allocation_id);
return url.toString();
}
catch (e) {
const delimiter = cartUrl.includes('?') ? '&' : '?';
const params = new URLSearchParams();
params.set('scope', String(scope.id));
if (scope.allocation_type)
params.set('allocation_type', scope.allocation_type);
if (scope.allocation_id)
params.set('allocation_id', scope.allocation_id);
return `${cartUrl}${delimiter}${params.toString()}`;
}
}
return cartUrl;
}
render() {
return (index.h(index.Host, { key: '918f027fd28cd25d653b8419f97223daaf22d428' }, index.h("a", { key: 'b74a2724ada356a01b915044d56dfb0f9953338e', class: "s-cart-summary-wrapper", href: this.getCartLink() }, index.h("div", { key: 'b9332fe1b66b895c1e9950efaa548f04eb053d46', id: "s-cart-icon" }, index.h("slot", { key: '2b5c1cf8dea4ca23a54beeb83cfad44538ca3ab7', name: "icon" }, index.h("i", { key: 'f3145ed4a994762441d925280a3234d78c378bef', class: "s-cart-summary-icon", innerHTML: cart.PendingOrdersIcon }))), index.h("span", { key: '26a78adf9b279019504e995216ea5373b6866876', class: "s-cart-summary-count" }, salla.helpers.number(this.cartSummaryCount)), index.h("p", { key: '60ad091221ed5cd3e2ac0d27ebc53ec9917ccd64', class: "s-cart-summary-content" }, this.showCartLabel && index.h("span", { key: '66819086b9ed7f6f21be2cd5e8baf0bc88021e40', class: "s-cart-summary-label" }, this.cartLabel), index.h("b", { key: 'a07c85971e50add3cdd5b51942e642d4daf19d82', class: "s-cart-summary-total", innerHTML: salla.money(this.cartSummaryTotal) })))));
}
get host() { return index.getElement(this); }
};
SallaCartSummary.style = sallaCartSummaryCss;
exports.salla_cart_item_offers = SallaCartItemOffers;
exports.salla_cart_summary = SallaCartSummary;