Przejdź do głównej treści

Odwiedź nasze salony | Wrocław: pl. Strzelecki 25 | Gdynia: ul. Orłowska 66

Darmowa już od 199zł ZOBACZ

Dostawa już od 199zł ZOBACZ
Produkty w koszyku: 0. Zobacz szczegóły
Twój koszyk jest pusty
język/waluta
PL / PLN
  • cd9987c4a86778579a1550c1b2cb5ebe
  • 4af139d14acd2d450c8712555c38d51b
  • 6fafee4905f18eee683bb0d465e2e3ea
  • 13c613814f0bb210565790a0680651c7
  • a21322585c1706740a5cfecc2bfba635
  • 49e322d19a3adc7f8ca2fdfc27a66a00
  • 692730e9443d25cf6a1f0932dd64b393

Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105

Czas wysyłki: 24 - 48 godziny
Lameo
Przejdź do sekcji Opinie
Cena 259,99 zł
szt

Płać nawet 30 dni po zakupie

const TapProductSample = { settings: { selectors: { root: '.js__tap-product-sample', button: '.js__tap-product-sample-button', nativeBuyButton: 'buy-button', basketProduct: '.basket-product', basketStepper: 'h-input-stepper', basketStepperButton: 'h-button-stepper', basketQuantityInput: '.input-stepper__value_input' }, classes: { loading: 'tap-product-sample__button_is-loading', modalActive: 'tap-product-sample-modal_is-active' }, storefront: null, basketUpdaterApi: null, basketProductsApi: null, basketProducts: [], basketWatcherBound: false, basketApisPromise: null, basketDomObserver: null, basketDomObserverQueued: false, basketInteractionGuardBound: false, protectionStyleInjected: false }, init: (storefront) => { TapProductSample.settings.storefront = storefront; TapProductSample.injectProtectionStyles(); TapProductSample.bindBasketInteractionGuard(); TapProductSample.ensureBasketDomObserver(); TapProductSample.load(); // Prewarmujemy koszyk tylko tam, gdzie moduł może go potrzebować. // Rejestracja dynamiczna zachowuje możliwość pierwszego dodania próbki // również wtedy, gdy użytkownik nie ma jeszcze sesji koszyka. if (TapProductSample.shouldPrepareBasketApis()) { TapProductSample.ensureBasketApis().catch((error) => { console.warn('[TapProductSample] Basket prewarm failed.', error); }); } if (storefront.eventBus && typeof storefront.eventBus.on === 'function') { storefront.eventBus.on('basket.initialized', () => { TapProductSample.ensureBasketApis().catch((error) => { console.warn( '[TapProductSample] Basket API resolve after basket.initialized failed.', error ); }); TapProductSample.scheduleBasketDomProtection(); }); } }, shouldPrepareBasketApis: () => { return Boolean( document.querySelector(TapProductSample.settings.selectors.root) || window.location.pathname.includes('/basket') ); }, ensureBasketApis: async () => { if ( TapProductSample.settings.basketUpdaterApi && TapProductSample.settings.basketProductsApi ) { return true; } if (TapProductSample.settings.basketApisPromise) { return TapProductSample.settings.basketApisPromise; } TapProductSample.settings.basketApisPromise = (async () => { const storefront = TapProductSample.settings.storefront; if (!storefront) { throw new Error('Storefront API is not available.'); } let basketUpdaterApi = typeof storefront.getApiSync === 'function' ? storefront.getApiSync('basketUpdaterApi') : null; let basketProductsApi = typeof storefront.getApiSync === 'function' ? storefront.getApiSync('basketProductsApi') : null; // Gdy nie ma jeszcze sesji koszyka, feature "basket" może nie być // zarejestrowany. Rejestrujemy go PRZED próbą pobrania API. if (!basketUpdaterApi || !basketProductsApi) { const featureSystemApi = typeof storefront.getApiSync === 'function' ? storefront.getApiSync('FeatureSystemApi') : null; if ( !featureSystemApi || typeof featureSystemApi.registerDynamic !== 'function' ) { throw new Error('FeatureSystemApi is not available.'); } try { await featureSystemApi.registerDynamic('basket', true); } catch (error) { // Inny moduł może zarejestrować basket w tym samym momencie. // Błąd rejestracji ignorujemy i od razu ponawiamy pobranie API. } basketUpdaterApi = typeof storefront.getApiSync === 'function' ? storefront.getApiSync('basketUpdaterApi') : null; basketProductsApi = typeof storefront.getApiSync === 'function' ? storefront.getApiSync('basketProductsApi') : null; } if (!basketUpdaterApi && typeof storefront.getApi === 'function') { try { basketUpdaterApi = await storefront.getApi('basketUpdaterApi'); } catch (error) { console.warn( '[TapProductSample] basketUpdaterApi getApi() failed.', error ); } } if (!basketProductsApi && typeof storefront.getApi === 'function') { try { basketProductsApi = await storefront.getApi('basketProductsApi'); } catch (error) { console.warn( '[TapProductSample] basketProductsApi getApi() failed.', error ); } } if (!basketUpdaterApi || !basketProductsApi) { throw new Error('Basket APIs could not be initialized.'); } TapProductSample.settings.basketUpdaterApi = basketUpdaterApi; TapProductSample.settings.basketProductsApi = basketProductsApi; TapProductSample.watchBasket(); return true; })(); try { return await TapProductSample.settings.basketApisPromise; } catch (error) { TapProductSample.settings.basketApisPromise = null; throw error; } }, waitForBasket: async () => { return TapProductSample.ensureBasketApis(); }, load: () => { TapProductSample.injectProtectionStyles(); TapProductSample.bindBasketInteractionGuard(); TapProductSample.ensureBasketDomObserver(); document .querySelectorAll(TapProductSample.settings.selectors.root) .forEach((root) => { if (root.dataset.tapProductSampleReady !== '1') { root.dataset.tapProductSampleReady = '1'; const button = root.querySelector( TapProductSample.settings.selectors.button ); if (button) { button.addEventListener('click', () => { TapProductSample.handleClick(root, button); }); } } TapProductSample.bindNativeSampleProductGuard(root); TapProductSample.protectNativeSampleProductQuantity(root); }); TapProductSample.scheduleBasketDomProtection(); }, injectProtectionStyles: () => { if (TapProductSample.settings.protectionStyleInjected) { return; } const style = document.createElement('style'); style.id = 'tap-product-sample-protection-styles'; style.textContent = ` .tap-product-sample-basket-item h-input-stepper h-button-stepper[type="increment"] { display: none !important; } .tap-product-sample-basket-item_quantity-valid h-input-stepper h-button-stepper[type="decrement"] { display: none !important; } .tap-product-sample-basket-item .input-stepper__value_input, .tap-product-sample-native-quantity-locked .input-stepper__value_input { pointer-events: none !important; user-select: none !important; caret-color: transparent !important; } .tap-product-sample-native-quantity-locked h-button-stepper { display: none !important; } `; document.head.appendChild(style); TapProductSample.settings.protectionStyleInjected = true; }, ensureBasketDomObserver: () => { if ( TapProductSample.settings.basketDomObserver || !document.body || typeof MutationObserver !== 'function' ) { return; } TapProductSample.settings.basketDomObserver = new MutationObserver( (mutations) => { const shouldProtect = mutations.some((mutation) => { if (mutation.type === 'childList') { return mutation.addedNodes && mutation.addedNodes.length > 0; } if (mutation.type === 'attributes') { return Boolean( mutation.target.closest?.( TapProductSample.settings.selectors.basketProduct ) ); } return false; }); if (shouldProtect) { TapProductSample.scheduleBasketDomProtection(); } } ); TapProductSample.settings.basketDomObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['value'] }); }, scheduleBasketDomProtection: () => { if (TapProductSample.settings.basketDomObserverQueued) { return; } TapProductSample.settings.basketDomObserverQueued = true; window.requestAnimationFrame(() => { TapProductSample.settings.basketDomObserverQueued = false; TapProductSample.protectBasketDom(); }); }, bindBasketInteractionGuard: () => { if (TapProductSample.settings.basketInteractionGuardBound) { return; } TapProductSample.settings.basketInteractionGuardBound = true; document.addEventListener( 'click', (event) => { const stepperButton = event.target.closest( TapProductSample.settings.selectors.basketStepperButton ); if (!stepperButton) { return; } const basketProduct = stepperButton.closest( TapProductSample.settings.selectors.basketProduct ); if ( !basketProduct || !TapProductSample.isBasketProductElementSample(basketProduct) ) { return; } const buttonType = stepperButton.getAttribute('type'); const quantity = TapProductSample.getBasketProductDomQuantity( basketProduct ); // Jeżeli przed wdrożeniem próbka miała już błędnie ilość > 1, // pozwalamy tylko ją zmniejszyć do 1. Zwiększanie jest zawsze blokowane. if (buttonType === 'decrement' && quantity > 1) { return; } event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); }, true ); document.addEventListener( 'keydown', (event) => { const input = event.target.closest( TapProductSample.settings.selectors.basketQuantityInput ); if (!input) { return; } const basketProduct = input.closest( TapProductSample.settings.selectors.basketProduct ); if ( !basketProduct || !TapProductSample.isBasketProductElementSample(basketProduct) ) { return; } event.preventDefault(); event.stopPropagation(); }, true ); document.addEventListener( 'beforeinput', (event) => { const input = event.target.closest( TapProductSample.settings.selectors.basketQuantityInput ); if (!input) { return; } const basketProduct = input.closest( TapProductSample.settings.selectors.basketProduct ); if ( !basketProduct || !TapProductSample.isBasketProductElementSample(basketProduct) ) { return; } event.preventDefault(); event.stopPropagation(); }, true ); }, watchBasket: () => { const basketProductsApi = TapProductSample.settings.basketProductsApi; if (!basketProductsApi || TapProductSample.settings.basketWatcherBound) { return; } TapProductSample.settings.basketWatcherBound = true; if (typeof basketProductsApi.get === 'function') { try { const products = basketProductsApi.get(); const items = TapProductSample.getBasketItemsFromBasketObject(products); if (items.length || Array.isArray(products)) { TapProductSample.settings.basketProducts = items; } } catch (error) { console.warn( '[TapProductSample] Initial basketProductsApi.get() failed.', error ); } } if (typeof basketProductsApi.select$ !== 'function') { return; } const basketProducts$ = basketProductsApi.select$(); if (basketProducts$ && typeof basketProducts$.subscribe === 'function') { basketProducts$.subscribe((products) => { TapProductSample.settings.basketProducts = TapProductSample.getBasketItemsFromBasketObject(products); TapProductSample.scheduleBasketDomProtection(); }); } }, splitIds: (value) => { return String(value || '') .split(/[\s,;]+/) .map((item) => item.trim()) .filter(Boolean); }, normalizeId: (value) => { return String(value || '').trim(); }, normalizeText: (value) => { return String(value || '') .trim() .toLocaleLowerCase('pl-PL') .normalize('NFD') .replace(/[\u0300-\u036f]/g, ''); }, getKnownSampleProductIdsFromDom: () => { const ids = new Set(); document .querySelectorAll(TapProductSample.settings.selectors.root) .forEach((root) => { TapProductSample.splitIds(root.dataset.allSampleProductIds).forEach( (id) => ids.add(id) ); TapProductSample.getSampleCategoryProductIds(root).forEach( (id) => ids.add(id) ); }); return Array.from(ids); }, getBasketProductOriginalProductId: (basketProduct) => { const optionNodes = basketProduct.querySelectorAll( '.basket-product__options [data-option-name]' ); for (const optionNode of optionNodes) { if ( TapProductSample.normalizeText(optionNode.dataset.optionName) === 'id produktu' ) { return TapProductSample.normalizeId(optionNode.dataset.optionValue); } } return ''; }, getBasketProductDisplayName: (basketProduct) => { const link = basketProduct.querySelector( '.basket-product__link, .basket-product__name a, .basket-product__name' ); return TapProductSample.normalizeText(link?.textContent || ''); }, isBasketProductElementSample: (basketProduct) => { if (!basketProduct) { return false; } // Próbki dodawane przez ten moduł mają w koszyku opcję "ID produktu". if (TapProductSample.getBasketProductOriginalProductId(basketProduct)) { return true; } const productId = TapProductSample.normalizeId( basketProduct.dataset.productId ); if ( productId && TapProductSample.getKnownSampleProductIdsFromDom().includes(productId) ) { return true; } // Na stronie koszyka skrypt modułu jest ładowany globalnie, ale nie ma tam // jego Twiga z konfiguracją. Produkty z kategorii /probniki rozpoznajemy // dodatkowo po ich nazwach ("Próbka...", "Zestaw próbek..."). const name = TapProductSample.getBasketProductDisplayName(basketProduct); return ( name.includes('probka') || name.includes('probek') || name.includes('probki') ); }, getBasketProductDomQuantity: (basketProduct) => { const stepper = basketProduct.querySelector( TapProductSample.settings.selectors.basketStepper ); const value = stepper?.getAttribute('value') || '1'; const quantity = parseInt(value, 10); return Number.isFinite(quantity) && quantity > 0 ? quantity : 1; }, countSamplesInDom: () => { return Array.from( document.querySelectorAll( TapProductSample.settings.selectors.basketProduct ) ).reduce((sum, basketProduct) => { if (!TapProductSample.isBasketProductElementSample(basketProduct)) { return sum; } return sum + TapProductSample.getBasketProductDomQuantity(basketProduct); }, 0); }, hasDuplicateSampleInDom: (root) => { const productId = TapProductSample.normalizeId(root?.dataset?.productId); if (!productId) { return false; } return Array.from( document.querySelectorAll( TapProductSample.settings.selectors.basketProduct ) ).some( (basketProduct) => TapProductSample.getBasketProductOriginalProductId(basketProduct) === productId ); }, hasNativeSampleProductInDom: (root) => { const productId = TapProductSample.normalizeId(root?.dataset?.productId); if (!productId) { return false; } return Array.from( document.querySelectorAll( TapProductSample.settings.selectors.basketProduct ) ).some( (basketProduct) => TapProductSample.normalizeId(basketProduct.dataset.productId) === productId ); }, lockBasketProductQuantity: (basketProduct) => { if (!basketProduct) { return; } basketProduct.classList.add('tap-product-sample-basket-item'); const stepper = basketProduct.querySelector( TapProductSample.settings.selectors.basketStepper ); if (!stepper) { return; } const quantity = TapProductSample.getBasketProductDomQuantity(basketProduct); const isValidQuantity = quantity <= 1; basketProduct.classList.toggle( 'tap-product-sample-basket-item_quantity-valid', isValidQuantity ); stepper.setAttribute('min', '1'); if (isValidQuantity) { stepper.setAttribute('max', '1'); } stepper .querySelectorAll(TapProductSample.settings.selectors.basketStepperButton) .forEach((button) => { const buttonType = button.getAttribute('type'); const canRepairQuantity = buttonType === 'decrement' && quantity > 1; if (canRepairQuantity) { button.removeAttribute('aria-disabled'); button.setAttribute('tabindex', '0'); return; } button.setAttribute('aria-disabled', 'true'); button.setAttribute('tabindex', '-1'); }); const input = stepper.querySelector( TapProductSample.settings.selectors.basketQuantityInput ); if (input) { input.readOnly = true; input.setAttribute('aria-readonly', 'true'); input.setAttribute('tabindex', '-1'); } }, protectBasketDom: () => { document .querySelectorAll(TapProductSample.settings.selectors.basketProduct) .forEach((basketProduct) => { if (TapProductSample.isBasketProductElementSample(basketProduct)) { TapProductSample.lockBasketProductQuantity(basketProduct); } }); }, protectNativeSampleProductQuantity: (root) => { if (root?.dataset?.isSampleCategoryProduct !== '1') { return; } const productId = TapProductSample.normalizeId(root.dataset.productId); if (!productId) { return; } document .querySelectorAll(`product-quantity[product-id="${productId}"]`) .forEach((productQuantity) => { productQuantity.classList.add( 'tap-product-sample-native-quantity-locked' ); productQuantity.setAttribute('value', '1'); const stepper = productQuantity.querySelector( TapProductSample.settings.selectors.basketStepper ); if (stepper) { stepper.setAttribute('min', '1'); stepper.setAttribute('max', '1'); stepper.setAttribute('value', '1'); stepper .querySelectorAll( TapProductSample.settings.selectors.basketStepperButton ) .forEach((button) => { button.setAttribute('aria-disabled', 'true'); button.setAttribute('tabindex', '-1'); }); const input = stepper.querySelector( TapProductSample.settings.selectors.basketQuantityInput ); if (input) { input.readOnly = true; input.setAttribute('aria-readonly', 'true'); input.setAttribute('tabindex', '-1'); } } }); document .querySelectorAll(`buy-button[product-id="${productId}"]`) .forEach((buyButton) => { buyButton.setAttribute('quantity', '1'); }); }, getSampleLimit: (root) => { const limit = parseInt(root?.dataset?.sampleLimit || '5', 10); return Number.isFinite(limit) && limit > 0 ? limit : 5; }, getSampleCategoryProductIds: (root) => { return TapProductSample.splitIds(root?.dataset?.sampleCategoryProductIds); }, getNativeBuyButtonQuantity: (buyButton) => { const quantity = parseInt(buyButton?.getAttribute('quantity') || '1', 10); return Number.isFinite(quantity) && quantity > 0 ? quantity : 1; }, getQuantity: (item) => { const quantity = item?.quantity ?? item?.count ?? item?.amount ?? item?.qty ?? 1; const parsed = parseInt(quantity, 10); return Number.isFinite(parsed) && parsed > 0 ? parsed : 1; }, getItemProductId: (item) => { return TapProductSample.normalizeId( item?.productId ?? item?.product_id ?? item?.product?.id ?? item?.product?.productId ?? item?.id ?? '' ); }, getItemVariantId: (item) => { return TapProductSample.normalizeId( item?.variantId ?? item?.variant_id ?? item?.stockId ?? item?.stock_id ?? item?.variant?.id ?? item?.stock?.id ?? '' ); }, collectStrings: (value, output = [], depth = 0) => { if (depth > 6 || value === null || value === undefined) { return output; } if (typeof value === 'string' || typeof value === 'number') { output.push(String(value)); return output; } if (Array.isArray(value)) { value.forEach((item) => { TapProductSample.collectStrings(item, output, depth + 1); }); return output; } if (typeof value === 'object') { Object.keys(value).forEach((key) => { output.push(String(key)); TapProductSample.collectStrings(value[key], output, depth + 1); }); } return output; }, getBasketItemsFromBasketObject: (basket) => { if (!basket) { return []; } if (Array.isArray(basket)) { return basket; } const candidates = [ basket.products?.list, basket.products, basket.items, basket.lines, basket.positions, basket.basket?.products?.list, basket.basket?.products, basket.basket?.items, basket.basket?.lines, basket.data?.products?.list, basket.data?.products, basket.data?.items ]; for (const candidate of candidates) { if (Array.isArray(candidate)) { return candidate; } } return []; }, getBasketItems: async () => { await TapProductSample.waitForBasket(); const basketProductsApi = TapProductSample.settings.basketProductsApi; const basketUpdaterApi = TapProductSample.settings.basketUpdaterApi; // Przy każdym sprawdzeniu limitu próbujemy pobrać najświeższy stan koszyka. // Poprzednio cache z subskrypcji mógł być jeszcze nieaktualny po szybkich zmianach. if (basketUpdaterApi && typeof basketUpdaterApi.getCurrentBasket === 'function') { try { const basket = await basketUpdaterApi.getCurrentBasket(); const items = TapProductSample.getBasketItemsFromBasketObject(basket); TapProductSample.settings.basketProducts = items; return items; } catch (error) {} } if (basketProductsApi && typeof basketProductsApi.get === 'function') { try { const products = basketProductsApi.get(); const items = TapProductSample.getBasketItemsFromBasketObject(products); if (items.length || Array.isArray(products)) { TapProductSample.settings.basketProducts = items; return items; } } catch (error) {} } return TapProductSample.settings.basketProducts; }, isSampleItem: ( item, sampleProductIds, sampleCategoryProductIds, sampleProductId, sampleVariantId ) => { const itemProductId = TapProductSample.getItemProductId(item); const itemVariantId = TapProductSample.getItemVariantId(item); const strings = TapProductSample.collectStrings(item); if (itemProductId && sampleProductIds.includes(itemProductId)) { return true; } if (itemProductId && sampleCategoryProductIds.includes(itemProductId)) { return true; } if (sampleProductId && itemProductId === sampleProductId) { return true; } if (sampleVariantId && itemVariantId === sampleVariantId) { return true; } if (sampleProductIds.some((id) => strings.includes(id))) { return true; } return sampleCategoryProductIds.some((id) => strings.includes(id)); }, hasDuplicateSample: (items, root) => { const productId = TapProductSample.normalizeId(root.dataset.productId); const sampleProductId = TapProductSample.normalizeId(root.dataset.sampleProductId); const sampleVariantId = TapProductSample.normalizeId(root.dataset.sampleVariantId); const sampleProductIds = TapProductSample.splitIds(root.dataset.allSampleProductIds); const sampleCategoryProductIds = TapProductSample.getSampleCategoryProductIds(root); return items.some((item) => { if ( !TapProductSample.isSampleItem( item, sampleProductIds, sampleCategoryProductIds, sampleProductId, sampleVariantId ) ) { return false; } const strings = TapProductSample.collectStrings(item); return productId && strings.includes(productId); }); }, countSamples: (items, root) => { const sampleProductId = TapProductSample.normalizeId(root.dataset.sampleProductId); const sampleVariantId = TapProductSample.normalizeId(root.dataset.sampleVariantId); const sampleProductIds = TapProductSample.splitIds(root.dataset.allSampleProductIds); const sampleCategoryProductIds = TapProductSample.getSampleCategoryProductIds(root); return items.reduce((sum, item) => { if ( TapProductSample.isSampleItem( item, sampleProductIds, sampleCategoryProductIds, sampleProductId, sampleVariantId ) ) { return sum + TapProductSample.getQuantity(item); } return sum; }, 0); }, hasNativeSampleProductDuplicate: (items, root) => { const productId = TapProductSample.normalizeId(root?.dataset?.productId); if (!productId) { return false; } return items.some((item) => { if (TapProductSample.getItemProductId(item) === productId) { return true; } return TapProductSample.collectStrings(item).includes(productId); }); }, bindNativeSampleProductGuard: (root) => { if (root.dataset.isSampleCategoryProduct !== '1') { return; } const currentProductId = TapProductSample.normalizeId(root.dataset.productId); document .querySelectorAll(TapProductSample.settings.selectors.nativeBuyButton) .forEach((buyButton) => { if ( TapProductSample.normalizeId(buyButton.getAttribute('product-id')) !== currentProductId || buyButton.dataset.tapProductSampleGuardReady === '1' ) { return; } buyButton.dataset.tapProductSampleGuardReady = '1'; buyButton.setAttribute('quantity', '1'); buyButton.addEventListener( 'click', async (event) => { if (buyButton.dataset.tapProductSampleGuardBypass === '1') { delete buyButton.dataset.tapProductSampleGuardBypass; return; } const nativeButton = event.target.closest('button'); if (!nativeButton || !buyButton.contains(nativeButton)) { return; } event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); try { const items = await TapProductSample.getBasketItems(); const sampleLimit = TapProductSample.getSampleLimit(root); const apiSamplesCount = TapProductSample.countSamples(items, root); const domSamplesCount = TapProductSample.countSamplesInDom(); const currentSamplesCount = Math.max( apiSamplesCount, domSamplesCount ); if ( TapProductSample.hasNativeSampleProductDuplicate(items, root) || TapProductSample.hasNativeSampleProductInDom(root) ) { TapProductSample.showModal( root.dataset.duplicateMessage || 'Już dodałeś próbkę tego produktu' ); return; } if (currentSamplesCount + 1 > sampleLimit) { TapProductSample.showModal( root.dataset.limitMessage || 'Możesz zamówić maksymalnie 5 próbek!' ); return; } TapProductSample.protectNativeSampleProductQuantity(root); buyButton.setAttribute('quantity', '1'); buyButton.dataset.tapProductSampleGuardBypass = '1'; nativeButton.click(); } catch (error) { console.error( '[TapProductSample] Native sample limit check failed.', error ); TapProductSample.showModal( root.dataset.errorMessage || 'Wystąpił błąd podczas dodawania próbki' ); } }, true ); }); }, createModal: () => { let modal = document.querySelector('.tap-product-sample-modal'); if (modal) { return modal; } modal = document.createElement('div'); modal.className = 'tap-product-sample-modal'; modal.innerHTML = ` `; document.body.appendChild(modal); modal.addEventListener('click', (event) => { if (event.target === modal) { TapProductSample.closeModal(); } }); modal.querySelector('.tap-product-sample-modal__close').addEventListener('click', () => { TapProductSample.closeModal(); }); document.addEventListener('keydown', (event) => { if (event.key === 'Escape') { TapProductSample.closeModal(); } }); return modal; }, showModal: (message, type = 'info') => { const modal = TapProductSample.createModal(); const messageNode = modal.querySelector('.tap-product-sample-modal__message'); const iconNode = modal.querySelector('.tap-product-sample-modal__icon'); if (messageNode) { messageNode.textContent = message; } if (iconNode) { if (type === 'success') { iconNode.innerHTML = ` `; } else { iconNode.textContent = 'i'; } } modal.classList.add(TapProductSample.settings.classes.modalActive); }, closeModal: () => { const modal = document.querySelector('.tap-product-sample-modal'); if (modal) { modal.classList.remove(TapProductSample.settings.classes.modalActive); } }, addSampleToBasket: async (root) => { await TapProductSample.waitForBasket(); const basketUpdaterApi = TapProductSample.settings.basketUpdaterApi; if (!basketUpdaterApi || typeof basketUpdaterApi.addItem !== 'function') { throw new Error('Basket updater API is not available.'); } const variantOptions = {}; variantOptions[root.dataset.productNameOptionId] = root.dataset.productName || ''; variantOptions[root.dataset.productIdOptionId] = root.dataset.productId || ''; const item = { variantId: Number(root.dataset.sampleVariantId), quantity: 1, variantOptions, showAddedModal: false, bundleItems: [] }; const basket = await basketUpdaterApi.addItem(item); const returnedItems = TapProductSample.getBasketItemsFromBasketObject(basket); if (returnedItems.length) { TapProductSample.settings.basketProducts = returnedItems; } if (basketUpdaterApi.refreshBasket && typeof basketUpdaterApi.refreshBasket === 'function') { try { await basketUpdaterApi.refreshBasket(); } catch (error) {} } return basket; }, handleClick: async (root, button) => { if (button.classList.contains(TapProductSample.settings.classes.loading)) { return; } button.classList.add(TapProductSample.settings.classes.loading); button.disabled = true; try { const items = await TapProductSample.getBasketItems(); const sampleLimit = TapProductSample.getSampleLimit(root); const apiSamplesCount = TapProductSample.countSamples(items, root); const domSamplesCount = TapProductSample.countSamplesInDom(); const currentSamplesCount = Math.max(apiSamplesCount, domSamplesCount); if ( TapProductSample.hasDuplicateSample(items, root) || TapProductSample.hasDuplicateSampleInDom(root) ) { TapProductSample.showModal( root.dataset.duplicateMessage || 'Już dodałeś próbkę tego produktu' ); return; } if (currentSamplesCount + 1 > sampleLimit) { TapProductSample.showModal(root.dataset.limitMessage || 'Możesz zamówić maksymalnie 5 próbek!'); return; } await TapProductSample.addSampleToBasket(root); TapProductSample.scheduleBasketDomProtection(); if (root.dataset.afterAddAction === 'cart') { window.location.href = root.dataset.basketUrl || '/basket'; return; } TapProductSample.showModal( root.dataset.addedMessage || 'Próbka została dodana do koszyka', 'success' ); } catch (error) { console.error('[TapProductSample] Sample add failed.', error); TapProductSample.showModal(root.dataset.errorMessage || 'Wystąpił błąd podczas dodawania próbki'); } finally { button.classList.remove(TapProductSample.settings.classes.loading); button.disabled = false; } } }; useStorefront(async (storefront) => { TapProductSample.init(storefront); storefront.eventBus.on('PageManager.loaded', () => { TapProductSample.load(); if (TapProductSample.shouldPrepareBasketApis()) { TapProductSample.ensureBasketApis().catch((error) => { console.warn( '[TapProductSample] Basket resolve after PageManager.loaded failed.', error ); }); } }); });
Długość: 275 cm
Szerokość: 30 cm
Typ: Lamele ścienne
Materiał:: Płyta HDF
Grubość: 2 cm

Potrzebujesz porady? Odpowiemy na Twoje pytania!

Gwarancja bezpiecznego zakupu

Sztukateria

  • Kolor Orzech
  • Materiał: Płyta HDF
  • Grubość 2 cm
  • Długość 275 cm
  • Szerokość 30 cm
  • Typ Lamele ścienne
Zapytaj o produkt
Udostępnij

Opis produktu

Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105 - do jakich wnętrz?

Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105 w kolorze orzechowym to elegancki i stylowy element dekoracyjny, który doskonale komponuje się przede wszystkim z nowoczesnymi wnętrzami, ale równie dobrze może znaleźć miejsce w aranżacjach loftowych, glamour, rustykalnych i wielu innych stylach. To, co wyróżnia te lamele, to ich oryginalność i jednocześnie wszechstronność, która pozwala na ich wykorzystanie w praktycznie każdej estetyce wnętrza. Kolor orzechowy jest zdecydowanie najciemniejszym i najbardziej wyrazistym spośród dostępnych odcieni drewna w naszej ofercie. Panele akustyczne z płyty HDF można łatwo zamontować zarówno na ścianie, jak i suficie. Płyta HDF jest gruba i gęsta, co sprawia, że skutecznie przyczynia się do redukcji hałasu w pomieszczeniu. To rozwiązanie, które łączy w sobie funkcję akustyczną z eleganckim wyglądem, tworząc wyjątkową atmosferę w każdym wnętrzu.

Lamele na płycie HDF – czym właściwie są?

Panele akustyczne HDF to dekoracyjne elementy, które są bardzo popularne i wszechstronne w zastosowaniach. Składają się z sześciu cienkich listew o grubości 2 cm, zamocowanych na płycie HDF o szerokości 30 cm i długości 275 cm. Montaż tych paneli jest prosty, można je łatwo przykleić za pomocą kleju, co sprawia, że nawet osoby bez doświadczenia w montażu poradzą sobie z nimi. Panele można umieszczać na ścianach lub sufitach, zarówno w poziomie, jak i w pionie, w zależności od potrzeb. Mogą one stanowić główny element dekoracyjny w pomieszczeniu lub też służyć jako tło lub uzupełnienie dla innych dekoracji lub mebli.

Czy lamele na płycie HDF tłumią hałas?

Panele akustyczne HDF posiadają właściwości tłumienia hałasu i redukują echa w pomieszczeniu. Dlatego często są stosowane w różnych miejscach, takich jak salon, sypialnia, przedpokój, biuro, kuchnia czy łazienka. Płyta HDF, z której są wykonane panele, ma grubość 3 mm, co sprawia, że jest lekka, ale jednocześnie trwała, co pozwala uniknąć uszkodzeń. Oprócz swojej funkcji akustycznej, te drewniane panele są również atrakcyjną i nowoczesną dekoracją do ścian i sufitów w różnych wnętrzach. Panele akustyczne z listwami dostępne są w różnych wzorach i dekorach, montowane na czarnym panelu HDF, który jest wytrzymały i lekki.

Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105 - proste w montażu

Proces instalacji jest prosty i pozwala w mgnieniu oka postawić wymarzone ściany! Po prostu zamontuj je na wybranej powierzchni za pomocą kleju, śrub lub kołków i przytnij zgodnie ze specyfikacjami za pomocą ostrej piły lub wyrzynarki. Dzięki łatwemu montażowi, trwałości i niesamowitemu stylowi Lamele na czarnej płycie HDF Lameo Dąb Naturalny LAMEO_H103 są koniecznością w każdym nowoczesnym domu.

Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105 do wyjątkowych aranżacji

Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105 idealnie nadają się do szerokiej gamy przestrzeni i ustawień. W sypialni można je wykorzystać do stworzenia charakterystycznej ściany za łóżkiem. W korytarzu mogą pomóc stworzyć ciepłą i przyjazną przestrzeń, kiedy wrócisz do domu. W salonie można z nich stworzyć przyciągającą wzrok ścianę medialną. Na tym nie kończy się wszechstronność naszych paneli ściennych z drewna listwowego. Są także doskonałym wyborem do obiektów komercyjnych, takich jak restauracje, kawiarnie i biura.


Zobacz wszystkie lamele ścienne

Producent: Lameo
Materiał:: Płyta HDF
Grubość: 2 cm
Długość: 275 cm
Szerokość: 30 cm
Typ: Lamele ścienne
cd9987c4a86778579a1550c1b2cb5ebe
Lamele na białej płycie HDF Lameo Orzech LAMEO_HB105

Inne produkty z tej kategorii