@salla.sa/twilight-components
Version:
Salla Web Component
287 lines (278 loc) • 17.2 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
'use strict';
var index = require('./index-WgjOGof0.js');
var BookingTime = `<!-- 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>calendar-time</title>
<path d="M22.667 17.333c-0.737 0-1.333 0.596-1.333 1.333v2.667h-2.667c-0.737 0-1.333 0.596-1.333 1.333s0.596 1.333 1.333 1.333h4c0.737 0 1.333-0.596 1.333-1.333v-4c0-0.737-0.596-1.333-1.333-1.333zM28 2.667h-2.667v-1.333c0-0.736-0.596-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-13.333v-1.333c0-0.736-0.596-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-2.667c-2.205 0-4 1.795-4 4v21.333c0 2.205 1.795 4 4 4h5.363c0.737 0 1.333-0.596 1.333-1.333s-0.596-1.333-1.333-1.333h-5.363c-0.736 0-1.333-0.597-1.333-1.333v-21.333c0-0.736 0.597-1.333 1.333-1.333h2.667v2.667c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h13.333v2.667c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h2.667c0.736 0 1.333 0.599 1.333 1.333v2.696c0 0.736 0.596 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.696c0-2.205-1.795-4-4-4zM22 12c-5.515 0-10 4.485-10 10s4.485 10 10 10 10-4.485 10-10-4.485-10-10-10zM22 29.333c-4.043 0-7.333-3.291-7.333-7.333s3.291-7.333 7.333-7.333 7.333 3.291 7.333 7.333-3.291 7.333-7.333 7.333z"></path>
</svg>
`;
var Calendar = `<!-- 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>calendar</title>
<path d="M28 2.667h-2.667v-1.333c0-0.736-0.597-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-13.333v-1.333c0-0.736-0.597-1.333-1.333-1.333s-1.333 0.597-1.333 1.333v1.333h-2.667c-2.205 0-4 1.795-4 4v21.333c0 2.205 1.795 4 4 4h24c2.205 0 4-1.795 4-4v-21.333c0-2.205-1.795-4-4-4zM29.333 28c0 0.736-0.599 1.333-1.333 1.333h-24c-0.736 0-1.333-0.599-1.333-1.333v-13.333h26.667zM29.333 12h-26.667v-5.333c0-0.736 0.599-1.333 1.333-1.333h2.667v2.667c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h13.333v2.667c0 0.736 0.597 1.333 1.333 1.333s1.333-0.597 1.333-1.333v-2.667h2.667c0.736 0 1.333 0.599 1.333 1.333z"></path>
</svg>
`;
var TimeIcon = `<!-- 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>time</title>
<path d="M16 0c-8.823 0-16 7.177-16 16s7.177 16 16 16 16-7.177 16-16-7.177-16-16-16zM16 29.333c-7.352 0-13.333-5.981-13.333-13.333s5.981-13.333 13.333-13.333 13.333 5.981 13.333 13.333-5.981 13.333-13.333 13.333zM16 8c-0.736 0-1.333 0.596-1.333 1.333v6.667h-4c-0.736 0-1.333 0.596-1.333 1.333s0.597 1.333 1.333 1.333h5.333c0.736 0 1.333-0.596 1.333-1.333v-8c0-0.737-0.597-1.333-1.333-1.333z"></path>
</svg>
`;
const sallaBookingFieldCss = ":host{display:block}";
const SallaBookingField = class {
constructor(hostRef) {
index.registerInstance(this, hostRef);
this.invalidInput = index.createEvent(this, "invalidInput");
this.bookNowLabel = salla.lang.get('pages.cart.book_an_appointment', 'حجز موعد');
this.editLabel = salla.lang.get('pages.cart.edit_an_appointment', 'تعديل الموعد');
this.bookedLabel = salla.lang.get('pages.cart.booked_successfully', 'تمت اضافة الموعد بنجاح');
this.selectDate = salla.lang.get('pages.cart.select_appointment_date', 'حدد تاريخ الموعد');
this.bookingUrl = '';
this.iframeReady = false;
this.reservations = [];
// Load translations
salla.lang.onLoaded(() => this.setTranslations());
// Register event listeners
Salla.event.on('booking::open', (data) => this.handleBookingOpen(data));
}
async setTranslations() {
const setNestedAsync = (lang, key, value) => {
return new Promise((resolve) => {
salla.helpers.setNested(salla.lang.messages[lang], key, value);
resolve(true);
});
};
await setNestedAsync('ar.trans', 'pages.cart.book_an_appointment', 'حجز موعد');
await setNestedAsync('en.trans', 'pages.cart.book_an_appointment', 'Book an Appointment');
await setNestedAsync('ar.trans', 'pages.cart.edit_an_appointment', 'تعديل الموعد');
await setNestedAsync('en.trans', 'pages.cart.edit_an_appointment', 'Edit an Appointment');
await setNestedAsync('ar.trans', 'pages.cart.booked_successfully', 'تمت اضافة الموعد بنجاح');
await setNestedAsync('en.trans', 'pages.cart.booked_successfully', 'Booked Successfully');
await setNestedAsync('ar.trans', 'pages.cart.select_appointment_date', 'حدد تاريخ الموعد');
await setNestedAsync('en.trans', 'pages.cart.select_appointment_date', 'Select appointment date');
this.bookNowLabel = salla.lang.get('pages.cart.book_an_appointment');
this.editLabel = salla.lang.get('pages.cart.edit_an_appointment');
this.bookedLabel = salla.lang.get('pages.cart.booked_successfully');
this.selectDate = salla.lang.get('pages.cart.select_appointment_date');
}
openBookingModal(event, afterReload = false) {
if (afterReload && (!event.detail || typeof event.detail !== 'number' || event.detail !== this.productId)) {
return;
}
if (salla.config.isGuest()) {
this.setAfterReloadEvent('booking::open-after-reload', this.productId);
salla.event.dispatch('login::open');
return;
}
salla.booking.add(this.productId, false)
.then((resp) => {
if (resp.data.redirect.to !== 'booking') {
throw new Error('Unexpected redirect!');
}
salla.event.dispatch('booking::open', { url: resp.data.redirect.url, id: this.productId });
})
.catch((error) => {
salla.error(salla.lang.get('common.errors.error_occurred'));
salla.logger.error(error.response || error);
});
}
handleBookingOpen(data) {
if (data.id !== this.productId)
return;
this.bookingUrl = salla.url.addParamToUrl('product_id', data.id, data.url);
this.iframeReady = true;
setTimeout(() => {
this.modal.setTitle(this.selectDate);
this.modal.open();
}, 100);
}
setAfterReloadEvent(event, payload) {
salla.storage.set('afterReloadEvent', { event, payload });
}
emitAfterReloadEvent() {
const eventDetails = salla.storage.get('afterReloadEvent');
if (eventDetails && eventDetails.event) {
const customEvent = new CustomEvent(eventDetails.event, {
detail: eventDetails.payload
});
window.dispatchEvent(customEvent);
salla.storage.remove('afterReloadEvent');
}
}
componentWillLoad() {
if (this.option && this.option.details.length) {
this.reservations = this.option.details;
}
}
componentDidLoad() {
window.addEventListener('booking::open-after-reload', (event) => this.openBookingModal(event, true));
this.emitAfterReloadEvent();
window.addEventListener('message', this.handleMessageEvent.bind(this));
this.reservationsInput.addEventListener('invalid', e => this.invalidInput.emit(e));
this.reservationsInput.addEventListener('input', () => {
this.reservationsInput.setCustomValidity('');
this.reservationsInput.reportValidity();
});
}
handleMessageEvent(event) {
var _a, _b;
if (event.data.source !== 'booking')
return;
const action = event.data.type;
const value = event.data.message;
if (localStorage.getItem('debug'))
console.log(`Received an action:${action}`, event.data);
if (action === 'error') {
if ((_a = value.fields) === null || _a === void 0 ? void 0 : _a.reservation) {
salla.notify.error(value.fields.reservation[0]);
return;
}
const errorList = Object.values(value.fields || [value.message]).flat().map(error => `<li>${error}</li>`).join('');
salla.notify.error(`<ul>${errorList}</ul>`);
}
if (action === 'success') {
if (Number(value.productId) !== Number(this.productId))
return;
this.reservations = value.data.reservations.map(schedule => {
if (schedule.time && schedule.time.length > 0) {
const timeSlot = schedule.time[0];
return {
date: schedule.date,
day: schedule.day,
from_timestamp: timeSlot.from,
to_timestamp: timeSlot.to,
};
}
return null;
}).filter(item => item !== null);
salla.notify.success(this.bookedLabel);
(_b = this.modal) === null || _b === void 0 ? void 0 : _b.close();
setTimeout(() => window.location.reload());
}
if (action === 'height') {
this.iframe.height = (value === null || value === void 0 ? void 0 : value.height) + 'px';
}
}
bookingModal() {
return (index.h("salla-modal", { class: "s-booking-field-modal", ref: modal => (this.modal = modal), width: "md", position: "middle", noPadding: true }, index.h("iframe", { ref: iframe => (this.iframe = iframe), src: this.bookingUrl, frameborder: "0" })));
}
renderReservationDate(reservation) {
return (index.h("span", { class: reservation.from_timestamp ? 's-booking-field-reservations-has-time' : '' }, index.h("i", { class: "s-booking-field-reservations-icon", innerHTML: Calendar }), reservation.date));
}
renderReservationTime(reservation) {
if (!reservation.from_timestamp)
return '';
return (index.h("span", { class: "s-booking-field-reservations-time" }, index.h("i", { class: "s-booking-field-reservations-icon", innerHTML: TimeIcon }), index.h("span", null, reservation.from_timestamp, " - ", reservation.to_timestamp)));
}
render() {
return (index.h(index.Host, { key: '9c5755ca98a3a3a1340414de0109133ffb6617c4' }, index.h("div", { key: 'dabd37fc3a9a1879fb0c5cb3899c28971d8724ef', class: "s-booking-field-main" }, this.option.required || this.reservations.length > 0 ? index.h("div", { class: "s-booking-field-price" }, index.h("span", { innerHTML: salla.money(this.option.price) })) : '', index.h("salla-button", { key: '7fbe8ff75abac48b86b7992c261ba0439514c786', class: "s-booking-field-book-now", size: "small", loaderPosition: "center", fill: "outline", onClick: event => this.openBookingModal(event, false) }, index.h("span", { key: '496907083ce40b1618c8a1b2228f91c70b83f60a', class: "s-booking-field-book-now-content" }, index.h("span", { key: 'e4455c6205055349b3137397f039125e0b3a6cf1', innerHTML: BookingTime }), this.reservations.length ? this.editLabel : this.bookNowLabel))), this.reservations.length > 0 && (index.h("div", { key: 'de68930ac2cab061c7f9b268f8887342528ba8e7', class: "s-booking-field-reservations" }, this.reservations.map((reservation, index$1) => (index.h("div", { key: index$1, class: "s-booking-field-reservations-item" }, this.renderReservationDate(reservation), this.renderReservationTime(reservation)))))), index.h("input", { key: 'f148bc7110984389035474c47fcc963a9fa14607', class: "s-hidden", name: this.option.name, required: this.option.required, value: JSON.stringify(this.reservations) === '[]' ? '' : JSON.stringify(this.reservations), ref: reservations => this.reservationsInput = reservations }), this.iframeReady && this.bookingModal()));
}
get host() { return index.getElement(this); }
};
SallaBookingField.style = sallaBookingFieldCss;
const SallaConditionalFields = class {
constructor(hostRef) {
index.registerInstance(this, hostRef);
}
hideAllOptions(optionId) {
this.host.querySelectorAll(`[data-show-when^="options[${optionId}"]`).forEach((field) => {
field.classList.add('hidden');
this.hideAllOptions(field.dataset.optionId);
this.disableInputs(field);
});
}
disableInputs(field) {
field.querySelectorAll('[name]').forEach((input) => {
var _a;
input.setAttribute('disabled', '');
input.removeAttribute('required');
if (((_a = input === null || input === void 0 ? void 0 : input.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'select') {
input.value = '';
}
if (['checkbox'].includes(input.getAttribute('type')) && input.hasOwnProperty('checked')) {
// @ts-ignore
input.checked = false;
}
});
}
changeHandler(event) {
var _a;
salla.event.emit('salla-onditional-fields::change', event);
salla.log('Received the change event: ', event);
if (!event.target || !['SELECT'].includes(event.target.tagName) && !['checkbox', 'radio'].includes(event.target.getAttribute('type'))) {
salla.log('Ignore the change because is not a supported input: ' + (((_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.tagName) || 'N/A'));
return;
}
let optionId = event.target.name.replace('[]', '');
let isMultiple = event.target.getAttribute('type') === 'checkbox';
let isRadio = event.target.getAttribute('type') === 'radio';
salla.log('Trying to find all elements with condition:', `[data-show-when^="${optionId}"]`);
this.host.querySelectorAll(`[data-show-when^="${optionId}"]`)
.forEach((field) => {
let isEqual = !(field === null || field === void 0 ? void 0 : field.dataset.showWhen.includes('!='));
let value = field === null || field === void 0 ? void 0 : field.dataset.showWhen.replace(/(.*)(=|!=)(.*)/gm, '$3').trim();
let isSelected;
if (isMultiple) {
let selectedValues = Array.from(this.host.querySelectorAll(`input[name="${event.target.name}"]:checked`), e => e === null || e === void 0 ? void 0 : e.value);
isSelected = selectedValues.includes(value.toString());
}
else if (isRadio) {
// Handle radio inputs.
isSelected = event.target.checked && event.target.value === value;
}
else {
isSelected = value === event.target.value;
}
salla.log('The input is ', isMultiple ? 'Multiple' : isRadio ? 'Radio' : 'Single', ' value:', isSelected);
let showTheInput = (isEqual && isSelected) || (!isEqual && !isSelected);
if (showTheInput) {
field.classList.remove('hidden');
field.querySelectorAll('[name]').forEach((input) => {
input.removeAttribute('disabled');
const closestProductOption = input.closest('.s-product-options-option');
if (closestProductOption.dataset.optionRequired === 'true') {
input.setAttribute('required', '');
}
if (input.getAttribute('type') === 'checkbox') {
const checkboxes = Array.from(document.querySelectorAll(`input[type="checkbox"][name="${input.getAttribute('name')}"]`));
const isAnyChecked = checkboxes.some((checkbox) => checkbox.checked);
if (isAnyChecked) {
checkboxes.forEach((checkbox) => {
checkbox.removeAttribute('required');
});
}
}
});
}
else {
this.hideAllOptions(field.dataset.optionId);
field.classList.add('hidden');
this.disableInputs(field);
}
});
}
componentDidRender() {
this.host.querySelectorAll(`[data-show-when]`).forEach((field) => {
var _a;
// @ts-ignore
let optionName = (_a = field === null || field === void 0 ? void 0 : field.dataset) === null || _a === void 0 ? void 0 : _a.showWhen.replace(/(.*)(=|!=)(.*)/gm, '$1').trim();
if (!optionName) {
return;
}
this.changeHandler({
target: this.host.querySelector('[name^="' + optionName + '"]')
});
});
}
render() {
return (index.h(index.Host, { key: 'f2c9836cd5e5667efd13ade5d4e064551c89d569' }, index.h("slot", { key: '980eef852261b13f477a2c2ad140e7c3e96e737f' })));
}
get host() { return index.getElement(this); }
};
exports.salla_booking_field = SallaBookingField;
exports.salla_conditional_fields = SallaConditionalFields;
//# sourceMappingURL=salla-booking-field.salla-conditional-fields.entry.cjs.js.map
//# sourceMappingURL=salla-booking-field_2.cjs.entry.js.map