Plan 02-01 (piece/crop configurator, complete):
- #piece reuse z shared partial product-cover-thumbnails.tpl
- 8 hidden inputs (is_crop, crop_pos_x/y, crop_width/height, piece_bg_top/left, is_reflection) w formie #add-to-cart-or-refresh
- Defensive setup w custom.js: setTimeout(600) init, no-op override totalpriceinfospecific/prod, DOM stubs
- CSS scope pod body#product .product-size-data .product-size-data--new
Plan 02-02 (add-to-cart submission, PARTIAL):
- Capture-phase native addEventListener (useCapture=true) blokuje PS core crash
(button poza formą w nowym layoucie — closest('form') zwracało 0)
- Manualny AJAX POST: form.serialize() + qty + add=1&action=update do /pl/koszyk
- Fancybox-blocker port z custom.js:327 (nie odpalał się bo selector 0 matches)
- Manual sync is_crop/crop_width/height przed POST (obejście crash checkedHandler)
- prestashop.emit('updatedCart') + defensive blockcart refresh fetch
- Loading spinner + success flash CSS
- Inline handler mirror w product.tpl z idempotency guard (window.__p02p02Bound)
— cache-buster dla browser cachowanego custom.js
Deferred do Plan 02-03 (customization + modal blocker dla production):
- Customization nie zapisuje się (squaremeter hook gate'owany discretion=on + brak dimension fields)
- Success modal (wymaga POST do /module/ps_shoppingcart/ajax)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
861 lines
37 KiB
Smarty
861 lines
37 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 != '89.69.31.86'}
|
|
{block name='content'}
|
|
|
|
<section id="main" 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}
|
|
{/if}
|
|
{if $smarty.server.REMOTE_ADDR == '89.69.31.86'}
|
|
{block name='content'}
|
|
<section id="main" 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-size-data" >
|
|
<div class="product-box--head">
|
|
<a rel="nofollow" href="javascript:void(0);" class="fancybox-size-controls">
|
|
<h4 class="block-title">Rozmiar i dostosowanie</h4>
|
|
</a>
|
|
</div>
|
|
<div class="product-box--data">
|
|
<div class="product-size-data--new">
|
|
<a rel="nofollow" href="javascript:void(0);" class="fancybox-size-controls piece-summary">
|
|
<span id="piece-size-view" class="strong">Wybierz rozmiar</span>
|
|
<span class="piece-hint">— kliknij aby zmienić</span>
|
|
</a>
|
|
<div id="button-mirror-reflection">
|
|
<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>
|
|
{* 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-texture-data">
|
|
<div class="product-box--head">
|
|
<a rel="nofollow" href="javascript:void(0);" class="fancybox-size-controls">
|
|
<h4 class="block-title">Tekstura materiału</h4>
|
|
</a>
|
|
</div>
|
|
<div class="product-box--data">
|
|
{$product_variant_mode = 1}
|
|
{block name='product_variants'}
|
|
{include file='catalog/_partials/product-variants.tpl'}
|
|
{/block}
|
|
</div>
|
|
</div>
|
|
{/block}
|
|
|
|
{block name='product_realization_time'}
|
|
<div class="product-box product-realization-time">
|
|
<div class="product-box--head">
|
|
<h4 class="block-title">Czas realizacji zamówienia</h4>
|
|
</div>
|
|
<div class="product-box--data">
|
|
|
|
</div>
|
|
</div>
|
|
{/block}
|
|
|
|
{block name='product_protect'}
|
|
<div class="product-box product-protect">
|
|
<div class="product-box--head">
|
|
<h4 class="block-title">Zabezpiecz tapetę</h4>
|
|
</div>
|
|
<div class="product-box--data">
|
|
|
|
</div>
|
|
</div>
|
|
{/block}
|
|
|
|
{block name='product_installation'}
|
|
<div class="product-box product-installation">
|
|
<div class="product-box--head">
|
|
<h4 class="block-title">Montaż</h4>
|
|
</div>
|
|
<div class="product-box--data">
|
|
|
|
</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>
|
|
{/block}
|
|
|
|
{* =========================================================================
|
|
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 (!jQuery('#checkbox-piece').is(':checked')) {
|
|
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;
|
|
var payload = $form.serialize() + '&qty=' + encodeURIComponent(qty) + '&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]);
|
|
|
|
if (window.prestashop && prestashop.urls && prestashop.urls.pages && prestashop.urls.pages.cart) {
|
|
jQuery.get(prestashop.urls.pages.cart, { action: 'refresh', ajax: 1 }, null, 'json')
|
|
.done(function(cartResp) {
|
|
if (cartResp && cartResp.preview) {
|
|
jQuery('.blockcart').replaceWith(cartResp.preview);
|
|
}
|
|
});
|
|
}
|
|
|
|
$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');
|
|
}
|
|
});
|
|
}, true);
|
|
})();
|
|
</script>
|
|
{/if}
|
|
|