Files
newwalls.pl/themes/ayon/templates/catalog/product.tpl
Roman Pyrih 4bbd4973b9 Save
2026-05-05 16:01:40 +02:00

1045 lines
46 KiB
Smarty

{**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{extends file=$layout}
{assign var="pl_manufacturer" value=Manufacturer::getNameById($product.id_manufacturer)}
{block name='head_seo' prepend}
<link rel="canonical" href="{$product.canonical_url}">
{/block}
{block name='head' append}
<meta property="og:type" content="product">
<meta property="og:url" content="{$urls.current_url}">
<meta property="og:title" content="{$page.meta.title}">
<meta property="og:site_name" content="{$shop.name}">
<meta property="og:description" content="{$page.meta.description}">
<meta property="og:image" content="{$product.cover.large.url}">
{if $product.show_price}
<meta property="product:pretax_price:amount" content="{$product.price_tax_exc}">
<meta property="product:pretax_price:currency" content="{$currency.iso_code}">
<meta property="product:price:amount" content="{$product.price_amount}">
<meta property="product:price:currency" content="{$currency.iso_code}">
{/if}
{if isset($product.weight) && ($product.weight != 0)}
<meta property="product:weight:value" content="{$product.weight}">
<meta property="product:weight:units" content="{$product.weight_unit}">
{/if}
{/block}
{if $smarty.server.REMOTE_ADDR != '193.243.155.179'}
{block name='content'}
<section id="main" t="{$smarty.server.REMOTE_ADDR}" itemscope itemtype="https://schema.org/Product">
<meta itemprop="url" content="{$product.url}">
<meta itemprop="gtin13" content="{$product.ean13}" />
<meta itemprop="brand" content="{if isset($pl_manufacturer)}{$pl_manufacturer}{else}{$shop.name}{/if}" />
{if isset($product.isbn)}<meta itemprop="productID" content="{$product.isbn}">{/if}
<div class="container">
{if isset($roythemes.b_pos_pro) && $roythemes.b_pos_pro == "2"}
{block name='breadcrumb'}
{include file='_partials/breadcrumb.tpl'}
{/block}
{/if}
{block name='page_header_container'}
{block name='page_header'}
<h1 class="h1 product-title" itemprop="name">{block name='page_title'}{$product.name}{/block}</h1>
{hook h='displayProductNav' product=$product}
{/block}
{/block}
<div class="product-block-prices">
{block name='product_discounts'}
{include file='catalog/_partials/product-discounts.tpl'}
{/block}
{if isset($roythemes.nc_pp_con) && $roythemes.nc_pp_con == "1"}
{block name='product_prices'}
{include file='catalog/_partials/product-prices.tpl'}
{/block}
{/if}
</div>
{$last_img = Product::getProductImages($product.link_rewrite,$product.id, $this->context)}
<!--
{$attrs = $product.attributes}
{foreach from=$attrs item=elem key=key}
{$elem.id_attribute}
{/foreach}
-->
<div class="product-top-banner">
<img src="{$last_img}" width="100" itemprop="image" draggable="false">
</div>
<div class="row {if isset($roythemes.pp_sticky) && $roythemes.pp_sticky == "1"}pp_stick_parent{/if}">
<div class="col-lg-6 col-image">
{block name='page_content_container'}
<section class="col-image-inside">
{block name='page_content'}
{block name='product_flags'}
<ul class="product-flags">
{foreach from=$product.flags item=flag}
<li class="product-flag {$flag.type}">{$flag.label}</li>
{/foreach}
</ul>
{/block}
<div class="product_image_wrapper">
{block name='product_cover_thumbnails'}
{include file='catalog/_partials/product-cover-thumbnails.tpl'}
{/block}
</div>
{/block}
</section>
{/block}
</div>
<div class="col-lg-6 col-content">
<div class="col-content-inside {if isset($roythemes.pp_sticky) && $roythemes.pp_sticky == "1"}pp_stick_it{/if}">
{if isset($nb_comments) && $nb_comments > 0}
<div class="comments-note">
{include file='module:productcomments/views/templates/hook/average-grade-stars.tpl' grade=$average_grade}
<a class="nb-comments noeffect goreviews" href="#tabsection"><span itemprop="reviewCount">{l s='%s'|sprintf:$nbComments mod='productcomments'}</span> {if isset($nbComments) && $nbComments == 1}{l s='Review'}{else}{l s='Reviews'}{/if}</a>
<div itemprop="aggregateRating" itemtype="http://schema.org/AggregateRating" itemscope>
<meta itemprop="reviewCount" content="{$nb_comments}" />
<meta itemprop="ratingValue" content="{$average_grade}" />
</div>
</div>
{/if}
{widget name='productcomments' hook='displayProductExtraContent'}
<div class="product-information">
{if $product.is_customizable && count($product.customizations.fields)}
{block name='product_customization'}
{include file="catalog/_partials/product-customization.tpl" customizations=$product.customizations}
{/block}
{/if}
{if isset($roythemes.nc_pp_con) && $roythemes.nc_pp_con == "2"}
{block name='product_additional_info'}
{include file='catalog/_partials/product-additional-info.tpl'}
{/block}
{/if}
{if isset($roythemes.nc_pp_con) && ($roythemes.nc_pp_con == "2" || $roythemes.nc_pp_con == "3")}
{block name='product_prices'}
{include file='catalog/_partials/product-prices.tpl'}
{/block}
{/if}
</div>
</div>
</div>
</div>
<div class="product-actions">{block name='product_buy'}{*<div id="zapisz">ZAPISZ</div> *}
<form action="{$urls.pages.cart}" method="post" id="add-to-cart-or-refresh">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="id_product" value="{$product.id}" id="product_page_product_id">
<input type="hidden" name="id_customization" value="{$product.id_customization}" id="product_customization_id" class="js-product-customization-id">
<input type="hidden" name="fixed_price" value="{$product.price_amount}" id="product_fixed_price">
<input type="hidden" name="base_price" value="{$product.price_amount}" id="product_base_price">
<input type="hidden" name="is_crop" value="0" id="product_is_crop">
<input type="hidden" name="is_reflection" value="0" id="product_is_reflection">
<input type="hidden" name="crop_pos_x" value="0" id="product_crop_pos_x">
<input type="hidden" name="crop_pos_y" value="0" id="product_crop_pos_y">
<input type="hidden" name="crop_width" value="0" id="product_crop_width">
<input type="hidden" name="crop_height" value="0" id="product_crop_height">
<input type="hidden" name="product_total_price_calc" id="product_total_price_calc" value='' />
<input type="hidden" name="piece_bg_top" id="piece_bg_top" value='' />
<input type="hidden" name="piece_bg_left" id="piece_bg_left" value='' />
<div class="product-bar-container 1">
<div class="product-bar product-bar-title container">
<h3>Konfigurator</h3>
<h2>Dopasuj tapetę do swoich potrzeb</h2>
</div>
<div class="product-bar product-bar-data container">
{$product_variant_mode = 1}
<a rel="nofollow" href="javascript:void(0);" class="fancybox-size-controls">
<div id="fancybox-size-controls" class="">
<div class="product-block-piece">
<div class="product-bar-label">
<p>1.</p>
</div>
<div class="product-bar-icon crop-icon">
<img src="/themes/ayon/assets/images/dopasuj-wymiar.png" alt="">
{* <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17 15h2V7c0-1.1-.9-2-2-2H9v2h8v8zM7 17V1H5v4H1v2h4v10c0 1.1.9 2 2 2h10v4h2v-4h4v-2H7z"/></svg> *}
</div>
<div class="product-bar-box">
<div class="piece-size-controls product-bar-box">
Dopasuj wymiar
{* {l s='Rozmiar:' d='Shop.Theme.Catalog'} <br/>
<span id="piece-size-view" class="strong">
{l s='Wybierz' d='Shop.Theme.Catalog'}
</span> *}
</div>
<div class="piece-size-controls hidden">
<input type="checkbox" id="checkbox-piece"><label for="checkbox-piece">Wymiary tapety</label>
</div>
<div class="piece-size-values hidden">
<input type="number" min="50" max="500" value="100" id="piece-width" readonly>
<input type="number" min="50" max="300" value="100" id="piece-height" readonly>
</div>
</div>
</div></a>
</div>
{block name='product_variants'}
{include file='catalog/_partials/product-variants.tpl'}
{/block}
<div id="button-mirror-reflection">
<div class="product-bar-label">
<p>3.</p>
</div>
<div class="product-bar-icon rotate-icon" style="margin-top: 0px !important;">
<img src="/themes/ayon/assets/images/odbicie-iustrzane.png" alt="">
{* <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"/></svg> *}
</div>
<div class="product-bar-box">
{* <p class="button-mirror-reflection-label">Odbicie<br/>lustrzane</p> *}
<p class="button-mirror-reflection-label">Odbicie lustrzane</p>
</div>
</div>
<div id="button-color-variants">
<div class="product-bar-label">
<p>4.</p>
</div>
<div class="product-bar-icon rotate-icon" style="margin-top: 0px !important;">
<img src="/themes/ayon/assets/images/wariant-kolorystyczny.png" alt="">
</div>
<div class="product-bar-box">
<p class="button-color-variants-label">Wariant kolorystyczny</p>
</div>
</div>
{* <div class="product-block-custom-price">
<div class="product-bar-icon"></div>
<div class="product-bar-box">
<div class="clearfix product-variants-item">
<p id="custom-wallpaper-price-label">Cena</p>
<p id="custom-wallpaper-price"></p>
</div>
</div>
</div> *}
{* {block name='product_add_to_cart'}
{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}
{block name='product_discounts'}
{include file='catalog/_partials/product-discounts.tpl'}
{/block} *}
</div>
</div>
<div id="box-color-variants">
{$product_variant_mode = 2}
{block name='product_variants'}
{include file='catalog/_partials/product-variants.tpl'}
{/block}
</div>
<div class="product-actions-custom">
<div class="product-bar container">
<div class="product-actions-custom--wrapper">
{block name='product_add_to_cart'}
{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}
{block name='product_discounts'}
{include file='catalog/_partials/product-discounts.tpl'}
{/block}
</div>
</div>
</div>
{* {$product_variant_mode = 2}
{block name='product_variants'}
{include file='catalog/_partials/product-variants.tpl'}
{/block} *}
</form>
{/block}
</div>
{if in_array(6,Product::getProductCategories($product->id|intval))}
<a href="https://designer.hpwallart.com/mcdn?external_link=true"><div class="wallcover-button">Stwórz wzór tapety</div></a>
{/if}
{block name='product_tabs'}
<div class="tabs" id="tabsection">
<div class="container">
<ul class="nav nav-tabs" role="tablist">
{if $product.description}
<li class="nav-item">
<a
class="nav-link{if $product.description} active{/if}"
data-toggle="tab"
href="#description"
role="tab"
aria-controls="description"
{if $product.description} aria-selected="true"{/if}>{l s='Description' d='Shop.Theme.Catalog'}</a>
</li>
{/if}
{if $product.features}
<li class="nav-item">
<a
class="nav-link{if !$product.description} active{/if}"
data-toggle="tab"
href="#product-details"
role="tab"
aria-controls="product-details"
{if !$product.description} aria-selected="true"{/if}>{l s='Product Details' d='Shop.Theme.Catalog'}</a>
</li>
{/if}
{if $product.attachments}
<li class="nav-item">
<a
class="nav-link"
data-toggle="tab"
href="#attachments"
role="tab"
aria-controls="attachments">{l s='Attachments' d='Shop.Theme.Catalog'}</a>
</li>
{/if}
{foreach from=$product.extraContent item=extra key=extraKey}
<li class="nav-item">
<a
class="nav-link"
data-toggle="tab"
href="#extra-{$extraKey}"
role="tab"
aria-controls="extra-{$extraKey}">{$extra.title}</a>
</li>
{/foreach}
</ul>
<div class="tab-content" id="tab-content">
<div class="tab-pane fade in{if $product.description} active{/if}" id="description" role="tabpanel">
{block name='product_description'}
<div class="product-description">{$product.description nofilter}</div>
{/block}
</div>
{block name='product_details'}
{include file='catalog/_partials/product-details.tpl'}
{/block}
{block name='product_attachments'}
{if $product.attachments}
<div class="tab-pane fade in" id="attachments" role="tabpanel">
<section class="product-attachments">
<h3 class="h5 text-uppercase">{l s='Download' d='Shop.Theme.Actions'}</h3>
{foreach from=$product.attachments item=attachment}
<div class="attachment">
<h4><a href="{url entity='attachment' params=['id_attachment' => $attachment.id_attachment]}">{$attachment.name}</a></h4>
<p>{$attachment.description}</p
<a href="{url entity='attachment' params=['id_attachment' => $attachment.id_attachment]}">
{l s='Download' d='Shop.Theme.Actions'} ({$attachment.file_size_formatted})
</a>
</div>
{/foreach}
</section>
</div>
{/if}
{/block}
{foreach from=$product.extraContent item=extra key=extraKey}
<div class="tab-pane fade in {$extra.attr.class}" id="extra-{$extraKey}" role="tabpanel" {foreach $extra.attr as $key => $val} {$key}="{$val}"{/foreach}>
{$extra.content nofilter}
</div>
{/foreach}
</div>
</div>
</div>
{/block}
{hook h='displayProductBeforeBuy' mod='roy_content'}
{block name='product_accessories'}
{if $accessories}
<section class="product-accessories featured-products slideme clearfix mt-3">
<div class="pp_products_wrapper">
<h2 class="products-section-title">
{l s='You might also like' d='Shop.Theme.Catalog'}
</h2>
<div class="products">
{foreach from=$accessories item="product_accessory"}
{block name='product_miniature'}
{include file='catalog/_partials/miniatures/product.tpl' product=$product_accessory}
{/block}
{/foreach}
</div>
</div>
</section>
{/if}
{/block}
<a href="/Instrukcja.pdf" class="product-manual-button">Pobierz instrukcję PDF</a>
{block name='special_order_modal'}
{include file='catalog/_partials/custom/special-order.tpl'}
{/block}
{block name='email_pattern_modal'}
{include file='catalog/_partials/custom/email-pattern.tpl'}
{/block}
{block name='product_footer'}
{hook h='displayFooterProduct' product=$product category=$category}
{/block}
{block name='product_images_modal'}
{include file='catalog/_partials/product-images-modal.tpl'}
{/block}
</div>
{block name='page_footer_container'}
<footer class="page-footer">
{block name='page_footer'}
<!-- Footer content -->
{/block}
</footer>
{/block}
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides.
PhotoSwipe keeps only 3 of them in the DOM to save memory.
Don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
</section>
<div class="piece-left-positon hidden">10</div>
<div class="piece-top-positon hidden">10</div>
{/block}
{else}
{block name='content'}
<section id="main" class="new-product-ui" itemscope itemtype="https://schema.org/Product">
<meta itemprop="url" content="{$product.url}">
<meta itemprop="gtin13" content="{$product.ean13}" />
<meta itemprop="brand" content="{if isset($pl_manufacturer)}{$pl_manufacturer}{else}{$shop.name}{/if}" />
{if isset($product.isbn)}<meta itemprop="productID" content="{$product.isbn}">{/if}
<div class="container">
{if isset($roythemes.b_pos_pro) && $roythemes.b_pos_pro == "2"}
{block name='breadcrumb'}
{include file='_partials/breadcrumb.tpl'}
{/block}
{/if}
<div class="row">
<div class="col-md-6">
<div class="product_image">
{block name='product_flags'}
<ul class="product-flags">
{foreach from=$product.flags item=flag}
<li class="product-flag {$flag.type}">{$flag.label}</li>
{/foreach}
</ul>
{/block}
<div class="product_image_wrapper">
{block name='product_cover_thumbnails'}
{include file='catalog/_partials/product-cover-thumbnails.tpl'}
{/block}
{* #piece jest wewnatrz product-cover-thumbnails.tpl (rendered inside .product-images li) — NIE duplikowac tutaj *}
</div>
</div>
</div>
<div class="col-md-6">
{block name='page_header_container'}
{block name='page_header'}
<h1 class="h1 product-title" itemprop="name">{block name='page_title'}{$product.name}{/block}</h1>
{hook h='displayProductNav' product=$product}
{/block}
{/block}
{block name='product_description'}
{if $product.description}
<div class="product-box block-description-data">
<h4 class="block-title" data-type="description">{l s='Wallpaper description' d='Shop.Theme.Catalog'}</h4>
<div class="product-description">{$product.description nofilter}</div>
</div>
{/if}
{/block}
{block name='product_config_info'}
<div class="product-box block-config-info-data">
<h4 class="block-title">Skonfiguruj tapetę do wymiarów swojej ściany</h4>
<p>Przed dodaniem do koszyka dopasuj tapetę do wymiarów swojej ściany. Nasz konfigurator pozwala na dostosowanie wymiarów i kolorystyki tapety.</p>
</div>
{/block}
{block name='product_price'}
<div class="product-box product-price-data">
<div class="product-price-data--wrapper">
<h4 class="block-title">Cena</h4>
<div class="product-prices-data">
{block name='product_prices'}
{include file='catalog/_partials/product-prices.tpl'}
{/block}
{block name='product_discounts'}
{include file='catalog/_partials/product-discounts.tpl'}
{/block}
</div>
</div>
<div class="product-config-btn">
<a href="#" class="_btn-1"><span>Skonfiguruj tapetę</span></a>
</div>
</div>
{/block}
{block name='product_variants'}
{$product_variant_mode = 2}
<div class="product-box product-variants-data product-variants-data--new">
<h4 class="block-title">Wybierz wersję kolorystyczną</h4>
<form action="{$urls.pages.cart}" method="post" id="add-to-cart-or-refresh">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="id_product" value="{$product.id}" id="product_page_product_id">
<input type="hidden" name="id_customization" value="{$product.id_customization}" id="product_customization_id" class="js-product-customization-id">
<input type="hidden" name="is_crop" value="0" id="product_is_crop">
<input type="hidden" name="is_reflection" value="0" id="product_is_reflection">
<input type="hidden" name="crop_pos_x" value="0" id="product_crop_pos_x">
<input type="hidden" name="crop_pos_y" value="0" id="product_crop_pos_y">
<input type="hidden" name="crop_width" value="0" id="product_crop_width">
<input type="hidden" name="crop_height" value="0" id="product_crop_height">
<input type="hidden" name="piece_bg_top" id="piece_bg_top" value="">
<input type="hidden" name="piece_bg_left" id="piece_bg_left" value="">
<div class="product-variants-grid">
{include file='catalog/_partials/product-variants.tpl'}
</div>
</form>
</div>
{/block}
{block name='product_size'}
<div class="product-box product-box-acc product-size-data" >
<div class="product-box--head">
<h4 class="block-title">Rozmiar i dostosowanie</h4>
</div>
<div class="product-box--data">
<div class="product-size-data--new">
<a rel="nofollow" href="javascript:void(0);" class="fancybox-size-controls">
<div class="variant-action-btn">
<div class="product-bar-icon crop-icon">
<img src="/themes/ayon/assets/images/dopasuj-wymiar.png" alt="">
</div>
<div class="product-bar-box">
<div class="piece-size-controls product-bar-box">
Dopasuj wymiar
</div>
<div class="piece-size-controls hidden">
<input type="checkbox" id="checkbox-piece"><label for="checkbox-piece">Wymiary tapety</label>
</div>
<div class="piece-size-values hidden">
<input type="number" min="50" max="500" value="100" id="piece-width" readonly>
<input type="number" min="50" max="300" value="100" id="piece-height" readonly>
</div>
</div>
</div>
</a>
<div id="button-mirror-reflection">
<div class="variant-action-btn">
<div class="product-bar-icon rotate-icon">
<img src="/themes/ayon/assets/images/odbicie-iustrzane.png" alt="">
</div>
<div class="product-bar-box">
<p class="button-mirror-reflection-label">Odbicie lustrzane</p>
</div>
</div>
</div>
{* Hidden state trzymane w DOM — istniejące handlery w custom.js bindują się po ID. *}
<input type="checkbox" id="checkbox-piece" checked style="display:none;">
<input type="number" min="50" max="500" value="100" id="piece-width" style="display:none;">
<input type="number" min="50" max="300" value="100" id="piece-height" style="display:none;">
<div class="piece-left-positon" style="display:none;">10</div>
<div class="piece-top-positon" style="display:none;">10</div>
</div>
</div>
</div>
{/block}
{block name='product_texture'}
<div class="product-box product-box-acc product-texture-data">
<div class="product-box--head">
<h4 class="block-title">Tekstura materiału</h4>
</div>
<div class="product-box--data">
<div class="product-size-data--new">
{$product_variant_mode = 1}
{block name='product_variants'}
{include file='catalog/_partials/product-variants.tpl'}
{/block}
</div>
</div>
</div>
{/block}
{block name='product_realization_time'}
<div class="product-box product-box-acc product-realization-time">
<div class="product-box--head">
<h4 class="block-title">Czas realizacji zamówienia</h4>
</div>
<div class="product-box--data">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error, necessitatibus.
</div>
</div>
{/block}
{block name='product_protect'}
<div class="product-box product-box-acc product-protect">
<div class="product-box--head">
<h4 class="block-title">Zabezpiecz tapetę</h4>
</div>
<div class="product-box--data">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi, minus.
</div>
</div>
{/block}
{block name='product_installation'}
<div class="product-box product-box-acc product-installation">
<div class="product-box--head">
<h4 class="block-title">Montaż</h4>
</div>
<div class="product-box--data">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi, minus.
</div>
</div>
{/block}
{block name='product_order_sample'}
<div class="product-box product-order-sample">
<div class="product-order-sample--wrapper">
<h4 class="block-title">Zamów próbkę</h4>
<p>Masz trudność w wyborze odpowiedniej tapety?<br/>Zamów próbkę o wymiarach 30x60 cm korzystając z konfiguratora.</p>
</div>
<div class="product-config-btn">
<a href="#" class="_btn-1"><span>Zamów próbkę</span></a>
</div>
</div>
{/block}
<div class="product-add-to-cart">
<div class="product-bar container">
<div class="product-actions-custom--wrapper">
{block name='product_add_to_cart'}
{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}
{block name='product_discounts'}
{include file='catalog/_partials/product-discounts.tpl'}
{/block}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="product-box-free-example">
<div class="container">
<div class="_c-row _c-row-1">
<div class="_c-col">
<p>Tekstura</p>
</div>
</div>
<div class="_c-row _c-row-2">
<div class="_c-col _c-col-1"><img src="/img/cms/home/image 5.png" alt="" /></div>
<div class="_c-col _c-col-2">
<h3>Zamów darmowy wzornik struktur</h3>
<div class="_box-text">
<p>Zamawiając nasz wzorki struktur masz możliwość sprawdzenia rzeczywistych barw wzoru oraz zapoznania się z wybraną teskturą.</p>
<p>W próbce uchwyciliśmy fragment grafiki, starannie pomniejszony, by maksymalnie zaprezentować wybrany wzór.</p>
</div>
<a href="#" class="_btn-1"><span>Dodaj do koszyka</span></a></div>
</div>
</div>
</div>
</section>
{* =========================================================================
Phase 02 Plan 02-02: inline add-to-cart handler (cache-buster).
Powod: <script src="custom.js"> w tym temacie jest serwowany bez wersji
i browser cache'uje stara wersje przy kolejnych iteracjach. Ten inline
<script> jest czescia HTML response wiec ZAWSZE jest swiezy. Idempotentny
guard `window.__p02p02Bound` zapobiega double-register jesli custom.js
tez jest aktualny (happy path z hard-reload).
Kod IDENTYCZNY z custom.js:994-1113 — zmiany wprowadzaj w OBU miejscach
do czasu dodania systemowego cache-bustera (Plan 02-03+).
========================================================================= *}
<script type="text/javascript">
(function() {
if (window.__p02p02Bound) return;
window.__p02p02Bound = true;
document.addEventListener('click', function(e) {
var btn = e.target.closest ? e.target.closest('[data-button-action=add-to-cart]') : null;
if (!btn) return;
if (!document.querySelector('.product-variants-data--new')) return;
var $form = jQuery('#add-to-cart-or-refresh');
if (!$form.length) return;
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
if (window.__p02p02InFlight) return;
window.__p02p02InFlight = true;
if (!jQuery('#checkbox-piece').is(':checked')) {
window.__p02p02InFlight = false;
jQuery.fancybox({
minWidth: 800, maxWidth: 1000, padding: 30, height: 100,
content: 'Proszę wybrać rozmiar i wycinek tapety przed dodaniem jej do koszyka.'
});
return;
}
if (jQuery('#product_is_crop').val() === '0' || !jQuery('#product_crop_width').val() || jQuery('#product_crop_width').val() === '0') {
jQuery('#product_is_crop').val('1');
var pw = parseInt(jQuery('#piece-width').val(), 10) || 100;
var ph = parseInt(jQuery('#piece-height').val(), 10) || 100;
jQuery('#product_crop_width').val(pw);
jQuery('#product_crop_height').val(ph);
}
var $btn = jQuery(btn);
$btn.prop('disabled', true).addClass('loading');
var qty = parseInt(jQuery('#quantity_wanted').val(), 10) || 1;
// Phase 02 Plan 02-03 Task 2: inject squaremeter fields (patrz custom.js komentarz).
var pwRaw = parseInt(jQuery('#piece-width').val(), 10) || 100;
var phRaw = parseInt(jQuery('#piece-height').val(), 10) || 100;
var wM = (pwRaw / 100).toFixed(1);
var hM = (phRaw / 100).toFixed(1);
var areaM2 = (parseFloat(wM) * parseFloat(hM)).toFixed(4);
var basePrice = parseFloat(jQuery('#product_base_price').val())
|| parseFloat(jQuery('#product_fixed_price').val())
|| parseFloat(jQuery('meta[property="product:price:amount"]').attr('content'))
|| parseFloat((jQuery('.product-prices .current-price, .current-price').first().text() || '').replace(/[^\d.,]/g, '').replace(',', '.'))
|| 0;
var totalPriceCalc = Math.round(basePrice * parseFloat(areaM2));
jQuery('#discretion').prop('checked', true);
if (jQuery('#product_total_price_calc').length) jQuery('#product_total_price_calc').val(totalPriceCalc);
if (jQuery('#calculated_total').length) jQuery('#calculated_total').val(areaM2);
if (jQuery('#converted_ea').length) jQuery('#converted_ea').val(areaM2);
if (jQuery('#grand_calculated_total').length) jQuery('#grand_calculated_total').val('');
if (jQuery('#extrafeevalue').length) jQuery('#extrafeevalue').val('0');
if (jQuery('#wastevalue').length) jQuery('#wastevalue').val('0');
if (jQuery('#quantity_wanted_alt').length) jQuery('#quantity_wanted_alt').val(wM);
if (jQuery('#quantity_wanted_alth').length) jQuery('#quantity_wanted_alth').val(hM);
var isRefl = parseInt(jQuery('#product_is_reflection').val(), 10) || 0;
var cropPosX = parseInt(jQuery('#product_crop_pos_x').val(), 10) || 0;
var cropPosY = parseInt(jQuery('#product_crop_pos_y').val(), 10) || 0;
var bgTop = jQuery('#piece_bg_top').val() || 0;
var bgLeft = jQuery('#piece_bg_left').val() || 0;
var dimStr = 'Szerokość ' + wM + ' m, Wysokość ' + hM + ' m, ' +
parseFloat(areaM2).toFixed(2) + ' m2, Pozycja ' + cropPosX + ' ' + cropPosY +
' <span> ,Pozycja tła ' + bgTop + ' ' + bgLeft + ' ,Odbicie ' + isRefl + ' </span>';
if (jQuery('#dim').length) jQuery('#dim').val(dimStr);
var sqFields = 'discretion=on' +
'&dim=' + encodeURIComponent(dimStr) +
'&converted_ea=' + encodeURIComponent(areaM2) +
'&calculated_total=' + encodeURIComponent(areaM2) +
'&grand_calculated_total=' +
'&extrafeevalue=0' +
'&wastevalue=0' +
'&product_total_price_calc=' + encodeURIComponent(totalPriceCalc) +
'&qty_alt=' + encodeURIComponent(wM) +
'&qty_alth=' + encodeURIComponent(hM);
// Plan 02-05: PS attribute groups POZA formą #add-to-cart-or-refresh (np. #group_5
// "Tekstura materiału" w .product-bar-box). Enumeruj i dołącz do payload.
var externalGroups = '';
jQuery('[name^="group["]').each(function() {
var $el = jQuery(this);
if ($el.closest('#add-to-cart-or-refresh').length) return;
var t = ($el.attr('type') || '').toLowerCase();
if ((t === 'radio' || t === 'checkbox') && !$el.prop('checked')) return;
var n = $el.attr('name');
var v = $el.val();
if (v === undefined || v === null || v === '') return;
externalGroups += '&' + encodeURIComponent(n) + '=' + encodeURIComponent(v);
});
var payload = $form.serialize() + '&qty=' + encodeURIComponent(qty) + externalGroups + '&' + sqFields + '&add=1&action=update';
var actionUrl = $form.attr('action') || window.location.href;
jQuery.ajax({
url: actionUrl,
type: 'POST',
data: payload,
dataType: 'json',
headers: { 'Accept': 'application/json' },
success: function(resp) {
var hasError = !resp || resp.hasError === true || resp.success === false ||
(resp.errors && (Array.isArray(resp.errors) ? resp.errors.length : Object.keys(resp.errors).length));
if (hasError) {
var errs = resp && resp.errors;
var msg = '';
if (Array.isArray(errs)) msg = errs.join('<br>');
else if (errs && typeof errs === 'object') msg = Object.values(errs).join('<br>');
else msg = 'Nie udało się dodać produktu do koszyka. Spróbuj ponownie.';
jQuery.fancybox({
minWidth: 400, maxWidth: 800, padding: 30, height: 100,
content: msg
});
return;
}
if (window.prestashop && typeof prestashop.emit === 'function') {
prestashop.emit('updatedCart', { resp: resp, reason: { linkAction: 'add-to-cart' } });
}
jQuery(document).trigger('updatedCart', [resp]);
// Phase 02 Plan 02-03 Task 3: fetch success modal + preview (patrz custom.js).
jQuery.ajax({
url: '/module/ps_shoppingcart/ajax',
type: 'POST',
data: {
action: 'add-to-cart',
id_product: resp.id_product || '',
id_product_attribute: resp.id_product_attribute || '',
id_customization: resp.id_customization || 0
},
dataType: 'json'
}).done(function(mr) {
if (mr && mr.preview) {
jQuery('.blockcart').replaceWith(mr.preview);
}
if (mr && mr.modal) {
jQuery('#blockcart-modal').remove();
jQuery('.modal-backdrop').remove();
jQuery('body').append(mr.modal);
var $modal = jQuery('#blockcart-modal');
if (typeof $modal.modal === 'function') {
$modal.modal('show');
} else {
$modal.addClass('show in').css('display', 'block').attr('aria-hidden', 'false');
jQuery('body').addClass('modal-open').append('<div class="modal-backdrop fade in show"></div>');
$modal.on('click.blockcartClose', '[data-dismiss=modal], .close', function() {
$modal.removeClass('show in').css('display', 'none').remove();
jQuery('body').removeClass('modal-open');
jQuery('.modal-backdrop').remove();
});
}
}
}).fail(function() {
if (resp.cart) { jQuery('.cart-products-count').text(resp.cart.products_count || ''); }
});
$btn.addClass('added-flash');
setTimeout(function() { $btn.removeClass('added-flash'); }, 1200);
},
error: function() {
jQuery.fancybox({
minWidth: 400, maxWidth: 800, padding: 30, height: 100,
content: 'Błąd połączenia z serwerem. Spróbuj ponownie za chwilę.'
});
},
complete: function() {
$btn.prop('disabled', false).removeClass('loading');
window.__p02p02InFlight = false;
}
});
}, true);
})();
/* =========================================================================
Phase 02 Plan 02-04: live cena per-sqm (inline mirror).
Separate IIFE + __p02p04Bound guard — niezalezny od __p02p02Bound, zeby
stale-cache custom.js (bez Plan 02-04) nie blokowalo tej rejestracji.
Kod identyczny z custom.js __p02p04 block (jQuery zamiast $).
========================================================================= */
(function() {
if (window.__p02p04Bound) return;
window.__p02p04Bound = true;
window.__p02p04EnsureLabel = function() {
var $label = jQuery('.p02p04-total-price');
if ($label.length) return $label;
var $add = jQuery('.product-quantity .add').first();
if (!$add.length) return jQuery();
$label = jQuery('<span class="p02p04-total-price" aria-live="polite" style="display:inline-block;margin-right:16px;font-weight:700;font-size:1.25rem;vertical-align:middle;"></span>');
$add.before($label);
return $label;
};
window.__p02p04RecalcPrice = function() {
if (!document.querySelector('.product-variants-data--new')) return;
var pwRaw = parseInt((jQuery('#piece-width').val() || 0), 10) || 0;
var phRaw = parseInt((jQuery('#piece-height').val() || 0), 10) || 0;
var $label = window.__p02p04EnsureLabel();
if (pwRaw <= 0 || phRaw <= 0) {
if ($label.length) $label.text('');
return;
}
var areaM2 = (pwRaw / 100) * (phRaw / 100);
var basePrice = parseFloat(jQuery('meta[property="product:price:amount"]').attr('content'))
|| parseFloat((jQuery('.product-prices .current-price, .current-price').first()
.text() || '').replace(/[^\d.,]/g, '').replace(',', '.'))
|| 0;
if (basePrice <= 0) return;
var total = basePrice * areaM2;
var formatted = total.toFixed(2).replace('.', ',') + ' zł';
if ($label.length) $label.text(formatted);
};
jQuery(document).on('input change keyup', '#piece-width, #piece-height', function() {
clearTimeout(window.__p02p04RecalcT);
window.__p02p04RecalcT = setTimeout(window.__p02p04RecalcPrice, 100);
});
// Initial render interval re-apply przez 5s (squaremeter init overwrituje
// .current-price po naszym pierwszym recalc). Patrz custom.js komentarz.
window.__p02p04TryInitial = function() {
var attempts = 0;
var iv = setInterval(function() {
attempts++;
window.__p02p04RecalcPrice();
if (attempts >= 10) clearInterval(iv);
}, 500);
};
// Uruchom synchronicznie jQuery ready w kontekscie inline Smarty block
// nie firuje konsekwentnie. Recalc early-return gdy inputy brak.
window.__p02p04TryInitial();
(function bindUpdatedProduct() {
if (window.prestashop && typeof prestashop.on === 'function') {
prestashop.on('updatedProduct', function() {
setTimeout(window.__p02p04RecalcPrice, 50);
});
} else {
setTimeout(bindUpdatedProduct, 200);
}
})();
jQuery(document).on('updatedProduct', function() {
setTimeout(window.__p02p04RecalcPrice, 50);
});
})();
</script>
{/block}{* /block name=content — Plan 02-03 fix: moved to wrap inline script so it renders in {extends} template *}
{/if}