UNPKG

@salla.sa/twilight-components

Version:
257 lines (256 loc) 11.2 kB
/*! * Crafted with ❤ by Salla */ import { Host, h } from "@stencil/core"; import BellRingIcon from "../../assets/svg/bell-ring.svg"; import Helper from "../../Helpers/Helper"; export class SallaProductAvailability { constructor() { this.isUser = salla.config.isUser(); this.translationLoaded = false; /** * Listen to product options availability. */ this.notifyOptionsAvailability = false; /** * is current user already subscribed */ this.isSubscribed = false; this.handleSubmitOptions = async () => { let payload = { id: this.productId }; if (!this.notifyOptionsAvailability) { return payload; } let optionsElement = document.querySelector(`salla-product-options[product-id="${this.productId}"]`); let options = Object.values(await optionsElement?.getSelectedOptionsData() || {}); //if all options not selected, show message && throw exception if (options.length && !await optionsElement?.reportValidity()) { let errorMessage = salla.lang.get('common.messages.required_fields'); salla.error(errorMessage); throw errorMessage; } payload.options = []; options.forEach(option => { //inject numbers only, without zeros if (option && !isNaN(option)) { payload.options.push(Number(option)); } }); return payload; }; // helpers this.typing = (e) => { const error = e.target.nextElementSibling; e.target.classList.remove('s-has-error'); error?.classList.contains('s-product-availability-error-msg') && (error.innerText = ''); e.keyCode === 13 && this.submit(); }; salla.lang.onLoaded(() => { this.translationLoaded = true; this.title_ = this.host.title || salla.lang.get('pages.products.notify_availability_title'); this.modal?.setTitle(this.title_); }); if (!this.productId) { this.productId = salla.config.get('page.id'); } if (this.isUser) return; this.channelsWatcher(this.channels); this.title_ = this.host.title || salla.lang.get('pages.products.notify_availability_title'); this.host.removeAttribute('title'); //todo:: fix this to cover options too this.isVisitorSubscribed = !this.notifyOptionsAvailability ? salla.storage.get(`product-${this.productId}-subscribed`) : ''; } channelsWatcher(newValue) { this.channels_ = !!newValue ? newValue.split(',') : []; } openModel() { this.handleSubmitOptions().then(isSuccess => isSuccess ? this.modal.open() : null); } async submit() { let payload = await this.handleSubmitOptions(); if (this.isUser) { return salla.api.product.availabilitySubscribe(payload) .then(() => this.isSubscribed = true); } if (this.channels_.includes('sms')) { let { phone, countryCode } = await this.mobileInput.getValues(); payload['country_code'] = countryCode; payload['phone'] = phone; } if (this.channels_.includes('email')) { this.email.value !== '' && (payload['email'] = this.email.value); } await this.validateform(); return this.btn.load() .then(() => this.btn.disable()) .then(() => salla.api.product.availabilitySubscribe(payload)) .then(() => { if (!this.notifyOptionsAvailability) { salla.storage.set(`product-${this.productId}-subscribed`, true); this.isSubscribed = true; return; } if (payload.options.length) { let options = salla.storage.get(`product-${this.productId}-subscribed-options`) || []; let selectedOptionsString = payload.options.join(','); if (!options.includes(selectedOptionsString)) { options.push(selectedOptionsString); salla.storage.set(`product-${this.productId}-subscribed-options`, options); this.isSubscribed = true; } else { salla.log('already subscribed to this options'); } } }) .then(() => this.btn.stop()) .then(() => this.modal.close()) .catch(() => this.btn.stop() && this.btn.enable()); } async validateform() { try { if (this.channels_.includes('email')) { const isEmailValid = Helper.isValidEmail(this.email.value); if (isEmailValid) return; !isEmailValid && this.validateField(this.email, salla.lang.get('common.elements.email_is_valid')); } if (this.channels_.includes('sms')) { const isPhoneValid = await this.mobileInput.isValid(); if (isPhoneValid) return; } } catch (error) { throw ('Please insert required fields'); } } validateField(field, errorMsg) { field.classList.add('s-has-error'); field.nextElementSibling['innerText'] = '* ' + errorMsg; } render() { return (h(Host, { key: 'aa627ba618b159913ad91efba99e57c14dd27832', class: "s-product-availability-wrap" }, this.isSubscribed || this.isVisitorSubscribed ? h("div", { class: "s-product-availability-subscribed" }, h("span", { innerHTML: BellRingIcon, class: "s-product-availability-subs-icon" }), salla.lang.get('pages.products.notify_availability_success')) : h("salla-button", { width: "wide", onClick: () => this.isUser ? this.submit() : this.openModel() }, salla.lang.get('pages.products.notify_availability')), this.isUser || this.isSubscribed || this.isVisitorSubscribed ? '' : this.renderModal())); } renderModal() { return (h("salla-modal", { ref: modal => this.modal = modal, "modal-title": this.title_, subTitle: salla.lang.get('pages.products.notify_availability_subtitle'), width: "sm" }, h("span", { slot: 'icon', class: "s-product-availability-header-icon", innerHTML: BellRingIcon }), h("div", { class: "s-product-availability-body" }, this.channels_.includes('email') ? [ h("label", { class: "s-product-availability-label" }, salla.lang.get('common.elements.email')), h("input", { class: "s-product-availability-input", onKeyDown: e => this.typing(e), placeholder: salla.lang.get('common.elements.email_placeholder') || 'your@email.com', ref: el => this.email = el, type: "email" }), h("span", { class: "s-product-availability-error-msg" }) ] : '', this.channels_.includes('sms') ? [ h("label", { class: "s-product-availability-label" }, salla.lang.get('common.elements.mobile')), h("salla-tel-input", { ref: el => this.mobileInput = el, onKeyDown: e => this.typing(e) }) ] : ''), h("div", { slot: "footer", class: "s-product-availability-footer" }, h("salla-button", { class: "modal-cancel-btn", width: "wide", color: "light", fill: "outline", onClick: () => this.modal.close() }, salla.lang.get('common.elements.cancel')), h("salla-button", { class: "submit-btn", "loader-position": 'center', width: "wide", ref: btn => this.btn = btn, onClick: () => this.submit() }, salla.lang.get('common.elements.submit'))))); } static get is() { return "salla-product-availability"; } static get originalStyleUrls() { return { "$": ["salla-product-availability.scss"] }; } static get styleUrls() { return { "$": ["salla-product-availability.css"] }; } static get properties() { return { "channels": { "type": "string", "attribute": "channels", "mutable": false, "complexType": { "original": "'sms' | 'email' | 'sms,email'", "resolved": "\"email\" | \"sms\" | \"sms,email\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Notification channels" }, "getter": false, "setter": false, "reflect": false }, "notifyOptionsAvailability": { "type": "boolean", "attribute": "notify-options-availability", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Listen to product options availability." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "productId": { "type": "number", "attribute": "product-id", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "product id that can visitor subscribe to its availability notification" }, "getter": false, "setter": false, "reflect": false }, "isSubscribed": { "type": "boolean", "attribute": "is-subscribed", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "is current user already subscribed" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" } }; } static get states() { return { "translationLoaded": {}, "title_": {}, "isVisitorSubscribed": {} }; } static get elementRef() { return "host"; } static get watchers() { return [{ "propName": "channels", "methodName": "channelsWatcher" }]; } }