UNPKG

@salla.sa/twilight-components

Version:
364 lines (358 loc) 18.8 kB
/*! * Crafted with ❤ by Salla */ import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client'; import { d as defineCustomElement$c } from './salla-add-product-button2.js'; import { d as defineCustomElement$b } from './salla-button2.js'; import { d as defineCustomElement$a } from './salla-count-down2.js'; import { d as defineCustomElement$9 } from './salla-loading2.js'; import { d as defineCustomElement$8 } from './salla-modal2.js'; import { d as defineCustomElement$7 } from './salla-product-availability2.js'; import { d as defineCustomElement$6 } from './salla-product-card2.js'; import { d as defineCustomElement$5 } from './salla-progress-bar2.js'; import { d as defineCustomElement$4 } from './salla-quick-buy2.js'; import { d as defineCustomElement$3 } from './salla-slider2.js'; import { d as defineCustomElement$2 } from './salla-tel-input2.js'; var PageType; (function (PageType) { PageType["ProductDetail"] = "product.single"; PageType["Cart"] = "cart"; })(PageType || (PageType = {})); var OfferType; (function (OfferType) { OfferType["Conditional"] = "conditional"; OfferType["PercentageOrFixed"] = "fixed"; OfferType["DiscountsTable"] = "discounts_table"; OfferType["Bank"] = "bank"; OfferType["BuyXGetY"] = "buy_x_get_y"; })(OfferType || (OfferType = {})); const sallaOfferCss = ".s-offer-wrapper .s-slider-block__title h2{font-size:1.125rem;line-height:1.75rem;color:#f87171}.s-offer-wrapper .s-slider-block__title h2::before{font-family:\"sallaicons\";content:\"\\ee30\" !important;position:absolute;top:1rem;font-size:3rem;font-weight:400;line-height:1;color:#fef2f2}.s-offer-bank-wrapper-sinlge-item{display:-ms-flexbox;display:flex;-ms-flex-align:center !important;align-items:center !important;gap:14px}.s-offer-bank-wrapper{display:-ms-flexbox !important;display:flex !important;width:100% !important}"; const SallaOffer$1 = /*@__PURE__*/ proxyCustomElement(class SallaOffer extends HTMLElement { constructor() { super(); this.__registerHost(); var _a; /** * Custom Card Component for the Salla Products List. * * This component allows you to customize the appearance of individual product cards within a Salla Products List. * * @example * <salla-products-list product-card-component="my-custom-card-style1" ... * <salla-products-list product-card-component="my-custom-card-style2" ... */ this.productCardComponent = 'custom-salla-product-card'; // Declare component state variables this.offersList = []; this.isMultipleBank = false; this.isBankOffer = false; this.canRender = false; this.showOffer = salla.config.get('store.settings.product.show_special_offers'); // Default translated texts this.offer_with_price_text = salla.lang.get('pages.offer.with_price', { price: '' }); this.with_discount_text = salla.lang.get('pages.products.with_a_discount'); this.product_discount_text = salla.lang.get('pages.products.discount'); this.special_offer_text = salla.lang.get('pages.products.special_offer'); this.multipleBankOfferTitleText = salla.lang.get('pages.offer.multiple_bank_offers_title'); this.multipleBankOfferTitleDescription = salla.lang.get('pages.offer.multiple_bank_offers_message'); this.buy_quantity_text = (quantity) => salla.lang.get('pages.offer.buy_quantity', { quantity }); // Language salla.lang.onLoaded(() => { this.offer_with_price_text = salla.lang.get('pages.offer.with_price'); this.with_discount_text = salla.lang.get('pages.products.with_a_discount'); this.product_discount_text = salla.lang.get('pages.products.discount'); this.special_offer_text = salla.lang.get('pages.products.special_offer'); this.multipleBankOfferTitleText = salla.lang.get('pages.offer.multiple_bank_offers_title'); this.multipleBankOfferTitleDescription = salla.lang.get('pages.offer.multiple_bank_offers_message'); this.buy_quantity_text(0); }); salla.onReady(() => { this.currentPage = salla.config.get('page.slug'); this.userCurrency = salla.config.get('currencies')[salla.config.get('user.currency_code')].symbol; }); this.categorySlot = ((_a = this.host.querySelector('[slot="category"]')) === null || _a === void 0 ? void 0 : _a.innerHTML) || '<a href={url} class="s-offer-slide-cat-entry"><i class={icon}></i><h4>{name}</h4></a>'; } getEndpointByPageName() { return { [PageType.Cart]: `offers/cart/${salla.storage.get('cart.id')}`, [PageType.ProductDetail]: `offers/product/${salla.config.get('page.id')}`, }[this.currentPage] || "offers"; } componentWillLoad() { this.hasCustomComponent = !!customElements.get(this.productCardComponent); // let offers = this.getOffersFromStorage(); // if (offers) { // return offers.then(offersFromStorage => this.offersList = offersFromStorage); // } return (new Promise(resolve => salla.onReady(resolve))) .then(() => { this.showOffer = !salla.url.is_page('product.single') || salla.config.get('store.settings.product.show_special_offers'); if (this.showOffer) { return; } throw new Error("Merchant disabled showing the offers on product page"); }) .then(() => salla.api.request(this.getEndpointByPageName())) .then((res) => { if (!(this.offersList = res.data).length) { throw new Error('salla-offers:: There is no offers!'); } //we support these offers only const offer = this.offersList.find(offer => [OfferType.Bank, OfferType.BuyXGetY, OfferType.DiscountsTable].includes(offer.type)); if (!offer) { throw new Error('salla-offers:: Offer type not supported yet!'); } //because there is no need for special handling for discounts table, just skip the other cases if (offer.type === OfferType.DiscountsTable) { return this.offersList = [offer]; } //if it's banks offer, we need to include the other banks overs if ((this.isBankOffer = offer.type === OfferType.Bank)) { this.offersList = this.offersList.filter(offer => offer.type === OfferType.Bank); this.isMultipleBank = this.offersList.length > 1; return this.offersList; } //BuyXGetY offers const getY = offer.details.get; return getY.source === 'products' //todo:: avoid this request, and the handling for the products, just use `salla-products-slider` and don't forget to pass the customcard ? salla.product.api.fetch({ source: "selected", source_value: getY.source_value }) .then((response) => { getY.products = response.data; offer.details.get = getY; return this.offersList = [offer]; }) //set the products : salla.product.api.categories() //get all categories in one query, then extract only the selected one, instead of sending multi requests .then((res) => { getY.categories = this.findCategories(res.data, getY.source_value); offer.details.get = getY; return this.offersList = [offer]; }); }) .then((offers) => { salla.storage.set(this.getStorageKey(), { offers, stored_at: new Date().getTime() }); this.canRender = true; }) .catch((error) => { salla.logger.warn(error); }); } componentDidLoad() { let nav = this.host.querySelector('.s-slider-block__title-nav'); nav === null || nav === void 0 ? void 0 : nav.classList.add("s-offer-bank-payment-nav"); } findCategories(categories, ids) { var _a; let found = []; for (const category of categories) { if (ids.includes(category.id_ || category.id)) { //here we are using || because we are planning to drop `id_` found.push(category); } if (((_a = category.sub_categories) === null || _a === void 0 ? void 0 : _a.length) > 0) { found = found.concat(this.findCategories(category.sub_categories, ids)); } } return found; } //todo::add to the key params, to make sure it will support multi offers in the same page if it's wanted getStorageKey() { try { const pageSlug = salla.config.get('page.slug').replace('.', '_'); const locale = salla.lang.getLocale(); const currencyCode = salla.config.currency().code; if (!pageSlug || !locale || !currencyCode) { throw new Error('Unable to get the storage key.'); } return `s-offers-${pageSlug}-${salla.config.get('page.id')}-${locale}-${currencyCode}`; } catch (error) { return ''; } } //@ts-ignore getOffersFromStorage() { let storageOffers = salla.storage.get(this.getStorageKey()); //if the offers not existed, or it has been stored before 10 minutes from now, ignore it; if (!storageOffers || storageOffers.stored_at < (new Date().getTime() - 10 * 60 * 1000)) { salla.storage.remove(this.getStorageKey()); return null; } this.canRender = true; //return it as resolve to support .then return Promise.resolve(storageOffers.offers); } render() { if (!this.offersList.length || !this.canRender || !this.showOffer) return null; const offer = this.offersList[0]; const blockTitle = this.isBankOffer ? (this.isMultipleBank ? this.multipleBankOfferTitleText : null) : offer.title; const blockSubTitle = this.isBankOffer ? (this.isMultipleBank ? this.multipleBankOfferTitleDescription : null) : offer.description; const titles = { 'block-title': blockTitle, 'block-subTitle': blockSubTitle, 'show-controls': this.isMultipleBank }; return (h("div", { class: "s-offer-wrapper" }, h("p", { class: "s-offer-corner-badge" }, this.special_offer_text), h("salla-slider", Object.assign({ type: "carousel", id: "offer-slider" }, titles), h("div", { slot: 'items' }, this.renderSectionForOfferType(offer.type))))); } renderSectionForOfferType(offerType) { if (this.isBankOffer) { return this.renderBankSection(); } if (offerType == OfferType.BuyXGetY) { return this.renderBuyXGetYSection(); } return this.renderDiscountTableSection(); } /** * Generates content for the categories section. * * @param offeredCategories - An array of Category objects. * @returns An array of HTML elements representing categories. */ getCategoriesSection(category) { return h("div", { class: "s-offer-slide-one-sixth swiper-slide", innerHTML: this.categorySlot .replace(/\{url\}/g, category.url) .replace(/\{icon\}/g, category.icon || "sicon-store") .replace(/\{name\}/g, category.name) }); } renderBuyXGetYSection() { var _a, _b; const details = this.offersList[0].details; return [ (_a = details.get.products) === null || _a === void 0 ? void 0 : _a.map((product) => (h("div", { class: "s-offer-slide-one-fourth" }, this.hasCustomComponent ? h(this.productCardComponent, { product: product }) : h("salla-product-card", { "shadow-on-hover": true, product: product })))), (_b = details.get.categories) === null || _b === void 0 ? void 0 : _b.map((category) => this.getCategoriesSection(category)) ]; } /** * Generates content for the bank section. * * @param offeredBank - An array of Bank objects. * @param name - The title of the current offer. * @param description - The description of the current offer. * @returns An array of HTML elements representing banks. * * TODO: loop over the list and filter bank types and pass it to this function */ renderBankSection() { return this.offersList.map((bankOffer) => { return h("div", { class: { "s-offer-slide-one-sixth": this.isMultipleBank, "s-offer-bank-wrapper-sinlge-item": !this.isMultipleBank } }, h("div", { class: { "s-offer-bank-wrapper": true, "s-offer-slide-one-sixth": !this.isMultipleBank, "s-offer-bank-wrapper-multi-spacer": this.isMultipleBank } }, h("div", { class: "s-offer-bank-logo" }, h("img", { src: bankOffer.details.logo || salla.url.cdn('images/s-empty.png'), "data-src": bankOffer.details.logo, alt: bankOffer.title + " offer" })), h("ul", { class: "s-offer-bank-payment-wrapper" }, bankOffer.details.payments.map((payment) => { return h("li", { class: "s-offer-bank-payment-single" }, h("img", { src: salla.url.cdn('images/payment/' + payment + '.png') || salla.url.cdn('images/s-empty.png'), "data-src": salla.url.cdn('images/payment/' + payment + '.png'), alt: "payment" })); })), this.isMultipleBank ? h("p", { class: "s-offer-bank-payment-discount-percent" }, `${this.product_discount_text} ${bankOffer.details.discount_value}${bankOffer.details.discount_type === "percentage" && '%'}`) : ""), !this.isMultipleBank ? h("div", { class: "s-offer-bank-message s-offer-slide-one-fourth" }, h("h2", null, this.offersList[0].title), h("p", { innerHTML: this.generateBankDescription(this.offersList[0].description, bankOffer.details.discount_value) })) : ""); }); } generateBankDescription(desc, value) { return desc.replace(new RegExp(`${value} %`), `<span class="s-offer-bank-message-amount">${value} %</span>`); } /** * Generates content for the discount table section. * * @param discountTable - An array of Discount objects. * @returns An array of HTML elements representing discounts_table. */ renderDiscountTableSection() { var _a; const offer = this.offersList[0]; let show_discounted_price = offer.details.show_price_after_discount; return (_a = this.offersList[0].details.discounts) === null || _a === void 0 ? void 0 : _a.map((discount) => h("div", { class: "s-offer-slide-one-fourth" }, h("div", { class: "s-offer-slide-offer-entry" }, h("div", { class: "s-offer-slide-offer-entry-price-quantity-container" }, h("p", { class: "s-offer-slide-offer-entry-quantity" }, this.buy_quantity_text(discount.quantity)), show_discounted_price ? h("div", { class: "s-offer-slide-offer-entry-price" }, h("span", null, this.offer_with_price_text), h("span", { class: "s-offer-slide-offer-entry-price-amount" }, discount.discounted_amount), " ", h("span", null, this.userCurrency)) : ""), h("p", { class: "s-offer-slide-offer-entry-price-amount-percent" }, this.with_discount_text, "(", h("span", null, discount.percentage, !!discount.percentage && '%'), ")")))); } get host() { return this; } static get style() { return sallaOfferCss; } }, [0, "salla-offer", { "productCardComponent": [1, "product-card-component"], "offersList": [32], "userCurrency": [32], "isMultipleBank": [32], "title": [32], "currentPage": [32], "hasCustomComponent": [32], "isBankOffer": [32], "canRender": [32], "showOffer": [32], "offer_with_price_text": [32], "with_discount_text": [32], "product_discount_text": [32], "special_offer_text": [32], "multipleBankOfferTitleText": [32], "multipleBankOfferTitleDescription": [32], "buy_quantity_text": [32] }]); function defineCustomElement$1() { if (typeof customElements === "undefined") { return; } const components = ["salla-offer", "salla-add-product-button", "salla-button", "salla-count-down", "salla-loading", "salla-modal", "salla-product-availability", "salla-product-card", "salla-progress-bar", "salla-quick-buy", "salla-slider", "salla-tel-input"]; components.forEach(tagName => { switch (tagName) { case "salla-offer": if (!customElements.get(tagName)) { customElements.define(tagName, SallaOffer$1); } break; case "salla-add-product-button": if (!customElements.get(tagName)) { defineCustomElement$c(); } break; case "salla-button": if (!customElements.get(tagName)) { defineCustomElement$b(); } break; case "salla-count-down": if (!customElements.get(tagName)) { defineCustomElement$a(); } break; case "salla-loading": if (!customElements.get(tagName)) { defineCustomElement$9(); } break; case "salla-modal": if (!customElements.get(tagName)) { defineCustomElement$8(); } break; case "salla-product-availability": if (!customElements.get(tagName)) { defineCustomElement$7(); } break; case "salla-product-card": if (!customElements.get(tagName)) { defineCustomElement$6(); } break; case "salla-progress-bar": if (!customElements.get(tagName)) { defineCustomElement$5(); } break; case "salla-quick-buy": if (!customElements.get(tagName)) { defineCustomElement$4(); } break; case "salla-slider": if (!customElements.get(tagName)) { defineCustomElement$3(); } break; case "salla-tel-input": if (!customElements.get(tagName)) { defineCustomElement$2(); } break; } }); } const SallaOffer = SallaOffer$1; const defineCustomElement = defineCustomElement$1; export { SallaOffer, defineCustomElement }; //# sourceMappingURL=salla-offer.js.map //# sourceMappingURL=salla-offer.js.map