@salla.sa/twilight-components
Version:
Salla Web Component
661 lines (655 loc) • 35.2 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-BHYtfMwX.js';
import { A as ArrowLeftIcon, a as ArrowRightIcon } from './keyboard_arrow_right-Vqpj4CWE.js';
const sallaMultipleBundleProductOptionsModalCss = ":host{display:block}";
const SallaMultipleBundleProductOptionsModal = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.optionsSaved = createEvent(this, "optionsSaved");
this.productSelected = createEvent(this, "productSelected");
this.product = null;
this.sectionId = null;
this.sectionIndex = 0;
this.productIndex = 0;
this.selectedOptions = {};
this.optionsResetTokens = {};
this.isLoading = false;
this.hasUnsavedChanges = false;
this.validationErrors = [];
this.isProductAlreadySelected = false;
}
/**
* Generate a unique cache key for selected options using section ID, product index, and product ID
*/
generateCacheKey(sectionId, productIndex, productId) {
return `${sectionId || 'unknown'}-${productIndex || 0}-${productId || 'unknown'}`;
}
handleProductChange(newValue) {
// Use setTimeout to ensure modal is ready
setTimeout(() => {
if (this.modal && newValue) {
const title = newValue.name || '';
this.modal.setTitle(title);
}
}, 100);
// Reset validation errors when product changes
this.validationErrors = [];
this.hasUnsavedChanges = false;
}
/** Opens the modal manually. */
async open() {
if (!this.modal) {
requestAnimationFrame(() => this.open());
return;
}
this.isLoading = true;
// Set the title before opening
if (this.product?.name) {
this.modal.setTitle(this.product.name);
}
this.modal.open();
// Initialize selectedOptions with current selections from the component
setTimeout(async () => {
if (this.product?.id) {
await this.initializeSelectedOptions();
}
// Set title again after modal is fully loaded
if (this.product?.name) {
this.modal.setTitle(this.product.name);
}
this.modal.stopLoading();
this.isLoading = false;
}, 300);
}
/** Closes the modal manually. */
async close() {
if (this.modal) {
this.modal.close();
}
}
/** Refreshes the internal options tracking state manually. */
async refreshOptionsState() {
// Force re-render by updating the component state
this.selectedOptions = { ...this.selectedOptions };
}
componentDidLoad() {
this.modalOpenListener = (data) => {
this.product = data.product;
this.sectionId = data.sectionId || null;
this.sectionIndex = data.sectionIndex || 0;
this.productIndex = data.productIndex || 0;
this.isProductAlreadySelected = !!data.isProductAlreadySelected;
this.open();
};
salla.event.on('multiple-bundle-product-modal::open', this.modalOpenListener);
// Listen for clear-options event when a product is deselected
this.clearOptionsListener = (data) => {
if (!data || !data.productId)
return;
this.clearProductOptions(data.productId, data.sectionId, data.productIndex);
};
salla.event.on('multiple-bundle-product-modal::clear-options', this.clearOptionsListener);
// Create and store the option change listener for proper cleanup
this.optionChangeListener = (e) => {
const data = e.detail || e;
const { option, detail } = data;
// If data is a detail object (has option_id), find the option from product
const actualOption = option || (data.option_id && this.product?.options?.find(opt => opt.id === data.option_id || String(opt.id) === String(data.option_id)));
const actualDetail = detail || (data.id ? data : null);
if (this.product?.id && actualOption) {
this.handleOptionChange(Number(this.product.id), actualOption, actualDetail);
}
};
salla.event.on('product-options::change', this.optionChangeListener);
// Create and store the checkbox change listener for proper cleanup
this.checkboxChangeListener = (e) => {
const target = e.target;
// Check if this is a product selection checkbox
if (target && target.type === 'checkbox' && target.name && target.name.includes('bundle[') && target.name.includes('][id]')) {
// Extract section info from the checkbox name: bundle[sectionId][productIndex][id]
const nameMatch = target.name.match(/^bundle\[([^\]]+)\]\[([^\]]+)\]\[id\]$/);
if (nameMatch && !target.checked) {
if (target.getAttribute('data-selection-locked') === 'true') {
target.checked = true;
return;
}
const [, sectionId, productIndex] = nameMatch;
const productId = target.value;
const form = this.host.closest('form');
this.cleanupProductDeselection({
sectionId,
productIndex: parseInt(productIndex, 10),
productId,
form,
uncheckedInput: target,
});
}
}
};
// Listen for product checkbox changes to reset options when product is deselected
document.addEventListener('change', this.checkboxChangeListener);
}
disconnectedCallback() {
// Clean up event listeners to prevent memory leaks
if (this.checkboxChangeListener) {
document.removeEventListener('change', this.checkboxChangeListener);
}
if (this.optionChangeListener) {
salla.event.off('product-options::change', this.optionChangeListener);
}
if (this.modalOpenListener) {
salla.event.off('multiple-bundle-product-modal::open', this.modalOpenListener);
}
if (this.clearOptionsListener) {
salla.event.off('multiple-bundle-product-modal::clear-options', this.clearOptionsListener);
}
}
cleanupProductDeselection(params) {
const { sectionId, productIndex, productId, form, uncheckedInput } = params;
this.clearProductOptions(productId, sectionId, productIndex);
if (form) {
const productInputPattern = `bundle[${sectionId}][${productIndex}]`;
Array.from(form.querySelectorAll(`input[name^="${productInputPattern}"]`)).forEach(input => {
if (input === uncheckedInput) {
return;
}
const shouldRemoveHidden = input.type === 'hidden';
const shouldRemoveByDataset = input.getAttribute('data-product-id') === String(productId) &&
input.name?.startsWith(productInputPattern);
if (shouldRemoveHidden || shouldRemoveByDataset) {
input.remove();
}
});
requestAnimationFrame(() => {
const changeEvent = new window.Event('change', { bubbles: true });
form.dispatchEvent(changeEvent);
});
}
}
generateFormInputName(sectionId, productIndex, optionParentId) {
return `bundle[${sectionId}][${productIndex}][options][${optionParentId}]`;
}
async initializeSelectedOptions() {
if (!this.product?.id)
return;
const productId = this.product.id;
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
if (optionsEl) {
try {
const selectedOptions = await optionsEl.getSelectedOptions();
if (selectedOptions && selectedOptions.length > 0) {
this.selectedOptions = {
...this.selectedOptions,
[cacheKey]: selectedOptions,
};
}
}
catch (e) {
console.warn('Could not initialize selected options:', e);
}
}
}
// Clear options state for a specific product
clearProductOptions(productId, sectionId, productIndex) {
const updatedSelectedOptions = { ...this.selectedOptions };
if (sectionId != null && productIndex != null && !Number.isNaN(productIndex)) {
const cacheKey = this.generateCacheKey(sectionId, productIndex, productId);
delete updatedSelectedOptions[cacheKey];
this.bumpOptionsResetToken(cacheKey);
}
else {
const productSuffix = `-${String(productId)}`;
const affectedKeys = [];
Object.keys(updatedSelectedOptions).forEach(key => {
if (key.endsWith(productSuffix)) {
delete updatedSelectedOptions[key];
affectedKeys.push(key);
}
});
affectedKeys.forEach(key => this.bumpOptionsResetToken(key));
}
this.selectedOptions = updatedSelectedOptions;
// Reset validation errors and unsaved changes
this.validationErrors = [];
this.hasUnsavedChanges = false;
}
bumpOptionsResetToken(cacheKey) {
if (!cacheKey)
return;
this.optionsResetTokens = {
...this.optionsResetTokens,
[cacheKey]: (this.optionsResetTokens[cacheKey] || 0) + 1,
};
}
async handleOptionChange(productId, option, detail) {
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
// Get the current state from the component to ensure we have the latest selections
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
let currentComponentSelections = [];
if (optionsEl) {
try {
currentComponentSelections = (await optionsEl.getSelectedOptions()) || [];
}
catch (e) {
console.warn('Could not get current selections from component:', e);
}
}
// If component returns data, use it; otherwise, fall back to manual tracking
if (currentComponentSelections.length > 0) {
// Component returned data, use it
this.selectedOptions = {
...this.selectedOptions,
[cacheKey]: currentComponentSelections,
};
}
else {
// If we have existing selections in internal state and component returns empty,
// it might be a deselection, so we should use manual tracking
if (this.selectedOptions[cacheKey] && this.selectedOptions[cacheKey].length > 0) {
// Component didn't return data, use manual tracking
const currentSelected = this.selectedOptions[cacheKey] || [];
const updatedSelected = [...currentSelected];
// Find existing selection for this specific option (by option_id)
const existingIndex = updatedSelected.findIndex(opt => opt.option_id === option.id);
if (existingIndex > -1) {
// Check if this is a deselection (detail might be null or undefined)
if (!detail || detail.id === null || detail.id === undefined) {
// Remove the option (deselection)
updatedSelected.splice(existingIndex, 1);
}
else {
// Replace existing selection for this option
updatedSelected[existingIndex] = { ...detail, option_id: option.id };
}
}
else {
// Only add if detail exists (not a deselection)
if (detail && detail.id !== null && detail.id !== undefined) {
updatedSelected.push({ ...detail, option_id: option.id });
}
}
this.selectedOptions = {
...this.selectedOptions,
[cacheKey]: updatedSelected,
};
}
else {
// No existing selections, component returned empty, and we're trying to add
// This might be the first selection, so add it manually
if (detail && detail.id !== null && detail.id !== undefined) {
this.selectedOptions = {
...this.selectedOptions,
[cacheKey]: [{ ...detail, option_id: option.id }],
};
}
}
}
this.hasUnsavedChanges = true;
this.validationErrors = []; // Clear validation errors when user makes changes
}
async validateOptions() {
if (!this.product?.options)
return true;
const errors = [];
const productId = this.product.id;
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
// Get the actual selected options from the component
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
let currentSelected = [];
if (optionsEl) {
try {
currentSelected = (await optionsEl.getSelectedOptions()) || [];
// Also check our internal state as fallback
const internalSelected = this.selectedOptions[cacheKey] || [];
// Use whichever has more selections, or if component returns empty but internal has data, use internal
if (internalSelected.length > currentSelected.length ||
(currentSelected.length === 0 && internalSelected.length > 0)) {
currentSelected = internalSelected;
}
}
catch (e) {
// Fallback to internal state
currentSelected = this.selectedOptions[cacheKey] || [];
}
}
else {
// Fallback to internal state
currentSelected = this.selectedOptions[cacheKey] || [];
}
// Check if any options are selected at all
if (currentSelected.length === 0) {
errors.push(salla.lang.get('pages.products.no_options_selected'));
}
// Check required options
this.product.options.forEach(option => {
if (option.required) {
const hasSelection = currentSelected.some(selected => {
return selected.option_id == option.id; // Use == instead of === for type flexibility
});
if (!hasSelection) {
errors.push(salla.lang.get('pages.products.required_option_missing', {
option: option.name,
}));
}
}
});
this.validationErrors = errors;
return errors.length === 0;
}
async onSave(e) {
e.preventDefault();
const productId = this.product?.id;
if (!productId)
return;
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
// Small delay to ensure component state is updated
await new Promise(resolve => setTimeout(resolve, 100));
// Validate options before saving
const isValid = await this.validateOptions();
if (!isValid) {
salla.notify.error(this.validationErrors.join(', '));
return;
}
if (!this.isProductAlreadySelected && this.sectionId != null) {
const details = this.host.closest('salla-multiple-bundle-product-details');
const canSelect = await details?.canSelectBundleProduct(this.sectionId, productId);
if (!canSelect) {
salla.notify.error(salla.lang.getWithDefault('pages.products.bundle_selection_limit_reached', 'لا يمكنك اختيار المزيد من المنتجات في هذا القسم'));
return;
}
}
this.isLoading = true;
try {
// please don't change this with this.host.querySelector it will return null
const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
let selectedOptions = await optionsEl?.getSelectedOptions();
// If component returns empty but we have internal state, use internal state
if ((!selectedOptions || selectedOptions.length === 0) &&
this.selectedOptions[cacheKey]?.length > 0) {
selectedOptions = this.selectedOptions[cacheKey];
}
if (!selectedOptions || selectedOptions.length === 0) {
this.isLoading = false;
return;
}
// Store the selected options for this product using cache key
this.selectedOptions = {
...this.selectedOptions,
[cacheKey]: selectedOptions,
};
const form = this.host.closest('form');
if (!form) {
this.isLoading = false;
return;
}
// remove old inputs for this specific product in this specific section/index only
const productInputPattern = `bundle[${this.sectionId}][${this.productIndex}]`;
// Remove only hidden inputs and inputs with data-product-id, but preserve visible checkboxes
Array.from(form.querySelectorAll(`input[name^="${productInputPattern}"][type="hidden"]`)).forEach(el => el.remove());
// Also remove any inputs with data-product-id that match this specific pattern
Array.from(form.querySelectorAll(`[data-product-id="${productId}"][name^="${productInputPattern}"]`)).forEach(el => el.remove());
// Ensure the actual checkbox in the UI is checked to reflect the selection visually
const checkboxId = `bundle[${this.sectionId}][${this.productIndex}][id]`;
const checkbox = document.getElementById(checkboxId);
if (checkbox) {
checkbox.checked = true;
// Don't dispatch change event here to avoid double API calls
}
else {
// If checkbox doesn't exist, create a hidden input as fallback
const productSelectionInput = document.createElement('input');
productSelectionInput.type = 'hidden';
productSelectionInput.name = `bundle[${this.sectionId}][${this.productIndex}][id]`;
productSelectionInput.value = String(productId);
productSelectionInput.dataset.productId = String(productId);
form.appendChild(productSelectionInput);
}
// append new hidden inputs for options
selectedOptions.forEach((option) => {
// how to get option parent id?
const optionParentId = option.option_id;
const hidden = document.createElement('input');
hidden.type = 'hidden';
// Use productIndex for the form input name
hidden.name = this.generateFormInputName(this.sectionId, this.productIndex ?? 0, optionParentId);
hidden.value = String(option.id);
hidden.dataset.productId = String(productId);
form.appendChild(hidden);
});
// Trigger single form change event with all updates (product selection + options)
const changeEvent = new window.Event('change', { bubbles: true });
form.dispatchEvent(changeEvent);
// Emit custom event
this.optionsSaved.emit({
productId: Number(productId),
selectedOptions,
sectionId: this.sectionId,
productIndex: this.productIndex,
});
// Emit product selected event to check the card
if (this.sectionId) {
this.productSelected.emit({
productId: Number(productId),
sectionId: this.sectionId,
product: this.product,
fromModal: true,
});
}
// Show success message
salla.notify.success(salla.lang.get('pages.products.options_saved'));
this.hasUnsavedChanges = false;
this.validationErrors = [];
// close modal
this.modal.close();
}
catch (error) {
salla.notify.error(salla.lang.get('pages.products.options_save_error'));
}
finally {
this.isLoading = false;
}
}
// Method to get options with selected state preserved
getOptionsWithSelectedState() {
if (!this.product?.options)
return [];
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, this.product.id);
const savedOptions = this.selectedOptions[cacheKey] || [];
return this.product.options.map(option => ({
...option,
details: option.details.map(detail => {
const isSelected = savedOptions.some(saved => {
return saved.id === detail.id;
});
return {
...detail,
is_selected: isSelected,
};
}),
}));
}
render() {
const productId = this.product?.id;
const optionsWithSelectedState = this.getOptionsWithSelectedState();
const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
const resetToken = this.optionsResetTokens[cacheKey] || 0;
const isDisabled = this.isLoading || optionsWithSelectedState.some(opt => opt.details.some(d => d.is_selected && d.is_out === true));
return (h(Host, { key: '6c1d1d3911867e30240676f3e2b7353e9ecf76c3' }, h("salla-modal", { key: 'b02110d80cd422d64962d78812ae0b0637c56237', isLoading: this.isLoading, ref: el => (this.modal = el), width: "md", centered: false, id: `s-multiple-bundle-product-options-modal-options-${productId}`, class: "s-multiple-bundle-product-options-modal-wrapper" }, h("div", { key: '20a52bbc732c6edfffde86577e99bbe300a1a4c8', slot: "loading" }, h("salla-skeleton", { key: '3a69fc75939d8b8f8639983d0f2f8dd8bf961152', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (h("salla-slider", { key: '185639c54f79188093df98ac1cece1958879f71d', id: `details-slider-${this.product?.id}`, type: "thumbs", loop: false, "auto-height": true, "listen-to-thumbnails-option": true, showThumbsControls: false, controlsOuter: false, showControls: false, class: "s-multiple-bundle-product-options-modal-slider", verticalThumbs: true, thumbsConfig: {
centeredSlides: true,
centeredSlidesBounds: true,
slidesPerView: Math.min(5, Math.max(1, this.product?.images.length)),
watchOverflow: true,
watchSlidesProgress: true,
direction: 'vertical',
spaceBetween: 10,
} }, h("div", { key: '3b6a88fe3862870d674dadc31967df6cc8fac365', slot: "items" }, this.product?.images &&
this.product?.images.map((image, index) => (h("div", { key: index, class: "swiper-slide" }, h("img", { src: image.url, alt: image.alt || `${this.product?.name} - Image ${index + 1}`, loading: "lazy", onError: e => {
e.target.style.display = 'none';
} }))))), this.product?.images && this.product?.images.length > 1 && (h("div", { key: '6fce48b5b035cc61866aaf6c339866fa2314be87', slot: "thumbs" }, this.product?.images &&
this.product?.images.map((image, index) => (h("div", { key: index, "data-caption": `${this.product?.name} - Image ${index + 1}` }, h("img", { src: image.url, loading: "eager", class: "s-multiple-bundle-product-options-modal-slider-thumb", title: `${this.product?.name} - ${index + 1}`, alt: image.alt || `${this.product?.name} - ${index + 1}`, onError: e => {
e.target.style.display = 'none';
} })))))))), h("salla-product-options", { options: JSON.stringify(optionsWithSelectedState), key: `${cacheKey}-reset-${resetToken}`, "product-id": productId, "unique-key": `${cacheKey}-reset-${resetToken}` }), h("div", { key: '3d555ea40fe5d9f3685fc6dafa4b6fad16732091', slot: "footer" }, h("div", { key: '1b4c6834899efbd09f3ea1db251999f50ec655b2', class: "s-multiple-bundle-product-options-modal-footer" }, h("salla-button", { key: '0818a75a444cca510c7f0cfea2ec53414c12db53', onClick: e => this.onSave(e), loading: this.isLoading, disabled: isDisabled }, this.isLoading
? salla.lang.get('common.elements.saving')
: salla.lang.get('common.elements.save')))))));
}
get host() { return getElement(this); }
static get watchers() { return {
"product": ["handleProductChange"]
}; }
};
SallaMultipleBundleProductOptionsModal.style = sallaMultipleBundleProductOptionsModalCss;
const sallaMultipleBundleProductSliderCss = "";
const SallaMultipleBundleProductSlider = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.productSelected = createEvent(this, "productSelected");
this.productOptionsSelected = createEvent(this, "productOptionsSelected");
/** A dictionary tracking which product IDs are currently selected per section. */
this.selectedProducts = {};
/** When true, the selected product cannot be deselected (single-product section with min = 1). */
this.isSelectionLocked = false;
/** Maximum selectable products for this section (empty max → all products in section). */
this.selectionLimit = 0;
this.savedOptionsByInstance = {};
this.handleProductClick = (product, productIndex) => {
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
const checkbox = this.getCheckbox(this.section.id, productIndex);
if (isChecked && this.isSelectionLocked) {
if (checkbox) {
checkbox.checked = true;
}
return;
}
if (!isChecked && this.isMaxSelectionReached() && this.selectionLimit !== 1) {
return;
}
// max = 1: parent replaces selection and syncs all checkboxes in the section
if (this.selectionLimit === 1 && !isChecked) {
this.productSelected.emit({
product,
sectionId: this.section.id,
});
return;
}
if (!checkbox)
return;
const willBeChecked = !checkbox.checked;
if (!willBeChecked) {
this.dispatchClearOptionsEvent(product, productIndex);
this.clearSavedOptionsState(this.section.id, productIndex);
}
checkbox.checked = willBeChecked;
requestAnimationFrame(() => {
const changeEvent = new window.Event('change', { bubbles: true });
checkbox.dispatchEvent(changeEvent);
});
this.productSelected.emit({
product,
sectionId: this.section.id,
});
};
this.handleOptionsClick = (product) => {
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
if (!isChecked && this.isMaxSelectionReached() && this.selectionLimit !== 1) {
return;
}
this.productOptionsSelected.emit({
product,
sectionId: this.section.id,
});
};
}
getSelectedCount() {
return this.selectedProducts[this.section?.id]?.size ?? 0;
}
isMaxSelectionReached() {
return this.selectionLimit > 1 && this.getSelectedCount() >= this.selectionLimit;
}
isProductSelectionDisabled(product, isChecked) {
if (product.quantity === 0) {
return true;
}
return !isChecked && this.isMaxSelectionReached();
}
getProductInstanceKey(sectionId, productIndex) {
return `${sectionId}::${productIndex}`;
}
dispatchClearOptionsEvent(product, productIndex) {
salla.event.dispatch('multiple-bundle-product-modal::clear-options', {
productId: product.id,
sectionId: this.section.id,
sectionIndex: this.sectionIndex,
productIndex,
});
}
handleOptionsSaved(event) {
const detail = event.detail;
if (!detail)
return;
const { sectionId, productIndex, selectedOptions } = detail;
if (sectionId == null || sectionId !== this.section?.id)
return;
if (productIndex == null || Number.isNaN(productIndex))
return;
const key = this.getProductInstanceKey(sectionId, productIndex);
const hasOptions = !!selectedOptions?.length;
if (hasOptions) {
this.savedOptionsByInstance = {
...this.savedOptionsByInstance,
[key]: true,
};
}
else if (this.savedOptionsByInstance[key]) {
const updatedState = { ...this.savedOptionsByInstance };
delete updatedState[key];
this.savedOptionsByInstance = updatedState;
}
}
clearSavedOptionsState(sectionId, productIndex) {
const key = this.getProductInstanceKey(sectionId, productIndex);
if (!this.savedOptionsByInstance[key])
return;
const updatedState = { ...this.savedOptionsByInstance };
delete updatedState[key];
this.savedOptionsByInstance = updatedState;
}
generateEventName(sectionId, productIndex) {
return `bundle[${sectionId}][${productIndex}][id]`;
}
getCheckbox(sectionId, productIndex) {
const name = this.generateEventName(sectionId, productIndex);
return this.host.querySelector(`input.s-multiple-bundle-product-checkbox[name="${name}"]`);
}
preventLockedDeselect(event, isChecked) {
if (!this.isSelectionLocked || !isChecked) {
return;
}
event.preventDefault();
event.stopPropagation();
const checkbox = event.target;
if (checkbox?.type === 'checkbox') {
checkbox.checked = true;
}
}
render() {
return (h(Host, { key: 'd52eb26454606df2526fa4c086110a54f7466644' }, h("salla-slider", { key: '1aa1fce5943c3721a8e4f762171c864d9097bb28', type: "carousel", controlsOuter: false, showControls: false, id: `accordion-multiple-bundle-product-${this.section.id}`, pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: { spaceBetween: 0 } }, h("div", { key: '9342381bc43389bae48b906a1ab23a4f3cf8d00a', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
const isLocked = isChecked && this.isSelectionLocked;
const isDisabled = this.isProductSelectionDisabled(product, isChecked);
const hasSavedOptions = this.savedOptionsByInstance[this.getProductInstanceKey(this.section.id, productIndex)];
const optionsButtonLabel = hasSavedOptions
? salla.lang.getWithDefault('pages.products.edit_selected_options', 'تعديل الخيارات')
: salla.lang.get('pages.products.choose_from_options');
let optionsArrowIcon = salla.config.get('theme.is_rtl', true)
? ArrowLeftIcon
: ArrowRightIcon;
return (h("div", { class: `s-multiple-bundle-product-slide-one-third${isDisabled ? ' s-multiple-bundle-product-slide-one-third-disabled' : ''}`, key: product.id }, h("div", { class: "s-multiple-bundle-product-card" }, h("div", { class: "s-multiple-bundle-product-image-wrapper", onClick: () => this.handleProductClick(product, productIndex) }, h("input", { id: this.generateEventName(this.section.id, productIndex), type: "checkbox", class: "s-multiple-bundle-product-checkbox", checked: isChecked, "data-selection-locked": isLocked ? 'true' : undefined, name: this.generateEventName(this.section.id, productIndex), value: product.id, onClick: event => this.preventLockedDeselect(event, isChecked), onChange: event => this.preventLockedDeselect(event, isChecked) }), h("img", { src: product.image.url || salla.url.cdn('images/s-empty.png'), loading: "lazy", alt: product.image.alt || product.name, class: "s-multiple-bundle-product-image" })), h("div", { class: "s-multiple-bundle-product-content-wrapper" }, h("div", { class: "s-multiple-bundle-product-content" }, h("div", { class: "s-multiple-bundle-product-details" }, h("div", { class: "s-multiple-bundle-product-title-wrapper" }, h("h2", { class: "s-multiple-bundle-product-title" }, h("a", { href: product?.url || '#', target: "_blank", rel: "noopener noreferrer" }, product.name))), h("div", { class: "s-multiple-bundle-product-price-wrapper" }, h("span", { class: "s-multiple-bundle-product-price" }, h("span", { innerHTML: salla.money(product.price) })), product.sale_price > 0 && (h("span", { class: "s-multiple-bundle-product-price-discount" }, h("span", { innerHTML: salla.money(product.regular_price) }))))), product.quantity_in_group > 0 && product.quantity !== 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.pieces'), h("span", null, product.quantity_in_group))), product.quantity === 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.quantity_in_group_finished')))), product.options?.length > 0 && (h("button", { class: "s-multiple-bundle-product-button", onClick: () => this.handleOptionsClick(product), type: "button" }, optionsButtonLabel, h("span", { class: "s-multiple-bundle-product-button-icon", innerHTML: optionsArrowIcon })))))));
})))));
}
get host() { return getElement(this); }
};
SallaMultipleBundleProductSlider.style = sallaMultipleBundleProductSliderCss;
export { SallaMultipleBundleProductOptionsModal as salla_multiple_bundle_product_options_modal, SallaMultipleBundleProductSlider as salla_multiple_bundle_product_slider };