Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
{extends file='customer/_partials/address-form.tpl'}
{block name='form_field'}
{if $field.name eq "alias" and $customer.is_guest}
{* we don't ask for alias here if customer is not registered *}
{else}
{$smarty.block.parent}
{/if}
{/block}
{block name='address_form_url'}
<form
method="POST"
action="{url entity='order' params=['id_address' => $id_address]}"
data-id-address="{$id_address}"
data-refresh-url="{url entity='order' params=['ajax' => 1, 'action' => 'addressForm', 'id_address' => $id_address]}"
data-ps-action="form-validation"
>
{/block}
{block name='form_fields' append}
<input type="hidden" name="saveAddress" value="{$type}">
{if $type === "delivery"}
<div class="mb-3 form-check">
<input class="form-check-input" name="use_same_address" id="use_same_address" type="checkbox" value="1" {if $use_same_address} checked {/if}>
<label class="form-check-label" for="use_same_address">{l s='Use this address for invoice too' d='Shop.Theme.Checkout'}</label>
</div>
{/if}
{/block}
{block name='form_buttons'}
{if !$form_has_continue_button}
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--no-fw-mobile buttons-wrapper--invert-mobile mt-3">
<a class="js-cancel-address btn btn-basic" href="{url entity='order' params=['cancelAddress' => {$type}]}">{l s='Cancel' d='Shop.Theme.Actions'}</a>
<button type="submit" class="btn btn-primary">{l s='Save' d='Shop.Theme.Actions'}</button>
</div>
{else}
<div class="buttons-wrapper {if $customer.addresses|count == 0}buttons-wrapper--end{else}buttons-wrapper--split buttons-wrapper--no-fw-mobile buttons-wrapper--invert-mobile{/if} mt-3">
{if $customer.addresses|count> 0}
<a class="js-cancel-address btn btn-basic" href="{url entity='order' params=['cancelAddress' => {$type}]}">{l s='Cancel' d='Shop.Theme.Actions'}</a>
{/if}
<button type="submit" class="btn btn-primary" name="confirm-addresses" value="1" data-ps-action="form-validation-submit">
{l s='Continue' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
</div>
{/if}
{/block}

View File

@@ -0,0 +1,66 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'address-card'}
{block name='address_selector_blocks'}
{foreach $addresses as $address}
<article id="{$name|classname}-address-{$address.id}" class="{$componentName} {$componentName}--radio js-address-item{if $address.id == $selected} selected{/if}" data-id-address="{$address.id}">
<label class="{$componentName}__container">
<div class="{$componentName}__header">
<span class="custom-radio">
<input
type="radio"
class="form-check-input"
name="{$name}"
value="{$address.id}"
{if $address.id == $selected}checked{/if}
aria-label="{l s='Select address: %addressAlias%' sprintf=['%addressAlias%' => $address.alias|lower] d='Shop.Theme.Actions'}"
aria-describedby="address-{$address.id}"
>
</span>
<span class="{$componentName}__alias">
{$address.alias}
</span>
</div>
<address class="{$componentName}__content" id="address-{$address.id}">
<span class="visually-hidden">{l s='Address details:' d='Shop.Theme.Actions'}</span>
{$address.formatted nofilter}
</address>
{block name='address_block_item_actions'}
{if $interactive}
<div class="{$componentName}__actions">
<a
class="{$componentName}__edit link-body-emphasis"
data-link-action="edit-address"
href="{url entity='order' params=['id_address' => $address.id, 'editAddress' => $type, 'token' => $token]}"
aria-label="{l s='Edit address: %addressAlias%' sprintf=['%addressAlias%' => $address.alias|lower] d='Shop.Theme.Actions'}"
>
{l s='Edit' d='Shop.Theme.Actions'}
</a>
<a
class="{$componentName}__delete link-danger"
data-link-action="delete-address"
href="{url entity='order' params=['id_address' => $address.id, 'deleteAddress' => true, 'token' => $token]}"
aria-label="{l s='Delete address: %addressAlias%' sprintf=['%addressAlias%' => $address.alias|lower] d='Shop.Theme.Actions'}"
>
{l s='Delete' d='Shop.Theme.Actions'}
</a>
</div>
{/if}
{/block}
</label>
</article>
{/foreach}
{if $interactive}
<div class="d-none">
<button class="ps-hidden-by-js form-control-submit center-block" type="submit">{l s='Save' d='Shop.Theme.Actions'}</button>
</div>
{/if}
{/block}

View File

@@ -0,0 +1,35 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='cart_detailed_actions'}
{$disableCheckout = false}
{foreach $cart.products as $product}
{if isset($product.availability) && $product.availability == 'unavailable' }
{$disableCheckout = true}
{/if}
{/foreach}
<div class="cart-summary__actions checkout js-cart-detailed-actions">
{if $cart.minimalPurchaseRequired}
<div class="alert alert-warning" role="alert">
{$cart.minimalPurchaseRequired}
</div>
<div class="d-grid">
<button type="button" class="btn btn-primary btn-lg disabled" disabled>{l s='Proceed to checkout' d='Shop.Theme.Actions'}</button>
</div>
{elseif empty($cart.products) || $disableCheckout === true}
<div class="d-grid">
<button type="button" class="btn btn-primary btn-lg disabled" disabled>{l s='Proceed to checkout' d='Shop.Theme.Actions'}</button>
</div>
{else}
<div class="d-grid">
<a href="{$urls.pages.order}" class="btn btn-primary btn-lg">{l s='Proceed to checkout' d='Shop.Theme.Actions'}</a>
{hook h='displayExpressCheckout'}
</div>
{/if}
</div>
{/block}

View File

@@ -0,0 +1,200 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="product-line">
<div class="product-line__image">
<a class="product-line__title product-line__item" href="{$product.url}"
data-id_customization="{$product.id_customization|intval}">
{if $product.default_image}
<picture>
{if isset($product.default_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.avif},
{$product.default_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($product.default_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.webp},
{$product.default_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="product-line__img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_md.url} 2x"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
loading="lazy"
alt="{$product.name|escape:'quotes'}"
title="{$product.name|escape:'quotes'}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.avif},
{$urls.no_picture_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.webp},
{$urls.no_picture_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="product-line__img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
</a>
</div>
<div class="product-line__content">
<div class="product-line__content-left">
<a class="product-line__title" href="{$product.url}"
data-id_customization="{$product.id_customization|intval}">
{$product.name}
</a>
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{foreach from=$product.attributes key="attribute" item="value"}
<div class="product-line__item product-line__item--info {$attribute|lower}">
<span class="product-line__item-label">{$attribute}:</span>
<span class="product-line__item-value">{$value}</span>
</div>
{/foreach}
{if !empty($product.availability_message)}
{if $product.availability == 'in_stock'}
{assign 'availability_icon' 'E5CA'}
{assign 'availability_class' 'text-success'}
{elseif $product.availability == 'available'}
{assign 'availability_icon' 'E002'}
{assign 'availability_class' 'text-warning'}
{elseif $product.availability == 'last_remaining_items'}
{assign 'availability_icon' 'E002'}
{assign 'availability_class' 'text-warning'}
{else}
{assign 'availability_icon' 'E14B'}
{assign 'availability_class' 'text-danger'}
{/if}
<div class="product-line__item product-line__item--availability">
<div class="product-line__item-availability-message {$availability_class}">
<i class="product-line__item-availability-icon material-icons rtl-no-flip">&#x{$availability_icon};</i>
{$product.availability_message}
</div>
</div>
{/if}
{if !empty($product.delivery_information)}
<div class="product-line__item product-line__item--small-info">
{$product.delivery_information}
</div>
{/if}
{hook h='displayCartExtraProductInfo' product=$product}
<div class="product-line__item product-line__item--prices">
<span class="product-line__item-price">{$product.price}</span>
{if $product.unit_price_full}
<span class="product-line__item-unit-price">{$product.unit_price_full}</span>
{/if}
{if $product.has_discount}
<span class="product-line__item-regular-price">{$product.regular_price}</span>
{if $product.discount_type === 'percentage'}
<span class="product-line__item-discount product-line__item-discount--percentage badge bg-primary">
-{$product.discount_percentage_absolute}
</span>
{else}
<span class="product-line__item-discount product-line__item-discount--amount badge bg-primary">
-{$product.discount_to_display}
</span>
{/if}
{/if}
{capture name='product_price_block'}{hook h='displayProductPriceBlock' product=$product type="unit_price"}{/capture}
{if $smarty.capture.product_price_block}
<div class="product-line__item-price-block">
{$smarty.capture.product_price_block nofilter}
</div>
{/if}
</div>
</div>
<div class="product-line__content-right">
<div class="product-line__quantity-button quantity-button js-quantity-button">
{if !empty($product.is_gift)}
<span class="product-line__gift">
<i class="product-line__gift-icon material-icons" aria-hidden="true">&#xE8B1;</i>{$product.quantity} {l s='Gift(s)' d='Shop.Theme.Checkout'}
</span>
{else}
{include file='components/qty-input.tpl'
attributes=[
"class"=>"js-cart-line-product-quantity form-control mw-100",
"name"=>"product-quantity-spin",
"data-update-url"=>"{$product.update_quantity_url}",
"data-product-id"=>"{$product.id_product}",
"value"=>"{$product.quantity}",
"min"=>"{$product.minimal_quantity}"
]
}
{/if}
</div>
{if empty($product.is_gift)}
<div class="product-line__price">{$product.total}</div>
{/if}
</div>
<div class="product-line__actions">
{if empty($product.is_gift)}
<a class="js-remove-from-cart"
rel="nofollow"
href="{$product.remove_from_cart_url}"
data-link-action="delete-from-cart" data-id-product="{$product.id_product|escape:'javascript'}"
data-id-product-attribute="{$product.id_product_attribute|escape:'javascript'}"
data-id-customization="{$product.id_customization|escape:'javascript'}"
data-product-url="{$product.url|escape:'javascript'}"
data-product-name="{$product.name|escape:'htmlall':'UTF-8'}"
aria-label="{l s='Remove %productName% from cart' sprintf=['%productName%' => $product.name] d='Shop.Theme.Checkout'}"
>
{l s='Remove' d='Shop.Theme.Checkout'}
</a>
{/if}
{block name='hook_cart_extra_product_actions'}
{hook h='displayCartExtraProductActions' product=$product}
{/block}
</div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='cart_detailed_totals'}
<div class="cart-summary__totals js-cart-detailed-totals">
<div class="cart-summary__subtotals">
{foreach from=$cart.subtotals item="subtotal"}
{if $subtotal && $subtotal.value|count_characters> 0 && $subtotal.type !== 'tax'}
<div class="cart-summary__line" id="cart-subtotal-{$subtotal.type}">
<span class="cart-summary__label{if $subtotal.type === 'products'} js-subtotal{/if}">
{if $subtotal.type === 'products'}
{$cart.summary_string}
{else}
{$subtotal.label}
{/if}
</span>
<span class="cart-summary__value">
{if $subtotal.type === 'discount'}
-{$subtotal.value}
{elseif $subtotal.type === 'shipping'}
{$subtotal.value}
<small class="cart-summary__value-inner">{hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal}</small>
{else}
{$subtotal.value}
{/if}
</span>
</div>
{/if}
{/foreach}
</div>
{block name='cart_summary_totals'}
{include file='checkout/_partials/cart-summary-totals.tpl' cart=$cart}
{/block}
{block name='cart_voucher'}
{include file='checkout/_partials/cart-voucher.tpl'}
{/block}
{block name='cart_actions'}
{include file='checkout/_partials/cart-detailed-actions.tpl' cart=$cart}
{/block}
</div>
{/block}

View File

@@ -0,0 +1,29 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='cart_detailed_product'}
{* .cart-overview needed for JS *}
<div class="cart__overview cart-overview js-cart"
data-refresh-url="{url entity='cart' params=['ajax' => true, 'action' => 'refresh']}"
tabindex="-1"
>
<hr>
{if $cart.products}
<div class="cart__list js-cart-list" role="list" aria-label="{l s='Products in cart' d='Shop.Theme.Checkout'}">
{foreach from=$cart.products item=product}
<div class="cart__item js-cart-item" role="listitem">
{block name='cart_detailed_product_line'}
{include file='checkout/_partials/cart-detailed-product-line.tpl' product=$product}
{/block}
</div>
{/foreach}
</div>
{else}
<p class="cart__empty">{l s='There are no more items in your cart' d='Shop.Theme.Checkout'}</p>
{/if}
<hr>
</div>
{/block}

View File

@@ -0,0 +1,128 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'cart-summary-product'}
{block name='cart_summary_product_line'}
<div class="{$componentName}">
<div class="{$componentName}__image">
<a href="{$product.url}" title="{$product.name}">
{if $product.default_image}
<picture>
{if isset($product.default_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.avif},
{$product.default_image.bySize.default_sm.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($product.default_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.webp},
{$product.default_image.bySize.default_sm.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_sm.url} 2x"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
loading="lazy"
alt="{$product.name}"
title="{$product.name}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.avif},
{$urls.no_picture_image.bySize.default_sm.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.webp},
{$urls.no_picture_image.bySize.default_sm.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_sm.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
</a>
</div>
<div class="{$componentName}__content">
<div class="{$componentName}__content-left">
<a class="{$componentName}__link" href="{$product.url}" target="_blank" rel="noopener noreferrer nofollow">
{$product.name}
</a>
{if !empty($product.attributes)}
<div class="{$componentName}__attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
<div class="{$componentName}__price">
<span class="label">{$product.price}</span>
{if $product.has_discount}
<span class="value">{$product.regular_price}</span>
{/if}
</div>
{if $product.unit_price_full}
<div class="{$componentName}__unit-price">
<span class="value">{$product.unit_price_full}</span>
</div>
{/if}
<div class="{$componentName}__quantity">
<span class="label">{l s='Quantity:' d='Shop.Theme.Checkout'}</span>
<span class="value">x{$product.quantity}</span>
</div>
<div class="{$componentName}__gift">
{if !empty($product.is_gift)}
<i class="{$componentName}__gift-icon material-icons" aria-hidden="true">&#xE8B1;</i> {l s='Gift(s)' d='Shop.Theme.Checkout'}
{/if}
</div>
</div>
<div class="{$componentName}__content-right">
<div class="{$componentName}__prices">
<div class="{$componentName}__total">{$product.total}</div>
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
</div>
</div>
</div>
{/block}

View File

@@ -0,0 +1,32 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__products js-cart-summary-products">
<div class="cart-summary__products-number">{$cart.summary_string}</div>
<hr class="mb-2">
<div class="cart-summary__products-accordion accordion accordion-flush accordion--small">
<div class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-target="#cart-summary-product-list" data-bs-toggle="collapse" aria-expanded="false" aria-label="{l s='Show cart details' d='Shop.Theme.Actions'}">
{l s='Show details' d='Shop.Theme.Actions'}
</button>
</div>
{block name='cart_summary__list'}
<div class="accordion-collapse collapse" id="cart-summary-product-list">
<div class="cart-summary__products-list">
{foreach from=$cart.products item=product}
<div class="cart-summary__product">
{include file='checkout/_partials/cart-summary-product-line.tpl' product=$product}
</div>
{/foreach}
</div>
</div>
{/block}
</div>
<hr class="mt-2">
</div>

View File

@@ -0,0 +1,20 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__subtotals js-cart-summary-subtotals-container">
{foreach from=$cart.subtotals item="subtotal"}
{if $subtotal && $subtotal.value|count_characters> 0 && $subtotal.type !== 'tax'}
<div class="cart-summary__line" id="cart-subtotal-{$subtotal.type}">
<span class="cart-summary__label">
{$subtotal.label}
</span>
<span class="cart-summary__value">
{if 'discount' == $subtotal.type}-&nbsp;{/if}{$subtotal.value}
</span>
</div>
{/if}
{/foreach}
</div>

View File

@@ -0,0 +1,8 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__top js-cart-summary-top">
{hook h='displayCheckoutSummaryTop'}
</div>

View File

@@ -0,0 +1,33 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div class="cart-summary__total js-cart-summary-totals">
{block name='cart_summary_total'}
{if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled}
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{$cart.totals.total.label}&nbsp;{$cart.labels.tax_short}</span>
<span class="cart-summary__value">{$cart.totals.total.value}</span>
</div>
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{$cart.totals.total_including_tax.label}</span>
<span class="cart-summary__value">{$cart.totals.total_including_tax.value}</span>
</div>
{else}
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{$cart.totals.total.label}&nbsp;{if $configuration.taxes_enabled}{$cart.labels.tax_short}{/if}</span>
<span class="cart-summary__value">{$cart.totals.total.value}</span>
</div>
{/if}
{/block}
{block name='cart_summary_tax'}
{if $cart.subtotals.tax}
<div class="cart-summary__line cart-summary__line--bold">
<span class="cart-summary__label">{l s='%label%:' sprintf=['%label%' => $cart.subtotals.tax.label] d='Shop.Theme.Global'}</span>
<span class="cart-summary__value">{$cart.subtotals.tax.value}</span>
</div>
{/if}
{/block}
</div>

View File

@@ -0,0 +1,27 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{* .js-cart needed for JS *}
<section id="js-checkout-summary" class="accordion-collapse collapse show js-cart" data-refresh-url="{$urls.pages.cart}?ajax=1&action=refresh">
{block name='hook_checkout_summary_top'}
{include file='checkout/_partials/cart-summary-top.tpl' cart=$cart}
{/block}
{block name='cart_summary_products'}
{include file='checkout/_partials/cart-summary-products.tpl' cart=$cart}
{/block}
{block name='cart_summary_subtotals'}
{include file='checkout/_partials/cart-summary-subtotals.tpl' cart=$cart}
{/block}
{block name='cart_summary_totals'}
{include file='checkout/_partials/cart-summary-totals.tpl' cart=$cart}
{/block}
{block name='cart_summary_voucher'}
{include file='checkout/_partials/cart-voucher.tpl'}
{/block}
</section>

View File

@@ -0,0 +1,78 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{if $cart.vouchers.allowed}
{block name='cart_voucher'}
<div class="cart-summary__voucher cart-voucher js-cart-voucher" tabindex="-1" data-ps-ref="voucher-container">
{if $cart.vouchers.added}
{block name='cart_voucher_list'}
<ul class="cart-voucher__list" tabindex="-1" data-ps-ref="voucher-list" aria-label="{l s='Added vouchers' d='Shop.Theme.Checkout'}">
{foreach from=$cart.vouchers.added item=voucher}
<li class="cart-summary__line">
<span class="cart-summary__label cart-summary__label--voucher">
<i class="material-icons" aria-hidden="true">&#xF05B;</i>
{$voucher.name}
</span>
<div class="cart-summary__value cart-summary__value--bold cart-voucher__value">
{$voucher.reduction_formatted}
{if isset($voucher.code) && $voucher.code !== ''}
<a class="cart-voucher__remove" href="{$voucher.delete_url}" data-link-action="remove-voucher" data-ps-ref="voucher-remove-button" aria-label="{l s='Remove voucher: %voucherName%' sprintf=['%voucherName%' => $voucher.name] d='Shop.Theme.Checkout'}">
<i class="material-icons" aria-hidden="true">&#xE872;</i>
</a>
{/if}
</div>
</li>
{/foreach}
</ul>
{/block}
{/if}
<div class="cart-voucher__accordion accordion accordion-flush accordion--small">
<div class="cart-voucher__accordion-item accordion-item">
<button class="cart-voucher__accordion-button accordion-button collapsed" type="button" data-bs-target="#promo-code" data-bs-toggle="collapse" data-ps-ref="voucher-accordion-button" aria-expanded="false">
{l s='Promo code' d='Shop.Theme.Checkout'}
</button>
<div id="promo-code" class="cart-voucher__accordion-collapse accordion-collapse collapse js-voucher-accordion">
<div class="accordion-body">
{block name='cart_voucher_form'}
<form class="cart-voucher__form" action="{$urls.pages.cart}" data-link-action="add-voucher" data-ps-ref="voucher-form" method="post">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="addDiscount" value="1">
<input class="form-control js-voucher-input" type="text" name="discount_name" placeholder="{l s='Paste your voucher here' d='Shop.Theme.Checkout'}" required>
<button type="submit" class="btn btn-primary" aria-label="{l s='Apply voucher' d='Shop.Theme.Actions'}">{l s='Apply' d='Shop.Theme.Actions'}</button>
</form>
{/block}
{block name='cart_voucher_notifications'}
<div class="cart-voucher__error alert alert-danger js-error" role="alert" tabindex="-1" style="display: none;" data-ps-ref="voucher-error">
<i class="cart-voucher__error-icon material-icons" aria-hidden="true">&#xE001;</i>
<span class="js-error-text"></span>
</div>
{/block}
</div>
</div>
</div>
</div>
{if $cart.discounts|count> 0}
<div class="cart-voucher__highlight">
<p class="h5">
{l s='Take advantage of our exclusive offers:' d='Shop.Theme.Actions'}
</p>
<ul class="cart-voucher__offers js-discount">
{foreach from=$cart.discounts item=discount}
<li class="cart-voucher__code">
<button class="cart-voucher__code-value js-voucher-code" aria-label="{l s='Fill %voucherCode% code into the voucher field' sprintf=['%voucherCode%' => $discount.code] d='Shop.Theme.Checkout'}">{$discount.code}</button> - {$discount.name}
</li>
{/foreach}
</ul>
</div>
{/if}
</div>
{/block}
{/if}

View File

@@ -0,0 +1,13 @@
{$componentName = 'checkout-steps'}
<div class="{$componentName}__step-mobile d-none" data-step="{$step}">
<p class="{$componentName}__title">
{$title}
</p>
{if !empty($subtitle)}
<p class="{$componentName}__subtitle">
{$subtitle}
</p>
{/if}
</div>

View File

@@ -0,0 +1,23 @@
{$componentName = 'checkout-steps'}
<li
class="{$componentName}__step js-step-item"
data-step="{$step}"
role="presentation"
>
<span class="{$componentName}__number">
{$number}
</span>
<button
class="{$componentName}__btn btn btn-link"
data-bs-toggle="tab"
data-bs-target="#{$step}"
role="tab"
data-ps-ref="step-button"
{if isset($virtual) && $virtual}
disabled
{/if}
>
{$title}
</button>
</li>

View File

@@ -0,0 +1,41 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends "customer/_partials/customer-form.tpl"}
{block "form_field"}
{if $field.name === 'password' and $guest_allowed}
<div class="mb-3">
<div class="form-check">
<input class="js-password-form__check form-check-input" id="password-form__check" type="checkbox" name="password-form__check">
<label class="form-check-label" for="password-form__check">
<span class="fw-bold">{l s='Create an account' d='Shop.Theme.Checkout'}</span> <small class="fw-normal">{l s='(optional)' d='Shop.Theme.Checkout'}</small>
<br>
<em>{l s='And save time on your next order!' d='Shop.Theme.Checkout'}</em>
</label>
</div>
<div class="js-password-form__input-wrapper d-none mt-3">
{$smarty.block.parent}
</div>
</div>
{else}
{$smarty.block.parent}
{/if}
{/block}
{block "form_buttons"}
<button
class="btn btn-primary"
name="continue"
data-link-action="register-new-customer"
type="submit"
value="1"
data-ps-action="form-validation-submit"
>
{l s='Continue' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
{/block}

View File

@@ -0,0 +1,19 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='customer/_partials/login-form.tpl'}
{block name='form_buttons'}
<button
class="btn btn-primary"
name="continue"
data-link-action="sign-in"
type="submit"
value="1"
data-ps-action="form-validation-submit"
>
{l s='Continue' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
{/block}

View File

@@ -0,0 +1,22 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<div id="checkout-modal" class="modal fade" tabindex="-1" role="dialog" aria-label="{l s='Terms and conditions' d='Shop.Theme.Checkout'}" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{l s='Close' d='Shop.Theme.Global'}"></button>
</div>
<div class="modal-body">
<div class="text-center">
<div class="spinner-border text-primary-emphasis" role="status">
<span class="visually-hidden">{l s='Loading...' d='Shop.Theme.Global'}</span>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,320 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'order-confirmation'}
<div class="{$componentName}__table {block name='order-confirmation-classes'}{/block}">
<div class="{$componentName}__products">
{foreach from=$products['physical_products'] item=product}
<div class="{$componentName}__carrier-info">
<div class="{$componentName}__carrier-info-content">
<b class="{$componentName}__carrier-info-label">{l s='Delivery option: %carrier_name%' sprintf=['%carrier_name%' => $product.carrier.name] d='Shop.Theme.Global'}</b>
<p class="{$componentName}__carrier-info-delay">{$product.carrier.delay}</p>
</div>
{if empty($hide_multishipment_edit_buttons)}
<button class="{$componentName}__carrier-info-edit-button btn btn-outline-primary btn-sm js-edit-shipping" data-step="checkout-delivery-step" aria-label="{l s='Edit your shipping method' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</button>
{/if}
</div>
{foreach from=$product['products'] item=product}
<div class="{$componentName}__product">
<div class="{$componentName}__product-image">
{if !empty($product.default_image)}
<picture>
{if isset($product.default_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.avif},
{$product.default_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($product.default_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.webp},
{$product.default_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__product-img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_md.url} 2x"
src="{$product.default_image.bySize.default_xs.url}"
loading="lazy"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
alt="{$product.default_image.legend}"
title="{$product.default_image.legend}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.avif},
{$urls.no_picture_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.webp},
{$urls.no_picture_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__product-img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
{if !empty($product.quantity) && $product.quantity > 1}
<p class="{$componentName}__product-quantity">{l s='x%quantity%' sprintf=['%quantity%' => $product.quantity] d='Shop.Theme.Global'}</p>
{/if}
</div>
<div class="{$componentName}__product-content">
<div class="{$componentName}__product-details">
{if $add_product_link}
<a class="{$componentName}__product-link" href="{$product.url}" target="_blank">
{/if}
<p class="{$componentName}__product-title">{$product.name}</p>
{if $add_product_link}
</a>
{/if}
{if !empty($product.attributes)}
<div class="{$componentName}__product-attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
{if !empty($product.reference)}
<p class="{$componentName}__product-reference">{l s='Reference:' d='Shop.Theme.Catalog'} {$product.reference}</p>
{/if}
{if $product.price}
<div class="{$componentName}__product-price">
{$product.price}
</div>
{/if}
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
<div class="{$componentName}__product-prices">
{if !empty($product.is_gift)}
<div class="{$componentName}__product-gift">
<i class="{$componentName}__product-gift-icon material-icons" aria-hidden="true">&#xE8B1;</i>{$product.quantity} {l s='Gift(s)' d='Shop.Theme.Checkout'}
</div>
{else}
<div class="{$componentName}__product-total">
{$product.total}
</div>
{/if}
</div>
</div>
</div>
{/foreach}
{/foreach}
{if isset($products['virtual_products']) && !empty($products['virtual_products'])}
<div class="{$componentName}__virtual-info {if isset($products['physical_products']) && empty($products['physical_products'])}mt-0{/if}">
<div class="{$componentName}__virtual-info-content">
<b class="{$componentName}__virtual-info-label">{l s='Virtual product(s)' d='Shop.Theme.Global'}</b>
<p class="{$componentName}__virtual-info-value">{l s='No delivery service' d='Shop.Theme.Global'}</p>
</div>
</div>
{foreach from=$products['virtual_products'] item=product}
<div class="{$componentName}__product">
<div class="{$componentName}__product-image">
{if !empty($product.default_image)}
<picture>
{if isset($product.default_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.avif},
{$product.default_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($product.default_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.webp},
{$product.default_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__product-img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_md.url} 2x"
src="{$product.default_image.bySize.default_xs.url}"
loading="lazy"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
alt="{$product.default_image.legend}"
title="{$product.default_image.legend}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.avif},
{$urls.no_picture_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.webp},
{$urls.no_picture_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__product-img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
loading="lazy"
>
</picture>
{/if}
{if !empty($product.quantity) && $product.quantity > 1}
<p class="{$componentName}__product-quantity">{l s='x%quantity%' sprintf=['%quantity%' => $product.quantity] d='Shop.Theme.Global'}</p>
{/if}
</div>
<div class="{$componentName}__product-content">
<div class="{$componentName}__product-details">
{if $add_product_link}
<a class="{$componentName}__product-link" href="{$product.url}" target="_blank">
{/if}
<p class="{$componentName}__product-title">{$product.name}</p>
{if $add_product_link}
</a>
{/if}
{if !empty($product.attributes)}
<div class="{$componentName}__product-attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
{if !empty($product.reference)}
<p class="{$componentName}__product-reference">{l s='Reference:' d='Shop.Theme.Catalog'} {$product.reference}</p>
{/if}
{if $product.price}
<div class="{$componentName}__product-price">
{$product.price}
</div>
{/if}
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
<div class="{$componentName}__product-prices">
<div class="{$componentName}__product-total">
{$product.total}
</div>
</div>
</div>
</div>
{/foreach}
{/if}
</div>
<hr>
<div class="{$componentName}__subtotals">
{foreach $subtotals as $subtotal}
{if $subtotal !== null && $subtotal.type !== 'tax' && $subtotal.label !== null}
<div class="{$componentName}__line">
<div class="{$componentName}__line-label">{$subtotal.label}</div>
<div class="{$componentName}__line-value">{if 'discount' == $subtotal.type}-&nbsp;{/if}{$subtotal.value}</div>
</div>
{/if}
{/foreach}
</div>
<hr>
<div class="{$componentName}__totals">
{if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{$labels.tax_short}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total_including_tax.label}</div>
<div class="{$componentName}__line-value">{$totals.total_including_tax.value}</div>
</div>
{else}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{if $configuration.taxes_enabled}{$labels.tax_short}{/if}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
{/if}
{if $subtotals.tax !== null && $subtotals.tax.label !== null}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{l s='%label%:' sprintf=['%label%' => $subtotals.tax.label] d='Shop.Theme.Global'}</div>
<div class="{$componentName}__line-value">{$subtotals.tax.value}</div>
</div>
{/if}
</div>
</div>

View File

@@ -0,0 +1,177 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{$componentName = 'order-confirmation'}
<div class="{$componentName}__table {block name='order-confirmation-classes'}{/block}">
<div class="{$componentName}__products">
{foreach from=$products item=product}
<div class="{$componentName}__product">
<div class="{$componentName}__product-image">
{if !empty($product.default_image)}
<picture>
{if isset($product.default_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.avif},
{$product.default_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($product.default_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$product.default_image.bySize.default_xs.sources.webp},
{$product.default_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__product-img img-fluid"
srcset="
{$product.default_image.bySize.default_xs.url},
{$product.default_image.bySize.default_md.url} 2x"
src="{$product.default_image.bySize.default_xs.url}"
loading="lazy"
width="{$product.default_image.bySize.default_xs.width}"
height="{$product.default_image.bySize.default_xs.height}"
alt="{$product.default_image.legend}"
title="{$product.default_image.legend}"
>
</picture>
{else}
<picture>
{if isset($urls.no_picture_image.bySize.default_xs.sources.avif)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.avif},
{$urls.no_picture_image.bySize.default_md.sources.avif} 2x"
type="image/avif"
>
{/if}
{if isset($urls.no_picture_image.bySize.default_xs.sources.webp)}
<source
srcset="
{$urls.no_picture_image.bySize.default_xs.sources.webp},
{$urls.no_picture_image.bySize.default_md.sources.webp} 2x"
type="image/webp"
>
{/if}
<img
class="{$componentName}__product-img img-fluid"
srcset="
{$urls.no_picture_image.bySize.default_xs.url},
{$urls.no_picture_image.bySize.default_md.url} 2x"
src="{$urls.no_picture_image.bySize.default_xs.url}"
loading="lazy"
width="{$urls.no_picture_image.bySize.default_xs.width}"
height="{$urls.no_picture_image.bySize.default_xs.height}"
>
</picture>
{/if}
{if !empty($product.quantity) && $product.quantity > 1}
<p class="{$componentName}__product-quantity">{l s='x%quantity%' sprintf=['%quantity%' => $product.quantity] d='Shop.Theme.Global'}</p>
{/if}
</div>
<div class="{$componentName}__product-content">
<div class="{$componentName}__product-details">
{if $add_product_link}
<a class="{$componentName}__product-link" href="{$product.url}" target="_blank">
{/if}
<p class="{$componentName}__product-title">{$product.name}</p>
{if $add_product_link}
</a>
{/if}
{if !empty($product.attributes)}
<div class="{$componentName}__product-attributes">
{foreach from=$product.attributes key="attribute" item="value"}
<div class="{$componentName}__product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
</div>
{/foreach}
</div>
{/if}
{if !empty($product.reference)}
<p class="{$componentName}__product-reference">{l s='Reference:' d='Shop.Theme.Catalog'} {$product.reference}</p>
{/if}
{if $product.price}
<div class="{$componentName}__product-price">
{$product.price}
</div>
{/if}
{if is_array($product.customizations) && $product.customizations|count}
{include file='catalog/_partials/product-customization-modal.tpl' product=$product}
{/if}
{hook h='displayProductPriceBlock' product=$product type="unit_price"}
</div>
<div class="{$componentName}__product-prices">
{if !empty($product.is_gift)}
<div class="{$componentName}__product-gift">
<i class="{$componentName}__product-gift-icon material-icons" aria-hidden="true">&#xE8B1;</i>{$product.quantity} {l s='Gift(s)' d='Shop.Theme.Checkout'}
</div>
{else}
<div class="{$componentName}__product-total">
{$product.total}
</div>
{/if}
</div>
</div>
</div>
{/foreach}
</div>
<hr>
<div class="{$componentName}__subtotals">
{foreach $subtotals as $subtotal}
{if $subtotal !== null && $subtotal.type !== 'tax' && $subtotal.label !== null}
<div class="{$componentName}__line">
<div class="{$componentName}__line-label">{$subtotal.label}</div>
<div class="{$componentName}__line-value">{if 'discount' == $subtotal.type}-&nbsp;{/if}{$subtotal.value}</div>
</div>
{/if}
{/foreach}
</div>
<hr>
<div class="{$componentName}__totals">
{if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{$labels.tax_short}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total_including_tax.label}</div>
<div class="{$componentName}__line-value">{$totals.total_including_tax.value}</div>
</div>
{else}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{$totals.total.label}&nbsp;{if $configuration.taxes_enabled}{$labels.tax_short}{/if}</div>
<div class="{$componentName}__line-value">{$totals.total.value}</div>
</div>
{/if}
{if $subtotals.tax !== null && $subtotals.tax.label !== null}
<div class="{$componentName}__line {$componentName}__line--bold">
<div class="{$componentName}__line-label">{l s='%label%:' sprintf=['%label%' => $subtotals.tax.label] d='Shop.Theme.Global'}</div>
<div class="{$componentName}__line-value">{$subtotals.tax.value}</div>
</div>
{/if}
</div>
</div>

View File

@@ -0,0 +1,5 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/order-confirmation-table-multishipment.tpl'}

View File

@@ -0,0 +1,5 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/order-confirmation-table.tpl'}

View File

@@ -0,0 +1,162 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
<hr>
<section id="order-summary-content" class="final-summary">
<p class="h2">{l s='Please check your order before payment' d='Shop.Theme.Checkout'}</p>
<p class="final-summary__header">
{l s='Addresses' d='Shop.Theme.Checkout'}
<button class="btn btn-outline-primary btn-sm js-edit-addresses" data-step="checkout-addresses-step" aria-label="{l s='Edit addresses' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</button>
</p>
<div class="address__list">
<div class="address-card">
<div class="address-card__container">
<div class="address-card__header">
<span class="address-card__alias">
{l s='Your Delivery Address' d='Shop.Theme.Checkout'}
</span>
</div>
<address class="address-card__content">
{$customer.addresses[$cart.id_address_delivery]['formatted'] nofilter}
</address>
<div class="address-card__actions">
<a
class="address-card__edit"
data-link-action="edit-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_delivery]['id'], 'editAddress' => 'editAddress', 'token' => $token]}"
aria-label="{l s='Edit your delivery address' d='Shop.Theme.Actions'}"
>
{l s='Edit' d='Shop.Theme.Actions'}
</a>
<a
class="address-card__delete link-danger"
data-link-action="delete-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_delivery]['id'], 'deleteAddress' => 'deleteAddress', 'token' => $token]}"
aria-label="{l s='Delete your delivery address' d='Shop.Theme.Actions'}"
>
{l s='Delete' d='Shop.Theme.Actions'}
</a>
</div>
</div>
</div>
<div class="address-card">
<div class="address-card__container">
<div class="address-card__header">
<span class="address-card__alias">
{l s='Your Invoice Address' d='Shop.Theme.Checkout'}
</span>
</div>
<address class="address-card__content">
{$customer.addresses[$cart.id_address_invoice]['formatted'] nofilter}
</address>
<div class="address-card__actions">
<a
class="address-card__edit"
data-link-action="edit-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_invoice]['id'], 'editAddress' => 'editAddress', 'token' => $token]}"
aria-label="{l s='Edit your invoice address' d='Shop.Theme.Actions'}"
>
{l s='Edit' d='Shop.Theme.Actions'}
</a>
<a
class="address-card__delete link-danger"
data-link-action="delete-address"
href="{url entity='order' params=['id_address' => $customer.addresses[$cart.id_address_invoice]['id'], 'deleteAddress' => 'deleteAddress', 'token' => $token]}"
aria-label="{l s='Delete your invoice address' d='Shop.Theme.Actions'}"
>
{l s='Delete' d='Shop.Theme.Actions'}
</a>
</div>
</div>
</div>
</div>
{if !$cart.is_virtual && !($is_multishipment_enabled|default:false)}
<p class="final-summary__header">
{l s='Shipping Method' d='Shop.Theme.Checkout'}
<button class="btn btn-outline-primary btn-sm js-edit-shipping" data-step="checkout-delivery-step" aria-label="{l s='Edit your shipping method' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</button>
</p>
<div class="grid-table" role="table" aria-label="{l s='Shipping Method' d='Shop.Theme.Checkout'}">
<div class="grid-table__inner grid-table__inner--3" role="rowgroup">
<div class="grid-table__header" role="row">
<span class="grid-table__cell" role="columnheader">{l s='Delivery Option' d='Shop.Theme.Checkout'}</span>
<span class="grid-table__cell" role="columnheader">{l s='Price' d='Shop.Theme.Checkout'}</span>
<span class="grid-table__cell" role="columnheader">{l s='Delivery Information' d='Shop.Theme.Checkout'}</span>
</div>
<div class="grid-table__row" role="row">
<span class="grid-table__cell" role="cell" data-ps-label="{l s='Delivery Option' d='Shop.Theme.Checkout'}">
<span class="grid-table__cell-group grid-table__cell-group--sm grid-table__cell-group--inline">
{if $selected_delivery_option.logo}
<img src="{$selected_delivery_option.logo}" class="rounded img-fluid" width="32" height="auto" alt="{$selected_delivery_option.name}" loading="lazy">
{/if}
{$selected_delivery_option.name}
</span>
</span>
<span class="grid-table__cell" role="cell" data-ps-label="{l s='Price' d='Shop.Theme.Checkout'}">
{$selected_delivery_option.price}
</span>
<span class="grid-table__cell" role="cell" data-ps-label="{l s='Delivery Information' d='Shop.Theme.Checkout'}">
{$selected_delivery_option.delay}
</span>
</div>
</div>
</div>
{/if}
{block name='order_confirmation_table'}
<p class="final-summary__header">
{l s='%product_count% order items' sprintf=['%product_count%' => $cart.products_count] d='Shop.Theme.Checkout'}
<a class="btn btn-outline-primary btn-sm" href="{url entity=cart params=['action' => 'show']}" aria-label="{l s='Edit your cart' d='Shop.Theme.Actions'}">
<i class="material-icons" aria-hidden="true">&#xE254;</i> {l s='Edit' d='Shop.Theme.Actions'}
</a>
</p>
<div class="final-summary__order-table card border-1 mb-4">
<div class="card-body">
{if isset($is_multishipment_enabled) && $is_multishipment_enabled}
{include file='checkout/_partials/order-final-summary-table-multishipment.tpl'
products=$products_carrier_mapping
products_count=$cart.products_count
subtotals=$cart.subtotals
totals=$cart.totals
labels=$cart.labels
add_product_link=true
}
{else}
{include file='checkout/_partials/order-final-summary-table.tpl'
products=$cart.products
products_count=$cart.products_count
subtotals=$cart.subtotals
totals=$cart.totals
labels=$cart.labels
add_product_link=true
}
{/if}
</div>
</div>
{/block}
</section>

View File

@@ -0,0 +1,129 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{block name='step_content'}
<div class="js-address-form">
<form
method="POST"
action="{url entity='order' params=['id_address' => $id_address]}"
data-refresh-url="{url entity='order' params=['ajax' => 1, 'action' => 'addressForm', 'id_address' => $id_address]}"
data-ps-action="form-validation"
>
{if $use_same_address}
<p>
{if $cart.is_virtual}
{l s='The selected address will be used as your personal address (for invoice).' d='Shop.Theme.Checkout'}
{else}
{l s='The selected address will be used both as your personal address (for invoice) and as your delivery address.' d='Shop.Theme.Checkout'}
{/if}
</p>
{else}
<p class="h3">{l s='Shipping Address' d='Shop.Theme.Checkout'}</p>
{/if}
{if $show_delivery_address_form}
<div id="delivery-address">
{render file = 'checkout/_partials/address-form.tpl'
ui = $address_form
use_same_address = $use_same_address
type = "delivery"
form_has_continue_button = $form_has_continue_button
}
</div>
{elseif $customer.addresses|count> 0}
<div id="delivery-addresses" class="address__list js-address-selector">
{include file = 'checkout/_partials/address-selector-block.tpl'
addresses = $customer.addresses
name = "id_address_delivery"
selected = $id_address_delivery
type = "delivery"
interactive = !$show_delivery_address_form and !$show_invoice_address_form
}
</div>
{if isset($delivery_address_error)}
<p class="alert alert-danger js-address-error" name="alert-delivery" id="id-failure-address-{$delivery_address_error.id_address}">{$delivery_address_error.exception}</p>
{else}
<p class="alert alert-danger js-address-error" name="alert-delivery" style="display: none">{l s='Your address is incomplete, please update it.' d='Shop.Notifications.Error'}</p>
{/if}
<div class="buttons-wrapper mb-3">
<a href="{$new_address_delivery_url}" class="btn btn-outline-primary">
<i class="material-icons" aria-hidden="true">&#xE145;</i>
{l s='Add new address' d='Shop.Theme.Actions'}
</a>
</div>
{if $use_same_address && !$cart.is_virtual}
<a data-link-action="different-invoice-address" href="{$use_different_address_url}" class="btn btn-basic">
{l s='Billing address differs from shipping address' d='Shop.Theme.Checkout'}
</a>
{/if}
{/if}
{if !$use_same_address}
<p class="h3 mt-4">{l s='Your Invoice Address' d='Shop.Theme.Checkout'}</p>
{if $show_invoice_address_form}
<div id="invoice-address">
{render file = 'checkout/_partials/address-form.tpl'
ui = $address_form
use_same_address = $use_same_address
type = "invoice"
form_has_continue_button = $form_has_continue_button
}
</div>
{else}
<div id="invoice-addresses" class="address__list js-address-selector">
{include file = 'checkout/_partials/address-selector-block.tpl'
addresses = $customer.addresses
name = "id_address_invoice"
selected = $id_address_invoice
type = "invoice"
interactive = !$show_delivery_address_form and !$show_invoice_address_form
}
</div>
{if isset($invoice_address_error)}
<p class="alert alert-danger js-address-error" name="alert-invoice" id="id-failure-address-{$invoice_address_error.id_address}">{$invoice_address_error.exception}</p>
{else}
<p class="alert alert-danger js-address-error" name="alert-invoice" style="display: none">{l s='Your address is incomplete, please update it.' d='Shop.Notifications.Error'}</p>
{/if}
<a href="{$new_address_invoice_url}" class="btn btn-outline-primary w-100 w-md-auto">
<i class="material-icons" aria-hidden="true">&#xE145;</i>
{l s='Add new address' d='Shop.Theme.Actions'}
</a>
{/if}
{/if}
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--invert-mobile mt-3">
<button class="btn btn-outline-primary js-back" type="button" data-step="checkout-personal-information-step">
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</i>
{l s='Back to Personal Information' d='Shop.Theme.Actions'}
</button>
{if !$form_has_continue_button}
<button type="submit" class="btn btn-primary" name="confirm-addresses" value="1">
{l s='Continue to Shipping' d='Shop.Theme.Actions'}
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</div>
</button>
<input type="hidden" id="not-valid-addresses" class="js-not-valid-addresses" value="{$not_valid_addresses}">
{/if}
</div>
</form>
{capture name="address_selector_bottom"}{hook h='displayAddressSelectorBottom'}{/capture}
{if $smarty.capture.address_selector_bottom}
{block name='address_selector_bottom'}
<div class="address-selector-bottom mt-3">
{$smarty.capture.address_selector_bottom nofilter}
</div>
{/block}
{/if}
</div>
{/block}

View File

@@ -0,0 +1,39 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='step'}
<section
id="{$identifier}"
class="{[
'step' => true,
'tab-pane' => true,
'collapse' => true,
'step--current' => $step_is_current,
'step--reachable' => $step_is_reachable,
'step--complete' => $step_is_complete && !$step_is_current,
'js-current-step' => $step_is_current,
'active' => $step_is_current,
'show' => $step_is_current
]|classnames}" role="tabpanel">
<div class="step__title js-step-title">
{if $step_is_current eq true}
<h1 class="page-title-section">
{else}
<p class="page-title-section">
{/if}
{$title}
{if $step_is_current eq true}
</h1>
{else}
</p>
{/if}
<hr>
</div>
<div class="step__content">
{block name='step_content'}DUMMY STEP CONTENT{/block}
</div>
</section>
{/block}

View File

@@ -0,0 +1,177 @@
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{block name='step_content'}
{hook h='displayPaymentTop'}
{* used by javascript to correctly handle cart updates when we are on payment step (eg vouchers added) *}
<div style="display:none" class="js-cart-payment-step-refresh"></div>
{if !empty($display_transaction_updated_info)}
<p class="payment-options__updated">
{l s='Transaction amount has been correctly updated' d='Shop.Theme.Checkout'}
</p>
{/if}
{if $is_free}
<p class="payment-options__free">{l s='No payment needed for this order' d='Shop.Theme.Checkout'}</p>
{/if}
<div class="payment-options__list{if $is_free} d-block d-sm-none{/if}">
{foreach from=$payment_options item="module_options"}
{foreach from=$module_options item="option"}
<div id="{$option.id}-container" class="payment-option">
{* This is the way an option should be selected when Javascript is enabled *}
<div class="payment-option__form-check form-check">
<input
class="payment-option__input form-check-input ps-shown-by-js {if $option.binary} binary{/if}"
type="radio"
name="payment-option"
data-module-name="{$option.module_name}"
id="{$option.id}"
{if ($selected_payment_option == $option.id || $is_free) || ($payment_options|@count === 1 && $module_options|@count === 1)} checked {/if}
>
<label class="payment-option__label form-check-label" for="{$option.id}">
{if $option.logo}
<img class="img-fluid" src="{$option.logo}" loading="lazy">
{/if}
{$option.call_to_action_text}
</label>
</div>
{* This is the way an option should be selected when Javascript is disabled *}
<form method="GET" class="payment-option__no-js-form ps-hidden-by-js">
{if $option.id === $selected_payment_option}
{l s='Selected' d='Shop.Theme.Checkout'}
{else}
<button class="ps-hidden-by-js" type="submit" name="select_payment_option" value="{$option.id}">
{l s='Choose' d='Shop.Theme.Actions'}
</button>
{/if}
</form>
{if $option.additionalInformation}
<div
id="{$option.id}-additional-information"
class="payment-option__additional-information js-additional-information"
{if $option.id != $selected_payment_option}style="display: none;"{/if}
>
{$option.additionalInformation nofilter}
</div>
{/if}
<div
id="pay-with-{$option.id}-form"
class="js-payment-option-form"
{if $option.id != $selected_payment_option}style="display: none;"{/if}
>
{if $option.form}
{$option.form nofilter}
{else}
<form id="payment-form" method="POST" action="{$option.action nofilter}">
{foreach from=$option.inputs item=input}
<input type="{$input.type}" name="{$input.name}" value="{$input.value}">
{/foreach}
<button style="display:none" id="pay-with-{$option.id}" type="submit"></button>
</form>
{/if}
</div>
</div>
{/foreach}
{foreachelse}
<p class="alert alert-danger">{l s='Unfortunately, there are no payment method available.' d='Shop.Theme.Checkout'}</p>
{/foreach}
</div>
{if $conditions_to_approve|count}
<p class="ps-hidden-by-js">
{* At the moment, we're not showing the checkboxes when JS is disabled
because it makes ensuring they were checked very tricky and overcomplicates
the template. Might change later.
*}
{l s='By confirming the order, you certify that you have read and agree with all of the conditions below:' d='Shop.Theme.Checkout'}
</p>
<form id="conditions-to-approve" class="js-conditions-to-approve mt-3" method="GET">
{foreach from=$conditions_to_approve item="condition" key="condition_name"}
<div class="my-2 form-check">
<input id = "conditions_to_approve[{$condition_name}]"
name = "conditions_to_approve[{$condition_name}]"
required
type = "checkbox"
value = "1"
class = "ps-shown-by-js form-check-input"
>
<label class="js-terms form-check-label" for="conditions_to_approve[{$condition_name}]">
{$condition nofilter}
</label>
</div>
{/foreach}
</form>
{/if}
{hook h='displayCheckoutBeforeConfirmation'}
{if $show_final_summary}
{include file='checkout/_partials/order-final-summary.tpl'}
{/if}
{if $show_final_summary}
<article class="alert alert-danger mb-4 js-alert-payment-conditions" role="alert">
{if isset($tos_cms) && $tos_cms && $conditions_to_approve|count == 1}
{l
s='Please make sure you\'ve chosen a [1]payment method[/1] and accepted the [2]terms and conditions[/2].'
sprintf=[
'[1]' => '<a href="#checkout-payment-step" class="alert-link">',
'[/1]' => '</a>',
'[2]' => '<a href="#conditions-to-approve" class="alert-link">',
'[/2]' => '</a>'
]
d='Shop.Theme.Checkout'
}
{elseif !empty($conditions_to_approve)}
{l
s='Please make sure you\'ve chosen a [1]payment method[/1] and accepted the required condition(s).'
sprintf=[
'[1]' => '<a href="#checkout-payment-step" class="alert-link">',
'[/1]' => '</a>'
]
d='Shop.Theme.Checkout'
}
{else}
{l s='Please make sure you\'ve chosen a [1]payment method[/1].'
sprintf=[
'[1]' => '<a href="#checkout-payment-step" class="alert-link">',
'[/1]' => '</a>'
]
d='Shop.Theme.Checkout'
}
{/if}
</article>
{/if}
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--invert-mobile mt-3">
<button class="btn btn-outline-primary js-back" type="button" data-step="checkout-delivery-step">
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</div>
{l s='Back to Shipping' d='Shop.Theme.Actions'}
</button>
<div id="payment-confirmation" class="js-payment-confirmation">
<div class="ps-shown-by-js">
<button type="submit" class="btn btn-primary {if !$selected_payment_option} disabled{/if}">
{l s='Place Order' d='Shop.Theme.Checkout'}
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</div>
</button>
</div>
<div class="ps-hidden-by-js">
{if $selected_payment_option and $all_conditions_approved}
<label for="pay-with-{$selected_payment_option}">{l s='Order with an obligation to pay' d='Shop.Theme.Checkout'}</label>
{/if}
</div>
</div>
</div>
{hook h='displayPaymentByBinaries'}
{/block}

View File

@@ -0,0 +1,100 @@
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{$stepName = 'personnal-information'}
{block name='step_content'}
{hook h='displayPersonalInformationTop' customer=$customer}
{if $customer.is_logged && !$customer.is_guest}
<div class="step__account">
<p>
{* [1][/1] is for a HTML tag. *}
{l s='Connected as [1]%firstname% %lastname%[/1].'
d='Shop.Theme.Customeraccount'
sprintf=[
'[1]' => "<a href='{$urls.pages.identity}' aria-label='{l s='My account (%firstname% %lastname%)' d='Shop.Theme.Customeraccount' sprintf=['%firstname%' => $customer.firstname, '%lastname%' => $customer.lastname]}'>",
'[/1]' => "</a>",
'%firstname%' => $customer.firstname,
'%lastname%' => $customer.lastname
]
}
</p>
<p class="mb-1">
{* [1][/1] is for a HTML tag. *}
{l
s='Not you? [1]Sign out[/1]'
d='Shop.Theme.Customeraccount'
sprintf=[
'[1]' => "<a class='text-danger' href='{$urls.actions.logout}'>",
'[/1]' => "</a>"
]
}
</p>
{if !isset($empty_cart_on_logout) || $empty_cart_on_logout}
<p class="mb-0">
<small class="text-body-tertiary">{l s='If you sign out now, your cart will be emptied.' d='Shop.Theme.Checkout'}</small>
</p>
{/if}
</div>
<form id="checkout-continue-form" method="GET" action="{$urls.pages.order}">
<div class="buttons-wrapper buttons-wrapper--end mt-3">
<button
class="btn btn-primary"
name="controller"
type="submit"
value="order"
>
{l s='Continue to Addresses' d='Shop.Theme.Actions'}
<i class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</i>
</button>
</div>
</form>
{else}
<ul class="nav nav-underline" id="personal-information-tabs" role="tablist">
<li class="nav-item" role="presentation">
<button
class="nav-link {if !$show_login_form}active{/if}"
data-bs-toggle="tab"
data-bs-target="#checkout-guest-form"
type="button"
role="tab"
aria-controls="checkout-guest-form"
aria-selected="{if !$show_login_form}true{else}false{/if}"
>
{if isset($guest_allowed) && $guest_allowed}
{l s='Order as a guest' d='Shop.Theme.Checkout'}
{else}
{l s='New customer' d='Shop.Theme.Checkout'}
{/if}
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link {if $show_login_form}active{/if}"
data-bs-toggle="tab"
data-bs-target="#checkout-login-form"
type="button"
role="tab"
aria-controls="checkout-login-form"
aria-selected="{if $show_login_form}true{else}false{/if}"
>
{l s='Sign in' d='Shop.Theme.Actions'}
</button>
</li>
</ul>
<div class="tab-content" id="personal-information-tabs-content">
<div class="tab-pane fade{if !$show_login_form} show active{/if}" id="checkout-guest-form" aria-labelledby="checkout-guest-form" role="tabpanel">
{render file='checkout/_partials/customer-form.tpl' ui=$register_form guest_allowed=$guest_allowed}
</div>
<div class="tab-pane fade{if $show_login_form} show active{/if}" id="checkout-login-form" aria-labelledby="checkout-login-form" role="tabpanel">
{render file='checkout/_partials/login-form.tpl' ui=$login_form}
</div>
</div>
{/if}
{/block}

View File

@@ -0,0 +1,113 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{extends file='checkout/_partials/steps/checkout-step.tpl'}
{block name='step_content'}
<div id="delivery-options__hook">
{$hookDisplayBeforeCarrier nofilter}
</div>
<div class="delivery-options__container">
{if $delivery_options|count}
<form
id="js-delivery"
data-url-update="{url entity='order' params=['ajax' => 1, 'action' => 'selectDeliveryOption']}"
method="post"
class="delivery-options__form"
>
{block name='delivery_options'}
<div class="delivery-options__list">
{foreach from=$delivery_options item=carrier key=carrier_id name=delivery_options}
<div class="delivery-option__item js-delivery-option">
<label class="delivery-option__label" for="delivery_option_{$carrier.id}">
<div class="delivery-option__left">
<span class="delivery-option__check form-check">
<input type="radio" class="form-check-input" name="delivery_option[{$id_address}]" id="delivery_option_{$carrier.id}" value="{$carrier_id}"{if $delivery_option == $carrier_id} checked{/if}>
</span>
<div class="delivery-option__carrier {if $carrier.logo} delivery-option__carrier--hasLogo{/if}">
{if $carrier.logo}
<img class="delivery-option__carrier-logo" src="{$carrier.logo}" class="img-fluid" alt="{$carrier.name}" loading="lazy" aria-hidden="true">
{/if}
<span class="delivery-option__carrier-name">{$carrier.name}</span>
</div>
</div>
<div class="delivery-option__content">
{$carrier.delay}
</div>
<div class="delivery-option__price">
{$carrier.price}
</div>
</label>
<div class="delivery-option__extra js-carrier-extra" {if $delivery_option == $carrier_id}data-active{/if}>
{capture name='delivery_option_extra_content'}{$carrier.extraContent nofilter}{/capture}
{if !empty($smarty.capture.delivery_option_extra_content)}
<div class="delivery-option__extra-content js-carrier-extra-content">
{$smarty.capture.delivery_option_extra_content nofilter}
</div>
{/if}
</div>
</div>
{/foreach}
</div>
{/block}
<div class="order-options">
<div id="delivery" class="mb-4">
<label for="delivery_message" class="form-label">{l s='Write a comment about this order' d='Shop.Theme.Checkout'}</label>
<textarea class="form-control" rows="2" cols="120" id="delivery_message" placeholder="{l s='Write your comment...' d='Shop.Theme.Checkout'}" name="delivery_message">{$delivery_message}</textarea>
</div>
{if $recyclablePackAllowed}
<div class="form-check" for="input_recyclable">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" id="input_recyclable" name="recyclable" value="1"{if $recyclable} checked{/if}>
{l s='I would like to receive my order in recycled packaging.' d='Shop.Theme.Checkout'}
</label>
</div>
{/if}
{if $gift.allowed}
<div class="form-check mb-4">
<label class="form-check-label" for="input_gift" data-bs-toggle="collapse" data-bs-target="#gift">
<input class="form-check-input js-gift-checkbox" id="input_gift" name="gift" type="checkbox" value="1"{if $gift.isGift} checked="checked"{/if}>
{$gift.label}
</label>
</div>
<div id="gift" class="collapse{if $gift.isGift} show{/if}">
<label for="gift_message" class="form-label">{l s='If you\'d like, you can add a note to the gift:' d='Shop.Theme.Checkout'}</label>
<textarea class="form-control" rows="2" cols="120" id="gift_message" name="gift_message">{$gift.message}</textarea>
</div>
{/if}
</div>
<div class="buttons-wrapper buttons-wrapper--split buttons-wrapper--invert-mobile mt-3">
<button class="btn btn-outline-primary w-100 w-md-auto mb-3 mb-md-0 js-back" type="button" data-step="checkout-addresses-step">
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C4;</div>
{l s='Back to Addresses' d='Shop.Theme.Actions'}
</button>
<button type="submit" class="btn btn-primary w-100 w-md-auto" name="confirmDeliveryOption" value="1">
{l s='Continue to Payment' d='Shop.Theme.Actions'}
<div class="material-icons rtl-flip" aria-hidden="true">&#xE5C8;</div>
</button>
</div>
</form>
{else}
<p class="alert alert-danger">{l s='Unfortunately, there are no carriers available for your delivery address.' d='Shop.Theme.Checkout'}</p>
{/if}
</div>
<div class="delivery-options__display-after-carrier" id="hook-display-after-carrier">
{$hookDisplayAfterCarrier nofilter}
</div>
<div class="delivery-options__extra-carrier" id="extra_carrier"></div>
{/block}

View File

@@ -0,0 +1,13 @@
{**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*}
{block name='step'}
<section class="step step--unreachable d-none" id="{$identifier}">
<div class="step__title js-step-title">
<p class="step__title-left h3">
{$title}
</p>
</div>
</section>
{/block}