<?php
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Extension\CoreExtension;
use Twig\Extension\SandboxExtension;
use Twig\Markup;
use Twig\Sandbox\SecurityError;
use Twig\Sandbox\SecurityNotAllowedTagError;
use Twig\Sandbox\SecurityNotAllowedFilterError;
use Twig\Sandbox\SecurityNotAllowedFunctionError;
use Twig\Source;
use Twig\Template;
use Twig\TemplateWrapper;
/* home/single-product.html.twig */
class __TwigTemplate_de682e8426eeeb206a96a6b28fceddbb extends Template
{
private Source $source;
/**
* @var array<string, Template>
*/
private array $macros = [];
public function __construct(Environment $env)
{
parent::__construct($env);
$this->source = $this->getSourceContext();
$this->blocks = [
'title' => [$this, 'block_title'],
'stylesheets' => [$this, 'block_stylesheets'],
'body' => [$this, 'block_body'],
];
}
protected function doGetParent(array $context): bool|string|Template|TemplateWrapper
{
// line 1
return "base_home.html.twig";
}
protected function doDisplay(array $context, array $blocks = []): iterable
{
$macros = $this->macros;
$__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
$__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "home/single-product.html.twig"));
$__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "home/single-product.html.twig"));
$this->parent = $this->load("base_home.html.twig", 1);
yield from $this->parent->unwrap()->yield($context, array_merge($this->blocks, $blocks));
$__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
}
// line 3
/**
* @return iterable<null|scalar|\Stringable>
*/
public function block_title(array $context, array $blocks = []): iterable
{
$macros = $this->macros;
$__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
$__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "title"));
$__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "title"));
// line 4
yield "\t";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 4), "html", null, true);
yield "
\t| MaketOu
";
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
$__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
yield from [];
}
// line 8
/**
* @return iterable<null|scalar|\Stringable>
*/
public function block_stylesheets(array $context, array $blocks = []): iterable
{
$macros = $this->macros;
$__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
$__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "stylesheets"));
$__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "stylesheets"));
// line 9
yield "\t<style>
\t\t/* Styles pour l'affichage de la boutique */
\t\t.shop-info {
\t\t\tpadding: 10px 0;
\t\t\tborder-bottom: 1px solid #f0f0f0;
\t\t\tmargin-bottom: 15px;
\t\t}
\t\t.shop-link {
\t\t\tcolor: #ffa200;
\t\t\ttext-decoration: none;
\t\t\tfont-weight: 500;
\t\t}
\t\t.shop-link:hover {
\t\t\tcolor: #e8910a;
\t\t\ttext-decoration: underline;
\t\t}
\t\t/* Styles pour les statistiques du produit */
\t\t.product-stats {
\t\t\tbackground: #f8f9fa;
\t\t\tpadding: 15px;
\t\t\tborder-radius: 8px;
\t\t\tborder: 1px solid #e9ecef;
\t\t}
\t\t.product-stats .stat-item {
\t\t\ttext-align: center;
\t\t}
\t\t.product-stats .stat-number {
\t\t\tdisplay: block;
\t\t\tfont-size: 1.2rem;
\t\t\tfont-weight: bold;
\t\t\tcolor: #ffa200;
\t\t}
\t\t.product-stats .stat-label {
\t\t\tcolor: #666;
\t\t\tfont-size: 0.8rem;
\t\t\ttext-transform: uppercase;
\t\t\tletter-spacing: 0.5px;
\t\t}
\t\t/* Message de confirmation */
\t\t#cart-message {
\t\t\tborder: none;
\t\t\tbackground: #d4edda;
\t\t\tcolor: #155724;
\t\t\tborder-radius: 6px;
\t\t\tpadding: 12px 16px;
\t\t\tmargin-top: 15px;
\t\t}
\t\t/* Amélioration des boutons */
\t\t.card_area .primary-btn {
\t\t\tbackground: #ffa200;
\t\t\tborder: none;
\t\t\tpadding: 12px 24px;
\t\t\tborder-radius: 6px;
\t\t\tcolor: white;
\t\t\tfont-weight: 500;
\t\t\ttransition: all 0.3s ease;
\t\t}
\t\t.card_area .primary-btn:hover {
\t\t\tbackground: #e8910a;
\t\t\ttransform: translateY(-2px);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.3);
\t\t}
\t\t.icon_btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tcolor: white;
\t\t\tborder-color: #ffa200;
\t\t}
\t\t/* Styles pour la galerie moderne de produits */
\t\t.product-gallery-modern {
\t\t\tdisplay: flex;
\t\t\tgap: 15px;
\t\t\tposition: relative;
\t\t}
\t\t.thumbnails-container {
\t\t\tposition: relative;
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\talign-items: center;
\t\t\twidth: 80px;
\t\t\tflex-shrink: 0;
\t\t}
\t\t/* Cacher les boutons jusqu'au survol */
\t\t.thumbnails-container .thumbnail-nav-btn {
\t\t\topacity: 0;
\t\t\tvisibility: hidden;
\t\t\ttransition: opacity 0.2s ease, visibility 0.2s ease;
\t\t}
\t\t.thumbnails-container:hover .thumbnail-nav-btn {
\t\t\topacity: 1;
\t\t\tvisibility: visible;
\t\t}
\t\t.product-thumbnails {
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\tgap: 10px;
\t\t\twidth: 100%;
\t\t\theight: 400px;
\t\t\toverflow: hidden;
\t\t\tposition: relative;
\t\t}
\t\t.thumbnails-wrapper {
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\tgap: 10px;
\t\t\ttransition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\twill-change: transform;
\t\t}
\t\t.thumbnail-nav-btn {
\t\t\twidth: 30px;
\t\t\theight: 30px;
\t\t\tborder-radius: 50%;
\t\t\tbackground: white;
\t\t\tborder: 2px solid #e0e0e0;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tcursor: pointer;
\t\t\ttransition: all 0.3s ease;
\t\t\tmargin: 0;
\t\t\tcolor: #666;
\t\t\tz-index: 10;
\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
\t\t\tposition: relative;
\t\t\tflex-shrink: 0;
\t\t}
\t\t.thumbnail-nav-btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tborder-color: #ffa200;
\t\t\tcolor: white;
\t\t\ttransform: scale(1.1);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.3);
\t\t}
\t\t.thumbnail-nav-btn:active {
\t\t\ttransform: scale(0.95);
\t\t}
\t\t.thumbnail-nav-btn.disabled {
\t\t\topacity: 0.3;
\t\t\tcursor: not-allowed;
\t\t\tpointer-events: none;
\t\t\tfilter: grayscale(1);
\t\t}
\t\t.thumbnail-nav-btn i {
\t\t\tfont-size: 20px;
\t\t\tfont-weight: bold;
\t\t}
\t\t.thumbnail-item {
\t\t\twidth: 80px;
\t\t\theight: 80px;
\t\t\tmin-width: 80px;
\t\t\tmin-height: 80px;
\t\t\tmax-width: 80px;
\t\t\tmax-height: 80px;
\t\t\tborder: 2px solid #e0e0e0;
\t\t\tborder-radius: 8px;
\t\t\toverflow: hidden;
\t\t\tcursor: pointer;
\t\t\ttransition: border-color 0.3s ease, border-width 0.3s ease, box-shadow 0.3s ease;
\t\t\tposition: relative;
\t\t\tbackground: #f8f9fa;
\t\t\tborder-bottom: 2px solid #e0e0e0;
\t\t\tflex-shrink: 0;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t}
\t\t.thumbnail-item:hover {
\t\t\tborder-color: #ffa200;
\t\t\tborder-bottom-color: #ffa200;
\t\t\tborder-width: 3px;
\t\t\tbox-shadow: 0 0 0 2px rgba(255, 162, 0, 0.2);
\t\t}
\t\t.thumbnail-item.active {
\t\t\tborder-color: #ffa200 !important;
\t\t\tborder-bottom-color: #ffa200 !important;
\t\t\tborder-width: 3px !important;
\t\t\tbox-shadow: 0 0 0 2px rgba(255, 162, 0, 0.2) !important;
\t\t}
\t\t.thumbnail-item::after,
\t\t.thumbnail-item::before {
\t\t\tdisplay: none !important;
\t\t\tcontent: none !important;
\t\t}
\t\t.thumbnail-item img {
\t\t\twidth: 100%;
\t\t\theight: 100%;
\t\t\tobject-fit: cover !important;
\t\t\tobject-position: center !important;
\t\t\ttransition: transform 0.3s ease;
\t\t}
\t\t.thumbnail-item:hover img {
\t\t\ttransform: scale(1.05);
\t\t}
\t\t.thumbnail-item.active img {
\t\t\ttransform: scale(1.05);
\t\t}
\t\t.product-main-image-wrapper {
\t\t\tflex: 1;
\t\t\tposition: relative;
\t\t\tbackground: #fff;
\t\t\theight: 400px;
\t\t\tborder-radius: 12px;
\t\t\toverflow: visible;
\t\t\tborder: 1px solid #e0e0e0;
\t\t\tz-index: 1;
\t\t}
\t\t.product-main-image {
\t\t\tposition: relative;
\t\t\twidth: 100%;
\t\t\tpadding-top: 100%;
\t\t\toverflow: visible;
\t\t\tbackground: #f8f9fa;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tz-index: 1;
\t\t}
\t\t.product-main-image img {
\t\t\tposition: absolute;
\t\t\ttop: 0;
\t\t\tleft: 0;
\t\t\twidth: 100%;
\t\t\theight: 100%;
\t\t\tobject-fit: contain !important;
\t\t\tobject-position: center !important;
\t\t\ttransition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
\t\t\topacity: 1;
\t\t}
\t\t.product-main-image img.loading {
\t\t\topacity: 0.5;
\t\t}
\t\t.product-main-image:hover img {
\t\t\ttransform: scale(1.08);
\t\t}
\t\t.product-main-image img.fade-in {
\t\t\tanimation: fadeInImage 0.4s ease;
\t\t}
\t\t@keyframes fadeInImage {
\t\t\tfrom {
\t\t\t\topacity: 0;
\t\t\t\ttransform: scale(0.95);
\t\t\t}
\t\t\tto {
\t\t\t\topacity: 1;
\t\t\t\ttransform: scale(1);
\t\t\t}
\t\t}
\t\t.image-overlay-icons {
\t\t\tposition: absolute !important;
\t\t\ttop: 20px !important;
\t\t\tright: 20px !important;
\t\t\tdisplay: flex !important;
\t\t\tflex-direction: column !important;
\t\t\tgap: 12px !important;
\t\t\tz-index: 10 !important;
\t\t\topacity: 0 !important;
\t\t\ttransition: opacity 0.3s ease, transform 0.3s ease !important;
\t\t\ttransform: translateX(10px) !important;
\t\t}
\t\t.product-main-image-wrapper:hover .image-overlay-icons {
\t\t\topacity: 1 !important;
\t\t\ttransform: translateX(0) !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn,
\t\t.image-overlay-icons .icon-btn {
\t\t\twidth: 48px !important;
\t\t\theight: 48px !important;
\t\t\tmin-width: 48px !important;
\t\t\tmin-height: 48px !important;
\t\t\tmax-width: 48px !important;
\t\t\tmax-height: 48px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 255, 255, 0.95) !important;
\t\t\tbackdrop-filter: blur(10px) !important;
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.8) !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
\t\t\tbox-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
\t\t\tcolor: #333 !important;
\t\t\tposition: relative !important;
\t\t\toverflow: hidden !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tfont-size: inherit !important;
\t\t\tfont-weight: normal !important;
\t\t\tline-height: 1 !important;
\t\t\ttext-align: center !important;
\t\t\ttext-decoration: none !important;
\t\t\twhite-space: nowrap !important;
\t\t\tvertical-align: middle !important;
\t\t\tfont-family: inherit !important;
\t\t\ttext-transform: none !important;
\t\t\tletter-spacing: normal !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn::before,
\t\t.image-overlay-icons .icon-btn::before {
\t\t\tcontent: '' !important;
\t\t\tposition: absolute !important;
\t\t\ttop: 50% !important;
\t\t\tleft: 50% !important;
\t\t\twidth: 0 !important;
\t\t\theight: 0 !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 162, 0, 0.2) !important;
\t\t\ttransform: translate(-50%, -50%) !important;
\t\t\ttransition: width 0.4s ease, height 0.4s ease !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:hover::before,
\t\t.image-overlay-icons .icon-btn:hover::before {
\t\t\twidth: 100% !important;
\t\t\theight: 100% !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:hover,
\t\t.image-overlay-icons .icon-btn:hover {
\t\t\tbackground: #ffa200 !important;
\t\t\tborder-color: #ffa200 !important;
\t\t\tcolor: white !important;
\t\t\ttransform: scale(1.15) rotate(5deg) !important;
\t\t\tbox-shadow: 0 6px 20px rgba(255, 162, 0, 0.5) !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:active,
\t\t.image-overlay-icons .icon-btn:active {
\t\t\ttransform: scale(1.05) rotate(0deg) !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn i,
\t\t.image-overlay-icons .icon-btn i {
\t\t\tfont-size: 20px !important;
\t\t\tposition: relative !important;
\t\t\tz-index: 1 !important;
\t\t\ttransition: transform 0.3s ease !important;
\t\t\tmargin: 0 !important;
\t\t\tdisplay: block !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:hover i,
\t\t.image-overlay-icons .icon-btn:hover i {
\t\t\ttransform: scale(1.1) !important;
\t\t}
\t\t.product-main-image-wrapper .favorite-btn.active,
\t\t.image-overlay-icons .favorite-btn.active {
\t\t\tbackground: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%) !important;
\t\t\tborder-color: #ff6b6b !important;
\t\t\tcolor: white !important;
\t\t\tbox-shadow: 0 4px 15px rgba(255, 107, 107, 0.4) !important;
\t\t}
\t\t.product-main-image-wrapper .favorite-btn.active:hover,
\t\t.image-overlay-icons .favorite-btn.active:hover {
\t\t\tbackground: linear-gradient(135deg, #ee5a6f 0%, #dd4a5f 100%) !important;
\t\t\ttransform: scale(1.15) rotate(-5deg) !important;
\t\t}
\t\t.product-main-image-wrapper .image-counter,
\t\t.image-counter {
\t\t\tposition: absolute !important;
\t\t\tbottom: 20px !important;
\t\t\tright: 20px !important;
\t\t\tbackground: rgba(0, 0, 0, 0.75) !important;
\t\t\tbackdrop-filter: blur(8px) !important;
\t\t\tcolor: white !important;
\t\t\tpadding: 8px 16px !important;
\t\t\tborder-radius: 25px !important;
\t\t\tfont-size: 14px !important;
\t\t\tfont-weight: 600 !important;
\t\t\tbox-shadow: 0 2px 10px rgba(0, 0, 0, 0.3) !important;
\t\t\tz-index: 5 !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tgap: 6px !important;
\t\t}
\t\t.product-main-image-wrapper .image-counter span,
\t\t.image-counter span {
\t\t\tfont-weight: 700 !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t.product-main-image-wrapper .image-indicators,
\t\t#image-indicators {
\t\t\tposition: absolute !important;
\t\t\tbottom: 20px !important;
\t\t\tleft: 50% !important;
\t\t\ttransform: translateX(-50%) !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\tgap: 10px !important;
\t\t\tbackground: rgba(0, 0, 0, 0.4) !important;
\t\t\tbackdrop-filter: blur(8px) !important;
\t\t\tpadding: 8px 16px !important;
\t\t\tborder-radius: 25px !important;
\t\t\tz-index: 5 !important;
\t\t}
\t\t.product-main-image-wrapper .indicator,
\t\t#image-indicators .indicator,
\t\t.image-indicators .indicator {
\t\t\twidth: 12px !important;
\t\t\theight: 12px !important;
\t\t\tmin-width: 12px !important;
\t\t\tmin-height: 12px !important;
\t\t\tmax-width: 12px !important;
\t\t\tmax-height: 12px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.6) !important;
\t\t\tbackground: rgba(255, 255, 255, 0.3) !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tposition: relative !important;
\t\t\tdisplay: block !important;
\t\t\ttext-align: center !important;
\t\t\ttext-decoration: none !important;
\t\t\twhite-space: nowrap !important;
\t\t\tvertical-align: middle !important;
\t\t\tfont-size: 0 !important;
\t\t\tline-height: 0 !important;
\t\t\tbox-sizing: border-box !important;
\t\t}
\t\t.product-main-image-wrapper .indicator::before,
\t\t#image-indicators .indicator::before,
\t\t.image-indicators .indicator::before {
\t\t\tcontent: '' !important;
\t\t\tposition: absolute !important;
\t\t\ttop: 50% !important;
\t\t\tleft: 50% !important;
\t\t\ttransform: translate(-50%, -50%) scale(0) !important;
\t\t\twidth: 20px !important;
\t\t\theight: 20px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 162, 0, 0.3) !important;
\t\t\ttransition: transform 0.3s ease !important;
\t\t}
\t\t.product-main-image-wrapper .indicator:hover,
\t\t#image-indicators .indicator:hover,
\t\t.image-indicators .indicator:hover {
\t\t\tborder-color: #ffa200 !important;
\t\t\tbackground: rgba(255, 162, 0, 0.6) !important;
\t\t\ttransform: scale(1.2) !important;
\t\t}
\t\t.product-main-image-wrapper .indicator:hover::before,
\t\t#image-indicators .indicator:hover::before,
\t\t.image-indicators .indicator:hover::before {
\t\t\ttransform: translate(-50%, -50%) scale(1) !important;
\t\t}
\t\t.product-main-image-wrapper .indicator.active,
\t\t#image-indicators .indicator.active,
\t\t.image-indicators .indicator.active {
\t\t\tborder-color: #ffa200 !important;
\t\t\tbackground: #ffa200 !important;
\t\t\tbox-shadow: 0 0 0 3px rgba(255, 162, 0, 0.3), 0 2px 8px rgba(255, 162, 0, 0.5) !important;
\t\t\ttransform: scale(1.3) !important;
\t\t}
\t\t.product-main-image-wrapper .indicator.active::before,
\t\t#image-indicators .indicator.active::before,
\t\t.image-indicators .indicator.active::before {
\t\t\ttransform: translate(-50%, -50%) scale(1) !important;
\t\t\tbackground: rgba(255, 162, 0, 0.4) !important;
\t\t}
\t\t/* Modal de zoom d'image avec transitions modernes */
\t\t.image-zoom-modal {
\t\t\tdisplay: none;
\t\t\tposition: fixed;
\t\t\tz-index: 9999;
\t\t\tleft: 0;
\t\t\ttop: 0;
\t\t\twidth: 100%;
\t\t\theight: 100%;
\t\t\tbackground: rgba(0, 0, 0, 0);
\t\t\toverflow: auto;
\t\t\topacity: 0;
\t\t\ttransition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), background 0.3s ease;
\t\t\tbackdrop-filter: blur(0px);
\t\t}
\t\t.image-zoom-modal.active {
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\topacity: 1;
\t\t\tbackground: rgba(0, 0, 0, 0.95);
\t\t\tbackdrop-filter: blur(10px);
\t\t}
\t\t.zoom-modal-content {
\t\t\tposition: relative;
\t\t\tmax-width: 90%;
\t\t\tmax-height: 90%;
\t\t\tmargin: auto;
\t\t\topacity: 0;
\t\t\ttransform: scale(0.8);
\t\t\ttransition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1), transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
\t\t}
\t\t.image-zoom-modal.active .zoom-modal-content {
\t\t\topacity: 1;
\t\t\ttransform: scale(1);
\t\t}
\t\t.zoom-modal-content img {
\t\t\twidth: 100%;
\t\t\theight: auto;
\t\t\tmax-height: 90vh;
\t\t\tobject-fit: contain !important;
\t\t\tobject-position: center !important;
\t\t\tborder-radius: 8px;
\t\t\tbox-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
\t\t\topacity: 0;
\t\t\ttransition: opacity 0.3s ease;
\t\t}
\t\t.zoom-modal-content img.loaded {
\t\t\topacity: 1;
\t\t}
\t\t/* Loader moderne */
\t\t.zoom-loader {
\t\t\tposition: absolute;
\t\t\ttop: 50%;
\t\t\tleft: 50%;
\t\t\ttransform: translate(-50%, -50%);
\t\t\tz-index: 1;
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t}
\t\t.zoom-loader-spinner {
\t\t\twidth: 60px;
\t\t\theight: 60px;
\t\t\tborder: 4px solid rgba(255, 255, 255, 0.1);
\t\t\tborder-top-color: #ffa200;
\t\t\tborder-radius: 50%;
\t\t\tanimation: spin 1s linear infinite;
\t\t}
\t\t@keyframes spin {
\t\t\tto {
\t\t\t\ttransform: rotate(360deg);
\t\t\t}
\t\t}
\t\t.zoom-loader-text {
\t\t\tcolor: white;
\t\t\tmargin-top: 15px;
\t\t\ttext-align: center;
\t\t\tfont-size: 14px;
\t\t\tfont-weight: 500;
\t\t}
\t\t.close-zoom {
\t\t\tposition: absolute;
\t\t\ttop: 30px;
\t\t\tright: 30px;
\t\t\tcolor: white;
\t\t\tfont-size: 32px;
\t\t\tfont-weight: 300;
\t\t\tcursor: pointer;
\t\t\tz-index: 10000;
\t\t\twidth: 50px;
\t\t\theight: 50px;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tbackground: rgba(255, 255, 255, 0.1);
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.2);
\t\t\tborder-radius: 50%;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\topacity: 0;
\t\t\ttransform: scale(0.8);
\t\t}
\t\t.image-zoom-modal.active .close-zoom {
\t\t\topacity: 1;
\t\t\ttransform: scale(1);
\t\t\ttransition-delay: 0.2s;
\t\t}
\t\t.close-zoom:hover {
\t\t\tbackground: rgba(255, 162, 0, 0.9);
\t\t\tborder-color: #ffa200;
\t\t\ttransform: scale(1.1) rotate(90deg);
\t\t\tbox-shadow: 0 4px 20px rgba(255, 162, 0, 0.4);
\t\t}
\t\t
\t\t/* Styles pour le contrôle de quantité amélioré */
\t\t.product_count {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tgap: 15px !important;
\t\t\tmargin-bottom: 24px !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t.product_count label {
\t\t\tfont-size: 14px !important;
\t\t\tcolor: #777777 !important;
\t\t\tfont-family: \"Roboto\", sans-serif !important;
\t\t\tfont-weight: normal !important;
\t\t\tmargin-bottom: 0 !important;
\t\t\twhite-space: nowrap !important;
\t\t\tpadding-right: 10px !important;
\t\t}
\t\t
\t\t.quantity-controls-wrapper {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tborder: 1px solid #eeeeee !important;
\t\t\tborder-radius: 4px !important;
\t\t\toverflow: hidden !important;
\t\t\tbackground: #fff !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t.quantity-btn {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s ease !important;
\t\t\tfont-size: 16px !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tposition: relative !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t}
\t\t
\t\t.quantity-btn:hover {
\t\t\tbackground: #e9ecef !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t
\t\t.quantity-btn:active {
\t\t\tbackground: #dee2e6 !important;
\t\t\ttransform: scale(0.95) !important;
\t\t}
\t\t
\t\t.quantity-btn i {
\t\t\tfont-size: 14px !important;
\t\t}
\t\t
\t\t.quantity-input {
\t\t\twidth: 60px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tborder-left: 1px solid #eeeeee !important;
\t\t\tborder-right: 1px solid #eeeeee !important;
\t\t\ttext-align: center !important;
\t\t\tfont-size: 14px !important;
\t\t\tfont-weight: 500 !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\toutline: none !important;
\t\t\tbackground: #fff !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t.quantity-input:focus {
\t\t\tborder-left-color: #ffa200 !important;
\t\t\tborder-right-color: #ffa200 !important;
\t\t}
\t\t
\t\t/* Surcharger les styles existants pour les boutons */
\t\t.product_count .quantity-btn {
\t\t\tposition: relative !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s ease !important;
\t\t\tfont-size: 16px !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn:hover {
\t\t\tbackground: #e9ecef !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn:active {
\t\t\tbackground: #dee2e6 !important;
\t\t\ttransform: scale(0.95) !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn i,
\t\t.product_count .quantity-btn .quantity-icon {
\t\t\tfont-size: 20px !important;
\t\t\tfont-weight: 300 !important;
\t\t\tline-height: 1 !important;
\t\t\tdisplay: inline-block !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn .quantity-icon {
\t\t\tfont-size: 24px !important;
\t\t\tfont-weight: 300 !important;
\t\t\tline-height: 1 !important;
\t\t}
\t\t
\t\t/* Désactiver les boutons si nécessaire */
\t\t.quantity-btn:disabled {
\t\t\topacity: 0.5 !important;
\t\t\tcursor: not-allowed !important;
\t\t}
\t\t
\t\t.quantity-btn:disabled:hover {
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t}
\t\t
\t\t/* Surcharger les styles pour le wrapper */
\t\t.product_count .quantity-controls-wrapper {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tborder: 1px solid #eeeeee !important;
\t\t\tborder-radius: 4px !important;
\t\t\toverflow: hidden !important;
\t\t\tbackground: #fff !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t/* Surcharger tous les styles de main.css pour les boutons dans product_count */
\t\t.product_count button.quantity-btn,
\t\t.product_count .quantity-btn {
\t\t\tdisplay: flex !important;
\t\t\tposition: relative !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tborder: none !important;
\t\t\tbox-shadow: none !important;
\t\t}
\t\t
\t\t.product_count button.quantity-btn:hover,
\t\t.product_count .quantity-btn:hover {
\t\t\tbackground: #e9ecef !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t
\t\t/* Surcharger les styles pour l'input */
\t\t.product_count .quantity-input,
\t\t.product_count input.quantity-input {
\t\t\twidth: 60px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tborder-left: 1px solid #eeeeee !important;
\t\t\tborder-right: 1px solid #eeeeee !important;
\t\t\ttext-align: center !important;
\t\t\tpadding: 0 !important;
\t\t\tpadding-left: 0 !important;
\t\t\tposition: relative !important;
\t\t}
\t\t/* Boutons de navigation sur l'image principale */
\t\t.main-image-nav {
\t\t\tposition: absolute;
\t\t\ttop: 50%;
\t\t\tleft: 0;
\t\t\tright: 0;
\t\t\ttransform: translateY(-50%);
\t\t\tdisplay: flex;
\t\t\tjustify-content: space-between;
\t\t\tpadding: 0 12px;
\t\t\tpointer-events: none !important;
\t\t\tz-index: 10 !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn,
\t\t.main-image-nav-btn {
\t\t\tpointer-events: all !important;
\t\t\tz-index: 1000 !important;
\t\t\tposition: relative !important;
\t\t\tcursor: pointer !important;
\t\t\t-webkit-user-select: none !important;
\t\t\t-moz-user-select: none !important;
\t\t\t-ms-user-select: none !important;
\t\t\tuser-select: none !important;
\t\t\tuser-select: none !important;
\t\t\t-webkit-user-select: none !important;
\t\t\t-moz-user-select: none !important;
\t\t\t-ms-user-select: none !important;
\t\t\twidth: 48px !important;
\t\t\theight: 48px !important;
\t\t\tmin-width: 48px !important;
\t\t\tmin-height: 48px !important;
\t\t\tmax-width: 48px !important;
\t\t\tmax-height: 48px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 255, 255, 0.95) !important;
\t\t\tbackdrop-filter: blur(10px) !important;
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.8) !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\tbox-shadow: 0 4px 15px rgba(0, 0, 0, 0.2) !important;
\t\t\tcolor: #333 !important;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
\t\t\tcursor: pointer !important;
\t\t\toverflow: hidden !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tfont-size: inherit !important;
\t\t\tfont-weight: normal !important;
\t\t\tline-height: 1 !important;
\t\t\ttext-align: center !important;
\t\t\ttext-decoration: none !important;
\t\t\twhite-space: nowrap !important;
\t\t\tvertical-align: middle !important;
\t\t\tfont-family: inherit !important;
\t\t\ttext-transform: none !important;
\t\t\tletter-spacing: normal !important;
\t\t\t-webkit-tap-highlight-color: transparent !important;
\t\t\ttouch-action: manipulation !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn::before,
\t\t.main-image-nav-btn::before {
\t\t\tcontent: '' !important;
\t\t\tposition: absolute !important;
\t\t\ttop: 50% !important;
\t\t\tleft: 50% !important;
\t\t\twidth: 0 !important;
\t\t\theight: 0 !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 162, 0, 0.2) !important;
\t\t\ttransform: translate(-50%, -50%) !important;
\t\t\ttransition: width 0.4s ease, height 0.4s ease !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:hover::before,
\t\t.main-image-nav-btn:hover::before {
\t\t\twidth: 100% !important;
\t\t\theight: 100% !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:hover,
\t\t.main-image-nav-btn:hover {
\t\t\tbackground: #ffa200 !important;
\t\t\tborder-color: #ffa200 !important;
\t\t\tcolor: #fff !important;
\t\t\ttransform: scale(1.15) !important;
\t\t\tbox-shadow: 0 6px 20px rgba(255, 162, 0, 0.5) !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:active,
\t\t.main-image-nav-btn:active {
\t\t\ttransform: scale(1.05) !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn i,
\t\t.main-image-nav-btn i {
\t\t\tposition: relative !important;
\t\t\tz-index: 1 !important;
\t\t\tfont-size: 20px !important;
\t\t\ttransition: transform 0.3s ease !important;
\t\t\tmargin: 0 !important;
\t\t\tdisplay: block !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:hover i,
\t\t.main-image-nav-btn:hover i {
\t\t\ttransform: scale(1.2) !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn.disabled,
\t\t.main-image-nav-btn.disabled {
\t\t\topacity: 0.4 !important;
\t\t\tcursor: not-allowed !important;
\t\t\tpointer-events: none !important;
\t\t}
\t\t/* Modal personnalisé pour remplacer les alert */
\t\t.custom-alert-modal .modal-content {
\t\t\tborder-radius: 12px;
\t\t\tborder: none;
\t\t\tbox-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
\t\t}
\t\t.custom-alert-modal .modal-header {
\t\t\tborder-bottom: none;
\t\t\tpadding: 1.5rem 1.5rem 0.5rem;
\t\t\tbackground: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
\t\t\tcolor: white;
\t\t\tborder-radius: 12px 12px 0 0;
\t\t}
\t\t.custom-alert-modal .modal-header .btn-close {
\t\t\tfilter: brightness(0) invert(1);
\t\t\topacity: 0.8;
\t\t}
\t\t.custom-alert-modal .modal-header .btn-close:hover {
\t\t\topacity: 1;
\t\t}
\t\t.custom-alert-modal .modal-body {
\t\t\tpadding: 1.5rem;
\t\t\ttext-align: center;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon {
\t\t\tfont-size: 3rem;
\t\t\tmargin-bottom: 1rem;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.success {
\t\t\tcolor: #28a745;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.error {
\t\t\tcolor: #dc3545;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.warning {
\t\t\tcolor: #ffc107;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.info {
\t\t\tcolor: #17a2b8;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-message {
\t\t\tfont-size: 1.1rem;
\t\t\tcolor: #333;
\t\t\tmargin-bottom: 1rem;
\t\t\tline-height: 1.6;
\t\t}
\t\t.custom-alert-modal .modal-footer {
\t\t\tborder-top: none;
\t\t\tpadding: 0.5rem 1.5rem 1.5rem;
\t\t\tjustify-content: center;
\t\t}
\t\t.custom-alert-modal .modal-footer .btn {
\t\t\tmin-width: 120px;
\t\t\tpadding: 0.6rem 1.5rem;
\t\t\tborder-radius: 8px;
\t\t\tfont-weight: 500;
\t\t}
\t\t/* Responsive pour single-product */
\t\t@media(max-width: 991.98px) {
\t\t\t.product-gallery-modern {
\t\t\t\tflex-direction: column;
\t\t\t}
\t\t\t.thumbnails-container {
\t\t\t\tflex-direction: row;
\t\t\t\twidth: 100%;
\t\t\t\toverflow-x: auto;
\t\t\t\tpadding: 10px 0;
\t\t\t}
\t\t\t.thumbnail-item {
\t\t\t\tflex-shrink: 0;
\t\t\t}
\t\t\t.main-image-container {
\t\t\t\twidth: 100%;
\t\t\t}
\t\t}
\t\t@media(max-width: 768px) {
\t\t\t.product-gallery-modern {
\t\t\t\tflex-direction: column;
\t\t\t}
\t\t\t.thumbnails-container {
\t\t\t\twidth: 100%;
\t\t\t\tflex-direction: row;
\t\t\t\talign-items: center;
\t\t\t}
\t\t\t.product-thumbnails {
\t\t\t\tflex-direction: row;
\t\t\t\twidth: 100%;
\t\t\t\tmax-height: 100px;
\t\t\t\toverflow-x: auto;
\t\t\t\toverflow-y: hidden;
\t\t\t}
\t\t\t.thumbnail-item {
\t\t\t\tflex-shrink: 0;
\t\t\t}
\t\t\t.thumbnail-nav-btn {
\t\t\t\tmargin: 0 5px;
\t\t\t}
\t\t\t.thumbnail-nav-up {
\t\t\t\torder: 1;
\t\t\t}
\t\t\t.product-thumbnails {
\t\t\t\torder: 2;
\t\t\t}
\t\t\t.thumbnail-nav-down {
\t\t\t\torder: 3;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-overlay-icons,
\t\t\t.image-overlay-icons {
\t\t\t\topacity: 1 !important;
\t\t\t\ttop: 10px !important;
\t\t\t\tright: 10px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn,
\t\t\t.image-overlay-icons .icon-btn {
\t\t\t\twidth: 40px !important;
\t\t\t\theight: 40px !important;
\t\t\t\tmin-width: 40px !important;
\t\t\t\tmin-height: 40px !important;
\t\t\t\tmax-width: 40px !important;
\t\t\t\tmax-height: 40px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn i,
\t\t\t.image-overlay-icons .icon-btn i {
\t\t\t\tfont-size: 18px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-indicators,
\t\t\t#image-indicators {
\t\t\t\tbottom: 15px !important;
\t\t\t\tpadding: 6px 12px !important;
\t\t\t\tgap: 8px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .indicator,
\t\t\t#image-indicators .indicator {
\t\t\t\twidth: 10px !important;
\t\t\t\theight: 10px !important;
\t\t\t\tmin-width: 10px !important;
\t\t\t\tmin-height: 10px !important;
\t\t\t\tmax-width: 10px !important;
\t\t\t\tmax-height: 10px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-counter,
\t\t\t.image-counter {
\t\t\t\tbottom: 15px !important;
\t\t\t\tright: 15px !important;
\t\t\t\tpadding: 6px 12px !important;
\t\t\t\tfont-size: 12px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn,
\t\t\t.main-image-nav-btn {
\t\t\t\twidth: 40px !important;
\t\t\t\theight: 40px !important;
\t\t\t\tmin-width: 40px !important;
\t\t\t\tmin-height: 40px !important;
\t\t\t\tmax-width: 40px !important;
\t\t\t\tmax-height: 40px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn i,
\t\t\t.main-image-nav-btn i {
\t\t\t\tfont-size: 18px !important;
\t\t\t}
\t\t}
\t\t@media(max-width: 576px) {
\t\t\t.product-main-image-wrapper .image-indicators,
\t\t\t#image-indicators {
\t\t\t\tbottom: 10px !important;
\t\t\t\tpadding: 5px 10px !important;
\t\t\t\tgap: 6px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .indicator,
\t\t\t#image-indicators .indicator {
\t\t\t\twidth: 8px !important;
\t\t\t\theight: 8px !important;
\t\t\t\tmin-width: 8px !important;
\t\t\t\tmin-height: 8px !important;
\t\t\t\tmax-width: 8px !important;
\t\t\t\tmax-height: 8px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-counter,
\t\t\t.image-counter {
\t\t\t\tbottom: 10px !important;
\t\t\t\tright: 10px !important;
\t\t\t\tpadding: 5px 10px !important;
\t\t\t\tfont-size: 11px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn,
\t\t\t.image-overlay-icons .icon-btn {
\t\t\t\twidth: 36px !important;
\t\t\t\theight: 36px !important;
\t\t\t\tmin-width: 36px !important;
\t\t\t\tmin-height: 36px !important;
\t\t\t\tmax-width: 36px !important;
\t\t\t\tmax-height: 36px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn i,
\t\t\t.image-overlay-icons .icon-btn i {
\t\t\t\tfont-size: 16px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn,
\t\t\t.main-image-nav-btn {
\t\t\t\twidth: 36px !important;
\t\t\t\theight: 36px !important;
\t\t\t\tmin-width: 36px !important;
\t\t\t\tmin-height: 36px !important;
\t\t\t\tmax-width: 36px !important;
\t\t\t\tmax-height: 36px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn i,
\t\t\t.main-image-nav-btn i {
\t\t\t\tfont-size: 16px !important;
\t\t\t}
\t\t}
\t\t
\t\t/* Styles finaux pour forcer l'affichage des boutons de quantité */
\t\t.product_count .quantity-controls-wrapper button.quantity-btn,
\t\t.product_count button.quantity-btn-decrease,
\t\t.product_count button.quantity-btn-increase {
\t\t\tdisplay: flex !important;
\t\t\tvisibility: visible !important;
\t\t\topacity: 1 !important;
\t\t\tposition: relative !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tborder: none !important;
\t\t\tbox-shadow: none !important;
\t\t\tmargin: 0 !important;
\t\t\tpadding: 0 !important;
\t\t}
\t\t
\t\t.product_count .quantity-controls-wrapper {
\t\t\tdisplay: flex !important;
\t\t\tvisibility: visible !important;
\t\t\topacity: 1 !important;
\t\t}
\t</style>
";
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
$__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
yield from [];
}
// line 1236
/**
* @return iterable<null|scalar|\Stringable>
*/
public function block_body(array $context, array $blocks = []): iterable
{
$macros = $this->macros;
$__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
$__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "body"));
$__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "body"));
// line 1237
yield "\t<!-- Start Banner Area -->
\t<section class=\"banner-area organic-breadcrumb\">
\t\t<div class=\"container\">
\t\t\t<div class=\"breadcrumb-banner d-flex flex-wrap align-items-center justify-content-end\">
\t\t\t\t<div class=\"col-first\">
\t\t\t\t\t<h1>Product Details Page</h1>
\t\t\t\t\t<nav class=\"d-flex align-items-center\">
\t\t\t\t\t\t<a href=\"index.html\">Home<span class=\"lnr lnr-arrow-right\"></span>
\t\t\t\t\t\t</a>
\t\t\t\t\t\t<a href=\"#\">Shop<span class=\"lnr lnr-arrow-right\"></span>
\t\t\t\t\t\t</a>
\t\t\t\t\t\t<a href=\"single-product.html\">product-details</a>
\t\t\t\t\t</nav>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</section>
\t<!-- End Banner Area -->
\t<!--================Single Product Area =================-->
\t<div class=\"product_image_area\">
\t\t<div class=\"container\">
\t\t\t<div class=\"row s_product_inner\">
\t\t\t\t<div class=\"col-lg-6\">
\t\t\t\t\t<div
\t\t\t\t\t\tclass=\"product-gallery-modern\">
\t\t\t\t\t\t<!-- Colonne de miniatures à gauche avec navigation -->
\t\t\t\t\t\t<div class=\"thumbnails-container\">
\t\t\t\t\t\t\t<button class=\"thumbnail-nav-btn thumbnail-nav-up\" id=\"thumbnail-nav-up\" title=\"Image précédente\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-up\"></i>
\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t<div class=\"product-thumbnails\" id=\"product-thumbnails\">
\t\t\t\t\t\t\t\t<div class=\"thumbnails-wrapper\" id=\"thumbnails-wrapper\">
\t\t\t\t\t\t\t\t\t";
// line 1270
$context["allProductImages"] = ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", true, true, false, 1270)) ? (Twig\Extension\CoreExtension::default(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 1270), [])) : ([]));
// line 1271
yield "\t\t\t\t\t\t\t\t\t";
if (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", true, true, false, 1271)) {
// line 1272
yield "\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1272));
foreach ($context['_seq'] as $context["_key"] => $context["variant"]) {
// line 1273
yield "\t\t\t\t\t\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "isActive", [], "any", false, false, false, 1273) && CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", true, true, false, 1273))) {
// line 1274
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", false, false, false, 1274));
foreach ($context['_seq'] as $context["_key"] => $context["variantImg"]) {
// line 1275
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t";
$context["allProductImages"] = Twig\Extension\CoreExtension::merge(($context["allProductImages"] ?? null), [$context["variantImg"]]);
// line 1276
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variantImg'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1277
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1278
yield "\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variant'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1279
yield "\t\t\t\t\t\t\t\t\t";
}
// line 1280
yield "\t\t\t\t\t\t\t\t\t";
if ((Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["allProductImages"] ?? null)) > 0)) {
// line 1281
yield "\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(($context["allProductImages"] ?? null));
$context['loop'] = [
'parent' => $context['_parent'],
'index0' => 0,
'index' => 1,
'first' => true,
];
if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
$length = count($context['_seq']);
$context['loop']['revindex0'] = $length - 1;
$context['loop']['revindex'] = $length;
$context['loop']['length'] = $length;
$context['loop']['last'] = 1 === $length;
}
foreach ($context['_seq'] as $context["_key"] => $context["img"]) {
// line 1282
yield "\t\t\t\t\t\t\t\t\t\t\t<div class=\"thumbnail-item ";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "first", [], "any", false, false, false, 1282)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield "active permanently-active";
}
yield "\" data-image=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["img"]), "html", null, true);
yield "\" data-index=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "index0", [], "any", false, false, false, 1282), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t\t\t<img src=\"";
// line 1283
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["img"]), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 1283), "html", null, true);
yield " - Image ";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "index", [], "any", false, false, false, 1283), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t";
++$context['loop']['index0'];
++$context['loop']['index'];
$context['loop']['first'] = false;
if (isset($context['loop']['revindex0'], $context['loop']['revindex'])) {
--$context['loop']['revindex0'];
--$context['loop']['revindex'];
$context['loop']['last'] = 0 === $context['loop']['revindex0'];
}
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['img'], $context['_parent'], $context['loop']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1286
yield "\t\t\t\t\t\t\t\t\t";
} else {
// line 1287
yield "\t\t\t\t\t\t\t\t\t\t<div class=\"thumbnail-item active permanently-active\" data-image=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("ui/img/category/s-p1.jpg"), "html", null, true);
yield "\" data-index=\"0\">
\t\t\t\t\t\t\t\t\t\t\t<img src=\"";
// line 1288
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("ui/img/category/s-p1.jpg"), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 1288), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t";
}
// line 1291
yield "\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<button class=\"thumbnail-nav-btn thumbnail-nav-down\" id=\"thumbnail-nav-down\" title=\"Image suivante\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-down\"></i>
\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- Grande image principale -->
\t\t\t\t\t\t<div class=\"product-main-image-wrapper\">
\t\t\t\t\t\t\t<div class=\"product-main-image\">
\t\t\t\t\t\t\t\t";
// line 1301
$context["allProductImages"] = ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", true, true, false, 1301)) ? (Twig\Extension\CoreExtension::default(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 1301), [])) : ([]));
// line 1302
yield "\t\t\t\t\t\t\t\t";
if (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", true, true, false, 1302)) {
// line 1303
yield "\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1303));
foreach ($context['_seq'] as $context["_key"] => $context["variant"]) {
// line 1304
yield "\t\t\t\t\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "isActive", [], "any", false, false, false, 1304) && CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", true, true, false, 1304))) {
// line 1305
yield "\t\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", false, false, false, 1305));
foreach ($context['_seq'] as $context["_key"] => $context["variantImg"]) {
// line 1306
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context["allProductImages"] = Twig\Extension\CoreExtension::merge(($context["allProductImages"] ?? null), [$context["variantImg"]]);
// line 1307
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variantImg'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1308
yield "\t\t\t\t\t\t\t\t\t\t";
}
// line 1309
yield "\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variant'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1310
yield "\t\t\t\t\t\t\t\t";
}
// line 1311
yield "\t\t\t\t\t\t\t\t";
if ((Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["allProductImages"] ?? null)) > 0)) {
// line 1312
yield "\t\t\t\t\t\t\t\t\t<img id=\"main-product-image\" src=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl((($_v0 = ($context["allProductImages"] ?? null)) && is_array($_v0) || $_v0 instanceof ArrayAccess ? ($_v0[0] ?? null) : null)), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 1312), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t";
} else {
// line 1314
yield "\t\t\t\t\t\t\t\t\t<img id=\"main-product-image\" src=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("ui/img/category/s-p1.jpg"), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 1314), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t";
}
// line 1316
yield "
\t\t\t\t\t\t\t\t<!-- Overlay avec icônes -->
\t\t\t\t\t\t\t\t<div class=\"image-overlay-icons\">
\t\t\t\t\t\t\t\t\t<button class=\"icon-btn zoom-btn\" onclick=\"openImageZoom()\" title=\"Agrandir l'image\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-magnifier\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t<button class=\"icon-btn favorite-btn\" ";
// line 1322
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1322)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield " onclick=\"toggleWishlist(";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1322), "html", null, true);
yield ", this); return false;\" ";
} else {
yield " onclick=\"showCustomAlert('Vous devez être connecté pour ajouter aux favoris', 'warning'); return false;\" ";
}
yield " title=\"Ajouter aux favoris\" data-product-id=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1322), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-heart\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<!-- Navigation sur l'image principale -->
\t\t\t\t\t\t\t\t<div class=\"main-image-nav\">
\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"main-image-nav-btn\" id=\"main-image-prev\" title=\"Image précédente\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-left\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"main-image-nav-btn\" id=\"main-image-next\" title=\"Image suivante\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-right\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Indicateur d'image active -->
\t\t\t\t\t\t\t<div class=\"image-counter\">
\t\t\t\t\t\t\t\t<span id=\"current-image-index\">1</span>
\t\t\t\t\t\t\t\t/
\t\t\t\t\t\t\t\t";
// line 1342
$context["allProductImages"] = ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", true, true, false, 1342)) ? (Twig\Extension\CoreExtension::default(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 1342), [])) : ([]));
// line 1343
yield "\t\t\t\t\t\t\t\t";
if (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", true, true, false, 1343)) {
// line 1344
yield "\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1344));
foreach ($context['_seq'] as $context["_key"] => $context["variant"]) {
// line 1345
yield "\t\t\t\t\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "isActive", [], "any", false, false, false, 1345) && CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", true, true, false, 1345))) {
// line 1346
yield "\t\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", false, false, false, 1346));
foreach ($context['_seq'] as $context["_key"] => $context["variantImg"]) {
// line 1347
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context["allProductImages"] = Twig\Extension\CoreExtension::merge(($context["allProductImages"] ?? null), [$context["variantImg"]]);
// line 1348
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variantImg'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1349
yield "\t\t\t\t\t\t\t\t\t\t";
}
// line 1350
yield "\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variant'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1351
yield "\t\t\t\t\t\t\t\t";
}
// line 1352
yield "\t\t\t\t\t\t\t\t<span id=\"total-images\">";
yield ((Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["allProductImages"] ?? null))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["allProductImages"] ?? null)), "html", null, true)) : (1));
yield "</span>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Indicateurs d'images (points) -->
\t\t\t\t\t\t\t<div class=\"image-indicators\" id=\"image-indicators\">
\t\t\t\t\t\t\t\t";
// line 1357
$context["allProductImages"] = ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", true, true, false, 1357)) ? (Twig\Extension\CoreExtension::default(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 1357), [])) : ([]));
// line 1358
yield "\t\t\t\t\t\t\t\t";
if (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", true, true, false, 1358)) {
// line 1359
yield "\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1359));
foreach ($context['_seq'] as $context["_key"] => $context["variant"]) {
// line 1360
yield "\t\t\t\t\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "isActive", [], "any", false, false, false, 1360) && CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", true, true, false, 1360))) {
// line 1361
yield "\t\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "images", [], "any", false, false, false, 1361));
foreach ($context['_seq'] as $context["_key"] => $context["variantImg"]) {
// line 1362
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context["allProductImages"] = Twig\Extension\CoreExtension::merge(($context["allProductImages"] ?? null), [$context["variantImg"]]);
// line 1363
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variantImg'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1364
yield "\t\t\t\t\t\t\t\t\t\t";
}
// line 1365
yield "\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variant'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1366
yield "\t\t\t\t\t\t\t\t";
}
// line 1367
yield "\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(range(0, (((Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["allProductImages"] ?? null))) ? (Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["allProductImages"] ?? null))) : (1)) - 1)));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
// line 1368
yield "\t\t\t\t\t\t\t\t<button class=\"indicator ";
yield ((($context["i"] == 0)) ? ("active") : (""));
yield "\" data-index=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($context["i"], "html", null, true);
yield "\" title=\"Image ";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(($context["i"] + 1), "html", null, true);
yield "\"></button>
\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['i'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1370
yield "\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"col-lg-5 offset-lg-1\">
\t\t\t\t\t<div class=\"s_product_text\">
\t\t\t\t\t\t<h3>";
// line 1376
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 1376), "html", null, true);
yield "</h3>
\t\t\t\t\t\t<h2>
\t\t\t\t\t\t\t<span id=\"main-unit-price\">";
// line 1378
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 1378), 2, ".", " "), "html", null, true);
yield "</span>
\t\t\t\t\t\t\tHTG
\t\t\t\t\t\t</h2>
\t\t\t\t\t\t<ul class=\"list\">
\t\t\t\t\t\t\t<li>
\t\t\t\t\t\t\t\t<a class=\"active\" href=\"#\">
\t\t\t\t\t\t\t\t\t<span>Category</span>
\t\t\t\t\t\t\t\t\t:
\t\t\t\t\t\t\t\t\t";
// line 1386
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "category", [], "any", false, false, false, 1386), "name", [], "any", false, false, false, 1386), "html", null, true);
yield "</a>
\t\t\t\t\t\t\t</li>
\t\t\t\t\t\t\t<li>
\t\t\t\t\t\t\t\t<a href=\"#\">
\t\t\t\t\t\t\t\t\t<span>Disponibilité</span>
\t\t\t\t\t\t\t\t\t:
\t\t\t\t\t\t\t\t\t";
// line 1392
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1392), "html", null, true);
yield "</a>
\t\t\t\t\t\t\t</li>
\t\t\t\t\t\t</ul>
\t\t\t\t\t\t<div class=\"product-description-preview\">";
// line 1395
yield (((Twig\Extension\CoreExtension::length($this->env->getCharset(), Twig\Extension\CoreExtension::striptags(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 1395))) > 150)) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((Twig\Extension\CoreExtension::slice($this->env->getCharset(), Twig\Extension\CoreExtension::striptags(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 1395)), 0, 150) . "..."), "html", null, true)) : ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::striptags(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 1395)), "html", null, true)));
yield "</div>
\t\t\t\t\t\t<!-- Sélection de variantes (Couleurs, Tailles, etc.) -->
\t\t\t\t\t\t";
// line 1398
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", true, true, false, 1398) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1398)) > 0))) {
// line 1399
yield "\t\t\t\t\t\t\t<div class=\"product-variants mb-4\" id=\"product-variants\" data-product-id=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1399), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t";
// line 1400
$context["variantAttributes"] = [];
// line 1401
yield "\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1401));
foreach ($context['_seq'] as $context["_key"] => $context["variant"]) {
// line 1402
yield "\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "isActive", [], "any", false, false, false, 1402)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1403
yield "\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["variant"], "attributeValues", [], "any", false, false, false, 1403));
foreach ($context['_seq'] as $context["_key"] => $context["attrValue"]) {
// line 1404
yield "\t\t\t\t\t\t\t\t\t\t\t";
$context["attrName"] = Twig\Extension\CoreExtension::lower($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "attribute", [], "any", false, false, false, 1404), "name", [], "any", false, false, false, 1404));
// line 1405
yield "\t\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = !CoreExtension::getAttribute($this->env, $this->source, ($context["variantAttributes"] ?? null), ($context["attrName"] ?? null), [], "array", true, true, false, 1405)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1406
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context["variantAttributes"] = Twig\Extension\CoreExtension::merge(($context["variantAttributes"] ?? null), [ (string)($context["attrName"] ?? null) => ["attribute" => CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "attribute", [], "any", false, false, false, 1406), "values" => []]]);
// line 1407
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1408
yield "\t\t\t\t\t\t\t\t\t\t\t";
if (!CoreExtension::inFilter($context["attrValue"], CoreExtension::getAttribute($this->env, $this->source, (($_v1 = ($context["variantAttributes"] ?? null)) && is_array($_v1) || $_v1 instanceof ArrayAccess ? ($_v1[($context["attrName"] ?? null)] ?? null) : null), "values", [], "any", false, false, false, 1408))) {
// line 1409
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context["variantAttributes"] = Twig\Extension\CoreExtension::merge(($context["variantAttributes"] ?? null), [ (string)($context["attrName"] ?? null) => Twig\Extension\CoreExtension::merge((($_v2 = ($context["variantAttributes"] ?? null)) && is_array($_v2) || $_v2 instanceof ArrayAccess ? ($_v2[($context["attrName"] ?? null)] ?? null) : null), ["values" => Twig\Extension\CoreExtension::merge(CoreExtension::getAttribute($this->env, $this->source, (($_v3 = ($context["variantAttributes"] ?? null)) && is_array($_v3) || $_v3 instanceof ArrayAccess ? ($_v3[($context["attrName"] ?? null)] ?? null) : null), "values", [], "any", false, false, false, 1409), [$context["attrValue"]])])]);
// line 1410
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1411
yield "\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['attrValue'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1412
yield "\t\t\t\t\t\t\t\t\t";
}
// line 1413
yield "\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['variant'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1414
yield "
\t\t\t\t\t\t\t\t";
// line 1415
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(($context["variantAttributes"] ?? null));
foreach ($context['_seq'] as $context["attrName"] => $context["attrData"]) {
// line 1416
yield "\t\t\t\t\t\t\t\t\t<div class=\"variant-selector mb-3\" data-attribute=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "attribute", [], "any", false, false, false, 1416), "slug", [], "any", false, false, false, 1416), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t<label class=\"variant-label mb-2\">
\t\t\t\t\t\t\t\t\t\t\t<strong>";
// line 1418
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "attribute", [], "any", false, false, false, 1418), "name", [], "any", false, false, false, 1418), "html", null, true);
yield ":</strong>
\t\t\t\t\t\t\t\t\t\t\t<span class=\"selected-variant-value\" id=\"selected-";
// line 1419
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "attribute", [], "any", false, false, false, 1419), "slug", [], "any", false, false, false, 1419), "html", null, true);
yield "\"></span>
\t\t\t\t\t\t\t\t\t\t</label>
\t\t\t\t\t\t\t\t\t\t<div class=\"variant-options d-flex flex-wrap gap-2\">
\t\t\t\t\t\t\t\t\t\t\t";
// line 1422
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "values", [], "any", false, false, false, 1422));
$context['loop'] = [
'parent' => $context['_parent'],
'index0' => 0,
'index' => 1,
'first' => true,
];
if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
$length = count($context['_seq']);
$context['loop']['revindex0'] = $length - 1;
$context['loop']['revindex'] = $length;
$context['loop']['length'] = $length;
$context['loop']['last'] = 1 === $length;
}
foreach ($context['_seq'] as $context["_key"] => $context["attrValue"]) {
// line 1423
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "isActive", [], "any", false, false, false, 1423)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1424
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "attribute", [], "any", false, false, false, 1424), "type", [], "any", false, false, false, 1424) == "color")) {
// line 1425
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button type=\"button\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"variant-option variant-color-option ";
// line 1426
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "first", [], "any", false, false, false, 1426)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield "selected";
}
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value-id=\"";
// line 1427
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "id", [], "any", false, false, false, 1427), "html", null, true);
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value=\"";
// line 1428
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "value", [], "any", false, false, false, 1428), "html", null, true);
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-attribute=\"";
// line 1429
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "attribute", [], "any", false, false, false, 1429), "slug", [], "any", false, false, false, 1429), "html", null, true);
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"";
// line 1430
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "value", [], "any", false, false, false, 1430), "html", null, true);
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle=\"";
// line 1431
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "colorCode", [], "any", false, false, false, 1431)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield "background-color: ";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "colorCode", [], "any", false, false, false, 1431), "html", null, true);
yield ";";
}
yield " width: 40px; height: 40px; border-radius: 50%; border: 2px solid ";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "first", [], "any", false, false, false, 1431)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield "#007bff";
} else {
yield "#ddd";
}
yield "; cursor: pointer; position: relative;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1432
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "first", [], "any", false, false, false, 1432)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1433
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"check-icon\" style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: ";
if ((CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "colorCode", [], "any", false, false, false, 1433) && $this->extensions['App\Twig\ColorExtension']->isDarkColor(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "colorCode", [], "any", false, false, false, 1433)))) {
yield "white";
} else {
yield "black";
}
yield "; font-size: 18px;\">✓</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1435
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t\t\t\t\t";
} else {
// line 1437
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button type=\"button\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"variant-option variant-text-option btn btn-outline-secondary ";
// line 1438
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "first", [], "any", false, false, false, 1438)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield "active";
}
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value-id=\"";
// line 1439
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "id", [], "any", false, false, false, 1439), "html", null, true);
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value=\"";
// line 1440
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "value", [], "any", false, false, false, 1440), "html", null, true);
yield "\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-attribute=\"";
// line 1441
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["attrData"], "attribute", [], "any", false, false, false, 1441), "slug", [], "any", false, false, false, 1441), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1442
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["attrValue"], "value", [], "any", false, false, false, 1442), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1445
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1446
yield "\t\t\t\t\t\t\t\t\t\t\t";
++$context['loop']['index0'];
++$context['loop']['index'];
$context['loop']['first'] = false;
if (isset($context['loop']['revindex0'], $context['loop']['revindex'])) {
--$context['loop']['revindex0'];
--$context['loop']['revindex'];
$context['loop']['last'] = 0 === $context['loop']['revindex0'];
}
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['attrValue'], $context['_parent'], $context['loop']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1447
yield "\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['attrName'], $context['attrData'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1450
yield "
\t\t\t\t\t\t\t\t<!-- Affichage du stock et du prix de la variante sélectionnée -->
\t\t\t\t\t\t\t\t<div class=\"variant-info mt-3 p-3 bg-light rounded\" id=\"variant-info\" style=\"display: none;\">
\t\t\t\t\t\t\t\t\t<div class=\"d-flex justify-content-between align-items-center mb-2\">
\t\t\t\t\t\t\t\t\t\t<span><strong>Prix:</strong></span>
\t\t\t\t\t\t\t\t\t\t<span class=\"variant-price text-primary fw-bold\" id=\"variant-price\"></span>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"d-flex justify-content-between align-items-center\">
\t\t\t\t\t\t\t\t\t\t<span><strong>Stock:</strong></span>
\t\t\t\t\t\t\t\t\t\t<span class=\"variant-stock\" id=\"variant-stock\"></span>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<input type=\"hidden\" id=\"selected-variant-id\" value=\"\">
\t\t\t\t\t\t\t\t\t<input type=\"hidden\" id=\"selected-variant-sku\" value=\"\">
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
}
// line 1466
yield "
\t\t\t\t\t\t<!-- Informations sur la boutique -->
\t\t\t\t\t\t<div class=\"shop-info mb-3\">
\t\t\t\t\t\t\t<small class=\"text-muted\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-store\"></i>
\t\t\t\t\t\t\t\tVendu par :
\t\t\t\t\t\t\t\t";
// line 1472
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "shop", [], "any", true, true, false, 1472) && CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "shop", [], "any", false, false, false, 1472))) {
// line 1473
yield "\t\t\t\t\t\t\t\t\t<a href=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_shop_show", ["slug" => CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "shop", [], "any", false, false, false, 1473), "slug", [], "any", false, false, false, 1473)]), "html", null, true);
yield "\" class=\"shop-link\">
\t\t\t\t\t\t\t\t\t\t";
// line 1474
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "shop", [], "any", false, false, false, 1474), "name", [], "any", false, false, false, 1474), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t";
} else {
// line 1477
yield "\t\t\t\t\t\t\t\t\t<span class=\"text-muted\">Boutique inconnue</span>
\t\t\t\t\t\t\t\t";
}
// line 1479
yield "\t\t\t\t\t\t\t</small>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<div class=\"product_count\">
\t\t\t\t\t\t\t<label for=\"qty\">Quantité :</label>
\t\t\t\t\t\t\t<div class=\"quantity-controls-wrapper\">
\t\t\t\t\t\t\t\t<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst > 1 ) result.value--;return false;\" class=\"quantity-btn quantity-btn-decrease\" type=\"button\" title=\"Diminuer\">
\t\t\t\t\t\t\t\t\t<span class=\"quantity-icon\">−</span>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t<input type=\"text\" name=\"qty\" id=\"sst\" maxlength=\"12\" value=\"1\" title=\"Quantité:\" class=\"input-text qty quantity-input\" max=\"";
// line 1488
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", true, true, false, 1488) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1488)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1488), "html", null, true)) : (99));
yield "\">
\t\t\t\t\t\t\t\t<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst < ";
// line 1489
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", true, true, false, 1489) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1489)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1489), "html", null, true)) : (99));
yield ") result.value++;return false;\" class=\"quantity-btn quantity-btn-increase\" type=\"button\" title=\"Augmenter\">
\t\t\t\t\t\t\t\t\t<span class=\"quantity-icon\">+</span>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<input
\t\t\t\t\t\ttype=\"hidden\" id=\"unit-price-input\" value=\"";
// line 1496
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 1496), 2, ".", ""), "html", null, true);
yield "\"/>
\t\t\t\t\t\t";
// line 1499
yield "\t\t\t\t\t\t";
if (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "hasTierPricing", [], "any", false, false, false, 1499) && CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "tierPrices", [], "any", true, true, false, 1499)) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "tierPrices", [], "any", false, false, false, 1499)) > 0))) {
// line 1500
yield "\t\t\t\t\t\t";
$context["tierPrices"] = [];
// line 1501
yield "\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "tierPrices", [], "any", false, false, false, 1501));
foreach ($context['_seq'] as $context["_key"] => $context["tier"]) {
// line 1502
yield "\t\t\t\t\t\t\t\t";
$context["tierPrices"] = Twig\Extension\CoreExtension::merge(($context["tierPrices"] ?? null), [["min" => CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "min", [], "any", false, false, false, 1502), "price" => CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "price", [], "any", false, false, false, 1502)]]);
// line 1503
yield "\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['tier'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1504
yield "
\t\t\t\t\t\t\t<div id=\"bulk-pricing\" class=\"mt-4 p-3 bg-light rounded\" data-tiers='";
// line 1505
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(json_encode(($context["tierPrices"] ?? null)), "html_attr");
yield "'>
\t\t\t\t\t\t\t\t<div class=\"d-flex align-items-center mb-3\">
\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-tag text-primary me-2\" style=\"font-size: 1.2rem;\"></i>
\t\t\t\t\t\t\t\t\t<strong class=\"me-2\">Prix de gros disponible</strong>
\t\t\t\t\t\t\t\t\t<span id=\"unit-price-value\" class=\"badge bg-primary ms-2 text-white p-2\">";
// line 1509
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 1509), 2, ".", " "), "html", null, true);
yield " HTG</span>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<div class=\"table-responsive\">
\t\t\t\t\t\t\t\t\t<table class=\"table table-sm mb-3\" style=\"border:1px solid #dee2e6; background: white;\">
\t\t\t\t\t\t\t\t\t\t<thead class=\"table-primary\">
\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<th style=\"font-weight: 600;\">Quantité minimale</th>
\t\t\t\t\t\t\t\t\t\t\t\t<th style=\"font-weight: 600;\">Prix unitaire (HTG)</th>
\t\t\t\t\t\t\t\t\t\t\t\t<th style=\"font-weight: 600;\">Économie</th>
\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t</thead>
\t\t\t\t\t\t\t\t\t<tbody id=\"bulk-tier-rows\">
\t\t\t\t\t\t\t\t\t\t";
// line 1521
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(Twig\Extension\CoreExtension::sort($this->env, ($context["tierPrices"] ?? null), function ($__a__, $__b__) use ($context, $macros) { $context["a"] = $__a__; $context["b"] = $__b__; return (CoreExtension::getAttribute($this->env, $this->source, ($context["a"] ?? null), "min", [], "any", false, false, false, 1521) <=> CoreExtension::getAttribute($this->env, $this->source, ($context["b"] ?? null), "min", [], "any", false, false, false, 1521)); }));
$context['loop'] = [
'parent' => $context['_parent'],
'index0' => 0,
'index' => 1,
'first' => true,
];
if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
$length = count($context['_seq']);
$context['loop']['revindex0'] = $length - 1;
$context['loop']['revindex'] = $length;
$context['loop']['length'] = $length;
$context['loop']['last'] = 1 === $length;
}
foreach ($context['_seq'] as $context["_key"] => $context["tier"]) {
// line 1522
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
$context["savings"] = Twig\Extension\CoreExtension::round((((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 1522) - CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "price", [], "any", false, false, false, 1522)) / CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 1522)) * 100), 1);
// line 1523
yield "\t\t\t\t\t\t\t\t\t\t\t\t<tr data-min=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "min", [], "any", false, false, false, 1523), "html", null, true);
yield "\" class=\"";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["loop"], "first", [], "any", false, false, false, 1523)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield "table-active";
}
yield "\">
\t\t\t\t\t\t\t\t\t\t\t\t\t<td><strong>≥ ";
// line 1524
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "min", [], "any", false, false, false, 1524), "html", null, true);
yield "</strong></td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td><strong class=\"text-primary\">";
// line 1525
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "price", [], "any", false, false, false, 1525), 2, ".", " "), "html", null, true);
yield "</strong></td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1527
if ((($context["savings"] ?? null) > 0)) {
// line 1528
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-success text-white p-2\">-";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(($context["savings"] ?? null), "html", null, true);
yield "%</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
} else {
// line 1530
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-muted\">-</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1532
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
++$context['loop']['index0'];
++$context['loop']['index'];
$context['loop']['first'] = false;
if (isset($context['loop']['revindex0'], $context['loop']['revindex'])) {
--$context['loop']['revindex0'];
--$context['loop']['revindex'];
$context['loop']['last'] = 0 === $context['loop']['revindex0'];
}
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['tier'], $context['_parent'], $context['loop']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1535
yield "\t\t\t\t\t\t\t\t\t</tbody>
\t\t\t\t\t\t\t\t</table>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"d-flex flex-wrap gap-3 align-items-baseline mb-2 p-2 bg-white rounded\">
\t\t\t\t\t\t\t\t<div>
\t\t\t\t\t\t\t\t\t<strong>Total:</strong>
\t\t\t\t\t\t\t\t\t\t<span id=\"total-price-value\" class=\"text-primary fs-5\">";
// line 1541
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 1541), 2, ".", " "), "html", null, true);
yield "</span>
\t\t\t\t\t\t\t\t\tHTG
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"text-success\">
\t\t\t\t\t\t\t\t\t<strong>Économies:</strong>
\t\t\t\t\t\t\t\t\t<span id=\"savings-amount\">0.00</span>
\t\t\t\t\t\t\t\t\tHTG
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(<span id=\"savings-percent\">0</span>%)
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<small class=\"text-muted d-block mt-2\">
\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle me-1\"></i>
\t\t\t\t\t\t\t\t\tLe prix et le total s'adaptent automatiquement selon la quantité sélectionnée.
\t\t\t\t\t\t\t\t</small>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
}
// line 1557
yield "
\t\t\t\t\t\t<!-- Stock disponible -->
\t\t\t\t\t\t";
// line 1559
if (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", true, true, false, 1559)) {
// line 1560
yield "\t\t\t\t\t\t\t<small class=\"text-muted\">Stock disponible :
\t\t\t\t\t\t\t\t";
// line 1561
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1561), "html", null, true);
yield "
\t\t\t\t\t\t\t\tunités</small>
\t\t\t\t\t\t";
}
// line 1564
yield "
\t\t\t\t\t\t<!-- Statistiques du produit -->
\t\t\t\t\t\t";
// line 1566
if (array_key_exists("productStats", $context)) {
// line 1567
yield "\t\t\t\t\t\t\t<div class=\"product-stats mt-3\">
\t\t\t\t\t\t\t\t<div class=\"row text-center\">
\t\t\t\t\t\t\t\t\t<div class=\"col-4\">
\t\t\t\t\t\t\t\t\t\t<div class=\"stat-item\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"stat-number\">";
// line 1571
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["productStats"] ?? null), "totalViews", [], "any", false, false, false, 1571), "html", null, true);
yield "</span>
\t\t\t\t\t\t\t\t\t\t\t<small class=\"stat-label\">Vues</small>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-4\">
\t\t\t\t\t\t\t\t\t\t<div class=\"stat-item\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"stat-number\">";
// line 1577
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["productStats"] ?? null), "salesCount", [], "any", false, false, false, 1577), "html", null, true);
yield "</span>
\t\t\t\t\t\t\t\t\t\t\t<small class=\"stat-label\">Ventes</small>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-4\">
\t\t\t\t\t\t\t\t\t\t<div class=\"stat-item\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"stat-number\">";
// line 1583
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["productStats"] ?? null), "conversionRate", [], "any", false, false, false, 1583), "html", null, true);
yield "%</span>
\t\t\t\t\t\t\t\t\t\t\t<small class=\"stat-label\">Conversion</small>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
}
// line 1590
yield "
\t\t\t\t\t\t<div class=\"card_area d-flex align-items-center\">
\t\t\t\t\t\t\t<a class=\"primary-btn btn-add-to-cart\" href=\"javascript:void(0);\" id=\"add-to-cart-btn\" data-product-id=\"";
// line 1592
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1592), "html", null, true);
yield "\" data-qty=\"1\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-cart\"></i>
\t\t\t\t\t\t\t\tAjouter au panier
\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t<a class=\"icon_btn wishlist-btn\" href=\"#\" title=\"Ajouter aux favoris\" data-product-id=\"";
// line 1596
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1596), "html", null, true);
yield "\" ";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1596)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield " onclick=\"toggleWishlist(";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1596), "html", null, true);
yield ", this); return false;\" ";
} else {
yield " onclick=\"showCustomAlert('Vous devez être connecté pour ajouter aux favoris', 'warning'); return false;\" ";
}
yield ">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-heart\"></i>
\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t<a class=\"icon_btn comparison-btn\" href=\"#\" title=\"Comparer\" data-product-id=\"";
// line 1599
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1599), "html", null, true);
yield "\" ";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1599)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
yield " onclick=\"toggleComparison(";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 1599), "html", null, true);
yield ", this); return false;\" ";
} else {
yield " onclick=\"showCustomAlert('Vous devez être connecté pour comparer des produits', 'warning'); return false;\" ";
}
yield ">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-sync\"></i>
\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- Message de confirmation -->
\t\t\t\t\t\t<div id=\"cart-message\" class=\"alert alert-success mt-3\" style=\"display: none;\">
\t\t\t\t\t\t\t<i class=\"lnr lnr-checkmark-circle\"></i>
\t\t\t\t\t\t\tProduit ajouté au panier avec succès !
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- ... existing code ... -->
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</div>
\t<!--================End Single Product Area =================-->
\t<!--================Product Description Area =================-->
\t<section class=\"product_description_area\">
\t\t<div class=\"container\">
\t\t\t<ul class=\"nav nav-tabs\" id=\"myTab\" role=\"tablist\">
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link active\" id=\"home-tab\" data-bs-toggle=\"tab\" href=\"#home\" role=\"tab\" aria-controls=\"home\" aria-selected=\"true\">Description</a>
\t\t\t\t</li>
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link\" id=\"profile-tab\" data-bs-toggle=\"tab\" href=\"#profile\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\">Spécifications</a>
\t\t\t\t</li>
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link\" id=\"contact-tab\" data-bs-toggle=\"tab\" href=\"#contact\" role=\"tab\" aria-controls=\"contact\" aria-selected=\"false\">Commentaires</a>
\t\t\t\t</li>
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link\" id=\"review-tab\" data-bs-toggle=\"tab\" href=\"#review\" role=\"tab\" aria-controls=\"review\" aria-selected=\"false\">Avis (";
// line 1631
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", true, true, false, 1631) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1631)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1631), "html", null, true)) : (0));
yield ")</a>
\t\t\t\t</li>
\t\t\t</ul>
\t\t\t<div class=\"tab-content\" id=\"myTabContent\">
\t\t\t\t<div class=\"tab-pane fade show active\" id=\"home\" role=\"tabpanel\" aria-labelledby=\"home-tab\">
\t\t\t\t\t<div class=\"description\">
\t\t\t\t\t\t";
// line 1637
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 1637)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1638
yield "\t\t\t\t\t\t\t<div class=\"product-description-content\">
\t\t\t\t\t\t\t\t";
// line 1639
yield CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 1639);
yield "
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
} else {
// line 1642
yield "\t\t\t\t\t\t\t<p class=\"text-muted\">Aucune description disponible pour ce produit.</p>
\t\t\t\t\t\t";
}
// line 1644
yield "\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"tab-pane fade\" id=\"profile\" role=\"tabpanel\" aria-labelledby=\"profile-tab\">
\t\t\t\t\t<div class=\"specification-table\">
\t\t\t\t\t\t";
// line 1648
if (((((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "weight", [], "any", false, false, false, 1648) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "length", [], "any", false, false, false, 1648)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 1648)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 1648)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "attributes", [], "any", false, false, false, 1648))) {
// line 1649
yield "\t\t\t\t\t\t\t<div class=\"table-responsive\">
\t\t\t\t\t\t\t\t<table class=\"table\">
\t\t\t\t\t\t\t\t\t<tbody>
\t\t\t\t\t\t\t\t\t\t";
// line 1652
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "sku", [], "any", false, false, false, 1652)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1653
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Référence (SKU)</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1658
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "sku", [], "any", false, false, false, 1658), "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1662
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "barcode", [], "any", false, false, false, 1662)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1663
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Code-barres</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1668
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "barcode", [], "any", false, false, false, 1668), "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1672
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "brand", [], "any", false, false, false, 1672)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1673
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Marque</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1678
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "brand", [], "any", false, false, false, 1678), "name", [], "any", false, false, false, 1678), "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1682
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "category", [], "any", false, false, false, 1682)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1683
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Catégorie</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1688
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "category", [], "any", false, false, false, 1688), "name", [], "any", false, false, false, 1688), "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1692
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "weight", [], "any", false, false, false, 1692)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1693
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Poids</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1698
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "weight", [], "any", false, false, false, 1698), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t\t\t\tkg</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1703
yield "\t\t\t\t\t\t\t\t\t\t";
if (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "length", [], "any", false, false, false, 1703) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 1703)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 1703))) {
// line 1704
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Dimensions</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1710
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "length", [], "any", false, false, false, 1710)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1711
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "length", [], "any", false, false, false, 1711), "html", null, true);
yield "cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1713
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 1713)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1714
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t×
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1715
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 1715), "html", null, true);
yield "cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1717
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 1717)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1718
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t×
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1719
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 1719), "html", null, true);
yield "cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1721
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1725
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1725))) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1726
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Stock disponible</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1731
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1731), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t\t\t\tunité(s)</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1736
yield "\t\t\t\t\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "details", [], "any", true, true, false, 1736) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "details", [], "any", false, false, false, 1736)) > 0))) {
// line 1737
yield "\t\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "details", [], "any", false, false, false, 1737));
foreach ($context['_seq'] as $context["_key"] => $context["detail"]) {
// line 1738
yield "\t\t\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["detail"], "isActive", [], "any", false, false, false, 1738)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1739
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1741
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["detail"], "label", [], "any", false, false, false, 1741), "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1744
yield CoreExtension::getAttribute($this->env, $this->source, $context["detail"], "value", [], "any", false, false, false, 1744);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1748
yield "\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['detail'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1749
yield "\t\t\t\t\t\t\t\t\t\t";
}
// line 1750
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1750)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1751
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Statut</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1757
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1757) == "in_stock")) {
// line 1758
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-success\">En stock</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
} elseif ((CoreExtension::getAttribute($this->env, $this->source, // line 1759
($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1759) == "out_of_stock")) {
// line 1760
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-danger\">Rupture de stock</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
} elseif ((CoreExtension::getAttribute($this->env, $this->source, // line 1761
($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1761) == "backorder")) {
// line 1762
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-warning\">Sur commande</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
} else {
// line 1764
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1764), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1766
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1770
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "isDigital", [], "any", false, false, false, 1770)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1771
yield "\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Type</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-info\">Produit digital</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t";
}
// line 1782
yield "\t\t\t\t\t\t\t\t\t\t";
if ((($tmp = !Twig\Extension\CoreExtension::testEmpty(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "attributes", [], "any", false, false, false, 1782))) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1783
yield "\t\t\t\t\t\t\t\t\t\t\t";
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "attributes", [], "any", false, false, false, 1783));
foreach ($context['_seq'] as $context["key"] => $context["value"]) {
// line 1784
yield "\t\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1786
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::titleCase($this->env->getCharset(), Twig\Extension\CoreExtension::replace($context["key"], ["_" => " "])), "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>";
// line 1789
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($context["value"], "html", null, true);
yield "</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['key'], $context['value'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1793
yield "\t\t\t\t\t\t\t\t\t\t";
}
// line 1794
yield "\t\t\t\t\t\t\t\t\t</tbody>
\t\t\t\t\t\t\t\t</table>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
} else {
// line 1798
yield "\t\t\t\t\t\t\t<p class=\"text-muted\">Aucune spécification disponible pour ce produit.</p>
\t\t\t\t\t\t";
}
// line 1800
yield "\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"tab-pane fade\" id=\"contact\" role=\"tabpanel\" aria-labelledby=\"contact-tab\">
\t\t\t\t\t<div class=\"comment-wrapper\">
\t\t\t\t\t\t<div class=\"alert alert-info\">
\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t\t\tLa fonctionnalité de commentaires sera bientôt disponible. Vous pourrez laisser des commentaires et poser des questions sur ce produit.
\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
// line 1808
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1808)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1809
yield "\t\t\t\t\t\t\t<div class=\"review_box mt-4\">
\t\t\t\t\t\t\t\t<h4>Poser une question</h4>
\t\t\t\t\t\t\t\t<form class=\"row contact_form\" method=\"post\" novalidate=\"novalidate\">
\t\t\t\t\t\t\t\t\t<div class=\"col-md-12\">
\t\t\t\t\t\t\t\t\t\t<div class=\"form-group\">
\t\t\t\t\t\t\t\t\t\t\t<textarea class=\"form-control\" name=\"comment\" id=\"comment\" rows=\"3\" placeholder=\"Votre question ou commentaire...\" required></textarea>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-md-12 text-right\">
\t\t\t\t\t\t\t\t\t\t<button type=\"submit\" class=\"btn primary-btn\">Envoyer</button>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</form>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
} else {
// line 1823
yield "\t\t\t\t\t\t\t<p class=\"text-center\">
\t\t\t\t\t\t\t\t<a href=\"";
// line 1824
yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_app_login");
yield "\" class=\"primary-btn\">Connectez-vous</a>
\t\t\t\t\t\t\t\tpour poser une question ou laisser un commentaire.
\t\t\t\t\t\t\t</p>
\t\t\t\t\t\t";
}
// line 1828
yield "\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"tab-pane fade\" id=\"review\" role=\"tabpanel\" aria-labelledby=\"review-tab\">
\t\t\t\t\t<div class=\"review-wrapper\">
\t\t\t\t\t\t<div class=\"row\">
\t\t\t\t\t\t\t<div class=\"col-lg-6\">
\t\t\t\t\t\t\t\t<div class=\"row total_rate\">
\t\t\t\t\t\t\t\t\t<div class=\"col-6\">
\t\t\t\t\t\t\t\t\t\t<div class=\"box_total\">
\t\t\t\t\t\t\t\t\t\t\t<h5>Note globale</h5>
\t\t\t\t\t\t\t\t\t\t\t<h4>";
// line 1838
yield (((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1838)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1838), 1, ".", ","), "html", null, true)) : ("0.0"));
yield "</h4>
\t\t\t\t\t\t\t\t\t\t\t<h6>(";
// line 1839
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", true, true, false, 1839) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1839)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1839), "html", null, true)) : (0));
yield "
\t\t\t\t\t\t\t\t\t\t\t\tAvis)</h6>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-6\">
\t\t\t\t\t\t\t\t\t\t<div class=\"rating_list\">
\t\t\t\t\t\t\t\t\t\t\t<h3>Basé sur
\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1846
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", true, true, false, 1846) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1846)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1846), "html", null, true)) : (0));
yield "
\t\t\t\t\t\t\t\t\t\t\t\tavis</h3>
\t\t\t\t\t\t\t\t\t\t\t<div class=\"rating-summary\">
\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1849
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1849)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1850
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"rating-display mb-3\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1851
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(range(1, 5));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
// line 1852
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-star";
if (($context["i"] <= CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1852))) {
} else {
yield "-o";
}
yield "\" style=\"color: #ffa200; font-size: 1.2rem;\"></i>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['i'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1854
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"ms-2\" style=\"font-size: 1.1rem; font-weight: bold;\">";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1854), 1, ".", ","), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/ 5.0</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t\t";
} else {
// line 1858
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"text-muted\">Aucune note disponible</p>
\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1860
yield "\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"review_list\">
\t\t\t\t\t\t\t\t\t";
// line 1865
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1865) && (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1865) > 0))) {
// line 1866
yield "\t\t\t\t\t\t\t\t\t\t<div class=\"alert alert-info\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t\t\t\t\t\t\tLe système d'affichage détaillé des avis sera disponible prochainement.
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tNote actuelle :
\t\t\t\t\t\t\t\t\t\t\t";
// line 1870
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1870), 1, ".", ","), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t/ 5.0 basée sur
\t\t\t\t\t\t\t\t\t\t\t";
// line 1872
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1872), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\tavis.
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t";
} else {
// line 1876
yield "\t\t\t\t\t\t\t\t\t\t<div class=\"alert alert-info\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t\t\t\t\t\t\tAucun avis pour ce produit pour le moment. Soyez le premier à laisser un avis après votre achat !
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t";
}
// line 1881
yield "\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<div class=\"col-lg-6\">
\t\t\t\t\t\t\t\t<div class=\"review_box\">
\t\t\t\t\t\t\t\t\t<h4>Laisser un avis</h4>
\t\t\t\t\t\t\t\t\t";
// line 1886
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1886)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1887
yield "\t\t\t\t\t\t\t\t\t\t<p class=\"text-muted\">Vous pouvez laisser un avis après avoir acheté ce produit.</p>
\t\t\t\t\t\t\t\t\t\t<form class=\"row contact_form\" method=\"post\" novalidate=\"novalidate\">
\t\t\t\t\t\t\t\t\t\t\t<div class=\"col-md-12\">
\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"form-group\">
\t\t\t\t\t\t\t\t\t\t\t\t\t<label>Votre note</label>
\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"rating-input mb-3\" style=\"display: flex; gap: 5px; flex-direction: row-reverse; justify-content: flex-end;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
// line 1893
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(range(5, 1));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
// line 1894
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input type=\"radio\" name=\"rating\" id=\"rating";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($context["i"], "html", null, true);
yield "\" value=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($context["i"], "html", null, true);
yield "\" required style=\"display: none;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"rating";
// line 1895
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($context["i"], "html", null, true);
yield "\" class=\"star-label\" style=\"cursor: pointer;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-star-o\" style=\"color: #ccc; font-size: 1.5rem;\"></i>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</label>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['i'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1899
yield "\t\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t<div class=\"col-md-12\">
\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"form-group\">
\t\t\t\t\t\t\t\t\t\t\t\t\t<textarea class=\"form-control\" name=\"review\" id=\"review\" rows=\"5\" placeholder=\"Votre avis...\" required onfocus=\"this.placeholder = ''\" onblur=\"this.placeholder = 'Votre avis...'\"></textarea>
\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t<div class=\"col-md-12 text-right\">
\t\t\t\t\t\t\t\t\t\t\t\t<button type=\"submit\" class=\"btn primary-btn\">Publier l'avis</button>
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t</form>
\t\t\t\t\t\t\t\t\t";
} else {
// line 1912
yield "\t\t\t\t\t\t\t\t\t\t<p class=\"text-center\">
\t\t\t\t\t\t\t\t\t\t\t<a href=\"";
// line 1913
yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_app_login");
yield "\" class=\"primary-btn\">Connectez-vous</a>
\t\t\t\t\t\t\t\t\t\t\tpour laisser un avis sur ce produit.
\t\t\t\t\t\t\t\t\t\t</p>
\t\t\t\t\t\t\t\t\t";
}
// line 1917
yield "\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</section>
\t<!--================End Product Description Area =================-->
\t<script>
\t\t// Données des variantes du produit
\t\tconst productVariants = ";
// line 1929
yield (((Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1929)) > 0)) ? (json_encode(Twig\Extension\CoreExtension::map($this->env, CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "variants", [], "any", false, false, false, 1929), function ($__v__) use ($context, $macros) { $context["v"] = $__v__; return ["id" => CoreExtension::getAttribute($this->env, $this->source, // line 1930
($context["v"] ?? null), "id", [], "any", false, false, false, 1930), "sku" => CoreExtension::getAttribute($this->env, $this->source, // line 1931
($context["v"] ?? null), "sku", [], "any", false, false, false, 1931), "price" => CoreExtension::getAttribute($this->env, $this->source, // line 1932
($context["v"] ?? null), "price", [], "any", false, false, false, 1932), "compareAtPrice" => CoreExtension::getAttribute($this->env, $this->source, // line 1933
($context["v"] ?? null), "compareAtPrice", [], "any", false, false, false, 1933), "stock" => CoreExtension::getAttribute($this->env, $this->source, // line 1934
($context["v"] ?? null), "stock", [], "any", false, false, false, 1934), "stockStatus" => CoreExtension::getAttribute($this->env, $this->source, // line 1935
($context["v"] ?? null), "stockStatus", [], "any", false, false, false, 1935), "isActive" => CoreExtension::getAttribute($this->env, $this->source, // line 1936
($context["v"] ?? null), "isActive", [], "any", false, false, false, 1936), "images" => CoreExtension::getAttribute($this->env, $this->source, // line 1937
($context["v"] ?? null), "images", [], "any", false, false, false, 1937), "attributeValues" => $this->extensions['App\Twig\ColorExtension']->toArray(Twig\Extension\CoreExtension::map($this->env, CoreExtension::getAttribute($this->env, $this->source, // line 1938
($context["v"] ?? null), "attributeValues", [], "any", false, false, false, 1938), function ($__av__) use ($context, $macros) { $context["av"] = $__av__; return ["attributeId" => CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, // line 1939
($context["av"] ?? null), "attribute", [], "any", false, false, false, 1939), "id", [], "any", false, false, false, 1939), "attributeSlug" => CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, // line 1940
($context["av"] ?? null), "attribute", [], "any", false, false, false, 1940), "slug", [], "any", false, false, false, 1940), "valueId" => CoreExtension::getAttribute($this->env, $this->source, // line 1941
($context["av"] ?? null), "id", [], "any", false, false, false, 1941), "value" => CoreExtension::getAttribute($this->env, $this->source, // line 1942
($context["av"] ?? null), "value", [], "any", false, false, false, 1942)]; }))]; }))) : ("[]"));
// line 1944
yield ";
\t\t// Gestion de la sélection de variantes
\t\tlet selectedAttributes = {};
\t\tlet currentVariant = null;
\t\t// Initialiser les onglets Bootstrap
document.addEventListener('DOMContentLoaded', function () { // Activer les onglets Bootstrap 5
const triggerTabList = document.querySelectorAll('#myTab button[data-bs-toggle=\"tab\"]');
triggerTabList.forEach(triggerEl => {
const tabTrigger = new bootstrap.Tab(triggerEl);
triggerEl.addEventListener('click', event => {
event.preventDefault();
tabTrigger.show();
});
});
// Gestion des étoiles pour les avis
const ratingInputs = document.querySelectorAll('.rating-input input[type=\"radio\"]');
const starLabels = document.querySelectorAll('.rating-input .star-label');
ratingInputs.forEach((input, index) => {
input.addEventListener('change', function () {
const rating = parseInt(this.value);
starLabels.forEach((label) => { // Trouver l'input associé à ce label
const labelInput = label.previousElementSibling;
if (labelInput && labelInput.type === 'radio') {
const starValue = parseInt(labelInput.value);
const star = label.querySelector('i');
if (starValue <= rating) {
star.style.color = '#ffa200';
star.classList.remove('fa-star-o');
star.classList.add('fa-star');
} else {
star.style.color = '#ccc';
star.classList.remove('fa-star');
star.classList.add('fa-star-o');
}
}
});
});
});
// Pré-remplir les étoiles au survol
starLabels.forEach((label) => {
label.addEventListener('mouseenter', function () { // Trouver l'input associé à ce label
const input = label.previousElementSibling;
if (input && input.type === 'radio') {
const rating = parseInt(input.value);
starLabels.forEach((l) => {
const lInput = l.previousElementSibling;
if (lInput && lInput.type === 'radio') {
const starValue = parseInt(lInput.value);
const star = l.querySelector('i');
if (starValue <= rating) {
star.style.color = '#ffa200';
star.classList.remove('fa-star-o');
star.classList.add('fa-star');
} else {
star.style.color = '#ccc';
star.classList.remove('fa-star');
star.classList.add('fa-star-o');
}
}
});
}
});
});
const ratingContainer = document.querySelector('.rating-input');
if (ratingContainer) {
ratingContainer.addEventListener('mouseleave', function () {
const checkedInput = document.querySelector('.rating-input input[type=\"radio\"]:checked');
if (checkedInput) {
checkedInput.dispatchEvent(new Event('change'));
} else {
starLabels.forEach(label => {
const star = label.querySelector('i');
star.style.color = '#ccc';
});
}
});
}
});
\t// Gestion de la sélection de variantes
\tif (typeof productVariants !== 'undefined' && productVariants.length > 0) {
\t\t// Initialiser avec la première variante active
\t\tconst firstVariant = productVariants.find(v => v.isActive);
\t\tif (firstVariant) {
\t\t\tfirstVariant.attributeValues.forEach(av => {
\t\t\t\tselectedAttributes[av.attributeSlug] = av.valueId;
\t\t\t});
\t\t\tupdateVariantDisplay(firstVariant);
\t\t} else {
\t\t\t// Si aucune variante active, afficher le prix de base
\t\t\tconst priceEl = document.getElementById('main-unit-price');
\t\t\tif (priceEl) {
\t\t\t\tpriceEl.textContent = '";
// line 2042
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 2042), 2, ".", " "), "html", null, true);
yield "';
\t\t\t}
\t\t}
\t\t// Écouter les clics sur les options de variantes
\t\tdocument.querySelectorAll('.variant-option').forEach(option => {
\t\t\toption.addEventListener('click', function() {
\t\t\t\tconst attributeSlug = this.getAttribute('data-attribute');
\t\t\t\tconst valueId = parseInt(this.getAttribute('data-value-id'));
\t\t\t\tconst value = this.getAttribute('data-value');
\t\t\t\t// Mettre à jour la sélection visuelle
\t\t\t\tdocument.querySelectorAll(`[data-attribute=\"\${attributeSlug}\"]`).forEach(opt => {
\t\t\t\t\topt.classList.remove('selected', 'active');
\t\t\t\t\tif (opt.classList.contains('variant-color-option')) {
\t\t\t\t\t\topt.style.borderColor = '#ddd';
\t\t\t\t\t\tconst checkIcon = opt.querySelector('.check-icon');
\t\t\t\t\t\tif (checkIcon) checkIcon.remove();
\t\t\t\t\t}
\t\t\t\t});
\t\t\t\tthis.classList.add('selected', 'active');
\t\t\t\tif (this.classList.contains('variant-color-option')) {
\t\t\t\t\tthis.style.borderColor = '#007bff';
\t\t\t\t\tconst checkIcon = document.createElement('span');
\t\t\t\t\tcheckIcon.className = 'check-icon';
\t\t\t\t\tconst bgColor = this.style.backgroundColor || '';
\t\t\t\t\tconst isDark = bgColor && getContrastColor(bgColor) < 128;
\t\t\t\t\tcheckIcon.style.cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: ' + (isDark ? 'white' : 'black') + '; font-size: 18px;';
\t\t\t\t\tcheckIcon.textContent = '✓';
\t\t\t\t\tthis.appendChild(checkIcon);
\t\t\t\t}
\t\t\t\t// Mettre à jour les attributs sélectionnés
\t\t\t\tselectedAttributes[attributeSlug] = valueId;
\t\t\t\tconst selectedSpan = document.getElementById(`selected-\${attributeSlug}`);
\t\t\t\tif (selectedSpan) {
\t\t\t\t\tselectedSpan.textContent = value;
\t\t\t\t}
\t\t\t\t// Trouver la variante correspondante
\t\t\t\tconst matchingVariant = findMatchingVariant();
\t\t\t\tif (matchingVariant) {
\t\t\t\t\tupdateVariantDisplay(matchingVariant);
\t\t\t\t} else {
\t\t\t\t\t// Aucune variante correspondante trouvée - afficher le produit de base
\t\t\t\t\tresetToBaseProduct();
\t\t\t\t}
\t\t\t});
\t\t});
\t}
\tfunction findMatchingVariant() {
\t\tif (!productVariants || productVariants.length === 0) return null;
\t\t
\t\treturn productVariants.find(variant => {
\t\t\tif (!variant.isActive) return false;
\t\t\t
\t\t\tconst variantAttributes = {};
\t\t\tvariant.attributeValues.forEach(av => {
\t\t\t\tvariantAttributes[av.attributeSlug] = av.valueId;
\t\t\t});
\t\t\t// Vérifier si tous les attributs sélectionnés correspondent
\t\t\tfor (const [attrSlug, valueId] of Object.entries(selectedAttributes)) {
\t\t\t\tif (!variantAttributes[attrSlug] || variantAttributes[attrSlug] !== valueId) {
\t\t\t\t\treturn false;
\t\t\t\t}
\t\t\t}
\t\t\t// Vérifier que le nombre d'attributs correspond
\t\t\treturn Object.keys(variantAttributes).length === Object.keys(selectedAttributes).length;
\t\t});
\t}
\tfunction updateVariantDisplay(variant) {
\t\tcurrentVariant = variant;
\t\t
\t\t// Mettre à jour le prix
\t\tconst priceElement = document.getElementById('main-unit-price');
\t\tconst variantPriceElement = document.getElementById('variant-price');
\t\tif (priceElement) {
\t\t\tpriceElement.textContent = variant.price.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ' ');
\t\t}
\t\tif (variantPriceElement) {
\t\t\tvariantPriceElement.textContent = variant.price.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ' ') + ' HTG';
\t\t}
\t\t// Mettre à jour le stock
\t\tconst stockElement = document.getElementById('variant-stock');
\t\tif (stockElement) {
\t\t\tif (variant.stock > 0) {
\t\t\t\tstockElement.textContent = variant.stock + ' disponible(s)';
\t\t\t\tstockElement.className = 'variant-stock text-success';
\t\t\t} else {
\t\t\t\tstockElement.textContent = 'Rupture de stock';
\t\t\t\tstockElement.className = 'variant-stock text-danger';
\t\t\t}
\t\t}
\t\t// Mettre à jour les champs cachés
\t\tconst variantIdInput = document.getElementById('selected-variant-id');
\t\tconst variantSkuInput = document.getElementById('selected-variant-sku');
\t\tif (variantIdInput) variantIdInput.value = variant.id;
\t\tif (variantSkuInput) variantSkuInput.value = variant.sku;
\t\t// Mettre à jour les images si disponibles
\t\tif (variant.images && variant.images.length > 0) {
\t\t\tconst mainImage = document.getElementById('main-product-image');
\t\t\tif (mainImage && variant.images[0]) {
\t\t\t\tmainImage.src = variant.images[0];
\t\t\t}
\t\t}
\t\t// Afficher les informations de la variante
\t\tconst variantInfo = document.getElementById('variant-info');
\t\tif (variantInfo) variantInfo.style.display = 'block';
\t\t// Mettre à jour la quantité maximale
\t\tconst qtyInput = document.getElementById('sst');
\t\tif (qtyInput) {
\t\t\tqtyInput.max = variant.stock;
\t\t}
\t}
\tfunction getContrastColor(hexColor) {
\t\t// Convertir hex en RGB et calculer la luminosité
\t\tconst rgb = hexColor.match(/\\d+/g);
\t\tif (rgb && rgb.length >= 3) {
\t\t\tconst r = parseInt(rgb[0]);
\t\t\tconst g = parseInt(rgb[1]);
\t\tconst b = parseInt(rgb[2]);
\t\treturn (r * 299 + g * 587 + b * 114) / 1000;
\t}
\treturn 128;
}
function resetToBaseProduct() {
\tcurrentVariant = null;
\t
\t// Réinitialiser les attributs sélectionnés
\tselectedAttributes = {};
\t
\t// Masquer les informations de variante
\tconst variantInfo = document.getElementById('variant-info');
\tif (variantInfo) variantInfo.style.display = 'none';
\t
\t// Réinitialiser le prix au prix de base
\tconst priceEl = document.getElementById('main-unit-price');
\tif (priceEl) priceEl.textContent = '";
// line 2190
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 2190), 2, ".", " "), "html", null, true);
yield "';
\t
\t// Réinitialiser les champs cachés
\tconst variantIdInput = document.getElementById('selected-variant-id');
\tconst variantSkuInput = document.getElementById('selected-variant-sku');
\tif (variantIdInput) variantIdInput.value = '';
\tif (variantSkuInput) variantSkuInput.value = '';
\t
\t// Réinitialiser les sélections visuelles
\tdocument.querySelectorAll('.variant-option').forEach(opt => {
\t\topt.classList.remove('selected', 'active');
\t\tif (opt.classList.contains('variant-color-option')) {
\t\t\topt.style.borderColor = '#ddd';
\t\t\tconst checkIcon = opt.querySelector('.check-icon');
\t\t\tif (checkIcon) checkIcon.remove();
\t\t}
\t});
\t
\t// Réinitialiser les labels de sélection
\tdocument.querySelectorAll('.selected-variant-value').forEach(span => {
\t\tspan.textContent = '';
\t});
\t
\t// Réinitialiser les images au produit de base
\tconst mainImage = document.getElementById('main-product-image');
\tif (mainImage && typeof productImages !== 'undefined' && productImages.length > 0) {
\t\tmainImage.src = productImages[0];
\t}
\t
\t// Réinitialiser la quantité maximale
\tconst qtyInput = document.getElementById('sst');
\tif (qtyInput) {
\t\tqtyInput.max = ";
// line 2222
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 2222), "html", null, true);
yield ";
\t}
}
</script>
\t";
// line 2228
if ((Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["youMightAlsoLike"] ?? null)) > 0)) {
// line 2229
yield "\t\t<section class=\"related-product-area section_gap_bottom py-5\" style=\"background: linear-gradient(to bottom, #f8f9fa 0%, #ffffff 100%);\">
\t\t\t<div class=\"container\">
\t\t\t\t<div class=\"row justify-content-center\">
\t\t\t\t\t<div class=\"col-lg-8 text-center\">
\t\t\t\t\t\t<div class=\"section-title\">
\t\t\t\t\t\t\t<h2 class=\"fw-bold mb-3\" style=\"font-size: 2.5rem; color: #2c3e50;\">Vous pourriez aussi aimer</h2>
\t\t\t\t\t\t\t<p class=\"text-muted\" style=\"font-size: 1.1rem;\">Produits sélectionnés pour vous en fonction de vos préférences</p>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"row g-4\">
\t\t\t\t\t";
// line 2240
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(($context["youMightAlsoLike"] ?? null));
foreach ($context['_seq'] as $context["_key"] => $context["relatedProduct"]) {
// line 2241
yield "\t\t\t\t\t\t<div class=\"col-6 col-md-4 col-lg-3 mb-3\">
\t\t\t\t\t\t\t<div class=\"modern-product-card\">
\t\t\t\t\t\t\t\t<div class=\"product-image-wrapper\">
\t\t\t\t\t\t\t\t\t<a href=\"";
// line 2244
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_product_show", ["slug" => CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "slug", [], "any", false, false, false, 2244)]), "html", null, true);
yield "\" class=\"product-image-link\">
\t\t\t\t\t\t\t\t\t\t";
// line 2245
if ((CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "images", [], "any", true, true, false, 2245) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "images", [], "any", false, false, false, 2245)) > 0))) {
// line 2246
yield "\t\t\t\t\t\t\t\t\t\t\t<img src=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl((($_v4 = CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "images", [], "any", false, false, false, 2246)) && is_array($_v4) || $_v4 instanceof ArrayAccess ? ($_v4[0] ?? null) : null)), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "name", [], "any", false, false, false, 2246), "html", null, true);
yield "\" class=\"product-image\">
\t\t\t\t\t\t\t\t\t\t";
} else {
// line 2248
yield "\t\t\t\t\t\t\t\t\t\t\t<img src=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("ui/img/product/p1.jpg"), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "name", [], "any", false, false, false, 2248), "html", null, true);
yield "\" class=\"product-image\">
\t\t\t\t\t\t\t\t\t\t";
}
// line 2250
yield "\t\t\t\t\t\t\t\t\t\t<div class=\"product-overlay\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"view-product-btn\">
\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"ti ti-eye\"></i> Voir
\t\t\t\t\t\t\t\t\t\t\t</span>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t\t<div class=\"product-badge\">
\t\t\t\t\t\t\t\t\t\t";
// line 2257
if ((CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2257) && (CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2257) > CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "price", [], "any", false, false, false, 2257)))) {
// line 2258
yield "\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge-discount\">
\t\t\t\t\t\t\t\t\t\t\t\t-";
// line 2259
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::round((((CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2259) - CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "price", [], "any", false, false, false, 2259)) / CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2259)) * 100)), "html", null, true);
yield "%
\t\t\t\t\t\t\t\t\t\t\t</span>
\t\t\t\t\t\t\t\t\t\t";
}
// line 2262
yield "\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"product-info\">
\t\t\t\t\t\t\t\t\t<h6 class=\"product-title\">
\t\t\t\t\t\t\t\t\t\t<a href=\"";
// line 2266
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_product_show", ["slug" => CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "slug", [], "any", false, false, false, 2266)]), "html", null, true);
yield "\">";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "name", [], "any", false, false, false, 2266), "html", null, true);
yield "</a>
\t\t\t\t\t\t\t\t\t</h6>
\t\t\t\t\t\t\t\t\t";
// line 2268
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "shop", [], "any", false, false, false, 2268)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 2269
yield "\t\t\t\t\t\t\t\t\t\t<div class=\"product-shop\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"ti ti-store\"></i>
\t\t\t\t\t\t\t\t\t\t\t<a href=\"";
// line 2271
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_shop_show", ["slug" => CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "shop", [], "any", false, false, false, 2271), "slug", [], "any", false, false, false, 2271)]), "html", null, true);
yield "\" class=\"shop-link\">";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "shop", [], "any", false, false, false, 2271), "name", [], "any", false, false, false, 2271), "html", null, true);
yield "</a>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t";
}
// line 2274
yield "\t\t\t\t\t\t\t\t\t<div class=\"product-price-wrapper\">
\t\t\t\t\t\t\t\t\t\t<span class=\"product-price\">";
// line 2275
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "price", [], "any", false, false, false, 2275), 0, ".", " "), "html", null, true);
yield " HTG</span>
\t\t\t\t\t\t\t\t\t\t";
// line 2276
if ((CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2276) && (CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2276) > CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "price", [], "any", false, false, false, 2276)))) {
// line 2277
yield "\t\t\t\t\t\t\t\t\t\t\t<span class=\"product-compare-price\">";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "compareAtPrice", [], "any", false, false, false, 2277), 0, ".", " "), "html", null, true);
yield " HTG</span>
\t\t\t\t\t\t\t\t\t\t";
}
// line 2279
yield "\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"product-actions\">
\t\t\t\t\t\t\t\t\t\t<a href=\"javascript:void(0)\" class=\"btn-add-to-cart\" data-product-id=\"";
// line 2281
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["relatedProduct"], "id", [], "any", false, false, false, 2281), "html", null, true);
yield "\" data-qty=\"1\" title=\"Ajouter au panier\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"ti ti-shopping-cart\"></i>
\t\t\t\t\t\t\t\t\t\t\t<span>Ajouter</span>
\t\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t";
}
$_parent = $context['_parent'];
unset($context['_seq'], $context['_key'], $context['relatedProduct'], $context['_parent']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 2290
yield "\t\t\t\t</div>
\t\t\t</div>
\t\t</section>
\t\t<style>
\t\t\t.modern-product-card {
\t\t\t\tbackground: #ffffff;
\t\t\t\tborder-radius: 16px;
\t\t\t\toverflow: hidden;
\t\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
\t\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\t\theight: 100%;
\t\t\t\tdisplay: flex;
\t\t\t\tflex-direction: column;
\t\t\t\tposition: relative;
\t\t\t}
\t\t\t.modern-product-card:hover {
\t\t\t\ttransform: translateY(-8px);
\t\t\t\tbox-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
\t\t\t}
\t\t\t.product-image-wrapper {
\t\t\t\tposition: relative;
\t\t\t\twidth: 100%;
\t\t\t\theight: 250px;
\t\t\t\toverflow: hidden;
\t\t\t\tbackground: #f8f9fa;
\t\t\t}
\t\t\t.product-image {
\t\t\t\twidth: 100%;
\t\t\t\theight: 100%;
\t\t\t\tobject-fit: cover !important;
\t\t\t\tobject-position: center !important;
\t\t\t\ttransition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\t}
\t\t\t.modern-product-card:hover .product-image {
\t\t\t\ttransform: scale(1.1);
\t\t\t}
\t\t\t.product-overlay {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 0;
\t\t\t\tleft: 0;
\t\t\t\tright: 0;
\t\t\t\tbottom: 0;
\t\t\t\tbackground: rgba(0, 0, 0, 0.5);
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\topacity: 0;
\t\t\t\ttransition: opacity 0.3s ease;
\t\t\t}
\t\t\t.modern-product-card:hover .product-overlay {
\t\t\t\topacity: 1;
\t\t\t}
\t\t\t.view-product-btn {
\t\t\t\tcolor: white;
\t\t\t\tpadding: 12px 24px;
\t\t\t\tbackground: rgba(255, 255, 255, 0.2);
\t\t\t\tbackdrop-filter: blur(10px);
\t\t\t\tborder-radius: 8px;
\t\t\t\tfont-weight: 600;
\t\t\t\tdisplay: inline-flex;
\t\t\t\talign-items: center;
\t\t\t\tgap: 8px;
\t\t\t\ttransition: all 0.3s ease;
\t\t\t}
\t\t\t.view-product-btn:hover {
\t\t\t\tbackground: rgba(255, 255, 255, 0.3);
\t\t\t\ttransform: scale(1.05);
\t\t\t}
\t\t\t.product-badge {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 12px;
\t\t\t\tright: 12px;
\t\t\t\tz-index: 2;
\t\t\t}
\t\t\t.badge-discount {
\t\t\t\tbackground: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
\t\t\t\tcolor: white;
\t\t\t\tpadding: 6px 12px;
\t\t\t\tborder-radius: 20px;
\t\t\t\tfont-size: 0.75rem;
\t\t\t\tfont-weight: 700;
\t\t\t\tbox-shadow: 0 2px 8px rgba(238, 90, 111, 0.4);
\t\t\t}
\t\t\t.product-info {
\t\t\t\tpadding: 20px;
\t\t\t\tflex-grow: 1;
\t\t\t\tdisplay: flex;
\t\t\t\tflex-direction: column;
\t\t\t}
\t\t\t.product-title {
\t\t\t\tmargin: 0 0 8px 0;
\t\t\t\tfont-size: 1rem;
\t\t\t\tfont-weight: 600;
\t\t\t\tline-height: 1.4;
\t\t\t\theight: 2.8em;
\t\t\t\toverflow: hidden;
\t\t\t\tdisplay: -webkit-box;
\t\t\t\t-webkit-line-clamp: 2;
\t\t\t\t-webkit-box-orient: vertical;
\t\t\t}
\t\t\t.product-title a {
\t\t\t\tcolor: #2c3e50;
\t\t\t\ttext-decoration: none;
\t\t\t\ttransition: color 0.3s ease;
\t\t\t}
\t\t\t.product-title a:hover {
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.product-shop {
\t\t\t\tfont-size: 0.85rem;
\t\t\t\tcolor: #6c757d;
\t\t\t\tmargin-bottom: 12px;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tgap: 6px;
\t\t\t}
\t\t\t.product-shop i {
\t\t\t\tfont-size: 0.9rem;
\t\t\t}
\t\t\t.shop-link {
\t\t\t\tcolor: #6c757d;
\t\t\t\ttext-decoration: none;
\t\t\t\ttransition: color 0.3s ease;
\t\t\t}
\t\t\t.shop-link:hover {
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.product-price-wrapper {
\t\t\t\tmargin-bottom: 16px;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tgap: 8px;
\t\t\t\tflex-wrap: wrap;
\t\t\t}
\t\t\t.product-price {
\t\t\t\tfont-size: 1.25rem;
\t\t\t\tfont-weight: 700;
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.product-compare-price {
\t\t\t\tfont-size: 0.9rem;
\t\t\t\tcolor: #adb5bd;
\t\t\t\ttext-decoration: line-through;
\t\t\t}
\t\t\t.product-actions {
\t\t\t\tmargin-top: auto;
\t\t\t}
\t\t\t/* Styles pour les boutons de la section \"Vous pourriez aussi aimer\" uniquement */
\t\t\t.modern-product-card .btn-add-to-cart {
\t\t\t\twidth: 100%;
\t\t\t\tpadding: 12px;
\t\t\t\tbackground: linear-gradient(135deg, #ffa200 0%, #e8910a 100%);
\t\t\t\tcolor: white;
\t\t\t\tborder: none;
\t\t\t\tborder-radius: 10px;
\t\t\t\tfont-weight: 600;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\tgap: 8px;
\t\t\t\ttext-decoration: none;
\t\t\t\ttransition: all 0.3s ease;
\t\t\t\tcursor: pointer;
\t\t\t}
\t\t\t.modern-product-card .btn-add-to-cart:hover {
\t\t\t\tbackground: linear-gradient(135deg, #e8910a 0%, #d6820a 100%);
\t\t\t\ttransform: translateY(-2px);
\t\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.4);
\t\t\t\tcolor: white;
\t\t\t}
\t\t\t/* Le bouton principal garde son design original */
\t\t\t.card_area .btn-add-to-cart {
\t\t\t\twidth: auto;
\t\t\t\tdisplay: inline-flex;
\t\t\t}
\t\t\t.modern-product-card .btn-add-to-cart:active {
\t\t\t\ttransform: translateY(0);
\t\t\t}
\t\t\t.modern-product-card .btn-add-to-cart i {
\t\t\t\tfont-size: 1.1rem;
\t\t\t}
\t\t\t/* Responsive adjustments */
\t\t\t@media (max-width: 768px) {
\t\t\t\t.product-image-wrapper {
\t\t\t\t\theight: 200px;
\t\t\t\t}
\t\t\t\t.product-info {
\t\t\t\t\tpadding: 16px;
\t\t\t\t}
\t\t\t\t.product-title {
\t\t\t\t\tfont-size: 0.95rem;
\t\t\t\t}
\t\t\t\t.product-price {
\t\t\t\t\tfont-size: 1.1rem;
\t\t\t\t}
\t\t\t\t.section-title h2 {
\t\t\t\t\tfont-size: 2rem !important;
\t\t\t\t}
\t\t\t}
\t\t\t@media (max-width: 576px) {
\t\t\t\t.product-image-wrapper {
\t\t\t\t\theight: 190px;
\t\t\t\t}
\t\t\t\t.product-info {
\t\t\t\t\tpadding: 14px;
\t\t\t\t}
\t\t\t\t.btn-add-to-cart {
\t\t\t\t\tpadding: 10px;
\t\t\t\t\tfont-size: 0.9rem;
\t\t\t\t}
\t\t\t}
\t\t\t/* Ensure fixed height for cards */
\t\t\t.col-6.col-md-4.col-lg-3 {
\t\t\t\tdisplay: flex;
\t\t\t}
\t\t\t.modern-product-card {
\t\t\t\twidth: 100%;
\t\t\t}
\t\t\t/* Loading state for add to cart button */
\t\t\t.btn-add-to-cart.loading {
\t\t\t\topacity: 0.7;
\t\t\t\tpointer-events: none;
\t\t\t}
\t\t\t.btn-add-to-cart.loading i {
\t\t\t\tanimation: spin 1s linear infinite;
\t\t\t}
\t\t\t@keyframes spin {
\t\t\t\tfrom { transform: rotate(0deg); }
\t\t\t\tto { transform: rotate(360deg); }
\t\t\t}
\t\t\t/* Success state - vert pour tous les boutons */
\t\t\t.btn-add-to-cart.success {
\t\t\t\tbackground: linear-gradient(135deg, #28a745 0%, #20c997 100%) !important;
\t\t\t}
\t\t\t/* Le bouton principal garde son style original même en success */
\t\t\t.card_area .btn-add-to-cart.success {
\t\t\t\tbackground: linear-gradient(135deg, #28a745 0%, #20c997 100%) !important;
\t\t\t}
\t";
}
// line 2574
yield "
\t<script src=\"/ui/js/vendor/jquery-2.2.4.min.js\"></script>
\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js\" integrity=\"sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4\" crossorigin=\"anonymous\"></script>
\t<script src=\"/ui/js/vendor/bootstrap.min.js\"></script>
\t<script src=\"/ui/js/jquery.ajaxchimp.min.js\"></script>
\t<script src=\"/ui/js/jquery.nice-select.min.js\"></script>
\t<script src=\"/ui/js/jquery.sticky.js\"></script>
\t<script src=\"/ui/js/nouislider.min.js\"></script>
\t<script src=\"/ui/js/jquery.magnific-popup.min.js\"></script>
\t<script src=\"/ui/js/owl.carousel.min.js\"></script>
\t<!--gmaps Js-->
\t<script src=\"https://maps.googleapis.com/maps/api/js?key=AIzaSyCjCGmQ0Uq4exrzdcL6rvxywDDOvfAu6eE\"></script>
\t<script src=\"/ui/js/gmaps.min.js\"></script>
\t<script src=\"/ui/js/main.js\"></script>
\t
\t<!-- Product Image Navigation - Chargé en dernier pour éviter les conflits -->
\t<script src=\"/ui/js/product-image-navigation.js\"></script>
\t
\t<script>
// Variables globales pour la navigation des images (utilisées par le script externe)
window.productImages = [];
window.currentImageIndex = 0;
let mainImageElement, currentIndexElement, indicatorsElements;
// Test pour vérifier que les fonctions sont définies
window.testImageNavigation = function() {
console.log('Testing image navigation functions...');
if (window.productImageNav) {
console.log('productImageNav object:', window.productImageNav);
console.log('nextImage function:', typeof window.productImageNav.nextImage);
console.log('prevImage function:', typeof window.productImageNav.prevImage);
console.log('changeMainImageByIndex function:', typeof window.productImageNav.changeMainImageByIndex);
console.log('State:', window.productImageNav.getState());
} else {
console.warn('productImageNav not available');
}
};
// Fonction pour nettoyer le cache PWA et désenregistrer le Service Worker
window.clearPWACache = function() {
console.log('🧹 Nettoyage du cache PWA...');
// Désenregistrer tous les Service Workers
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
console.log('Désenregistrement du Service Worker:', registration.scope);
registration.unregister().then(function(boolean) {
console.log('Service Worker désenregistré:', boolean);
});
}
});
}
// Vider tous les caches
if ('caches' in window) {
caches.keys().then(function(names) {
for (let name of names) {
console.log('Suppression du cache:', name);
caches.delete(name);
}
});
}
// Forcer le rechargement de la page après nettoyage
setTimeout(function() {
console.log('🔄 Rechargement de la page...');
window.location.reload(true);
}, 1000);
};
console.log('💡 Pour nettoyer le cache PWA, tapez: clearPWACache() dans la console');
// Fonction pour vérifier l'état du cache PWA
window.checkPWACache = function() {
console.log('🔍 Vérification de l\\'état PWA...');
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then(function(registrations) {
console.log('Service Workers enregistrés:', registrations.length);
registrations.forEach(function(registration, index) {
console.log(`SW \${index + 1}:`, registration.scope, registration.active ? 'ACTIF' : 'INACTIF');
});
});
} else {
console.log('Service Worker non supporté');
}
if ('caches' in window) {
caches.keys().then(function(names) {
console.log('Caches disponibles:', names.length);
names.forEach(function(name) {
console.log('- Cache:', name);
});
});
} else {
console.log('Cache API non supporté');
}
};
console.log('💡 Pour vérifier l\\'état PWA, tapez: checkPWACache() dans la console');
// Nettoyage automatique du cache PWA pour les tests (à supprimer en production)
if (window.location.search.includes('clearcache')) {
console.log('🧹 Nettoyage automatique du cache PWA demandé via URL');
clearPWACache();
}
// NOTE: La navigation des images principales est gérée par product-image-navigation.js
// Les fonctions sont exposées via window.productImageNav pour le débogage
// NOTE: La navigation des images principales est gérée par product-image-navigation.js
// Le script externe initialise automatiquement les images depuis les thumbnails
// Pas besoin de réinitialiser ici pour éviter les conflits
// Gestion du carrousel de miniatures avec taille fixe carrée
const navUpBtn = document.getElementById('thumbnail-nav-up');
const navDownBtn = document.getElementById('thumbnail-nav-down');
const thumbnailsContainer = document.getElementById('product-thumbnails');
const thumbnailsWrapper = document.getElementById('thumbnails-wrapper');
const thumbnailItems = Array.from(document.querySelectorAll('.thumbnail-item'));
let currentThumbnailOffset = 0;
const thumbnailHeight = 90;
// 80px (hauteur) + 10px (gap)
// Calculer la hauteur disponible pour les miniatures dynamiquement
const thumbnailsEl = document.getElementById('product-thumbnails');
let containerHeight = thumbnailsEl ? thumbnailsEl.clientHeight : 520; // Hauteur par défaut si non disponible
let visibleThumbnails = Math.floor(containerHeight / thumbnailHeight);
// Recalculer après le chargement pour avoir la vraie hauteur
setTimeout(() => {
if (thumbnailsEl) {
containerHeight = thumbnailsEl.clientHeight;
visibleThumbnails = Math.floor(containerHeight / thumbnailHeight);
updateThumbnailsPosition();
}
}, 100);
function getCurrentIndex() {
const current = document.querySelector('.thumbnail-item.permanently-active') || document.querySelector('.thumbnail-item.active');
if (! current)
return 0;
const idxAttr = current.getAttribute('data-index');
if (idxAttr !== null) {
return parseInt(idxAttr, 10);
}
const index = thumbnailItems.indexOf(current);
return index >= 0 ? index : 0;
}
function selectThumbnailByIndex(newIndex) {
if (! thumbnailItems.length)
return;
const total = thumbnailItems.length;
if (newIndex < 0)
newIndex = 0;
if (newIndex > total - 1)
newIndex = total - 1;
// Reset classes
thumbnailItems.forEach(t => t.classList.remove('active', 'permanently-active'));
const target = thumbnailItems[newIndex];
if (! target)
return;
target.classList.add('active', 'permanently-active');
// Utiliser la fonction du script externe si disponible
if (window.productImageNav && typeof window.productImageNav.changeMainImageByIndex === 'function') {
window.productImageNav.changeMainImageByIndex(newIndex);
} else {
// Fallback : changer l'image directement
const imageUrl = target.getAttribute('data-image');
const mainImg = document.getElementById('main-product-image');
if (mainImg && imageUrl) {
mainImg.src = imageUrl;
}
}
// Ajuster le carrousel pour voir la miniature sélectionnée
ensureThumbnailVisible(newIndex);
}
function ensureThumbnailVisible(index) {
if (! thumbnailsWrapper || ! thumbnailItems.length)
return;
const targetTop = index * thumbnailHeight;
const visibleTop = currentThumbnailOffset * thumbnailHeight;
const visibleBottom = visibleTop + containerHeight;
// Si la miniature est au-dessus de la zone visible
if (targetTop < visibleTop) {
currentThumbnailOffset = index;
updateThumbnailsPosition();
}
// Si la miniature est en-dessous de la zone visible else if (targetTop + thumbnailHeight > visibleBottom) {
currentThumbnailOffset = Math.max(0, index - visibleThumbnails + 1);
updateThumbnailsPosition();
}
}
function updateThumbnailsPosition() {
if (!thumbnailsWrapper)
return;
const maxOffset = Math.max(0, thumbnailItems.length - visibleThumbnails);
currentThumbnailOffset = Math.max(0, Math.min(currentThumbnailOffset, maxOffset));
thumbnailsWrapper.style.transform = `translateY(-\${
currentThumbnailOffset * thumbnailHeight
}px)`;
updateNavButtons();
}
function updateNavButtons() {
if (!thumbnailItems.length)
return;
const maxOffset = Math.max(0, thumbnailItems.length - visibleThumbnails);
const canScrollUp = currentThumbnailOffset > 0;
const canScrollDown = currentThumbnailOffset < maxOffset;
if (navUpBtn) {
navUpBtn.classList.toggle('disabled', ! canScrollUp);
}
if (navDownBtn) {
navDownBtn.classList.toggle('disabled', ! canScrollDown);
}
}
// Navigation avec les boutons
if(navUpBtn) {
navUpBtn.addEventListener('click', function (e) {
e.preventDefault();
if (currentThumbnailOffset > 0) {
currentThumbnailOffset --;
updateThumbnailsPosition();
}
});
}
if(navDownBtn) {
navDownBtn.addEventListener('click', function (e) {
e.preventDefault();
const maxOffset = Math.max(0, thumbnailItems.length - visibleThumbnails);
if (currentThumbnailOffset < maxOffset) {
currentThumbnailOffset ++;
updateThumbnailsPosition();
}
});
}
// Initialiser le carrousel
if(thumbnailsWrapper && thumbnailItems.length > 0) {
updateThumbnailsPosition();
// S'assurer que la première miniature est visible
ensureThumbnailVisible(0);
// Sélectionner la première image par défaut si aucune n'est sélectionnée
if (!document.querySelector('.thumbnail-item.permanently-active') && !document.querySelector('.thumbnail-item.active')) {
selectThumbnailByIndex(0);
}
// Initialiser l'index actuel via le script externe si disponible
// Le script externe product-image-navigation.js gère déjà l'initialisation
if (window.productImageNav && typeof window.productImageNav.getState === 'function') {
const state = window.productImageNav.getState();
if (state.productImages && state.productImages.length > 0) {
window.productImageNav.changeMainImageByIndex(0);
}
}
}
// NOTE: La navigation des images principales est maintenant gérée par product-image-navigation.js
// Ce fichier externe évite les conflits avec cart-modal.js et autres scripts
}, 100); // Fin du setTimeout
}); // Fin du DOMContentLoaded
// --- Prix de gros : calcul du prix unitaire dynamique ---
(function () {
const bulk = document.getElementById('bulk-pricing');
const qtyInputEl = document.getElementById('sst');
const unitPriceSpan = document.getElementById('unit-price-value');
const mainUnitPriceSpan = document.getElementById('main-unit-price');
const totalPriceSpan = document.getElementById('total-price-value');
const savingsAmountSpan = document.getElementById('savings-amount');
const savingsPercentSpan = document.getElementById('savings-percent');
const unitPriceInput = document.getElementById('unit-price-input');
const tierRowsTbody = document.getElementById('bulk-tier-rows');
if (! bulk || ! qtyInputEl || ! unitPriceSpan || ! mainUnitPriceSpan || ! unitPriceInput)
return;
let tiers = [];
try {
tiers = JSON.parse(bulk.getAttribute('data-tiers') || '[]');
} catch (e) {
tiers = [];
}
if (!Array.isArray(tiers) || tiers.length === 0)
return;
tiers.sort(function (a, b) {
return(a.min || 0) - (b.min || 0);
});
const basePrice = (function () {
const one = tiers.find(t => (t.min || 0) <= 1);
return one ? parseFloat(one.price) : parseFloat(tiers[0].price);
})();
function getUnitPriceForQty(qty) {
let candidate = tiers[0] || null;
for (let i = 0; i < tiers.length; i++) {
if (qty >= (tiers[i].min || 1)) {
candidate = tiers[i];
}
}
return candidate ? parseFloat(candidate.price) : (tiers[0] ? parseFloat(tiers[0].price) : basePrice);
}
function formatPrice(val) {
return(parseFloat(val) || 0).toFixed(2);
}
function highlightActiveTier(qty) {
if (! tierRowsTbody)
return;
const rows = tierRowsTbody.querySelectorAll('tr');
rows.forEach(r => r.classList.remove('table-warning'));
let activeRow = null;
rows.forEach(r => {
const m = parseInt(r.getAttribute('data-min'), 10) || 1;
if (qty >= m)
activeRow = r;
});
if (activeRow)
activeRow.classList.add('table-warning');
}
function refreshPrices() {
const qty = Math.max(1, parseInt(qtyInputEl.value, 10) || 1);
const unit = getUnitPriceForQty(qty);
const total = unit * qty;
const saveAmount = Math.max(0, (basePrice - unit) * qty);
const savePercent = Math.max(0, 100 * (basePrice - unit) / basePrice);
unitPriceSpan.textContent = formatPrice(unit) + ' HTG';
mainUnitPriceSpan.textContent = formatPrice(unit);
if (totalPriceSpan)
totalPriceSpan.textContent = formatPrice(total);
if (savingsAmountSpan)
savingsAmountSpan.textContent = formatPrice(saveAmount);
if (savingsPercentSpan)
savingsPercentSpan.textContent = Math.round(savePercent);
unitPriceInput.value = formatPrice(unit);
highlightActiveTier(qty);
}
qtyInputEl.addEventListener('input', refreshPrices);
qtyInputEl.addEventListener('change', refreshPrices);
setTimeout(refreshPrices, 50);
setInterval(refreshPrices, 350);
})();
// --- /Prix de gros ---
// Améliorer les boutons de quantité avec gestion de l'état disabled
(function() {
const qtyInput = document.getElementById('sst');
const decreaseBtn = document.querySelector('.quantity-btn-decrease');
const increaseBtn = document.querySelector('.quantity-btn-increase');
if (!qtyInput || !decreaseBtn || !increaseBtn) return;
const maxStock = parseInt(qtyInput.getAttribute('max') || '99', 10);
function updateButtonStates() {
const currentValue = parseInt(qtyInput.value, 10) || 1;
// Désactiver le bouton decrease si la valeur est 1
if (currentValue <= 1) {
decreaseBtn.disabled = true;
} else {
decreaseBtn.disabled = false;
}
// Désactiver le bouton increase si la valeur est au maximum
if (currentValue >= maxStock) {
increaseBtn.disabled = true;
} else {
increaseBtn.disabled = false;
}
}
// Mettre à jour l'état des boutons au chargement
updateButtonStates();
// Mettre à jour l'état des boutons lors des changements
qtyInput.addEventListener('input', updateButtonStates);
qtyInput.addEventListener('change', updateButtonStates);
// Mettre à jour l'état après les clics sur les boutons
decreaseBtn.addEventListener('click', function() {
setTimeout(updateButtonStates, 10);
});
increaseBtn.addEventListener('click', function() {
setTimeout(updateButtonStates, 10);
});
})();
// Injection du prix unitaire dans l'ajout au panier
(function () {
const addToCartBtn = document.getElementById('add-to-cart-btn');
if (! addToCartBtn)
return;
addToCartBtn.addEventListener('click', function () {
const unitPriceInput = document.getElementById('unit-price-input');
if (unitPriceInput) {
addToCartBtn.setAttribute('data-unit-price', unitPriceInput.value);
}
});
})();
// Fonction pour ouvrir le modal de zoom avec loader
function openImageZoom () {
const mainImage = document.getElementById('main-product-image');
const zoomModal = document.getElementById('image-zoom-modal');
const zoomImage = document.getElementById('zoom-modal-image');
const zoomLoader = document.getElementById('zoom-loader');
if (mainImage && zoomModal && zoomImage) { // Afficher le loader
if (zoomLoader) {
zoomLoader.style.display = 'flex';
}
// Masquer l'image et réinitialiser
zoomImage.classList.remove('loaded');
zoomImage.style.opacity = '0';
// Ouvrir le modal avec animation
zoomModal.classList.add('active');
document.body.style.overflow = 'hidden';
// Charger l'image
const imageUrl = mainImage.src;
const tempImage = new Image();
tempImage.onload = function () {
zoomImage.src = imageUrl;
// Masquer le loader et afficher l'image avec transition
setTimeout(function () {
if (zoomLoader) {
zoomLoader.style.display = 'none';
}
zoomImage.classList.add('loaded');
zoomImage.style.opacity = '1';
}, 200);
};
tempImage.onerror = function () {
if (zoomLoader) {
zoomLoader.style.display = 'none';
}
zoomImage.src = imageUrl;
zoomImage.classList.add('loaded');
};
tempImage.src = imageUrl;
}
}
// Fonction pour fermer le modal de zoom avec animation
function closeImageZoom () {
const zoomModal = document.getElementById('image-zoom-modal');
const zoomImage = document.getElementById('zoom-modal-image');
const zoomLoader = document.getElementById('zoom-loader');
if (zoomModal) { // Animation de fermeture
if (zoomImage) {
zoomImage.style.opacity = '0';
zoomImage.classList.remove('loaded');
}
setTimeout(function () {
zoomModal.classList.remove('active');
document.body.style.overflow = 'auto';
// Réinitialiser le loader pour la prochaine ouverture
if (zoomLoader) {
zoomLoader.style.display = 'none';
}
}, 200);
}
}
// Fermer le modal en cliquant en dehors
document.addEventListener('DOMContentLoaded', function () {
const zoomModal = document.getElementById('image-zoom-modal');
if (zoomModal) {
zoomModal.addEventListener('click', function (e) {
if (e.target === zoomModal) {
closeImageZoom();
}
});
}
});
\t</script>
\t<!-- Modal de zoom d'image -->
\t<div id=\"image-zoom-modal\" class=\"image-zoom-modal\">
\t\t<span class=\"close-zoom\" onclick=\"closeImageZoom()\" title=\"Fermer\">×</span>
\t\t<div
\t\t\tclass=\"zoom-modal-content\">
\t\t\t<!-- Loader -->
\t\t\t<div class=\"zoom-loader\" id=\"zoom-loader\" style=\"display: none;\">
\t\t\t\t<div class=\"zoom-loader-spinner\"></div>
\t\t\t\t<div class=\"zoom-loader-text\">Chargement...</div>
\t\t\t</div>
\t\t\t<!-- Image -->
\t\t\t<img id=\"zoom-modal-image\" src=\"\" alt=\"";
// line 3129
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 3129), "html", null, true);
yield "\">
\t\t</div>
\t</div>
\t";
// line 3133
if ((($tmp = ($context["dropshipReferral"] ?? null)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 3134
yield "\t\t<!-- Modal d'affiliation -->
\t\t<div id=\"dropship-modal\" class=\"dropship-referral-modal\" style=\"display: none;\">
\t\t\t<div class=\"dropship-modal-overlay\"></div>
\t\t\t<div class=\"dropship-modal-content\">
\t\t\t\t<button type=\"button\" class=\"dropship-modal-close\" onclick=\"closeDropshipModal()\" aria-label=\"Fermer\">
\t\t\t\t\t×
\t\t\t\t</button>
\t\t\t\t<div class=\"dropship-modal-header\">
\t\t\t\t\t<div class=\"dropship-icon\">
\t\t\t\t\t\t<i class=\"fas fa-gift\"></i>
\t\t\t\t\t</div>
\t\t\t\t\t<h3>Produit recommandé par
\t\t\t\t\t\t";
// line 3146
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["dropshipReferral"] ?? null), "affiliateName", [], "any", false, false, false, 3146), "html", null, true);
yield "</h3>
\t\t\t\t\t<p class=\"dropship-subtitle\">Vous avez été dirigé vers ce produit par un de nos partenaires</p>
\t\t\t\t</div>
\t\t\t\t<div class=\"dropship-modal-body\">
\t\t\t\t\t<div class=\"dropship-product-info\">
\t\t\t\t\t\t";
// line 3151
if ((Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 3151)) > 0)) {
// line 3152
yield "\t\t\t\t\t\t\t<img src=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl((($_v5 = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 3152)) && is_array($_v5) || $_v5 instanceof ArrayAccess ? ($_v5[0] ?? null) : null)), "html", null, true);
yield "\" alt=\"";
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 3152), "html", null, true);
yield "\" class=\"dropship-product-image\" onerror=\"this.style.display='none'; this.nextElementSibling.style.display='flex';\">
\t\t\t\t\t\t\t<div class=\"dropship-product-image-placeholder\" style=\"display: none; width: 100px; height: 100px; background: #f0f0f0; border-radius: 8px; align-items: center; justify-content: center; color: #999;\">
\t\t\t\t\t\t\t\t<i class=\"fas fa-image\" style=\"font-size: 32px;\"></i>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
} else {
// line 3157
yield "\t\t\t\t\t\t\t<div class=\"dropship-product-image-placeholder\" style=\"width: 100px; height: 100px; background: #f0f0f0; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #999;\">
\t\t\t\t\t\t\t\t<i class=\"fas fa-image\" style=\"font-size: 32px;\"></i>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
}
// line 3161
yield "\t\t\t\t\t\t<div class=\"dropship-product-details\">
\t\t\t\t\t\t\t<h4>";
// line 3162
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 3162), "html", null, true);
yield "</h4>
\t\t\t\t\t\t\t<div class=\"dropship-product-price\">
\t\t\t\t\t\t\t\t<span class=\"price\">";
// line 3164
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Twig\Extension\CoreExtension']->formatNumber(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "price", [], "any", false, false, false, 3164), 2, ",", " "), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\tHTG</span>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t\t<div class=\"dropship-message\">
\t\t\t\t\t\t<p>
\t\t\t\t\t\t\t<strong>";
// line 3171
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["dropshipReferral"] ?? null), "affiliateName", [], "any", false, false, false, 3171), "html", null, true);
yield "</strong>
\t\t\t\t\t\t\tvous recommande ce produit. Souhaitez-vous l'ajouter à votre panier ?</p>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"dropship-modal-footer\">
\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" onclick=\"closeDropshipModal()\">
\t\t\t\t\t\tParcourir d'abord
\t\t\t\t\t</button>
\t\t\t\t\t<button type=\"button\" class=\"btn btn-primary dropship-add-to-cart\" onclick=\"addToCartFromDropship()\">
\t\t\t\t\t\t<i class=\"fas fa-shopping-cart\"></i>
\t\t\t\t\t\tAjouter au panier
\t\t\t\t\t</button>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t\t<style>
\t\t\t.dropship-referral-modal {
\t\t\t\tposition: fixed;
\t\t\t\ttop: 0;
\t\t\t\tleft: 0;
\t\t\t\twidth: 100%;
\t\t\t\theight: 100%;
\t\t\t\tz-index: 10000;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t}
\t\t\t.dropship-modal-overlay {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 0;
\t\t\t\tleft: 0;
\t\t\t\twidth: 100%;
\t\t\t\theight: 100%;
\t\t\t\tbackground: rgba(0, 0, 0, 0.6);
\t\t\t\tbackdrop-filter: blur(4px);
\t\t\t}
\t\t\t.dropship-modal-content {
\t\t\t\tposition: relative;
\t\t\t\tbackground: white;
\t\t\t\tborder-radius: 16px;
\t\t\t\tbox-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
\t\t\t\tmax-width: 500px;
\t\t\t\twidth: 90%;
\t\t\t\tmax-height: 90vh;
\t\t\t\toverflow-y: auto;
\t\t\t\tz-index: 10001;
\t\t\t\tanimation: dropshipModalSlideIn 0.3s ease-out;
\t\t\t}
\t\t\t@keyframes dropshipModalSlideIn {
\t\t\t\tfrom {
\t\t\t\t\topacity: 0;
\t\t\t\t\ttransform: translateY(-30px) scale(0.95);
\t\t\t\t}
\t\t\t\tto {
\t\t\t\t\topacity: 1;
\t\t\t\t\ttransform: translateY(0) scale(1);
\t\t\t\t}
\t\t\t}
\t\t\t.dropship-modal-close {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 15px;
\t\t\t\tright: 15px;
\t\t\t\tbackground: none;
\t\t\t\tborder: none;
\t\t\t\tfont-size: 28px;
\t\t\t\tcolor: #666;
\t\t\t\tcursor: pointer;
\t\t\t\twidth: 35px;
\t\t\t\theight: 35px;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\tborder-radius: 50%;
\t\t\t\ttransition: all 0.2s;
\t\t\t\tz-index: 10;
\t\t\t}
\t\t\t.dropship-modal-close:hover {
\t\t\t\tbackground: #f0f0f0;
\t\t\t\tcolor: #333;
\t\t\t}
\t\t\t.dropship-modal-header {
\t\t\t\tpadding: 30px 30px 20px;
\t\t\t\ttext-align: center;
\t\t\t\tborder-bottom: 1px solid #f0f0f0;
\t\t\t}
\t\t\t.dropship-icon {
\t\t\t\twidth: 70px;
\t\t\t\theight: 70px;
\t\t\t\tmargin: 0 auto 15px;
\t\t\t\tbackground: linear-gradient(135deg, #ffa200 0%, #ff8c00 100%);
\t\t\t\tborder-radius: 50%;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\tfont-size: 32px;
\t\t\t\tcolor: white;
\t\t\t\tbox-shadow: 0 4px 15px rgba(255, 162, 0, 0.3);
\t\t\t}
\t\t\t.dropship-modal-header h3 {
\t\t\t\tmargin: 0 0 8px;
\t\t\t\tfont-size: 22px;
\t\t\t\tfont-weight: 600;
\t\t\t\tcolor: #333;
\t\t\t}
\t\t\t.dropship-subtitle {
\t\t\t\tmargin: 0;
\t\t\t\tcolor: #666;
\t\t\t\tfont-size: 14px;
\t\t\t}
\t\t\t.dropship-modal-body {
\t\t\t\tpadding: 25px 30px;
\t\t\t}
\t\t\t.dropship-product-info {
\t\t\t\tdisplay: flex;
\t\t\t\tgap: 15px;
\t\t\t\tmargin-bottom: 20px;
\t\t\t\tpadding: 15px;
\t\t\t\tbackground: #f8f9fa;
\t\t\t\tborder-radius: 10px;
\t\t\t}
\t\t\t.dropship-product-image {
\t\t\t\twidth: 80px;
\t\t\t\theight: 80px;
\t\t\t\tobject-fit: cover;
\t\t\t\tborder-radius: 8px;
\t\t\t\tflex-shrink: 0;
\t\t\t}
\t\t\t.dropship-product-details {
\t\t\t\tflex: 1;
\t\t\t}
\t\t\t.dropship-product-details h4 {
\t\t\t\tmargin: 0 0 8px;
\t\t\t\tfont-size: 16px;
\t\t\t\tfont-weight: 600;
\t\t\t\tcolor: #333;
\t\t\t}
\t\t\t.dropship-product-price {
\t\t\t\tmargin-top: 5px;
\t\t\t}
\t\t\t.dropship-product-price .price {
\t\t\t\tfont-size: 20px;
\t\t\t\tfont-weight: 700;
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.dropship-message {
\t\t\t\tpadding: 15px;
\t\t\t\tbackground: #fff9e6;
\t\t\t\tborder-left: 4px solid #ffa200;
\t\t\t\tborder-radius: 6px;
\t\t\t}
\t\t\t.dropship-message p {
\t\t\t\tmargin: 0;
\t\t\t\tcolor: #666;
\t\t\t\tline-height: 1.6;
\t\t\t}
\t\t\t.dropship-modal-footer {
\t\t\t\tpadding: 20px 30px 30px;
\t\t\t\tdisplay: flex;
\t\t\t\tgap: 12px;
\t\t\t\tjustify-content: flex-end;
\t\t\t\tborder-top: 1px solid #f0f0f0;
\t\t\t}
\t\t\t.dropship-modal-footer .btn {
\t\t\t\tpadding: 12px 24px;
\t\t\t\tborder-radius: 8px;
\t\t\t\tfont-weight: 500;
\t\t\t\tborder: none;
\t\t\t\tcursor: pointer;
\t\t\t\ttransition: all 0.2s;
\t\t\t\tfont-size: 15px;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-secondary {
\t\t\t\tbackground: #f0f0f0;
\t\t\t\tcolor: #666;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-secondary:hover {
\t\t\t\tbackground: #e0e0e0;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-primary {
\t\t\t\tbackground: #ffa200;
\t\t\t\tcolor: white;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-primary:hover {
\t\t\t\tbackground: #e8910a;
\t\t\t\ttransform: translateY(-2px);
\t\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.3);
\t\t\t}
\t\t\t.dropship-modal-footer .btn-primary:disabled {
\t\t\t\topacity: 0.6;
\t\t\t\tcursor: not-allowed;
\t\t\t\ttransform: none;
\t\t\t}
\t\t</style>
\t\t<script>
\t\t\t// Afficher le modal automatiquement au chargement de la page
document.addEventListener('DOMContentLoaded', function () {
const dropshipModal = document.getElementById('dropship-modal');
if (dropshipModal) {
setTimeout(function () {
dropshipModal.style.display = 'flex';
document.body.style.overflow = 'hidden';
}, 500); // Délai de 500ms pour une meilleure UX
}
});
function closeDropshipModal () {
const dropshipModal = document.getElementById('dropship-modal');
if (dropshipModal) {
dropshipModal.style.display = 'none';
document.body.style.overflow = 'auto';
}
}
function addToCartFromDropship () {
const addBtn = document.querySelector('.dropship-add-to-cart');
if (! addBtn)
return;
// Désactiver le bouton pendant le traitement
addBtn.disabled = true;
addBtn.innerHTML = '<i class=\"fas fa-spinner fa-spin\"></i> Ajout en cours...';
const productId = ";
// line 3422
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 3422), "html", null, true);
yield ";
const qty = parseInt(document.getElementById('sst') ?. value || '1');
// Utiliser fetch pour ajouter au panier
fetch('";
// line 3426
yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_cart_add");
yield "', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
},
body: new URLSearchParams(
{productId: productId, qty: qty}
)
}).then(response => response.json()).then(data => {
if (data.ok) { // Afficher un message de succès
const modalBody = document.querySelector('.dropship-modal-body');
if (modalBody) {
modalBody.innerHTML = `
\t\t\t\t\t\t\t\t<div style=\"text-align: center; padding: 30px 20px;\">
\t\t\t\t\t\t\t\t\t<div style=\"width: 80px; height: 80px; margin: 0 auto 20px; background: #d4edda; border-radius: 50%; display: flex; align-items: center; justify-content: center;\">
\t\t\t\t\t\t\t\t\t\t<i class=\"fas fa-check\" style=\"font-size: 40px; color: #28a745;\"></i>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<h3 style=\"color: #28a745; margin-bottom: 10px;\">Produit ajouté avec succès !</h3>
\t\t\t\t\t\t\t\t\t<p style=\"color: #666; margin-bottom: 20px;\">Merci d'avoir utilisé le lien de recommandation de <strong>";
// line 3445
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["dropshipReferral"] ?? null), "affiliateName", [], "any", false, false, false, 3445), "html", null, true);
yield "</strong></p>
\t\t\t\t\t\t\t\t\t<p style=\"color: #666; font-size: 14px;\">Vous pouvez continuer vos achats ou aller directement au panier.</p>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t`;
}
const modalFooter = document.querySelector('.dropship-modal-footer');
if (modalFooter) {
modalFooter.innerHTML = `
\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" onclick=\"closeDropshipModal()\">
\t\t\t\t\t\t\t\t\tContinuer les achats
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t<a href=\"";
// line 3457
yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("cart");
yield "\" class=\"btn btn-primary\" style=\"text-decoration: none; display: inline-block;\">
\t\t\t\t\t\t\t\t\t<i class=\"fas fa-shopping-cart\"></i> Voir le panier
\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t`;
}
// Mettre à jour le compteur du panier si présent
const cartCount = document.querySelector('.cart-count, .cart_count, [data-cart-count]');
if (cartCount) {
cartCount.textContent = data.totalQty || 0;
}
} else {
showCustomAlert('Erreur lors de l\\'ajout au panier. Veuillez réessayer.', 'error');
addBtn.disabled = false;
addBtn.innerHTML = '<i class=\"fas fa-shopping-cart\"></i> Ajouter au panier';
}
}).catch(error => {
console.error('Erreur:', error);
showCustomAlert('Une erreur est survenue. Veuillez réessayer.', 'error');
addBtn.disabled = false;
addBtn.innerHTML = '<i class=\"fas fa-shopping-cart\"></i> Ajouter au panier';
});
}
// Fermer le modal en cliquant sur l'overlay
document.addEventListener('DOMContentLoaded', function () {
const dropshipModal = document.getElementById('dropship-modal');
if (dropshipModal) {
const overlay = dropshipModal.querySelector('.dropship-modal-overlay');
if (overlay) {
overlay.addEventListener('click', function () {
closeDropshipModal();
});
}
}
});
\t\t</script>
\t";
}
// line 3495
yield "
\t<!-- Modal personnalisé pour remplacer les alert -->
\t<div class=\"modal fade custom-alert-modal\" id=\"customAlertModal\" tabindex=\"-1\" aria-labelledby=\"customAlertModalLabel\" aria-hidden=\"true\">
\t\t<div class=\"modal-dialog modal-dialog-centered\">
\t\t\t<div class=\"modal-content\">
\t\t\t\t<div class=\"modal-header\">
\t\t\t\t\t<h5 class=\"modal-title text-white\" id=\"customAlertModalLabel\">Notification</h5>
\t\t\t\t\t<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>
\t\t\t\t</div>
\t\t\t\t<div class=\"modal-body\">
\t\t\t\t\t<div class=\"alert-icon\" id=\"alertIcon\">
\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t</div>
\t\t\t\t\t<p class=\"alert-message\" id=\"alertMessage\"></p>
\t\t\t\t</div>
\t\t\t\t<div class=\"modal-footer\">
\t\t\t\t\t<button type=\"button\" class=\"btn btn-primary\" data-bs-dismiss=\"modal\">OK</button>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</div>
\t<script>
\t\t// Fonction pour remplacer alert()
function showCustomAlert (message, type = 'info') {
const modal = new bootstrap.Modal(document.getElementById('customAlertModal'));
const alertMessage = document.getElementById('alertMessage');
const alertIcon = document.getElementById('alertIcon');
const modalTitle = document.getElementById('customAlertModalLabel');
alertMessage.textContent = message;
// Définir l'icône et le titre selon le type
let iconClass = 'lnr lnr-info-circle';
let title = 'Information';
switch (type) {
case 'success': iconClass = 'lnr lnr-checkmark-circle';
title = 'Succès';
alertIcon.className = 'alert-icon success';
break;
case 'error':
case 'danger': iconClass = 'lnr lnr-warning';
title = 'Erreur';
alertIcon.className = 'alert-icon error';
break;
case 'warning': iconClass = 'lnr lnr-warning';
title = 'Attention';
alertIcon.className = 'alert-icon warning';
break;
default: iconClass = 'lnr lnr-info-circle';
title = 'Information';
alertIcon.className = 'alert-icon info';
}
alertIcon.innerHTML = `<i class=\"\${iconClass}\"></i>`;
modalTitle.textContent = title;
modal.show();
}
// Remplacer window.alert par showCustomAlert
window.alert = showCustomAlert;
\t</script>
";
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
$__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
yield from [];
}
/**
* @codeCoverageIgnore
*/
public function getTemplateName(): string
{
return "home/single-product.html.twig";
}
/**
* @codeCoverageIgnore
*/
public function isTraitable(): bool
{
return false;
}
/**
* @codeCoverageIgnore
*/
public function getDebugInfo(): array
{
return array ( 4523 => 3495, 4482 => 3457, 4467 => 3445, 4445 => 3426, 4438 => 3422, 4184 => 3171, 4174 => 3164, 4169 => 3162, 4166 => 3161, 4160 => 3157, 4149 => 3152, 4147 => 3151, 4139 => 3146, 4125 => 3134, 4123 => 3133, 4116 => 3129, 3559 => 2574, 3273 => 2290, 3258 => 2281, 3254 => 2279, 3248 => 2277, 3246 => 2276, 3242 => 2275, 3239 => 2274, 3231 => 2271, 3227 => 2269, 3225 => 2268, 3218 => 2266, 3212 => 2262, 3206 => 2259, 3203 => 2258, 3201 => 2257, 3192 => 2250, 3184 => 2248, 3176 => 2246, 3174 => 2245, 3170 => 2244, 3165 => 2241, 3161 => 2240, 3148 => 2229, 3146 => 2228, 3137 => 2222, 3102 => 2190, 2951 => 2042, 2851 => 1944, 2849 => 1942, 2848 => 1941, 2847 => 1940, 2846 => 1939, 2845 => 1938, 2844 => 1937, 2843 => 1936, 2842 => 1935, 2841 => 1934, 2840 => 1933, 2839 => 1932, 2838 => 1931, 2837 => 1930, 2836 => 1929, 2822 => 1917, 2815 => 1913, 2812 => 1912, 2797 => 1899, 2787 => 1895, 2780 => 1894, 2776 => 1893, 2768 => 1887, 2766 => 1886, 2759 => 1881, 2752 => 1876, 2745 => 1872, 2740 => 1870, 2734 => 1866, 2732 => 1865, 2725 => 1860, 2721 => 1858, 2713 => 1854, 2701 => 1852, 2697 => 1851, 2694 => 1850, 2692 => 1849, 2686 => 1846, 2676 => 1839, 2672 => 1838, 2660 => 1828, 2653 => 1824, 2650 => 1823, 2634 => 1809, 2632 => 1808, 2622 => 1800, 2618 => 1798, 2612 => 1794, 2609 => 1793, 2599 => 1789, 2593 => 1786, 2589 => 1784, 2584 => 1783, 2581 => 1782, 2568 => 1771, 2565 => 1770, 2559 => 1766, 2553 => 1764, 2549 => 1762, 2547 => 1761, 2544 => 1760, 2542 => 1759, 2539 => 1758, 2537 => 1757, 2529 => 1751, 2526 => 1750, 2523 => 1749, 2517 => 1748, 2510 => 1744, 2504 => 1741, 2500 => 1739, 2497 => 1738, 2492 => 1737, 2489 => 1736, 2481 => 1731, 2474 => 1726, 2471 => 1725, 2465 => 1721, 2460 => 1719, 2457 => 1718, 2454 => 1717, 2449 => 1715, 2446 => 1714, 2443 => 1713, 2437 => 1711, 2435 => 1710, 2427 => 1704, 2424 => 1703, 2416 => 1698, 2409 => 1693, 2406 => 1692, 2399 => 1688, 2392 => 1683, 2389 => 1682, 2382 => 1678, 2375 => 1673, 2372 => 1672, 2365 => 1668, 2358 => 1663, 2355 => 1662, 2348 => 1658, 2341 => 1653, 2339 => 1652, 2334 => 1649, 2332 => 1648, 2326 => 1644, 2322 => 1642, 2316 => 1639, 2313 => 1638, 2311 => 1637, 2302 => 1631, 2259 => 1599, 2245 => 1596, 2238 => 1592, 2234 => 1590, 2224 => 1583, 2215 => 1577, 2206 => 1571, 2200 => 1567, 2198 => 1566, 2194 => 1564, 2188 => 1561, 2185 => 1560, 2183 => 1559, 2179 => 1557, 2160 => 1541, 2152 => 1535, 2136 => 1532, 2132 => 1530, 2126 => 1528, 2124 => 1527, 2119 => 1525, 2115 => 1524, 2106 => 1523, 2103 => 1522, 2086 => 1521, 2071 => 1509, 2064 => 1505, 2061 => 1504, 2055 => 1503, 2052 => 1502, 2047 => 1501, 2044 => 1500, 2041 => 1499, 2036 => 1496, 2026 => 1489, 2022 => 1488, 2011 => 1479, 2007 => 1477, 2001 => 1474, 1996 => 1473, 1994 => 1472, 1986 => 1466, 1968 => 1450, 1960 => 1447, 1946 => 1446, 1943 => 1445, 1937 => 1442, 1933 => 1441, 1929 => 1440, 1925 => 1439, 1919 => 1438, 1916 => 1437, 1912 => 1435, 1902 => 1433, 1900 => 1432, 1886 => 1431, 1882 => 1430, 1878 => 1429, 1874 => 1428, 1870 => 1427, 1864 => 1426, 1861 => 1425, 1858 => 1424, 1855 => 1423, 1838 => 1422, 1832 => 1419, 1828 => 1418, 1822 => 1416, 1818 => 1415, 1815 => 1414, 1809 => 1413, 1806 => 1412, 1800 => 1411, 1797 => 1410, 1794 => 1409, 1791 => 1408, 1788 => 1407, 1785 => 1406, 1782 => 1405, 1779 => 1404, 1774 => 1403, 1771 => 1402, 1766 => 1401, 1764 => 1400, 1759 => 1399, 1757 => 1398, 1751 => 1395, 1745 => 1392, 1736 => 1386, 1725 => 1378, 1720 => 1376, 1712 => 1370, 1699 => 1368, 1694 => 1367, 1691 => 1366, 1685 => 1365, 1682 => 1364, 1676 => 1363, 1673 => 1362, 1668 => 1361, 1665 => 1360, 1660 => 1359, 1657 => 1358, 1655 => 1357, 1646 => 1352, 1643 => 1351, 1637 => 1350, 1634 => 1349, 1628 => 1348, 1625 => 1347, 1620 => 1346, 1617 => 1345, 1612 => 1344, 1609 => 1343, 1607 => 1342, 1576 => 1322, 1568 => 1316, 1560 => 1314, 1552 => 1312, 1549 => 1311, 1546 => 1310, 1540 => 1309, 1537 => 1308, 1531 => 1307, 1528 => 1306, 1523 => 1305, 1520 => 1304, 1515 => 1303, 1512 => 1302, 1510 => 1301, 1498 => 1291, 1490 => 1288, 1485 => 1287, 1482 => 1286, 1461 => 1283, 1450 => 1282, 1432 => 1281, 1429 => 1280, 1426 => 1279, 1420 => 1278, 1417 => 1277, 1411 => 1276, 1408 => 1275, 1403 => 1274, 1400 => 1273, 1395 => 1272, 1392 => 1271, 1390 => 1270, 1355 => 1237, 1342 => 1236, 106 => 9, 93 => 8, 78 => 4, 65 => 3, 42 => 1,);
}
public function getSourceContext(): Source
{
return new Source("{% extends 'base_home.html.twig' %}
{% block title %}
\t{{ product.name }}
\t| MaketOu
{% endblock %}
{% block stylesheets %}
\t<style>
\t\t/* Styles pour l'affichage de la boutique */
\t\t.shop-info {
\t\t\tpadding: 10px 0;
\t\t\tborder-bottom: 1px solid #f0f0f0;
\t\t\tmargin-bottom: 15px;
\t\t}
\t\t.shop-link {
\t\t\tcolor: #ffa200;
\t\t\ttext-decoration: none;
\t\t\tfont-weight: 500;
\t\t}
\t\t.shop-link:hover {
\t\t\tcolor: #e8910a;
\t\t\ttext-decoration: underline;
\t\t}
\t\t/* Styles pour les statistiques du produit */
\t\t.product-stats {
\t\t\tbackground: #f8f9fa;
\t\t\tpadding: 15px;
\t\t\tborder-radius: 8px;
\t\t\tborder: 1px solid #e9ecef;
\t\t}
\t\t.product-stats .stat-item {
\t\t\ttext-align: center;
\t\t}
\t\t.product-stats .stat-number {
\t\t\tdisplay: block;
\t\t\tfont-size: 1.2rem;
\t\t\tfont-weight: bold;
\t\t\tcolor: #ffa200;
\t\t}
\t\t.product-stats .stat-label {
\t\t\tcolor: #666;
\t\t\tfont-size: 0.8rem;
\t\t\ttext-transform: uppercase;
\t\t\tletter-spacing: 0.5px;
\t\t}
\t\t/* Message de confirmation */
\t\t#cart-message {
\t\t\tborder: none;
\t\t\tbackground: #d4edda;
\t\t\tcolor: #155724;
\t\t\tborder-radius: 6px;
\t\t\tpadding: 12px 16px;
\t\t\tmargin-top: 15px;
\t\t}
\t\t/* Amélioration des boutons */
\t\t.card_area .primary-btn {
\t\t\tbackground: #ffa200;
\t\t\tborder: none;
\t\t\tpadding: 12px 24px;
\t\t\tborder-radius: 6px;
\t\t\tcolor: white;
\t\t\tfont-weight: 500;
\t\t\ttransition: all 0.3s ease;
\t\t}
\t\t.card_area .primary-btn:hover {
\t\t\tbackground: #e8910a;
\t\t\ttransform: translateY(-2px);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.3);
\t\t}
\t\t.icon_btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tcolor: white;
\t\t\tborder-color: #ffa200;
\t\t}
\t\t/* Styles pour la galerie moderne de produits */
\t\t.product-gallery-modern {
\t\t\tdisplay: flex;
\t\t\tgap: 15px;
\t\t\tposition: relative;
\t\t}
\t\t.thumbnails-container {
\t\t\tposition: relative;
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\talign-items: center;
\t\t\twidth: 80px;
\t\t\tflex-shrink: 0;
\t\t}
\t\t/* Cacher les boutons jusqu'au survol */
\t\t.thumbnails-container .thumbnail-nav-btn {
\t\t\topacity: 0;
\t\t\tvisibility: hidden;
\t\t\ttransition: opacity 0.2s ease, visibility 0.2s ease;
\t\t}
\t\t.thumbnails-container:hover .thumbnail-nav-btn {
\t\t\topacity: 1;
\t\t\tvisibility: visible;
\t\t}
\t\t.product-thumbnails {
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\tgap: 10px;
\t\t\twidth: 100%;
\t\t\theight: 400px;
\t\t\toverflow: hidden;
\t\t\tposition: relative;
\t\t}
\t\t.thumbnails-wrapper {
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\tgap: 10px;
\t\t\ttransition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\twill-change: transform;
\t\t}
\t\t.thumbnail-nav-btn {
\t\t\twidth: 30px;
\t\t\theight: 30px;
\t\t\tborder-radius: 50%;
\t\t\tbackground: white;
\t\t\tborder: 2px solid #e0e0e0;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tcursor: pointer;
\t\t\ttransition: all 0.3s ease;
\t\t\tmargin: 0;
\t\t\tcolor: #666;
\t\t\tz-index: 10;
\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
\t\t\tposition: relative;
\t\t\tflex-shrink: 0;
\t\t}
\t\t.thumbnail-nav-btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tborder-color: #ffa200;
\t\t\tcolor: white;
\t\t\ttransform: scale(1.1);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.3);
\t\t}
\t\t.thumbnail-nav-btn:active {
\t\t\ttransform: scale(0.95);
\t\t}
\t\t.thumbnail-nav-btn.disabled {
\t\t\topacity: 0.3;
\t\t\tcursor: not-allowed;
\t\t\tpointer-events: none;
\t\t\tfilter: grayscale(1);
\t\t}
\t\t.thumbnail-nav-btn i {
\t\t\tfont-size: 20px;
\t\t\tfont-weight: bold;
\t\t}
\t\t.thumbnail-item {
\t\t\twidth: 80px;
\t\t\theight: 80px;
\t\t\tmin-width: 80px;
\t\t\tmin-height: 80px;
\t\t\tmax-width: 80px;
\t\t\tmax-height: 80px;
\t\t\tborder: 2px solid #e0e0e0;
\t\t\tborder-radius: 8px;
\t\t\toverflow: hidden;
\t\t\tcursor: pointer;
\t\t\ttransition: border-color 0.3s ease, border-width 0.3s ease, box-shadow 0.3s ease;
\t\t\tposition: relative;
\t\t\tbackground: #f8f9fa;
\t\t\tborder-bottom: 2px solid #e0e0e0;
\t\t\tflex-shrink: 0;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t}
\t\t.thumbnail-item:hover {
\t\t\tborder-color: #ffa200;
\t\t\tborder-bottom-color: #ffa200;
\t\t\tborder-width: 3px;
\t\t\tbox-shadow: 0 0 0 2px rgba(255, 162, 0, 0.2);
\t\t}
\t\t.thumbnail-item.active {
\t\t\tborder-color: #ffa200 !important;
\t\t\tborder-bottom-color: #ffa200 !important;
\t\t\tborder-width: 3px !important;
\t\t\tbox-shadow: 0 0 0 2px rgba(255, 162, 0, 0.2) !important;
\t\t}
\t\t.thumbnail-item::after,
\t\t.thumbnail-item::before {
\t\t\tdisplay: none !important;
\t\t\tcontent: none !important;
\t\t}
\t\t.thumbnail-item img {
\t\t\twidth: 100%;
\t\t\theight: 100%;
\t\t\tobject-fit: cover !important;
\t\t\tobject-position: center !important;
\t\t\ttransition: transform 0.3s ease;
\t\t}
\t\t.thumbnail-item:hover img {
\t\t\ttransform: scale(1.05);
\t\t}
\t\t.thumbnail-item.active img {
\t\t\ttransform: scale(1.05);
\t\t}
\t\t.product-main-image-wrapper {
\t\t\tflex: 1;
\t\t\tposition: relative;
\t\t\tbackground: #fff;
\t\t\theight: 400px;
\t\t\tborder-radius: 12px;
\t\t\toverflow: visible;
\t\t\tborder: 1px solid #e0e0e0;
\t\t\tz-index: 1;
\t\t}
\t\t.product-main-image {
\t\t\tposition: relative;
\t\t\twidth: 100%;
\t\t\tpadding-top: 100%;
\t\t\toverflow: visible;
\t\t\tbackground: #f8f9fa;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tz-index: 1;
\t\t}
\t\t.product-main-image img {
\t\t\tposition: absolute;
\t\t\ttop: 0;
\t\t\tleft: 0;
\t\t\twidth: 100%;
\t\t\theight: 100%;
\t\t\tobject-fit: contain !important;
\t\t\tobject-position: center !important;
\t\t\ttransition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
\t\t\topacity: 1;
\t\t}
\t\t.product-main-image img.loading {
\t\t\topacity: 0.5;
\t\t}
\t\t.product-main-image:hover img {
\t\t\ttransform: scale(1.08);
\t\t}
\t\t.product-main-image img.fade-in {
\t\t\tanimation: fadeInImage 0.4s ease;
\t\t}
\t\t@keyframes fadeInImage {
\t\t\tfrom {
\t\t\t\topacity: 0;
\t\t\t\ttransform: scale(0.95);
\t\t\t}
\t\t\tto {
\t\t\t\topacity: 1;
\t\t\t\ttransform: scale(1);
\t\t\t}
\t\t}
\t\t.image-overlay-icons {
\t\t\tposition: absolute !important;
\t\t\ttop: 20px !important;
\t\t\tright: 20px !important;
\t\t\tdisplay: flex !important;
\t\t\tflex-direction: column !important;
\t\t\tgap: 12px !important;
\t\t\tz-index: 10 !important;
\t\t\topacity: 0 !important;
\t\t\ttransition: opacity 0.3s ease, transform 0.3s ease !important;
\t\t\ttransform: translateX(10px) !important;
\t\t}
\t\t.product-main-image-wrapper:hover .image-overlay-icons {
\t\t\topacity: 1 !important;
\t\t\ttransform: translateX(0) !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn,
\t\t.image-overlay-icons .icon-btn {
\t\t\twidth: 48px !important;
\t\t\theight: 48px !important;
\t\t\tmin-width: 48px !important;
\t\t\tmin-height: 48px !important;
\t\t\tmax-width: 48px !important;
\t\t\tmax-height: 48px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 255, 255, 0.95) !important;
\t\t\tbackdrop-filter: blur(10px) !important;
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.8) !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
\t\t\tbox-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
\t\t\tcolor: #333 !important;
\t\t\tposition: relative !important;
\t\t\toverflow: hidden !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tfont-size: inherit !important;
\t\t\tfont-weight: normal !important;
\t\t\tline-height: 1 !important;
\t\t\ttext-align: center !important;
\t\t\ttext-decoration: none !important;
\t\t\twhite-space: nowrap !important;
\t\t\tvertical-align: middle !important;
\t\t\tfont-family: inherit !important;
\t\t\ttext-transform: none !important;
\t\t\tletter-spacing: normal !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn::before,
\t\t.image-overlay-icons .icon-btn::before {
\t\t\tcontent: '' !important;
\t\t\tposition: absolute !important;
\t\t\ttop: 50% !important;
\t\t\tleft: 50% !important;
\t\t\twidth: 0 !important;
\t\t\theight: 0 !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 162, 0, 0.2) !important;
\t\t\ttransform: translate(-50%, -50%) !important;
\t\t\ttransition: width 0.4s ease, height 0.4s ease !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:hover::before,
\t\t.image-overlay-icons .icon-btn:hover::before {
\t\t\twidth: 100% !important;
\t\t\theight: 100% !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:hover,
\t\t.image-overlay-icons .icon-btn:hover {
\t\t\tbackground: #ffa200 !important;
\t\t\tborder-color: #ffa200 !important;
\t\t\tcolor: white !important;
\t\t\ttransform: scale(1.15) rotate(5deg) !important;
\t\t\tbox-shadow: 0 6px 20px rgba(255, 162, 0, 0.5) !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:active,
\t\t.image-overlay-icons .icon-btn:active {
\t\t\ttransform: scale(1.05) rotate(0deg) !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn i,
\t\t.image-overlay-icons .icon-btn i {
\t\t\tfont-size: 20px !important;
\t\t\tposition: relative !important;
\t\t\tz-index: 1 !important;
\t\t\ttransition: transform 0.3s ease !important;
\t\t\tmargin: 0 !important;
\t\t\tdisplay: block !important;
\t\t}
\t\t.product-main-image-wrapper .icon-btn:hover i,
\t\t.image-overlay-icons .icon-btn:hover i {
\t\t\ttransform: scale(1.1) !important;
\t\t}
\t\t.product-main-image-wrapper .favorite-btn.active,
\t\t.image-overlay-icons .favorite-btn.active {
\t\t\tbackground: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%) !important;
\t\t\tborder-color: #ff6b6b !important;
\t\t\tcolor: white !important;
\t\t\tbox-shadow: 0 4px 15px rgba(255, 107, 107, 0.4) !important;
\t\t}
\t\t.product-main-image-wrapper .favorite-btn.active:hover,
\t\t.image-overlay-icons .favorite-btn.active:hover {
\t\t\tbackground: linear-gradient(135deg, #ee5a6f 0%, #dd4a5f 100%) !important;
\t\t\ttransform: scale(1.15) rotate(-5deg) !important;
\t\t}
\t\t.product-main-image-wrapper .image-counter,
\t\t.image-counter {
\t\t\tposition: absolute !important;
\t\t\tbottom: 20px !important;
\t\t\tright: 20px !important;
\t\t\tbackground: rgba(0, 0, 0, 0.75) !important;
\t\t\tbackdrop-filter: blur(8px) !important;
\t\t\tcolor: white !important;
\t\t\tpadding: 8px 16px !important;
\t\t\tborder-radius: 25px !important;
\t\t\tfont-size: 14px !important;
\t\t\tfont-weight: 600 !important;
\t\t\tbox-shadow: 0 2px 10px rgba(0, 0, 0, 0.3) !important;
\t\t\tz-index: 5 !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tgap: 6px !important;
\t\t}
\t\t.product-main-image-wrapper .image-counter span,
\t\t.image-counter span {
\t\t\tfont-weight: 700 !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t.product-main-image-wrapper .image-indicators,
\t\t#image-indicators {
\t\t\tposition: absolute !important;
\t\t\tbottom: 20px !important;
\t\t\tleft: 50% !important;
\t\t\ttransform: translateX(-50%) !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\tgap: 10px !important;
\t\t\tbackground: rgba(0, 0, 0, 0.4) !important;
\t\t\tbackdrop-filter: blur(8px) !important;
\t\t\tpadding: 8px 16px !important;
\t\t\tborder-radius: 25px !important;
\t\t\tz-index: 5 !important;
\t\t}
\t\t.product-main-image-wrapper .indicator,
\t\t#image-indicators .indicator,
\t\t.image-indicators .indicator {
\t\t\twidth: 12px !important;
\t\t\theight: 12px !important;
\t\t\tmin-width: 12px !important;
\t\t\tmin-height: 12px !important;
\t\t\tmax-width: 12px !important;
\t\t\tmax-height: 12px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.6) !important;
\t\t\tbackground: rgba(255, 255, 255, 0.3) !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tposition: relative !important;
\t\t\tdisplay: block !important;
\t\t\ttext-align: center !important;
\t\t\ttext-decoration: none !important;
\t\t\twhite-space: nowrap !important;
\t\t\tvertical-align: middle !important;
\t\t\tfont-size: 0 !important;
\t\t\tline-height: 0 !important;
\t\t\tbox-sizing: border-box !important;
\t\t}
\t\t.product-main-image-wrapper .indicator::before,
\t\t#image-indicators .indicator::before,
\t\t.image-indicators .indicator::before {
\t\t\tcontent: '' !important;
\t\t\tposition: absolute !important;
\t\t\ttop: 50% !important;
\t\t\tleft: 50% !important;
\t\t\ttransform: translate(-50%, -50%) scale(0) !important;
\t\t\twidth: 20px !important;
\t\t\theight: 20px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 162, 0, 0.3) !important;
\t\t\ttransition: transform 0.3s ease !important;
\t\t}
\t\t.product-main-image-wrapper .indicator:hover,
\t\t#image-indicators .indicator:hover,
\t\t.image-indicators .indicator:hover {
\t\t\tborder-color: #ffa200 !important;
\t\t\tbackground: rgba(255, 162, 0, 0.6) !important;
\t\t\ttransform: scale(1.2) !important;
\t\t}
\t\t.product-main-image-wrapper .indicator:hover::before,
\t\t#image-indicators .indicator:hover::before,
\t\t.image-indicators .indicator:hover::before {
\t\t\ttransform: translate(-50%, -50%) scale(1) !important;
\t\t}
\t\t.product-main-image-wrapper .indicator.active,
\t\t#image-indicators .indicator.active,
\t\t.image-indicators .indicator.active {
\t\t\tborder-color: #ffa200 !important;
\t\t\tbackground: #ffa200 !important;
\t\t\tbox-shadow: 0 0 0 3px rgba(255, 162, 0, 0.3), 0 2px 8px rgba(255, 162, 0, 0.5) !important;
\t\t\ttransform: scale(1.3) !important;
\t\t}
\t\t.product-main-image-wrapper .indicator.active::before,
\t\t#image-indicators .indicator.active::before,
\t\t.image-indicators .indicator.active::before {
\t\t\ttransform: translate(-50%, -50%) scale(1) !important;
\t\t\tbackground: rgba(255, 162, 0, 0.4) !important;
\t\t}
\t\t/* Modal de zoom d'image avec transitions modernes */
\t\t.image-zoom-modal {
\t\t\tdisplay: none;
\t\t\tposition: fixed;
\t\t\tz-index: 9999;
\t\t\tleft: 0;
\t\t\ttop: 0;
\t\t\twidth: 100%;
\t\t\theight: 100%;
\t\t\tbackground: rgba(0, 0, 0, 0);
\t\t\toverflow: auto;
\t\t\topacity: 0;
\t\t\ttransition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), background 0.3s ease;
\t\t\tbackdrop-filter: blur(0px);
\t\t}
\t\t.image-zoom-modal.active {
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\topacity: 1;
\t\t\tbackground: rgba(0, 0, 0, 0.95);
\t\t\tbackdrop-filter: blur(10px);
\t\t}
\t\t.zoom-modal-content {
\t\t\tposition: relative;
\t\t\tmax-width: 90%;
\t\t\tmax-height: 90%;
\t\t\tmargin: auto;
\t\t\topacity: 0;
\t\t\ttransform: scale(0.8);
\t\t\ttransition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1), transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
\t\t}
\t\t.image-zoom-modal.active .zoom-modal-content {
\t\t\topacity: 1;
\t\t\ttransform: scale(1);
\t\t}
\t\t.zoom-modal-content img {
\t\t\twidth: 100%;
\t\t\theight: auto;
\t\t\tmax-height: 90vh;
\t\t\tobject-fit: contain !important;
\t\t\tobject-position: center !important;
\t\t\tborder-radius: 8px;
\t\t\tbox-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
\t\t\topacity: 0;
\t\t\ttransition: opacity 0.3s ease;
\t\t}
\t\t.zoom-modal-content img.loaded {
\t\t\topacity: 1;
\t\t}
\t\t/* Loader moderne */
\t\t.zoom-loader {
\t\t\tposition: absolute;
\t\t\ttop: 50%;
\t\t\tleft: 50%;
\t\t\ttransform: translate(-50%, -50%);
\t\t\tz-index: 1;
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t}
\t\t.zoom-loader-spinner {
\t\t\twidth: 60px;
\t\t\theight: 60px;
\t\t\tborder: 4px solid rgba(255, 255, 255, 0.1);
\t\t\tborder-top-color: #ffa200;
\t\t\tborder-radius: 50%;
\t\t\tanimation: spin 1s linear infinite;
\t\t}
\t\t@keyframes spin {
\t\t\tto {
\t\t\t\ttransform: rotate(360deg);
\t\t\t}
\t\t}
\t\t.zoom-loader-text {
\t\t\tcolor: white;
\t\t\tmargin-top: 15px;
\t\t\ttext-align: center;
\t\t\tfont-size: 14px;
\t\t\tfont-weight: 500;
\t\t}
\t\t.close-zoom {
\t\t\tposition: absolute;
\t\t\ttop: 30px;
\t\t\tright: 30px;
\t\t\tcolor: white;
\t\t\tfont-size: 32px;
\t\t\tfont-weight: 300;
\t\t\tcursor: pointer;
\t\t\tz-index: 10000;
\t\t\twidth: 50px;
\t\t\theight: 50px;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tbackground: rgba(255, 255, 255, 0.1);
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.2);
\t\t\tborder-radius: 50%;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\topacity: 0;
\t\t\ttransform: scale(0.8);
\t\t}
\t\t.image-zoom-modal.active .close-zoom {
\t\t\topacity: 1;
\t\t\ttransform: scale(1);
\t\t\ttransition-delay: 0.2s;
\t\t}
\t\t.close-zoom:hover {
\t\t\tbackground: rgba(255, 162, 0, 0.9);
\t\t\tborder-color: #ffa200;
\t\t\ttransform: scale(1.1) rotate(90deg);
\t\t\tbox-shadow: 0 4px 20px rgba(255, 162, 0, 0.4);
\t\t}
\t\t
\t\t/* Styles pour le contrôle de quantité amélioré */
\t\t.product_count {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tgap: 15px !important;
\t\t\tmargin-bottom: 24px !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t.product_count label {
\t\t\tfont-size: 14px !important;
\t\t\tcolor: #777777 !important;
\t\t\tfont-family: \"Roboto\", sans-serif !important;
\t\t\tfont-weight: normal !important;
\t\t\tmargin-bottom: 0 !important;
\t\t\twhite-space: nowrap !important;
\t\t\tpadding-right: 10px !important;
\t\t}
\t\t
\t\t.quantity-controls-wrapper {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tborder: 1px solid #eeeeee !important;
\t\t\tborder-radius: 4px !important;
\t\t\toverflow: hidden !important;
\t\t\tbackground: #fff !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t.quantity-btn {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s ease !important;
\t\t\tfont-size: 16px !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tposition: relative !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t}
\t\t
\t\t.quantity-btn:hover {
\t\t\tbackground: #e9ecef !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t
\t\t.quantity-btn:active {
\t\t\tbackground: #dee2e6 !important;
\t\t\ttransform: scale(0.95) !important;
\t\t}
\t\t
\t\t.quantity-btn i {
\t\t\tfont-size: 14px !important;
\t\t}
\t\t
\t\t.quantity-input {
\t\t\twidth: 60px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tborder-left: 1px solid #eeeeee !important;
\t\t\tborder-right: 1px solid #eeeeee !important;
\t\t\ttext-align: center !important;
\t\t\tfont-size: 14px !important;
\t\t\tfont-weight: 500 !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\toutline: none !important;
\t\t\tbackground: #fff !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t.quantity-input:focus {
\t\t\tborder-left-color: #ffa200 !important;
\t\t\tborder-right-color: #ffa200 !important;
\t\t}
\t\t
\t\t/* Surcharger les styles existants pour les boutons */
\t\t.product_count .quantity-btn {
\t\t\tposition: relative !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tcursor: pointer !important;
\t\t\ttransition: all 0.3s ease !important;
\t\t\tfont-size: 16px !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn:hover {
\t\t\tbackground: #e9ecef !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn:active {
\t\t\tbackground: #dee2e6 !important;
\t\t\ttransform: scale(0.95) !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn i,
\t\t.product_count .quantity-btn .quantity-icon {
\t\t\tfont-size: 20px !important;
\t\t\tfont-weight: 300 !important;
\t\t\tline-height: 1 !important;
\t\t\tdisplay: inline-block !important;
\t\t}
\t\t
\t\t.product_count .quantity-btn .quantity-icon {
\t\t\tfont-size: 24px !important;
\t\t\tfont-weight: 300 !important;
\t\t\tline-height: 1 !important;
\t\t}
\t\t
\t\t/* Désactiver les boutons si nécessaire */
\t\t.quantity-btn:disabled {
\t\t\topacity: 0.5 !important;
\t\t\tcursor: not-allowed !important;
\t\t}
\t\t
\t\t.quantity-btn:disabled:hover {
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t}
\t\t
\t\t/* Surcharger les styles pour le wrapper */
\t\t.product_count .quantity-controls-wrapper {
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tborder: 1px solid #eeeeee !important;
\t\t\tborder-radius: 4px !important;
\t\t\toverflow: hidden !important;
\t\t\tbackground: #fff !important;
\t\t\tposition: relative !important;
\t\t}
\t\t
\t\t/* Surcharger tous les styles de main.css pour les boutons dans product_count */
\t\t.product_count button.quantity-btn,
\t\t.product_count .quantity-btn {
\t\t\tdisplay: flex !important;
\t\t\tposition: relative !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tborder: none !important;
\t\t\tbox-shadow: none !important;
\t\t}
\t\t
\t\t.product_count button.quantity-btn:hover,
\t\t.product_count .quantity-btn:hover {
\t\t\tbackground: #e9ecef !important;
\t\t\tcolor: #ffa200 !important;
\t\t}
\t\t
\t\t/* Surcharger les styles pour l'input */
\t\t.product_count .quantity-input,
\t\t.product_count input.quantity-input {
\t\t\twidth: 60px !important;
\t\t\theight: 40px !important;
\t\t\tborder: none !important;
\t\t\tborder-left: 1px solid #eeeeee !important;
\t\t\tborder-right: 1px solid #eeeeee !important;
\t\t\ttext-align: center !important;
\t\t\tpadding: 0 !important;
\t\t\tpadding-left: 0 !important;
\t\t\tposition: relative !important;
\t\t}
\t\t/* Boutons de navigation sur l'image principale */
\t\t.main-image-nav {
\t\t\tposition: absolute;
\t\t\ttop: 50%;
\t\t\tleft: 0;
\t\t\tright: 0;
\t\t\ttransform: translateY(-50%);
\t\t\tdisplay: flex;
\t\t\tjustify-content: space-between;
\t\t\tpadding: 0 12px;
\t\t\tpointer-events: none !important;
\t\t\tz-index: 10 !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn,
\t\t.main-image-nav-btn {
\t\t\tpointer-events: all !important;
\t\t\tz-index: 1000 !important;
\t\t\tposition: relative !important;
\t\t\tcursor: pointer !important;
\t\t\t-webkit-user-select: none !important;
\t\t\t-moz-user-select: none !important;
\t\t\t-ms-user-select: none !important;
\t\t\tuser-select: none !important;
\t\t\tuser-select: none !important;
\t\t\t-webkit-user-select: none !important;
\t\t\t-moz-user-select: none !important;
\t\t\t-ms-user-select: none !important;
\t\t\twidth: 48px !important;
\t\t\theight: 48px !important;
\t\t\tmin-width: 48px !important;
\t\t\tmin-height: 48px !important;
\t\t\tmax-width: 48px !important;
\t\t\tmax-height: 48px !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 255, 255, 0.95) !important;
\t\t\tbackdrop-filter: blur(10px) !important;
\t\t\tborder: 2px solid rgba(255, 255, 255, 0.8) !important;
\t\t\tdisplay: flex !important;
\t\t\talign-items: center !important;
\t\t\tjustify-content: center !important;
\t\t\tbox-shadow: 0 4px 15px rgba(0, 0, 0, 0.2) !important;
\t\t\tcolor: #333 !important;
\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
\t\t\tcursor: pointer !important;
\t\t\toverflow: hidden !important;
\t\t\tpadding: 0 !important;
\t\t\tmargin: 0 !important;
\t\t\tfont-size: inherit !important;
\t\t\tfont-weight: normal !important;
\t\t\tline-height: 1 !important;
\t\t\ttext-align: center !important;
\t\t\ttext-decoration: none !important;
\t\t\twhite-space: nowrap !important;
\t\t\tvertical-align: middle !important;
\t\t\tfont-family: inherit !important;
\t\t\ttext-transform: none !important;
\t\t\tletter-spacing: normal !important;
\t\t\t-webkit-tap-highlight-color: transparent !important;
\t\t\ttouch-action: manipulation !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn::before,
\t\t.main-image-nav-btn::before {
\t\t\tcontent: '' !important;
\t\t\tposition: absolute !important;
\t\t\ttop: 50% !important;
\t\t\tleft: 50% !important;
\t\t\twidth: 0 !important;
\t\t\theight: 0 !important;
\t\t\tborder-radius: 50% !important;
\t\t\tbackground: rgba(255, 162, 0, 0.2) !important;
\t\t\ttransform: translate(-50%, -50%) !important;
\t\t\ttransition: width 0.4s ease, height 0.4s ease !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:hover::before,
\t\t.main-image-nav-btn:hover::before {
\t\t\twidth: 100% !important;
\t\t\theight: 100% !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:hover,
\t\t.main-image-nav-btn:hover {
\t\t\tbackground: #ffa200 !important;
\t\t\tborder-color: #ffa200 !important;
\t\t\tcolor: #fff !important;
\t\t\ttransform: scale(1.15) !important;
\t\t\tbox-shadow: 0 6px 20px rgba(255, 162, 0, 0.5) !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:active,
\t\t.main-image-nav-btn:active {
\t\t\ttransform: scale(1.05) !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn i,
\t\t.main-image-nav-btn i {
\t\t\tposition: relative !important;
\t\t\tz-index: 1 !important;
\t\t\tfont-size: 20px !important;
\t\t\ttransition: transform 0.3s ease !important;
\t\t\tmargin: 0 !important;
\t\t\tdisplay: block !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn:hover i,
\t\t.main-image-nav-btn:hover i {
\t\t\ttransform: scale(1.2) !important;
\t\t}
\t\t.main-image-nav .main-image-nav-btn.disabled,
\t\t.main-image-nav-btn.disabled {
\t\t\topacity: 0.4 !important;
\t\t\tcursor: not-allowed !important;
\t\t\tpointer-events: none !important;
\t\t}
\t\t/* Modal personnalisé pour remplacer les alert */
\t\t.custom-alert-modal .modal-content {
\t\t\tborder-radius: 12px;
\t\t\tborder: none;
\t\t\tbox-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
\t\t}
\t\t.custom-alert-modal .modal-header {
\t\t\tborder-bottom: none;
\t\t\tpadding: 1.5rem 1.5rem 0.5rem;
\t\t\tbackground: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
\t\t\tcolor: white;
\t\t\tborder-radius: 12px 12px 0 0;
\t\t}
\t\t.custom-alert-modal .modal-header .btn-close {
\t\t\tfilter: brightness(0) invert(1);
\t\t\topacity: 0.8;
\t\t}
\t\t.custom-alert-modal .modal-header .btn-close:hover {
\t\t\topacity: 1;
\t\t}
\t\t.custom-alert-modal .modal-body {
\t\t\tpadding: 1.5rem;
\t\t\ttext-align: center;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon {
\t\t\tfont-size: 3rem;
\t\t\tmargin-bottom: 1rem;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.success {
\t\t\tcolor: #28a745;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.error {
\t\t\tcolor: #dc3545;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.warning {
\t\t\tcolor: #ffc107;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-icon.info {
\t\t\tcolor: #17a2b8;
\t\t}
\t\t.custom-alert-modal .modal-body .alert-message {
\t\t\tfont-size: 1.1rem;
\t\t\tcolor: #333;
\t\t\tmargin-bottom: 1rem;
\t\t\tline-height: 1.6;
\t\t}
\t\t.custom-alert-modal .modal-footer {
\t\t\tborder-top: none;
\t\t\tpadding: 0.5rem 1.5rem 1.5rem;
\t\t\tjustify-content: center;
\t\t}
\t\t.custom-alert-modal .modal-footer .btn {
\t\t\tmin-width: 120px;
\t\t\tpadding: 0.6rem 1.5rem;
\t\t\tborder-radius: 8px;
\t\t\tfont-weight: 500;
\t\t}
\t\t/* Responsive pour single-product */
\t\t@media(max-width: 991.98px) {
\t\t\t.product-gallery-modern {
\t\t\t\tflex-direction: column;
\t\t\t}
\t\t\t.thumbnails-container {
\t\t\t\tflex-direction: row;
\t\t\t\twidth: 100%;
\t\t\t\toverflow-x: auto;
\t\t\t\tpadding: 10px 0;
\t\t\t}
\t\t\t.thumbnail-item {
\t\t\t\tflex-shrink: 0;
\t\t\t}
\t\t\t.main-image-container {
\t\t\t\twidth: 100%;
\t\t\t}
\t\t}
\t\t@media(max-width: 768px) {
\t\t\t.product-gallery-modern {
\t\t\t\tflex-direction: column;
\t\t\t}
\t\t\t.thumbnails-container {
\t\t\t\twidth: 100%;
\t\t\t\tflex-direction: row;
\t\t\t\talign-items: center;
\t\t\t}
\t\t\t.product-thumbnails {
\t\t\t\tflex-direction: row;
\t\t\t\twidth: 100%;
\t\t\t\tmax-height: 100px;
\t\t\t\toverflow-x: auto;
\t\t\t\toverflow-y: hidden;
\t\t\t}
\t\t\t.thumbnail-item {
\t\t\t\tflex-shrink: 0;
\t\t\t}
\t\t\t.thumbnail-nav-btn {
\t\t\t\tmargin: 0 5px;
\t\t\t}
\t\t\t.thumbnail-nav-up {
\t\t\t\torder: 1;
\t\t\t}
\t\t\t.product-thumbnails {
\t\t\t\torder: 2;
\t\t\t}
\t\t\t.thumbnail-nav-down {
\t\t\t\torder: 3;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-overlay-icons,
\t\t\t.image-overlay-icons {
\t\t\t\topacity: 1 !important;
\t\t\t\ttop: 10px !important;
\t\t\t\tright: 10px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn,
\t\t\t.image-overlay-icons .icon-btn {
\t\t\t\twidth: 40px !important;
\t\t\t\theight: 40px !important;
\t\t\t\tmin-width: 40px !important;
\t\t\t\tmin-height: 40px !important;
\t\t\t\tmax-width: 40px !important;
\t\t\t\tmax-height: 40px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn i,
\t\t\t.image-overlay-icons .icon-btn i {
\t\t\t\tfont-size: 18px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-indicators,
\t\t\t#image-indicators {
\t\t\t\tbottom: 15px !important;
\t\t\t\tpadding: 6px 12px !important;
\t\t\t\tgap: 8px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .indicator,
\t\t\t#image-indicators .indicator {
\t\t\t\twidth: 10px !important;
\t\t\t\theight: 10px !important;
\t\t\t\tmin-width: 10px !important;
\t\t\t\tmin-height: 10px !important;
\t\t\t\tmax-width: 10px !important;
\t\t\t\tmax-height: 10px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-counter,
\t\t\t.image-counter {
\t\t\t\tbottom: 15px !important;
\t\t\t\tright: 15px !important;
\t\t\t\tpadding: 6px 12px !important;
\t\t\t\tfont-size: 12px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn,
\t\t\t.main-image-nav-btn {
\t\t\t\twidth: 40px !important;
\t\t\t\theight: 40px !important;
\t\t\t\tmin-width: 40px !important;
\t\t\t\tmin-height: 40px !important;
\t\t\t\tmax-width: 40px !important;
\t\t\t\tmax-height: 40px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn i,
\t\t\t.main-image-nav-btn i {
\t\t\t\tfont-size: 18px !important;
\t\t\t}
\t\t}
\t\t@media(max-width: 576px) {
\t\t\t.product-main-image-wrapper .image-indicators,
\t\t\t#image-indicators {
\t\t\t\tbottom: 10px !important;
\t\t\t\tpadding: 5px 10px !important;
\t\t\t\tgap: 6px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .indicator,
\t\t\t#image-indicators .indicator {
\t\t\t\twidth: 8px !important;
\t\t\t\theight: 8px !important;
\t\t\t\tmin-width: 8px !important;
\t\t\t\tmin-height: 8px !important;
\t\t\t\tmax-width: 8px !important;
\t\t\t\tmax-height: 8px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .image-counter,
\t\t\t.image-counter {
\t\t\t\tbottom: 10px !important;
\t\t\t\tright: 10px !important;
\t\t\t\tpadding: 5px 10px !important;
\t\t\t\tfont-size: 11px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn,
\t\t\t.image-overlay-icons .icon-btn {
\t\t\t\twidth: 36px !important;
\t\t\t\theight: 36px !important;
\t\t\t\tmin-width: 36px !important;
\t\t\t\tmin-height: 36px !important;
\t\t\t\tmax-width: 36px !important;
\t\t\t\tmax-height: 36px !important;
\t\t\t}
\t\t\t.product-main-image-wrapper .icon-btn i,
\t\t\t.image-overlay-icons .icon-btn i {
\t\t\t\tfont-size: 16px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn,
\t\t\t.main-image-nav-btn {
\t\t\t\twidth: 36px !important;
\t\t\t\theight: 36px !important;
\t\t\t\tmin-width: 36px !important;
\t\t\t\tmin-height: 36px !important;
\t\t\t\tmax-width: 36px !important;
\t\t\t\tmax-height: 36px !important;
\t\t\t}
\t\t\t.main-image-nav .main-image-nav-btn i,
\t\t\t.main-image-nav-btn i {
\t\t\t\tfont-size: 16px !important;
\t\t\t}
\t\t}
\t\t
\t\t/* Styles finaux pour forcer l'affichage des boutons de quantité */
\t\t.product_count .quantity-controls-wrapper button.quantity-btn,
\t\t.product_count button.quantity-btn-decrease,
\t\t.product_count button.quantity-btn-increase {
\t\t\tdisplay: flex !important;
\t\t\tvisibility: visible !important;
\t\t\topacity: 1 !important;
\t\t\tposition: relative !important;
\t\t\ttop: auto !important;
\t\t\tbottom: auto !important;
\t\t\tright: auto !important;
\t\t\tleft: auto !important;
\t\t\twidth: 40px !important;
\t\t\theight: 40px !important;
\t\t\tbackground: #f8f9fa !important;
\t\t\tcolor: #666 !important;
\t\t\tborder: none !important;
\t\t\tbox-shadow: none !important;
\t\t\tmargin: 0 !important;
\t\t\tpadding: 0 !important;
\t\t}
\t\t
\t\t.product_count .quantity-controls-wrapper {
\t\t\tdisplay: flex !important;
\t\t\tvisibility: visible !important;
\t\t\topacity: 1 !important;
\t\t}
\t</style>
{% endblock %}
{% block body %}
\t<!-- Start Banner Area -->
\t<section class=\"banner-area organic-breadcrumb\">
\t\t<div class=\"container\">
\t\t\t<div class=\"breadcrumb-banner d-flex flex-wrap align-items-center justify-content-end\">
\t\t\t\t<div class=\"col-first\">
\t\t\t\t\t<h1>Product Details Page</h1>
\t\t\t\t\t<nav class=\"d-flex align-items-center\">
\t\t\t\t\t\t<a href=\"index.html\">Home<span class=\"lnr lnr-arrow-right\"></span>
\t\t\t\t\t\t</a>
\t\t\t\t\t\t<a href=\"#\">Shop<span class=\"lnr lnr-arrow-right\"></span>
\t\t\t\t\t\t</a>
\t\t\t\t\t\t<a href=\"single-product.html\">product-details</a>
\t\t\t\t\t</nav>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</section>
\t<!-- End Banner Area -->
\t<!--================Single Product Area =================-->
\t<div class=\"product_image_area\">
\t\t<div class=\"container\">
\t\t\t<div class=\"row s_product_inner\">
\t\t\t\t<div class=\"col-lg-6\">
\t\t\t\t\t<div
\t\t\t\t\t\tclass=\"product-gallery-modern\">
\t\t\t\t\t\t<!-- Colonne de miniatures à gauche avec navigation -->
\t\t\t\t\t\t<div class=\"thumbnails-container\">
\t\t\t\t\t\t\t<button class=\"thumbnail-nav-btn thumbnail-nav-up\" id=\"thumbnail-nav-up\" title=\"Image précédente\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-up\"></i>
\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t<div class=\"product-thumbnails\" id=\"product-thumbnails\">
\t\t\t\t\t\t\t\t<div class=\"thumbnails-wrapper\" id=\"thumbnails-wrapper\">
\t\t\t\t\t\t\t\t\t{% set allProductImages = product.images|default([]) %}
\t\t\t\t\t\t\t\t\t{% if product.variants is defined %}
\t\t\t\t\t\t\t\t\t\t{% for variant in product.variants %}
\t\t\t\t\t\t\t\t\t\t\t{% if variant.isActive and variant.images is defined %}
\t\t\t\t\t\t\t\t\t\t\t\t{% for variantImg in variant.images %}
\t\t\t\t\t\t\t\t\t\t\t\t\t{% set allProductImages = allProductImages|merge([variantImg]) %}
\t\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t{% if allProductImages|length > 0 %}
\t\t\t\t\t\t\t\t\t\t{% for img in allProductImages %}
\t\t\t\t\t\t\t\t\t\t\t<div class=\"thumbnail-item {% if loop.first %}active permanently-active{% endif %}\" data-image=\"{{ asset(img) }}\" data-index=\"{{ loop.index0 }}\">
\t\t\t\t\t\t\t\t\t\t\t\t<img src=\"{{ asset(img) }}\" alt=\"{{ product.name }} - Image {{ loop.index }}\">
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t<div class=\"thumbnail-item active permanently-active\" data-image=\"{{ asset('ui/img/category/s-p1.jpg') }}\" data-index=\"0\">
\t\t\t\t\t\t\t\t\t\t\t<img src=\"{{ asset('ui/img/category/s-p1.jpg') }}\" alt=\"{{ product.name }}\">
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<button class=\"thumbnail-nav-btn thumbnail-nav-down\" id=\"thumbnail-nav-down\" title=\"Image suivante\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-down\"></i>
\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- Grande image principale -->
\t\t\t\t\t\t<div class=\"product-main-image-wrapper\">
\t\t\t\t\t\t\t<div class=\"product-main-image\">
\t\t\t\t\t\t\t\t{% set allProductImages = product.images|default([]) %}
\t\t\t\t\t\t\t\t{% if product.variants is defined %}
\t\t\t\t\t\t\t\t\t{% for variant in product.variants %}
\t\t\t\t\t\t\t\t\t\t{% if variant.isActive and variant.images is defined %}
\t\t\t\t\t\t\t\t\t\t\t{% for variantImg in variant.images %}
\t\t\t\t\t\t\t\t\t\t\t\t{% set allProductImages = allProductImages|merge([variantImg]) %}
\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t{% if allProductImages|length > 0 %}
\t\t\t\t\t\t\t\t\t<img id=\"main-product-image\" src=\"{{ asset(allProductImages[0]) }}\" alt=\"{{ product.name }}\">
\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t<img id=\"main-product-image\" src=\"{{ asset('ui/img/category/s-p1.jpg') }}\" alt=\"{{ product.name }}\">
\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t<!-- Overlay avec icônes -->
\t\t\t\t\t\t\t\t<div class=\"image-overlay-icons\">
\t\t\t\t\t\t\t\t\t<button class=\"icon-btn zoom-btn\" onclick=\"openImageZoom()\" title=\"Agrandir l'image\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-magnifier\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t<button class=\"icon-btn favorite-btn\" {% if app.user %} onclick=\"toggleWishlist({{ product.id }}, this); return false;\" {% else %} onclick=\"showCustomAlert('Vous devez être connecté pour ajouter aux favoris', 'warning'); return false;\" {% endif %} title=\"Ajouter aux favoris\" data-product-id=\"{{ product.id }}\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-heart\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<!-- Navigation sur l'image principale -->
\t\t\t\t\t\t\t\t<div class=\"main-image-nav\">
\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"main-image-nav-btn\" id=\"main-image-prev\" title=\"Image précédente\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-left\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"main-image-nav-btn\" id=\"main-image-next\" title=\"Image suivante\">
\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-chevron-right\"></i>
\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Indicateur d'image active -->
\t\t\t\t\t\t\t<div class=\"image-counter\">
\t\t\t\t\t\t\t\t<span id=\"current-image-index\">1</span>
\t\t\t\t\t\t\t\t/
\t\t\t\t\t\t\t\t{% set allProductImages = product.images|default([]) %}
\t\t\t\t\t\t\t\t{% if product.variants is defined %}
\t\t\t\t\t\t\t\t\t{% for variant in product.variants %}
\t\t\t\t\t\t\t\t\t\t{% if variant.isActive and variant.images is defined %}
\t\t\t\t\t\t\t\t\t\t\t{% for variantImg in variant.images %}
\t\t\t\t\t\t\t\t\t\t\t\t{% set allProductImages = allProductImages|merge([variantImg]) %}
\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t<span id=\"total-images\">{{ (allProductImages|length) ?: 1 }}</span>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Indicateurs d'images (points) -->
\t\t\t\t\t\t\t<div class=\"image-indicators\" id=\"image-indicators\">
\t\t\t\t\t\t\t\t{% set allProductImages = product.images|default([]) %}
\t\t\t\t\t\t\t\t{% if product.variants is defined %}
\t\t\t\t\t\t\t\t\t{% for variant in product.variants %}
\t\t\t\t\t\t\t\t\t\t{% if variant.isActive and variant.images is defined %}
\t\t\t\t\t\t\t\t\t\t\t{% for variantImg in variant.images %}
\t\t\t\t\t\t\t\t\t\t\t\t{% set allProductImages = allProductImages|merge([variantImg]) %}
\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t{% for i in 0..((allProductImages|length) ?: 1) - 1 %}
\t\t\t\t\t\t\t\t<button class=\"indicator {{ i == 0 ? 'active' : '' }}\" data-index=\"{{ i }}\" title=\"Image {{ i + 1 }}\"></button>
\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"col-lg-5 offset-lg-1\">
\t\t\t\t\t<div class=\"s_product_text\">
\t\t\t\t\t\t<h3>{{ product.name }}</h3>
\t\t\t\t\t\t<h2>
\t\t\t\t\t\t\t<span id=\"main-unit-price\">{{ product.price|number_format(2, '.', ' ') }}</span>
\t\t\t\t\t\t\tHTG
\t\t\t\t\t\t</h2>
\t\t\t\t\t\t<ul class=\"list\">
\t\t\t\t\t\t\t<li>
\t\t\t\t\t\t\t\t<a class=\"active\" href=\"#\">
\t\t\t\t\t\t\t\t\t<span>Category</span>
\t\t\t\t\t\t\t\t\t:
\t\t\t\t\t\t\t\t\t{{ product.category.name }}</a>
\t\t\t\t\t\t\t</li>
\t\t\t\t\t\t\t<li>
\t\t\t\t\t\t\t\t<a href=\"#\">
\t\t\t\t\t\t\t\t\t<span>Disponibilité</span>
\t\t\t\t\t\t\t\t\t:
\t\t\t\t\t\t\t\t\t{{ product.stockStatus }}</a>
\t\t\t\t\t\t\t</li>
\t\t\t\t\t\t</ul>
\t\t\t\t\t\t<div class=\"product-description-preview\">{{ product.description|striptags|length > 150 ? product.description|striptags|slice(0, 150) ~ '...' : product.description|striptags }}</div>
\t\t\t\t\t\t<!-- Sélection de variantes (Couleurs, Tailles, etc.) -->
\t\t\t\t\t\t{% if product.variants is defined and product.variants|length > 0 %}
\t\t\t\t\t\t\t<div class=\"product-variants mb-4\" id=\"product-variants\" data-product-id=\"{{ product.id }}\">
\t\t\t\t\t\t\t\t{% set variantAttributes = {} %}
\t\t\t\t\t\t\t\t{% for variant in product.variants %}
\t\t\t\t\t\t\t\t\t{% if variant.isActive %}
\t\t\t\t\t\t\t\t\t\t{% for attrValue in variant.attributeValues %}
\t\t\t\t\t\t\t\t\t\t\t{% set attrName = attrValue.attribute.name|lower %}
\t\t\t\t\t\t\t\t\t\t\t{% if variantAttributes[attrName] is not defined %}
\t\t\t\t\t\t\t\t\t\t\t\t{% set variantAttributes = variantAttributes|merge({(attrName): {'attribute': attrValue.attribute, 'values': []}}) %}
\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t{% if attrValue not in variantAttributes[attrName].values %}
\t\t\t\t\t\t\t\t\t\t\t\t{% set variantAttributes = variantAttributes|merge({(attrName): variantAttributes[attrName]|merge({'values': variantAttributes[attrName].values|merge([attrValue])})}) %}
\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t{% for attrName, attrData in variantAttributes %}
\t\t\t\t\t\t\t\t\t<div class=\"variant-selector mb-3\" data-attribute=\"{{ attrData.attribute.slug }}\">
\t\t\t\t\t\t\t\t\t\t<label class=\"variant-label mb-2\">
\t\t\t\t\t\t\t\t\t\t\t<strong>{{ attrData.attribute.name }}:</strong>
\t\t\t\t\t\t\t\t\t\t\t<span class=\"selected-variant-value\" id=\"selected-{{ attrData.attribute.slug }}\"></span>
\t\t\t\t\t\t\t\t\t\t</label>
\t\t\t\t\t\t\t\t\t\t<div class=\"variant-options d-flex flex-wrap gap-2\">
\t\t\t\t\t\t\t\t\t\t\t{% for attrValue in attrData.values %}
\t\t\t\t\t\t\t\t\t\t\t\t{% if attrValue.isActive %}
\t\t\t\t\t\t\t\t\t\t\t\t\t{% if attrData.attribute.type == 'color' %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button type=\"button\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"variant-option variant-color-option {% if loop.first %}selected{% endif %}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value-id=\"{{ attrValue.id }}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value=\"{{ attrValue.value }}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-attribute=\"{{ attrData.attribute.slug }}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"{{ attrValue.value }}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle=\"{% if attrValue.colorCode %}background-color: {{ attrValue.colorCode }};{% endif %} width: 40px; height: 40px; border-radius: 50%; border: 2px solid {% if loop.first %}#007bff{% else %}#ddd{% endif %}; cursor: pointer; position: relative;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if loop.first %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"check-icon\" style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: {% if attrValue.colorCode and attrValue.colorCode|is_dark_color %}white{% else %}black{% endif %}; font-size: 18px;\">✓</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button type=\"button\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"variant-option variant-text-option btn btn-outline-secondary {% if loop.first %}active{% endif %}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value-id=\"{{ attrValue.id }}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-value=\"{{ attrValue.value }}\"
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-attribute=\"{{ attrData.attribute.slug }}\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ attrValue.value }}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t<!-- Affichage du stock et du prix de la variante sélectionnée -->
\t\t\t\t\t\t\t\t<div class=\"variant-info mt-3 p-3 bg-light rounded\" id=\"variant-info\" style=\"display: none;\">
\t\t\t\t\t\t\t\t\t<div class=\"d-flex justify-content-between align-items-center mb-2\">
\t\t\t\t\t\t\t\t\t\t<span><strong>Prix:</strong></span>
\t\t\t\t\t\t\t\t\t\t<span class=\"variant-price text-primary fw-bold\" id=\"variant-price\"></span>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"d-flex justify-content-between align-items-center\">
\t\t\t\t\t\t\t\t\t\t<span><strong>Stock:</strong></span>
\t\t\t\t\t\t\t\t\t\t<span class=\"variant-stock\" id=\"variant-stock\"></span>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<input type=\"hidden\" id=\"selected-variant-id\" value=\"\">
\t\t\t\t\t\t\t\t\t<input type=\"hidden\" id=\"selected-variant-sku\" value=\"\">
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t<!-- Informations sur la boutique -->
\t\t\t\t\t\t<div class=\"shop-info mb-3\">
\t\t\t\t\t\t\t<small class=\"text-muted\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-store\"></i>
\t\t\t\t\t\t\t\tVendu par :
\t\t\t\t\t\t\t\t{% if product.shop is defined and product.shop %}
\t\t\t\t\t\t\t\t\t<a href=\"{{ path('ui_shop_show', {'slug': product.shop.slug}) }}\" class=\"shop-link\">
\t\t\t\t\t\t\t\t\t\t{{ product.shop.name }}
\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t<span class=\"text-muted\">Boutique inconnue</span>
\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t</small>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<div class=\"product_count\">
\t\t\t\t\t\t\t<label for=\"qty\">Quantité :</label>
\t\t\t\t\t\t\t<div class=\"quantity-controls-wrapper\">
\t\t\t\t\t\t\t\t<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst > 1 ) result.value--;return false;\" class=\"quantity-btn quantity-btn-decrease\" type=\"button\" title=\"Diminuer\">
\t\t\t\t\t\t\t\t\t<span class=\"quantity-icon\">−</span>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t<input type=\"text\" name=\"qty\" id=\"sst\" maxlength=\"12\" value=\"1\" title=\"Quantité:\" class=\"input-text qty quantity-input\" max=\"{{ product.stock ?? 99 }}\">
\t\t\t\t\t\t\t\t<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst < {{ product.stock ?? 99 }}) result.value++;return false;\" class=\"quantity-btn quantity-btn-increase\" type=\"button\" title=\"Augmenter\">
\t\t\t\t\t\t\t\t\t<span class=\"quantity-icon\">+</span>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<input
\t\t\t\t\t\ttype=\"hidden\" id=\"unit-price-input\" value=\"{{ product.price|number_format(2, '.', '') }}\"/>
\t\t\t\t\t\t{# Prix de gros (bulk pricing) - Affiché uniquement si activé par le vendeur #}
\t\t\t\t\t\t{% if product.hasTierPricing and product.tierPrices is defined and product.tierPrices|length > 0 %}
\t\t\t\t\t\t{% set tierPrices = [] %}
\t\t\t\t\t\t\t{% for tier in product.tierPrices %}
\t\t\t\t\t\t\t\t{% set tierPrices = tierPrices|merge([{ 'min': tier.min, 'price': tier.price }]) %}
\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t<div id=\"bulk-pricing\" class=\"mt-4 p-3 bg-light rounded\" data-tiers='{{ tierPrices|json_encode|e('html_attr') }}'>
\t\t\t\t\t\t\t\t<div class=\"d-flex align-items-center mb-3\">
\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-tag text-primary me-2\" style=\"font-size: 1.2rem;\"></i>
\t\t\t\t\t\t\t\t\t<strong class=\"me-2\">Prix de gros disponible</strong>
\t\t\t\t\t\t\t\t\t<span id=\"unit-price-value\" class=\"badge bg-primary ms-2 text-white p-2\">{{ product.price|number_format(2, '.', ' ') }} HTG</span>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<div class=\"table-responsive\">
\t\t\t\t\t\t\t\t\t<table class=\"table table-sm mb-3\" style=\"border:1px solid #dee2e6; background: white;\">
\t\t\t\t\t\t\t\t\t\t<thead class=\"table-primary\">
\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<th style=\"font-weight: 600;\">Quantité minimale</th>
\t\t\t\t\t\t\t\t\t\t\t\t<th style=\"font-weight: 600;\">Prix unitaire (HTG)</th>
\t\t\t\t\t\t\t\t\t\t\t\t<th style=\"font-weight: 600;\">Économie</th>
\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t</thead>
\t\t\t\t\t\t\t\t\t<tbody id=\"bulk-tier-rows\">
\t\t\t\t\t\t\t\t\t\t{% for tier in tierPrices|sort((a,b)=> a.min <=> b.min) %}
\t\t\t\t\t\t\t\t\t\t\t\t{% set savings = ((product.price - tier.price) / product.price * 100)|round(1) %}
\t\t\t\t\t\t\t\t\t\t\t\t<tr data-min=\"{{ tier.min }}\" class=\"{% if loop.first %}table-active{% endif %}\">
\t\t\t\t\t\t\t\t\t\t\t\t\t<td><strong>≥ {{ tier.min }}</strong></td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td><strong class=\"text-primary\">{{ tier.price|number_format(2, '.', ' ') }}</strong></td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if savings > 0 %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-success text-white p-2\">-{{ savings }}%</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-muted\">-</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t</tbody>
\t\t\t\t\t\t\t\t</table>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"d-flex flex-wrap gap-3 align-items-baseline mb-2 p-2 bg-white rounded\">
\t\t\t\t\t\t\t\t<div>
\t\t\t\t\t\t\t\t\t<strong>Total:</strong>
\t\t\t\t\t\t\t\t\t\t<span id=\"total-price-value\" class=\"text-primary fs-5\">{{ product.price|number_format(2, '.', ' ') }}</span>
\t\t\t\t\t\t\t\t\tHTG
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"text-success\">
\t\t\t\t\t\t\t\t\t<strong>Économies:</strong>
\t\t\t\t\t\t\t\t\t<span id=\"savings-amount\">0.00</span>
\t\t\t\t\t\t\t\t\tHTG
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(<span id=\"savings-percent\">0</span>%)
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<small class=\"text-muted d-block mt-2\">
\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle me-1\"></i>
\t\t\t\t\t\t\t\t\tLe prix et le total s'adaptent automatiquement selon la quantité sélectionnée.
\t\t\t\t\t\t\t\t</small>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t<!-- Stock disponible -->
\t\t\t\t\t\t{% if product.stock is defined %}
\t\t\t\t\t\t\t<small class=\"text-muted\">Stock disponible :
\t\t\t\t\t\t\t\t{{ product.stock }}
\t\t\t\t\t\t\t\tunités</small>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t<!-- Statistiques du produit -->
\t\t\t\t\t\t{% if productStats is defined %}
\t\t\t\t\t\t\t<div class=\"product-stats mt-3\">
\t\t\t\t\t\t\t\t<div class=\"row text-center\">
\t\t\t\t\t\t\t\t\t<div class=\"col-4\">
\t\t\t\t\t\t\t\t\t\t<div class=\"stat-item\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"stat-number\">{{ productStats.totalViews }}</span>
\t\t\t\t\t\t\t\t\t\t\t<small class=\"stat-label\">Vues</small>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-4\">
\t\t\t\t\t\t\t\t\t\t<div class=\"stat-item\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"stat-number\">{{ productStats.salesCount }}</span>
\t\t\t\t\t\t\t\t\t\t\t<small class=\"stat-label\">Ventes</small>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-4\">
\t\t\t\t\t\t\t\t\t\t<div class=\"stat-item\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"stat-number\">{{ productStats.conversionRate }}%</span>
\t\t\t\t\t\t\t\t\t\t\t<small class=\"stat-label\">Conversion</small>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t<div class=\"card_area d-flex align-items-center\">
\t\t\t\t\t\t\t<a class=\"primary-btn btn-add-to-cart\" href=\"javascript:void(0);\" id=\"add-to-cart-btn\" data-product-id=\"{{ product.id }}\" data-qty=\"1\">
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-cart\"></i>
\t\t\t\t\t\t\t\tAjouter au panier
\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t<a class=\"icon_btn wishlist-btn\" href=\"#\" title=\"Ajouter aux favoris\" data-product-id=\"{{ product.id }}\" {% if app.user %} onclick=\"toggleWishlist({{ product.id }}, this); return false;\" {% else %} onclick=\"showCustomAlert('Vous devez être connecté pour ajouter aux favoris', 'warning'); return false;\" {% endif %}>
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-heart\"></i>
\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t<a class=\"icon_btn comparison-btn\" href=\"#\" title=\"Comparer\" data-product-id=\"{{ product.id }}\" {% if app.user %} onclick=\"toggleComparison({{ product.id }}, this); return false;\" {% else %} onclick=\"showCustomAlert('Vous devez être connecté pour comparer des produits', 'warning'); return false;\" {% endif %}>
\t\t\t\t\t\t\t\t<i class=\"lnr lnr-sync\"></i>
\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- Message de confirmation -->
\t\t\t\t\t\t<div id=\"cart-message\" class=\"alert alert-success mt-3\" style=\"display: none;\">
\t\t\t\t\t\t\t<i class=\"lnr lnr-checkmark-circle\"></i>
\t\t\t\t\t\t\tProduit ajouté au panier avec succès !
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- ... existing code ... -->
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</div>
\t<!--================End Single Product Area =================-->
\t<!--================Product Description Area =================-->
\t<section class=\"product_description_area\">
\t\t<div class=\"container\">
\t\t\t<ul class=\"nav nav-tabs\" id=\"myTab\" role=\"tablist\">
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link active\" id=\"home-tab\" data-bs-toggle=\"tab\" href=\"#home\" role=\"tab\" aria-controls=\"home\" aria-selected=\"true\">Description</a>
\t\t\t\t</li>
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link\" id=\"profile-tab\" data-bs-toggle=\"tab\" href=\"#profile\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\">Spécifications</a>
\t\t\t\t</li>
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link\" id=\"contact-tab\" data-bs-toggle=\"tab\" href=\"#contact\" role=\"tab\" aria-controls=\"contact\" aria-selected=\"false\">Commentaires</a>
\t\t\t\t</li>
\t\t\t\t<li class=\"nav-item\">
\t\t\t\t\t<a class=\"nav-link\" id=\"review-tab\" data-bs-toggle=\"tab\" href=\"#review\" role=\"tab\" aria-controls=\"review\" aria-selected=\"false\">Avis ({{ product.reviewCount ?? 0 }})</a>
\t\t\t\t</li>
\t\t\t</ul>
\t\t\t<div class=\"tab-content\" id=\"myTabContent\">
\t\t\t\t<div class=\"tab-pane fade show active\" id=\"home\" role=\"tabpanel\" aria-labelledby=\"home-tab\">
\t\t\t\t\t<div class=\"description\">
\t\t\t\t\t\t{% if product.description %}
\t\t\t\t\t\t\t<div class=\"product-description-content\">
\t\t\t\t\t\t\t\t{{ product.description|raw }}
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t<p class=\"text-muted\">Aucune description disponible pour ce produit.</p>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"tab-pane fade\" id=\"profile\" role=\"tabpanel\" aria-labelledby=\"profile-tab\">
\t\t\t\t\t<div class=\"specification-table\">
\t\t\t\t\t\t{% if product.weight or product.length or product.width or product.height or product.attributes %}
\t\t\t\t\t\t\t<div class=\"table-responsive\">
\t\t\t\t\t\t\t\t<table class=\"table\">
\t\t\t\t\t\t\t\t\t<tbody>
\t\t\t\t\t\t\t\t\t\t{% if product.sku %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Référence (SKU)</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ product.sku }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.barcode %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Code-barres</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ product.barcode }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.brand %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Marque</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ product.brand.name }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.category %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Catégorie</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ product.category.name }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.weight %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Poids</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ product.weight }}
\t\t\t\t\t\t\t\t\t\t\t\t\t\tkg</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.length or product.width or product.height %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Dimensions</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if product.length %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ product.length }}cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if product.width %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t×
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ product.width }}cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if product.height %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t×
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ product.height }}cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t\t</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.stock is not null %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Stock disponible</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ product.stock }}
\t\t\t\t\t\t\t\t\t\t\t\t\t\tunité(s)</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.details is defined and product.details|length > 0 %}
\t\t\t\t\t\t\t\t\t\t\t{% for detail in product.details %}
\t\t\t\t\t\t\t\t\t\t\t\t{% if detail.isActive %}
\t\t\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ detail.label }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ detail.value|raw }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.stockStatus %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Statut</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% if product.stockStatus == 'in_stock' %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-success\">En stock</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% elseif product.stockStatus == 'out_of_stock' %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-danger\">Rupture de stock</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% elseif product.stockStatus == 'backorder' %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-warning\">Sur commande</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{{ product.stockStatus }}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t\t\t</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.isDigital %}
\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>Type</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge bg-info\">Produit digital</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t</h5>
\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t{% if product.attributes is not empty %}
\t\t\t\t\t\t\t\t\t\t\t{% for key, value in product.attributes %}
\t\t\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ key|replace({'_': ' '})|title }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t\t<td>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<h5>{{ value }}</h5>
\t\t\t\t\t\t\t\t\t\t\t\t\t</td>
\t\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t</tbody>
\t\t\t\t\t\t\t\t</table>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t<p class=\"text-muted\">Aucune spécification disponible pour ce produit.</p>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"tab-pane fade\" id=\"contact\" role=\"tabpanel\" aria-labelledby=\"contact-tab\">
\t\t\t\t\t<div class=\"comment-wrapper\">
\t\t\t\t\t\t<div class=\"alert alert-info\">
\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t\t\tLa fonctionnalité de commentaires sera bientôt disponible. Vous pourrez laisser des commentaires et poser des questions sur ce produit.
\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% if app.user %}
\t\t\t\t\t\t\t<div class=\"review_box mt-4\">
\t\t\t\t\t\t\t\t<h4>Poser une question</h4>
\t\t\t\t\t\t\t\t<form class=\"row contact_form\" method=\"post\" novalidate=\"novalidate\">
\t\t\t\t\t\t\t\t\t<div class=\"col-md-12\">
\t\t\t\t\t\t\t\t\t\t<div class=\"form-group\">
\t\t\t\t\t\t\t\t\t\t\t<textarea class=\"form-control\" name=\"comment\" id=\"comment\" rows=\"3\" placeholder=\"Votre question ou commentaire...\" required></textarea>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-md-12 text-right\">
\t\t\t\t\t\t\t\t\t\t<button type=\"submit\" class=\"btn primary-btn\">Envoyer</button>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</form>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t<p class=\"text-center\">
\t\t\t\t\t\t\t\t<a href=\"{{ path('ui_app_login') }}\" class=\"primary-btn\">Connectez-vous</a>
\t\t\t\t\t\t\t\tpour poser une question ou laisser un commentaire.
\t\t\t\t\t\t\t</p>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"tab-pane fade\" id=\"review\" role=\"tabpanel\" aria-labelledby=\"review-tab\">
\t\t\t\t\t<div class=\"review-wrapper\">
\t\t\t\t\t\t<div class=\"row\">
\t\t\t\t\t\t\t<div class=\"col-lg-6\">
\t\t\t\t\t\t\t\t<div class=\"row total_rate\">
\t\t\t\t\t\t\t\t\t<div class=\"col-6\">
\t\t\t\t\t\t\t\t\t\t<div class=\"box_total\">
\t\t\t\t\t\t\t\t\t\t\t<h5>Note globale</h5>
\t\t\t\t\t\t\t\t\t\t\t<h4>{{ product.averageRating ? product.averageRating|number_format(1, '.', ',') : '0.0' }}</h4>
\t\t\t\t\t\t\t\t\t\t\t<h6>({{ product.reviewCount ?? 0 }}
\t\t\t\t\t\t\t\t\t\t\t\tAvis)</h6>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"col-6\">
\t\t\t\t\t\t\t\t\t\t<div class=\"rating_list\">
\t\t\t\t\t\t\t\t\t\t\t<h3>Basé sur
\t\t\t\t\t\t\t\t\t\t\t\t{{ product.reviewCount ?? 0 }}
\t\t\t\t\t\t\t\t\t\t\t\tavis</h3>
\t\t\t\t\t\t\t\t\t\t\t<div class=\"rating-summary\">
\t\t\t\t\t\t\t\t\t\t\t\t{% if product.averageRating %}
\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"rating-display mb-3\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% for i in 1..5 %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-star{% if i <= product.averageRating %}{% else %}-o{% endif %}\" style=\"color: #ffa200; font-size: 1.2rem;\"></i>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"ms-2\" style=\"font-size: 1.1rem; font-weight: bold;\">{{ product.averageRating|number_format(1, '.', ',') }}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/ 5.0</span>
\t\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"text-muted\">Aucune note disponible</p>
\t\t\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"review_list\">
\t\t\t\t\t\t\t\t\t{% if product.reviewCount and product.reviewCount > 0 %}
\t\t\t\t\t\t\t\t\t\t<div class=\"alert alert-info\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t\t\t\t\t\t\tLe système d'affichage détaillé des avis sera disponible prochainement.
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tNote actuelle :
\t\t\t\t\t\t\t\t\t\t\t{{ product.averageRating|number_format(1, '.', ',') }}
\t\t\t\t\t\t\t\t\t\t\t/ 5.0 basée sur
\t\t\t\t\t\t\t\t\t\t\t{{ product.reviewCount }}
\t\t\t\t\t\t\t\t\t\t\tavis.
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t<div class=\"alert alert-info\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t\t\t\t\t\t\tAucun avis pour ce produit pour le moment. Soyez le premier à laisser un avis après votre achat !
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<div class=\"col-lg-6\">
\t\t\t\t\t\t\t\t<div class=\"review_box\">
\t\t\t\t\t\t\t\t\t<h4>Laisser un avis</h4>
\t\t\t\t\t\t\t\t\t{% if app.user %}
\t\t\t\t\t\t\t\t\t\t<p class=\"text-muted\">Vous pouvez laisser un avis après avoir acheté ce produit.</p>
\t\t\t\t\t\t\t\t\t\t<form class=\"row contact_form\" method=\"post\" novalidate=\"novalidate\">
\t\t\t\t\t\t\t\t\t\t\t<div class=\"col-md-12\">
\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"form-group\">
\t\t\t\t\t\t\t\t\t\t\t\t\t<label>Votre note</label>
\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"rating-input mb-3\" style=\"display: flex; gap: 5px; flex-direction: row-reverse; justify-content: flex-end;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% for i in 5..1 %}
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input type=\"radio\" name=\"rating\" id=\"rating{{ i }}\" value=\"{{ i }}\" required style=\"display: none;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"rating{{ i }}\" class=\"star-label\" style=\"cursor: pointer;\">
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"fa fa-star-o\" style=\"color: #ccc; font-size: 1.5rem;\"></i>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</label>
\t\t\t\t\t\t\t\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t<div class=\"col-md-12\">
\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"form-group\">
\t\t\t\t\t\t\t\t\t\t\t\t\t<textarea class=\"form-control\" name=\"review\" id=\"review\" rows=\"5\" placeholder=\"Votre avis...\" required onfocus=\"this.placeholder = ''\" onblur=\"this.placeholder = 'Votre avis...'\"></textarea>
\t\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t\t<div class=\"col-md-12 text-right\">
\t\t\t\t\t\t\t\t\t\t\t\t<button type=\"submit\" class=\"btn primary-btn\">Publier l'avis</button>
\t\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t\t</form>
\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t<p class=\"text-center\">
\t\t\t\t\t\t\t\t\t\t\t<a href=\"{{ path('ui_app_login') }}\" class=\"primary-btn\">Connectez-vous</a>
\t\t\t\t\t\t\t\t\t\t\tpour laisser un avis sur ce produit.
\t\t\t\t\t\t\t\t\t\t</p>
\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</section>
\t<!--================End Product Description Area =================-->
\t<script>
\t\t// Données des variantes du produit
\t\tconst productVariants = {{ product.variants|length > 0 ? product.variants|map(v => {
\t\t\t'id': v.id,
\t\t\t'sku': v.sku,
\t\t\t'price': v.price,
\t\t\t'compareAtPrice': v.compareAtPrice,
\t\t\t'stock': v.stock,
\t\t\t'stockStatus': v.stockStatus,
\t\t\t'isActive': v.isActive,
\t\t\t'images': v.images,
\t\t\t'attributeValues': v.attributeValues|map(av => {
\t\t\t\t'attributeId': av.attribute.id,
\t\t\t\t'attributeSlug': av.attribute.slug,
\t\t\t\t'valueId': av.id,
\t\t\t\t'value': av.value
\t\t\t})|to_array
\t\t})|json_encode|raw : '[]' }};
\t\t// Gestion de la sélection de variantes
\t\tlet selectedAttributes = {};
\t\tlet currentVariant = null;
\t\t// Initialiser les onglets Bootstrap
document.addEventListener('DOMContentLoaded', function () { // Activer les onglets Bootstrap 5
const triggerTabList = document.querySelectorAll('#myTab button[data-bs-toggle=\"tab\"]');
triggerTabList.forEach(triggerEl => {
const tabTrigger = new bootstrap.Tab(triggerEl);
triggerEl.addEventListener('click', event => {
event.preventDefault();
tabTrigger.show();
});
});
// Gestion des étoiles pour les avis
const ratingInputs = document.querySelectorAll('.rating-input input[type=\"radio\"]');
const starLabels = document.querySelectorAll('.rating-input .star-label');
ratingInputs.forEach((input, index) => {
input.addEventListener('change', function () {
const rating = parseInt(this.value);
starLabels.forEach((label) => { // Trouver l'input associé à ce label
const labelInput = label.previousElementSibling;
if (labelInput && labelInput.type === 'radio') {
const starValue = parseInt(labelInput.value);
const star = label.querySelector('i');
if (starValue <= rating) {
star.style.color = '#ffa200';
star.classList.remove('fa-star-o');
star.classList.add('fa-star');
} else {
star.style.color = '#ccc';
star.classList.remove('fa-star');
star.classList.add('fa-star-o');
}
}
});
});
});
// Pré-remplir les étoiles au survol
starLabels.forEach((label) => {
label.addEventListener('mouseenter', function () { // Trouver l'input associé à ce label
const input = label.previousElementSibling;
if (input && input.type === 'radio') {
const rating = parseInt(input.value);
starLabels.forEach((l) => {
const lInput = l.previousElementSibling;
if (lInput && lInput.type === 'radio') {
const starValue = parseInt(lInput.value);
const star = l.querySelector('i');
if (starValue <= rating) {
star.style.color = '#ffa200';
star.classList.remove('fa-star-o');
star.classList.add('fa-star');
} else {
star.style.color = '#ccc';
star.classList.remove('fa-star');
star.classList.add('fa-star-o');
}
}
});
}
});
});
const ratingContainer = document.querySelector('.rating-input');
if (ratingContainer) {
ratingContainer.addEventListener('mouseleave', function () {
const checkedInput = document.querySelector('.rating-input input[type=\"radio\"]:checked');
if (checkedInput) {
checkedInput.dispatchEvent(new Event('change'));
} else {
starLabels.forEach(label => {
const star = label.querySelector('i');
star.style.color = '#ccc';
});
}
});
}
});
\t// Gestion de la sélection de variantes
\tif (typeof productVariants !== 'undefined' && productVariants.length > 0) {
\t\t// Initialiser avec la première variante active
\t\tconst firstVariant = productVariants.find(v => v.isActive);
\t\tif (firstVariant) {
\t\t\tfirstVariant.attributeValues.forEach(av => {
\t\t\t\tselectedAttributes[av.attributeSlug] = av.valueId;
\t\t\t});
\t\t\tupdateVariantDisplay(firstVariant);
\t\t} else {
\t\t\t// Si aucune variante active, afficher le prix de base
\t\t\tconst priceEl = document.getElementById('main-unit-price');
\t\t\tif (priceEl) {
\t\t\t\tpriceEl.textContent = '{{ product.price|number_format(2, '.', ' ') }}';
\t\t\t}
\t\t}
\t\t// Écouter les clics sur les options de variantes
\t\tdocument.querySelectorAll('.variant-option').forEach(option => {
\t\t\toption.addEventListener('click', function() {
\t\t\t\tconst attributeSlug = this.getAttribute('data-attribute');
\t\t\t\tconst valueId = parseInt(this.getAttribute('data-value-id'));
\t\t\t\tconst value = this.getAttribute('data-value');
\t\t\t\t// Mettre à jour la sélection visuelle
\t\t\t\tdocument.querySelectorAll(`[data-attribute=\"\${attributeSlug}\"]`).forEach(opt => {
\t\t\t\t\topt.classList.remove('selected', 'active');
\t\t\t\t\tif (opt.classList.contains('variant-color-option')) {
\t\t\t\t\t\topt.style.borderColor = '#ddd';
\t\t\t\t\t\tconst checkIcon = opt.querySelector('.check-icon');
\t\t\t\t\t\tif (checkIcon) checkIcon.remove();
\t\t\t\t\t}
\t\t\t\t});
\t\t\t\tthis.classList.add('selected', 'active');
\t\t\t\tif (this.classList.contains('variant-color-option')) {
\t\t\t\t\tthis.style.borderColor = '#007bff';
\t\t\t\t\tconst checkIcon = document.createElement('span');
\t\t\t\t\tcheckIcon.className = 'check-icon';
\t\t\t\t\tconst bgColor = this.style.backgroundColor || '';
\t\t\t\t\tconst isDark = bgColor && getContrastColor(bgColor) < 128;
\t\t\t\t\tcheckIcon.style.cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: ' + (isDark ? 'white' : 'black') + '; font-size: 18px;';
\t\t\t\t\tcheckIcon.textContent = '✓';
\t\t\t\t\tthis.appendChild(checkIcon);
\t\t\t\t}
\t\t\t\t// Mettre à jour les attributs sélectionnés
\t\t\t\tselectedAttributes[attributeSlug] = valueId;
\t\t\t\tconst selectedSpan = document.getElementById(`selected-\${attributeSlug}`);
\t\t\t\tif (selectedSpan) {
\t\t\t\t\tselectedSpan.textContent = value;
\t\t\t\t}
\t\t\t\t// Trouver la variante correspondante
\t\t\t\tconst matchingVariant = findMatchingVariant();
\t\t\t\tif (matchingVariant) {
\t\t\t\t\tupdateVariantDisplay(matchingVariant);
\t\t\t\t} else {
\t\t\t\t\t// Aucune variante correspondante trouvée - afficher le produit de base
\t\t\t\t\tresetToBaseProduct();
\t\t\t\t}
\t\t\t});
\t\t});
\t}
\tfunction findMatchingVariant() {
\t\tif (!productVariants || productVariants.length === 0) return null;
\t\t
\t\treturn productVariants.find(variant => {
\t\t\tif (!variant.isActive) return false;
\t\t\t
\t\t\tconst variantAttributes = {};
\t\t\tvariant.attributeValues.forEach(av => {
\t\t\t\tvariantAttributes[av.attributeSlug] = av.valueId;
\t\t\t});
\t\t\t// Vérifier si tous les attributs sélectionnés correspondent
\t\t\tfor (const [attrSlug, valueId] of Object.entries(selectedAttributes)) {
\t\t\t\tif (!variantAttributes[attrSlug] || variantAttributes[attrSlug] !== valueId) {
\t\t\t\t\treturn false;
\t\t\t\t}
\t\t\t}
\t\t\t// Vérifier que le nombre d'attributs correspond
\t\t\treturn Object.keys(variantAttributes).length === Object.keys(selectedAttributes).length;
\t\t});
\t}
\tfunction updateVariantDisplay(variant) {
\t\tcurrentVariant = variant;
\t\t
\t\t// Mettre à jour le prix
\t\tconst priceElement = document.getElementById('main-unit-price');
\t\tconst variantPriceElement = document.getElementById('variant-price');
\t\tif (priceElement) {
\t\t\tpriceElement.textContent = variant.price.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ' ');
\t\t}
\t\tif (variantPriceElement) {
\t\t\tvariantPriceElement.textContent = variant.price.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ' ') + ' HTG';
\t\t}
\t\t// Mettre à jour le stock
\t\tconst stockElement = document.getElementById('variant-stock');
\t\tif (stockElement) {
\t\t\tif (variant.stock > 0) {
\t\t\t\tstockElement.textContent = variant.stock + ' disponible(s)';
\t\t\t\tstockElement.className = 'variant-stock text-success';
\t\t\t} else {
\t\t\t\tstockElement.textContent = 'Rupture de stock';
\t\t\t\tstockElement.className = 'variant-stock text-danger';
\t\t\t}
\t\t}
\t\t// Mettre à jour les champs cachés
\t\tconst variantIdInput = document.getElementById('selected-variant-id');
\t\tconst variantSkuInput = document.getElementById('selected-variant-sku');
\t\tif (variantIdInput) variantIdInput.value = variant.id;
\t\tif (variantSkuInput) variantSkuInput.value = variant.sku;
\t\t// Mettre à jour les images si disponibles
\t\tif (variant.images && variant.images.length > 0) {
\t\t\tconst mainImage = document.getElementById('main-product-image');
\t\t\tif (mainImage && variant.images[0]) {
\t\t\t\tmainImage.src = variant.images[0];
\t\t\t}
\t\t}
\t\t// Afficher les informations de la variante
\t\tconst variantInfo = document.getElementById('variant-info');
\t\tif (variantInfo) variantInfo.style.display = 'block';
\t\t// Mettre à jour la quantité maximale
\t\tconst qtyInput = document.getElementById('sst');
\t\tif (qtyInput) {
\t\t\tqtyInput.max = variant.stock;
\t\t}
\t}
\tfunction getContrastColor(hexColor) {
\t\t// Convertir hex en RGB et calculer la luminosité
\t\tconst rgb = hexColor.match(/\\d+/g);
\t\tif (rgb && rgb.length >= 3) {
\t\t\tconst r = parseInt(rgb[0]);
\t\t\tconst g = parseInt(rgb[1]);
\t\tconst b = parseInt(rgb[2]);
\t\treturn (r * 299 + g * 587 + b * 114) / 1000;
\t}
\treturn 128;
}
function resetToBaseProduct() {
\tcurrentVariant = null;
\t
\t// Réinitialiser les attributs sélectionnés
\tselectedAttributes = {};
\t
\t// Masquer les informations de variante
\tconst variantInfo = document.getElementById('variant-info');
\tif (variantInfo) variantInfo.style.display = 'none';
\t
\t// Réinitialiser le prix au prix de base
\tconst priceEl = document.getElementById('main-unit-price');
\tif (priceEl) priceEl.textContent = '{{ product.price|number_format(2, '.', ' ') }}';
\t
\t// Réinitialiser les champs cachés
\tconst variantIdInput = document.getElementById('selected-variant-id');
\tconst variantSkuInput = document.getElementById('selected-variant-sku');
\tif (variantIdInput) variantIdInput.value = '';
\tif (variantSkuInput) variantSkuInput.value = '';
\t
\t// Réinitialiser les sélections visuelles
\tdocument.querySelectorAll('.variant-option').forEach(opt => {
\t\topt.classList.remove('selected', 'active');
\t\tif (opt.classList.contains('variant-color-option')) {
\t\t\topt.style.borderColor = '#ddd';
\t\t\tconst checkIcon = opt.querySelector('.check-icon');
\t\t\tif (checkIcon) checkIcon.remove();
\t\t}
\t});
\t
\t// Réinitialiser les labels de sélection
\tdocument.querySelectorAll('.selected-variant-value').forEach(span => {
\t\tspan.textContent = '';
\t});
\t
\t// Réinitialiser les images au produit de base
\tconst mainImage = document.getElementById('main-product-image');
\tif (mainImage && typeof productImages !== 'undefined' && productImages.length > 0) {
\t\tmainImage.src = productImages[0];
\t}
\t
\t// Réinitialiser la quantité maximale
\tconst qtyInput = document.getElementById('sst');
\tif (qtyInput) {
\t\tqtyInput.max = {{ product.stock }};
\t}
}
</script>
\t{% if youMightAlsoLike|length > 0 %}
\t\t<section class=\"related-product-area section_gap_bottom py-5\" style=\"background: linear-gradient(to bottom, #f8f9fa 0%, #ffffff 100%);\">
\t\t\t<div class=\"container\">
\t\t\t\t<div class=\"row justify-content-center\">
\t\t\t\t\t<div class=\"col-lg-8 text-center\">
\t\t\t\t\t\t<div class=\"section-title\">
\t\t\t\t\t\t\t<h2 class=\"fw-bold mb-3\" style=\"font-size: 2.5rem; color: #2c3e50;\">Vous pourriez aussi aimer</h2>
\t\t\t\t\t\t\t<p class=\"text-muted\" style=\"font-size: 1.1rem;\">Produits sélectionnés pour vous en fonction de vos préférences</p>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"row g-4\">
\t\t\t\t\t{% for relatedProduct in youMightAlsoLike %}
\t\t\t\t\t\t<div class=\"col-6 col-md-4 col-lg-3 mb-3\">
\t\t\t\t\t\t\t<div class=\"modern-product-card\">
\t\t\t\t\t\t\t\t<div class=\"product-image-wrapper\">
\t\t\t\t\t\t\t\t\t<a href=\"{{ path('ui_product_show', { slug: relatedProduct.slug }) }}\" class=\"product-image-link\">
\t\t\t\t\t\t\t\t\t\t{% if relatedProduct.images is defined and relatedProduct.images|length > 0 %}
\t\t\t\t\t\t\t\t\t\t\t<img src=\"{{ asset(relatedProduct.images[0]) }}\" alt=\"{{ relatedProduct.name }}\" class=\"product-image\">
\t\t\t\t\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t\t\t\t\t<img src=\"{{ asset('ui/img/product/p1.jpg') }}\" alt=\"{{ relatedProduct.name }}\" class=\"product-image\">
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t\t<div class=\"product-overlay\">
\t\t\t\t\t\t\t\t\t\t\t<span class=\"view-product-btn\">
\t\t\t\t\t\t\t\t\t\t\t\t<i class=\"ti ti-eye\"></i> Voir
\t\t\t\t\t\t\t\t\t\t\t</span>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t\t<div class=\"product-badge\">
\t\t\t\t\t\t\t\t\t\t{% if relatedProduct.compareAtPrice and relatedProduct.compareAtPrice > relatedProduct.price %}
\t\t\t\t\t\t\t\t\t\t\t<span class=\"badge-discount\">
\t\t\t\t\t\t\t\t\t\t\t\t-{{ ((relatedProduct.compareAtPrice - relatedProduct.price) / relatedProduct.compareAtPrice * 100)|round }}%
\t\t\t\t\t\t\t\t\t\t\t</span>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t<div class=\"product-info\">
\t\t\t\t\t\t\t\t\t<h6 class=\"product-title\">
\t\t\t\t\t\t\t\t\t\t<a href=\"{{ path('ui_product_show', { slug: relatedProduct.slug }) }}\">{{ relatedProduct.name }}</a>
\t\t\t\t\t\t\t\t\t</h6>
\t\t\t\t\t\t\t\t\t{% if relatedProduct.shop %}
\t\t\t\t\t\t\t\t\t\t<div class=\"product-shop\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"ti ti-store\"></i>
\t\t\t\t\t\t\t\t\t\t\t<a href=\"{{ path('ui_shop_show', {'slug': relatedProduct.shop.slug}) }}\" class=\"shop-link\">{{ relatedProduct.shop.name }}</a>
\t\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t<div class=\"product-price-wrapper\">
\t\t\t\t\t\t\t\t\t\t<span class=\"product-price\">{{ relatedProduct.price|number_format(0, '.', ' ') }} HTG</span>
\t\t\t\t\t\t\t\t\t\t{% if relatedProduct.compareAtPrice and relatedProduct.compareAtPrice > relatedProduct.price %}
\t\t\t\t\t\t\t\t\t\t\t<span class=\"product-compare-price\">{{ relatedProduct.compareAtPrice|number_format(0, '.', ' ') }} HTG</span>
\t\t\t\t\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<div class=\"product-actions\">
\t\t\t\t\t\t\t\t\t\t<a href=\"javascript:void(0)\" class=\"btn-add-to-cart\" data-product-id=\"{{ relatedProduct.id }}\" data-qty=\"1\" title=\"Ajouter au panier\">
\t\t\t\t\t\t\t\t\t\t\t<i class=\"ti ti-shopping-cart\"></i>
\t\t\t\t\t\t\t\t\t\t\t<span>Ajouter</span>
\t\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t{% endfor %}
\t\t\t\t</div>
\t\t\t</div>
\t\t</section>
\t\t<style>
\t\t\t.modern-product-card {
\t\t\t\tbackground: #ffffff;
\t\t\t\tborder-radius: 16px;
\t\t\t\toverflow: hidden;
\t\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
\t\t\t\ttransition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\t\theight: 100%;
\t\t\t\tdisplay: flex;
\t\t\t\tflex-direction: column;
\t\t\t\tposition: relative;
\t\t\t}
\t\t\t.modern-product-card:hover {
\t\t\t\ttransform: translateY(-8px);
\t\t\t\tbox-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
\t\t\t}
\t\t\t.product-image-wrapper {
\t\t\t\tposition: relative;
\t\t\t\twidth: 100%;
\t\t\t\theight: 250px;
\t\t\t\toverflow: hidden;
\t\t\t\tbackground: #f8f9fa;
\t\t\t}
\t\t\t.product-image {
\t\t\t\twidth: 100%;
\t\t\t\theight: 100%;
\t\t\t\tobject-fit: cover !important;
\t\t\t\tobject-position: center !important;
\t\t\t\ttransition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
\t\t\t}
\t\t\t.modern-product-card:hover .product-image {
\t\t\t\ttransform: scale(1.1);
\t\t\t}
\t\t\t.product-overlay {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 0;
\t\t\t\tleft: 0;
\t\t\t\tright: 0;
\t\t\t\tbottom: 0;
\t\t\t\tbackground: rgba(0, 0, 0, 0.5);
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\topacity: 0;
\t\t\t\ttransition: opacity 0.3s ease;
\t\t\t}
\t\t\t.modern-product-card:hover .product-overlay {
\t\t\t\topacity: 1;
\t\t\t}
\t\t\t.view-product-btn {
\t\t\t\tcolor: white;
\t\t\t\tpadding: 12px 24px;
\t\t\t\tbackground: rgba(255, 255, 255, 0.2);
\t\t\t\tbackdrop-filter: blur(10px);
\t\t\t\tborder-radius: 8px;
\t\t\t\tfont-weight: 600;
\t\t\t\tdisplay: inline-flex;
\t\t\t\talign-items: center;
\t\t\t\tgap: 8px;
\t\t\t\ttransition: all 0.3s ease;
\t\t\t}
\t\t\t.view-product-btn:hover {
\t\t\t\tbackground: rgba(255, 255, 255, 0.3);
\t\t\t\ttransform: scale(1.05);
\t\t\t}
\t\t\t.product-badge {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 12px;
\t\t\t\tright: 12px;
\t\t\t\tz-index: 2;
\t\t\t}
\t\t\t.badge-discount {
\t\t\t\tbackground: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
\t\t\t\tcolor: white;
\t\t\t\tpadding: 6px 12px;
\t\t\t\tborder-radius: 20px;
\t\t\t\tfont-size: 0.75rem;
\t\t\t\tfont-weight: 700;
\t\t\t\tbox-shadow: 0 2px 8px rgba(238, 90, 111, 0.4);
\t\t\t}
\t\t\t.product-info {
\t\t\t\tpadding: 20px;
\t\t\t\tflex-grow: 1;
\t\t\t\tdisplay: flex;
\t\t\t\tflex-direction: column;
\t\t\t}
\t\t\t.product-title {
\t\t\t\tmargin: 0 0 8px 0;
\t\t\t\tfont-size: 1rem;
\t\t\t\tfont-weight: 600;
\t\t\t\tline-height: 1.4;
\t\t\t\theight: 2.8em;
\t\t\t\toverflow: hidden;
\t\t\t\tdisplay: -webkit-box;
\t\t\t\t-webkit-line-clamp: 2;
\t\t\t\t-webkit-box-orient: vertical;
\t\t\t}
\t\t\t.product-title a {
\t\t\t\tcolor: #2c3e50;
\t\t\t\ttext-decoration: none;
\t\t\t\ttransition: color 0.3s ease;
\t\t\t}
\t\t\t.product-title a:hover {
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.product-shop {
\t\t\t\tfont-size: 0.85rem;
\t\t\t\tcolor: #6c757d;
\t\t\t\tmargin-bottom: 12px;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tgap: 6px;
\t\t\t}
\t\t\t.product-shop i {
\t\t\t\tfont-size: 0.9rem;
\t\t\t}
\t\t\t.shop-link {
\t\t\t\tcolor: #6c757d;
\t\t\t\ttext-decoration: none;
\t\t\t\ttransition: color 0.3s ease;
\t\t\t}
\t\t\t.shop-link:hover {
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.product-price-wrapper {
\t\t\t\tmargin-bottom: 16px;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tgap: 8px;
\t\t\t\tflex-wrap: wrap;
\t\t\t}
\t\t\t.product-price {
\t\t\t\tfont-size: 1.25rem;
\t\t\t\tfont-weight: 700;
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.product-compare-price {
\t\t\t\tfont-size: 0.9rem;
\t\t\t\tcolor: #adb5bd;
\t\t\t\ttext-decoration: line-through;
\t\t\t}
\t\t\t.product-actions {
\t\t\t\tmargin-top: auto;
\t\t\t}
\t\t\t/* Styles pour les boutons de la section \"Vous pourriez aussi aimer\" uniquement */
\t\t\t.modern-product-card .btn-add-to-cart {
\t\t\t\twidth: 100%;
\t\t\t\tpadding: 12px;
\t\t\t\tbackground: linear-gradient(135deg, #ffa200 0%, #e8910a 100%);
\t\t\t\tcolor: white;
\t\t\t\tborder: none;
\t\t\t\tborder-radius: 10px;
\t\t\t\tfont-weight: 600;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\tgap: 8px;
\t\t\t\ttext-decoration: none;
\t\t\t\ttransition: all 0.3s ease;
\t\t\t\tcursor: pointer;
\t\t\t}
\t\t\t.modern-product-card .btn-add-to-cart:hover {
\t\t\t\tbackground: linear-gradient(135deg, #e8910a 0%, #d6820a 100%);
\t\t\t\ttransform: translateY(-2px);
\t\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.4);
\t\t\t\tcolor: white;
\t\t\t}
\t\t\t/* Le bouton principal garde son design original */
\t\t\t.card_area .btn-add-to-cart {
\t\t\t\twidth: auto;
\t\t\t\tdisplay: inline-flex;
\t\t\t}
\t\t\t.modern-product-card .btn-add-to-cart:active {
\t\t\t\ttransform: translateY(0);
\t\t\t}
\t\t\t.modern-product-card .btn-add-to-cart i {
\t\t\t\tfont-size: 1.1rem;
\t\t\t}
\t\t\t/* Responsive adjustments */
\t\t\t@media (max-width: 768px) {
\t\t\t\t.product-image-wrapper {
\t\t\t\t\theight: 200px;
\t\t\t\t}
\t\t\t\t.product-info {
\t\t\t\t\tpadding: 16px;
\t\t\t\t}
\t\t\t\t.product-title {
\t\t\t\t\tfont-size: 0.95rem;
\t\t\t\t}
\t\t\t\t.product-price {
\t\t\t\t\tfont-size: 1.1rem;
\t\t\t\t}
\t\t\t\t.section-title h2 {
\t\t\t\t\tfont-size: 2rem !important;
\t\t\t\t}
\t\t\t}
\t\t\t@media (max-width: 576px) {
\t\t\t\t.product-image-wrapper {
\t\t\t\t\theight: 190px;
\t\t\t\t}
\t\t\t\t.product-info {
\t\t\t\t\tpadding: 14px;
\t\t\t\t}
\t\t\t\t.btn-add-to-cart {
\t\t\t\t\tpadding: 10px;
\t\t\t\t\tfont-size: 0.9rem;
\t\t\t\t}
\t\t\t}
\t\t\t/* Ensure fixed height for cards */
\t\t\t.col-6.col-md-4.col-lg-3 {
\t\t\t\tdisplay: flex;
\t\t\t}
\t\t\t.modern-product-card {
\t\t\t\twidth: 100%;
\t\t\t}
\t\t\t/* Loading state for add to cart button */
\t\t\t.btn-add-to-cart.loading {
\t\t\t\topacity: 0.7;
\t\t\t\tpointer-events: none;
\t\t\t}
\t\t\t.btn-add-to-cart.loading i {
\t\t\t\tanimation: spin 1s linear infinite;
\t\t\t}
\t\t\t@keyframes spin {
\t\t\t\tfrom { transform: rotate(0deg); }
\t\t\t\tto { transform: rotate(360deg); }
\t\t\t}
\t\t\t/* Success state - vert pour tous les boutons */
\t\t\t.btn-add-to-cart.success {
\t\t\t\tbackground: linear-gradient(135deg, #28a745 0%, #20c997 100%) !important;
\t\t\t}
\t\t\t/* Le bouton principal garde son style original même en success */
\t\t\t.card_area .btn-add-to-cart.success {
\t\t\t\tbackground: linear-gradient(135deg, #28a745 0%, #20c997 100%) !important;
\t\t\t}
\t{% endif %}
\t<script src=\"/ui/js/vendor/jquery-2.2.4.min.js\"></script>
\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js\" integrity=\"sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4\" crossorigin=\"anonymous\"></script>
\t<script src=\"/ui/js/vendor/bootstrap.min.js\"></script>
\t<script src=\"/ui/js/jquery.ajaxchimp.min.js\"></script>
\t<script src=\"/ui/js/jquery.nice-select.min.js\"></script>
\t<script src=\"/ui/js/jquery.sticky.js\"></script>
\t<script src=\"/ui/js/nouislider.min.js\"></script>
\t<script src=\"/ui/js/jquery.magnific-popup.min.js\"></script>
\t<script src=\"/ui/js/owl.carousel.min.js\"></script>
\t<!--gmaps Js-->
\t<script src=\"https://maps.googleapis.com/maps/api/js?key=AIzaSyCjCGmQ0Uq4exrzdcL6rvxywDDOvfAu6eE\"></script>
\t<script src=\"/ui/js/gmaps.min.js\"></script>
\t<script src=\"/ui/js/main.js\"></script>
\t
\t<!-- Product Image Navigation - Chargé en dernier pour éviter les conflits -->
\t<script src=\"/ui/js/product-image-navigation.js\"></script>
\t
\t<script>
// Variables globales pour la navigation des images (utilisées par le script externe)
window.productImages = [];
window.currentImageIndex = 0;
let mainImageElement, currentIndexElement, indicatorsElements;
// Test pour vérifier que les fonctions sont définies
window.testImageNavigation = function() {
console.log('Testing image navigation functions...');
if (window.productImageNav) {
console.log('productImageNav object:', window.productImageNav);
console.log('nextImage function:', typeof window.productImageNav.nextImage);
console.log('prevImage function:', typeof window.productImageNav.prevImage);
console.log('changeMainImageByIndex function:', typeof window.productImageNav.changeMainImageByIndex);
console.log('State:', window.productImageNav.getState());
} else {
console.warn('productImageNav not available');
}
};
// Fonction pour nettoyer le cache PWA et désenregistrer le Service Worker
window.clearPWACache = function() {
console.log('🧹 Nettoyage du cache PWA...');
// Désenregistrer tous les Service Workers
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
console.log('Désenregistrement du Service Worker:', registration.scope);
registration.unregister().then(function(boolean) {
console.log('Service Worker désenregistré:', boolean);
});
}
});
}
// Vider tous les caches
if ('caches' in window) {
caches.keys().then(function(names) {
for (let name of names) {
console.log('Suppression du cache:', name);
caches.delete(name);
}
});
}
// Forcer le rechargement de la page après nettoyage
setTimeout(function() {
console.log('🔄 Rechargement de la page...');
window.location.reload(true);
}, 1000);
};
console.log('💡 Pour nettoyer le cache PWA, tapez: clearPWACache() dans la console');
// Fonction pour vérifier l'état du cache PWA
window.checkPWACache = function() {
console.log('🔍 Vérification de l\\'état PWA...');
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then(function(registrations) {
console.log('Service Workers enregistrés:', registrations.length);
registrations.forEach(function(registration, index) {
console.log(`SW \${index + 1}:`, registration.scope, registration.active ? 'ACTIF' : 'INACTIF');
});
});
} else {
console.log('Service Worker non supporté');
}
if ('caches' in window) {
caches.keys().then(function(names) {
console.log('Caches disponibles:', names.length);
names.forEach(function(name) {
console.log('- Cache:', name);
});
});
} else {
console.log('Cache API non supporté');
}
};
console.log('💡 Pour vérifier l\\'état PWA, tapez: checkPWACache() dans la console');
// Nettoyage automatique du cache PWA pour les tests (à supprimer en production)
if (window.location.search.includes('clearcache')) {
console.log('🧹 Nettoyage automatique du cache PWA demandé via URL');
clearPWACache();
}
// NOTE: La navigation des images principales est gérée par product-image-navigation.js
// Les fonctions sont exposées via window.productImageNav pour le débogage
// NOTE: La navigation des images principales est gérée par product-image-navigation.js
// Le script externe initialise automatiquement les images depuis les thumbnails
// Pas besoin de réinitialiser ici pour éviter les conflits
// Gestion du carrousel de miniatures avec taille fixe carrée
const navUpBtn = document.getElementById('thumbnail-nav-up');
const navDownBtn = document.getElementById('thumbnail-nav-down');
const thumbnailsContainer = document.getElementById('product-thumbnails');
const thumbnailsWrapper = document.getElementById('thumbnails-wrapper');
const thumbnailItems = Array.from(document.querySelectorAll('.thumbnail-item'));
let currentThumbnailOffset = 0;
const thumbnailHeight = 90;
// 80px (hauteur) + 10px (gap)
// Calculer la hauteur disponible pour les miniatures dynamiquement
const thumbnailsEl = document.getElementById('product-thumbnails');
let containerHeight = thumbnailsEl ? thumbnailsEl.clientHeight : 520; // Hauteur par défaut si non disponible
let visibleThumbnails = Math.floor(containerHeight / thumbnailHeight);
// Recalculer après le chargement pour avoir la vraie hauteur
setTimeout(() => {
if (thumbnailsEl) {
containerHeight = thumbnailsEl.clientHeight;
visibleThumbnails = Math.floor(containerHeight / thumbnailHeight);
updateThumbnailsPosition();
}
}, 100);
function getCurrentIndex() {
const current = document.querySelector('.thumbnail-item.permanently-active') || document.querySelector('.thumbnail-item.active');
if (! current)
return 0;
const idxAttr = current.getAttribute('data-index');
if (idxAttr !== null) {
return parseInt(idxAttr, 10);
}
const index = thumbnailItems.indexOf(current);
return index >= 0 ? index : 0;
}
function selectThumbnailByIndex(newIndex) {
if (! thumbnailItems.length)
return;
const total = thumbnailItems.length;
if (newIndex < 0)
newIndex = 0;
if (newIndex > total - 1)
newIndex = total - 1;
// Reset classes
thumbnailItems.forEach(t => t.classList.remove('active', 'permanently-active'));
const target = thumbnailItems[newIndex];
if (! target)
return;
target.classList.add('active', 'permanently-active');
// Utiliser la fonction du script externe si disponible
if (window.productImageNav && typeof window.productImageNav.changeMainImageByIndex === 'function') {
window.productImageNav.changeMainImageByIndex(newIndex);
} else {
// Fallback : changer l'image directement
const imageUrl = target.getAttribute('data-image');
const mainImg = document.getElementById('main-product-image');
if (mainImg && imageUrl) {
mainImg.src = imageUrl;
}
}
// Ajuster le carrousel pour voir la miniature sélectionnée
ensureThumbnailVisible(newIndex);
}
function ensureThumbnailVisible(index) {
if (! thumbnailsWrapper || ! thumbnailItems.length)
return;
const targetTop = index * thumbnailHeight;
const visibleTop = currentThumbnailOffset * thumbnailHeight;
const visibleBottom = visibleTop + containerHeight;
// Si la miniature est au-dessus de la zone visible
if (targetTop < visibleTop) {
currentThumbnailOffset = index;
updateThumbnailsPosition();
}
// Si la miniature est en-dessous de la zone visible else if (targetTop + thumbnailHeight > visibleBottom) {
currentThumbnailOffset = Math.max(0, index - visibleThumbnails + 1);
updateThumbnailsPosition();
}
}
function updateThumbnailsPosition() {
if (!thumbnailsWrapper)
return;
const maxOffset = Math.max(0, thumbnailItems.length - visibleThumbnails);
currentThumbnailOffset = Math.max(0, Math.min(currentThumbnailOffset, maxOffset));
thumbnailsWrapper.style.transform = `translateY(-\${
currentThumbnailOffset * thumbnailHeight
}px)`;
updateNavButtons();
}
function updateNavButtons() {
if (!thumbnailItems.length)
return;
const maxOffset = Math.max(0, thumbnailItems.length - visibleThumbnails);
const canScrollUp = currentThumbnailOffset > 0;
const canScrollDown = currentThumbnailOffset < maxOffset;
if (navUpBtn) {
navUpBtn.classList.toggle('disabled', ! canScrollUp);
}
if (navDownBtn) {
navDownBtn.classList.toggle('disabled', ! canScrollDown);
}
}
// Navigation avec les boutons
if(navUpBtn) {
navUpBtn.addEventListener('click', function (e) {
e.preventDefault();
if (currentThumbnailOffset > 0) {
currentThumbnailOffset --;
updateThumbnailsPosition();
}
});
}
if(navDownBtn) {
navDownBtn.addEventListener('click', function (e) {
e.preventDefault();
const maxOffset = Math.max(0, thumbnailItems.length - visibleThumbnails);
if (currentThumbnailOffset < maxOffset) {
currentThumbnailOffset ++;
updateThumbnailsPosition();
}
});
}
// Initialiser le carrousel
if(thumbnailsWrapper && thumbnailItems.length > 0) {
updateThumbnailsPosition();
// S'assurer que la première miniature est visible
ensureThumbnailVisible(0);
// Sélectionner la première image par défaut si aucune n'est sélectionnée
if (!document.querySelector('.thumbnail-item.permanently-active') && !document.querySelector('.thumbnail-item.active')) {
selectThumbnailByIndex(0);
}
// Initialiser l'index actuel via le script externe si disponible
// Le script externe product-image-navigation.js gère déjà l'initialisation
if (window.productImageNav && typeof window.productImageNav.getState === 'function') {
const state = window.productImageNav.getState();
if (state.productImages && state.productImages.length > 0) {
window.productImageNav.changeMainImageByIndex(0);
}
}
}
// NOTE: La navigation des images principales est maintenant gérée par product-image-navigation.js
// Ce fichier externe évite les conflits avec cart-modal.js et autres scripts
}, 100); // Fin du setTimeout
}); // Fin du DOMContentLoaded
// --- Prix de gros : calcul du prix unitaire dynamique ---
(function () {
const bulk = document.getElementById('bulk-pricing');
const qtyInputEl = document.getElementById('sst');
const unitPriceSpan = document.getElementById('unit-price-value');
const mainUnitPriceSpan = document.getElementById('main-unit-price');
const totalPriceSpan = document.getElementById('total-price-value');
const savingsAmountSpan = document.getElementById('savings-amount');
const savingsPercentSpan = document.getElementById('savings-percent');
const unitPriceInput = document.getElementById('unit-price-input');
const tierRowsTbody = document.getElementById('bulk-tier-rows');
if (! bulk || ! qtyInputEl || ! unitPriceSpan || ! mainUnitPriceSpan || ! unitPriceInput)
return;
let tiers = [];
try {
tiers = JSON.parse(bulk.getAttribute('data-tiers') || '[]');
} catch (e) {
tiers = [];
}
if (!Array.isArray(tiers) || tiers.length === 0)
return;
tiers.sort(function (a, b) {
return(a.min || 0) - (b.min || 0);
});
const basePrice = (function () {
const one = tiers.find(t => (t.min || 0) <= 1);
return one ? parseFloat(one.price) : parseFloat(tiers[0].price);
})();
function getUnitPriceForQty(qty) {
let candidate = tiers[0] || null;
for (let i = 0; i < tiers.length; i++) {
if (qty >= (tiers[i].min || 1)) {
candidate = tiers[i];
}
}
return candidate ? parseFloat(candidate.price) : (tiers[0] ? parseFloat(tiers[0].price) : basePrice);
}
function formatPrice(val) {
return(parseFloat(val) || 0).toFixed(2);
}
function highlightActiveTier(qty) {
if (! tierRowsTbody)
return;
const rows = tierRowsTbody.querySelectorAll('tr');
rows.forEach(r => r.classList.remove('table-warning'));
let activeRow = null;
rows.forEach(r => {
const m = parseInt(r.getAttribute('data-min'), 10) || 1;
if (qty >= m)
activeRow = r;
});
if (activeRow)
activeRow.classList.add('table-warning');
}
function refreshPrices() {
const qty = Math.max(1, parseInt(qtyInputEl.value, 10) || 1);
const unit = getUnitPriceForQty(qty);
const total = unit * qty;
const saveAmount = Math.max(0, (basePrice - unit) * qty);
const savePercent = Math.max(0, 100 * (basePrice - unit) / basePrice);
unitPriceSpan.textContent = formatPrice(unit) + ' HTG';
mainUnitPriceSpan.textContent = formatPrice(unit);
if (totalPriceSpan)
totalPriceSpan.textContent = formatPrice(total);
if (savingsAmountSpan)
savingsAmountSpan.textContent = formatPrice(saveAmount);
if (savingsPercentSpan)
savingsPercentSpan.textContent = Math.round(savePercent);
unitPriceInput.value = formatPrice(unit);
highlightActiveTier(qty);
}
qtyInputEl.addEventListener('input', refreshPrices);
qtyInputEl.addEventListener('change', refreshPrices);
setTimeout(refreshPrices, 50);
setInterval(refreshPrices, 350);
})();
// --- /Prix de gros ---
// Améliorer les boutons de quantité avec gestion de l'état disabled
(function() {
const qtyInput = document.getElementById('sst');
const decreaseBtn = document.querySelector('.quantity-btn-decrease');
const increaseBtn = document.querySelector('.quantity-btn-increase');
if (!qtyInput || !decreaseBtn || !increaseBtn) return;
const maxStock = parseInt(qtyInput.getAttribute('max') || '99', 10);
function updateButtonStates() {
const currentValue = parseInt(qtyInput.value, 10) || 1;
// Désactiver le bouton decrease si la valeur est 1
if (currentValue <= 1) {
decreaseBtn.disabled = true;
} else {
decreaseBtn.disabled = false;
}
// Désactiver le bouton increase si la valeur est au maximum
if (currentValue >= maxStock) {
increaseBtn.disabled = true;
} else {
increaseBtn.disabled = false;
}
}
// Mettre à jour l'état des boutons au chargement
updateButtonStates();
// Mettre à jour l'état des boutons lors des changements
qtyInput.addEventListener('input', updateButtonStates);
qtyInput.addEventListener('change', updateButtonStates);
// Mettre à jour l'état après les clics sur les boutons
decreaseBtn.addEventListener('click', function() {
setTimeout(updateButtonStates, 10);
});
increaseBtn.addEventListener('click', function() {
setTimeout(updateButtonStates, 10);
});
})();
// Injection du prix unitaire dans l'ajout au panier
(function () {
const addToCartBtn = document.getElementById('add-to-cart-btn');
if (! addToCartBtn)
return;
addToCartBtn.addEventListener('click', function () {
const unitPriceInput = document.getElementById('unit-price-input');
if (unitPriceInput) {
addToCartBtn.setAttribute('data-unit-price', unitPriceInput.value);
}
});
})();
// Fonction pour ouvrir le modal de zoom avec loader
function openImageZoom () {
const mainImage = document.getElementById('main-product-image');
const zoomModal = document.getElementById('image-zoom-modal');
const zoomImage = document.getElementById('zoom-modal-image');
const zoomLoader = document.getElementById('zoom-loader');
if (mainImage && zoomModal && zoomImage) { // Afficher le loader
if (zoomLoader) {
zoomLoader.style.display = 'flex';
}
// Masquer l'image et réinitialiser
zoomImage.classList.remove('loaded');
zoomImage.style.opacity = '0';
// Ouvrir le modal avec animation
zoomModal.classList.add('active');
document.body.style.overflow = 'hidden';
// Charger l'image
const imageUrl = mainImage.src;
const tempImage = new Image();
tempImage.onload = function () {
zoomImage.src = imageUrl;
// Masquer le loader et afficher l'image avec transition
setTimeout(function () {
if (zoomLoader) {
zoomLoader.style.display = 'none';
}
zoomImage.classList.add('loaded');
zoomImage.style.opacity = '1';
}, 200);
};
tempImage.onerror = function () {
if (zoomLoader) {
zoomLoader.style.display = 'none';
}
zoomImage.src = imageUrl;
zoomImage.classList.add('loaded');
};
tempImage.src = imageUrl;
}
}
// Fonction pour fermer le modal de zoom avec animation
function closeImageZoom () {
const zoomModal = document.getElementById('image-zoom-modal');
const zoomImage = document.getElementById('zoom-modal-image');
const zoomLoader = document.getElementById('zoom-loader');
if (zoomModal) { // Animation de fermeture
if (zoomImage) {
zoomImage.style.opacity = '0';
zoomImage.classList.remove('loaded');
}
setTimeout(function () {
zoomModal.classList.remove('active');
document.body.style.overflow = 'auto';
// Réinitialiser le loader pour la prochaine ouverture
if (zoomLoader) {
zoomLoader.style.display = 'none';
}
}, 200);
}
}
// Fermer le modal en cliquant en dehors
document.addEventListener('DOMContentLoaded', function () {
const zoomModal = document.getElementById('image-zoom-modal');
if (zoomModal) {
zoomModal.addEventListener('click', function (e) {
if (e.target === zoomModal) {
closeImageZoom();
}
});
}
});
\t</script>
\t<!-- Modal de zoom d'image -->
\t<div id=\"image-zoom-modal\" class=\"image-zoom-modal\">
\t\t<span class=\"close-zoom\" onclick=\"closeImageZoom()\" title=\"Fermer\">×</span>
\t\t<div
\t\t\tclass=\"zoom-modal-content\">
\t\t\t<!-- Loader -->
\t\t\t<div class=\"zoom-loader\" id=\"zoom-loader\" style=\"display: none;\">
\t\t\t\t<div class=\"zoom-loader-spinner\"></div>
\t\t\t\t<div class=\"zoom-loader-text\">Chargement...</div>
\t\t\t</div>
\t\t\t<!-- Image -->
\t\t\t<img id=\"zoom-modal-image\" src=\"\" alt=\"{{ product.name }}\">
\t\t</div>
\t</div>
\t{% if dropshipReferral %}
\t\t<!-- Modal d'affiliation -->
\t\t<div id=\"dropship-modal\" class=\"dropship-referral-modal\" style=\"display: none;\">
\t\t\t<div class=\"dropship-modal-overlay\"></div>
\t\t\t<div class=\"dropship-modal-content\">
\t\t\t\t<button type=\"button\" class=\"dropship-modal-close\" onclick=\"closeDropshipModal()\" aria-label=\"Fermer\">
\t\t\t\t\t×
\t\t\t\t</button>
\t\t\t\t<div class=\"dropship-modal-header\">
\t\t\t\t\t<div class=\"dropship-icon\">
\t\t\t\t\t\t<i class=\"fas fa-gift\"></i>
\t\t\t\t\t</div>
\t\t\t\t\t<h3>Produit recommandé par
\t\t\t\t\t\t{{ dropshipReferral.affiliateName }}</h3>
\t\t\t\t\t<p class=\"dropship-subtitle\">Vous avez été dirigé vers ce produit par un de nos partenaires</p>
\t\t\t\t</div>
\t\t\t\t<div class=\"dropship-modal-body\">
\t\t\t\t\t<div class=\"dropship-product-info\">
\t\t\t\t\t\t{% if product.images|length > 0 %}
\t\t\t\t\t\t\t<img src=\"{{ asset(product.images[0]) }}\" alt=\"{{ product.name }}\" class=\"dropship-product-image\" onerror=\"this.style.display='none'; this.nextElementSibling.style.display='flex';\">
\t\t\t\t\t\t\t<div class=\"dropship-product-image-placeholder\" style=\"display: none; width: 100px; height: 100px; background: #f0f0f0; border-radius: 8px; align-items: center; justify-content: center; color: #999;\">
\t\t\t\t\t\t\t\t<i class=\"fas fa-image\" style=\"font-size: 32px;\"></i>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t<div class=\"dropship-product-image-placeholder\" style=\"width: 100px; height: 100px; background: #f0f0f0; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #999;\">
\t\t\t\t\t\t\t\t<i class=\"fas fa-image\" style=\"font-size: 32px;\"></i>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t<div class=\"dropship-product-details\">
\t\t\t\t\t\t\t<h4>{{ product.name }}</h4>
\t\t\t\t\t\t\t<div class=\"dropship-product-price\">
\t\t\t\t\t\t\t\t<span class=\"price\">{{ product.price|number_format(2, ',', ' ') }}
\t\t\t\t\t\t\t\t\tHTG</span>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t</div>
\t\t\t\t\t</div>
\t\t\t\t\t<div class=\"dropship-message\">
\t\t\t\t\t\t<p>
\t\t\t\t\t\t\t<strong>{{ dropshipReferral.affiliateName }}</strong>
\t\t\t\t\t\t\tvous recommande ce produit. Souhaitez-vous l'ajouter à votre panier ?</p>
\t\t\t\t\t</div>
\t\t\t\t</div>
\t\t\t\t<div class=\"dropship-modal-footer\">
\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" onclick=\"closeDropshipModal()\">
\t\t\t\t\t\tParcourir d'abord
\t\t\t\t\t</button>
\t\t\t\t\t<button type=\"button\" class=\"btn btn-primary dropship-add-to-cart\" onclick=\"addToCartFromDropship()\">
\t\t\t\t\t\t<i class=\"fas fa-shopping-cart\"></i>
\t\t\t\t\t\tAjouter au panier
\t\t\t\t\t</button>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t\t<style>
\t\t\t.dropship-referral-modal {
\t\t\t\tposition: fixed;
\t\t\t\ttop: 0;
\t\t\t\tleft: 0;
\t\t\t\twidth: 100%;
\t\t\t\theight: 100%;
\t\t\t\tz-index: 10000;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t}
\t\t\t.dropship-modal-overlay {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 0;
\t\t\t\tleft: 0;
\t\t\t\twidth: 100%;
\t\t\t\theight: 100%;
\t\t\t\tbackground: rgba(0, 0, 0, 0.6);
\t\t\t\tbackdrop-filter: blur(4px);
\t\t\t}
\t\t\t.dropship-modal-content {
\t\t\t\tposition: relative;
\t\t\t\tbackground: white;
\t\t\t\tborder-radius: 16px;
\t\t\t\tbox-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
\t\t\t\tmax-width: 500px;
\t\t\t\twidth: 90%;
\t\t\t\tmax-height: 90vh;
\t\t\t\toverflow-y: auto;
\t\t\t\tz-index: 10001;
\t\t\t\tanimation: dropshipModalSlideIn 0.3s ease-out;
\t\t\t}
\t\t\t@keyframes dropshipModalSlideIn {
\t\t\t\tfrom {
\t\t\t\t\topacity: 0;
\t\t\t\t\ttransform: translateY(-30px) scale(0.95);
\t\t\t\t}
\t\t\t\tto {
\t\t\t\t\topacity: 1;
\t\t\t\t\ttransform: translateY(0) scale(1);
\t\t\t\t}
\t\t\t}
\t\t\t.dropship-modal-close {
\t\t\t\tposition: absolute;
\t\t\t\ttop: 15px;
\t\t\t\tright: 15px;
\t\t\t\tbackground: none;
\t\t\t\tborder: none;
\t\t\t\tfont-size: 28px;
\t\t\t\tcolor: #666;
\t\t\t\tcursor: pointer;
\t\t\t\twidth: 35px;
\t\t\t\theight: 35px;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\tborder-radius: 50%;
\t\t\t\ttransition: all 0.2s;
\t\t\t\tz-index: 10;
\t\t\t}
\t\t\t.dropship-modal-close:hover {
\t\t\t\tbackground: #f0f0f0;
\t\t\t\tcolor: #333;
\t\t\t}
\t\t\t.dropship-modal-header {
\t\t\t\tpadding: 30px 30px 20px;
\t\t\t\ttext-align: center;
\t\t\t\tborder-bottom: 1px solid #f0f0f0;
\t\t\t}
\t\t\t.dropship-icon {
\t\t\t\twidth: 70px;
\t\t\t\theight: 70px;
\t\t\t\tmargin: 0 auto 15px;
\t\t\t\tbackground: linear-gradient(135deg, #ffa200 0%, #ff8c00 100%);
\t\t\t\tborder-radius: 50%;
\t\t\t\tdisplay: flex;
\t\t\t\talign-items: center;
\t\t\t\tjustify-content: center;
\t\t\t\tfont-size: 32px;
\t\t\t\tcolor: white;
\t\t\t\tbox-shadow: 0 4px 15px rgba(255, 162, 0, 0.3);
\t\t\t}
\t\t\t.dropship-modal-header h3 {
\t\t\t\tmargin: 0 0 8px;
\t\t\t\tfont-size: 22px;
\t\t\t\tfont-weight: 600;
\t\t\t\tcolor: #333;
\t\t\t}
\t\t\t.dropship-subtitle {
\t\t\t\tmargin: 0;
\t\t\t\tcolor: #666;
\t\t\t\tfont-size: 14px;
\t\t\t}
\t\t\t.dropship-modal-body {
\t\t\t\tpadding: 25px 30px;
\t\t\t}
\t\t\t.dropship-product-info {
\t\t\t\tdisplay: flex;
\t\t\t\tgap: 15px;
\t\t\t\tmargin-bottom: 20px;
\t\t\t\tpadding: 15px;
\t\t\t\tbackground: #f8f9fa;
\t\t\t\tborder-radius: 10px;
\t\t\t}
\t\t\t.dropship-product-image {
\t\t\t\twidth: 80px;
\t\t\t\theight: 80px;
\t\t\t\tobject-fit: cover;
\t\t\t\tborder-radius: 8px;
\t\t\t\tflex-shrink: 0;
\t\t\t}
\t\t\t.dropship-product-details {
\t\t\t\tflex: 1;
\t\t\t}
\t\t\t.dropship-product-details h4 {
\t\t\t\tmargin: 0 0 8px;
\t\t\t\tfont-size: 16px;
\t\t\t\tfont-weight: 600;
\t\t\t\tcolor: #333;
\t\t\t}
\t\t\t.dropship-product-price {
\t\t\t\tmargin-top: 5px;
\t\t\t}
\t\t\t.dropship-product-price .price {
\t\t\t\tfont-size: 20px;
\t\t\t\tfont-weight: 700;
\t\t\t\tcolor: #ffa200;
\t\t\t}
\t\t\t.dropship-message {
\t\t\t\tpadding: 15px;
\t\t\t\tbackground: #fff9e6;
\t\t\t\tborder-left: 4px solid #ffa200;
\t\t\t\tborder-radius: 6px;
\t\t\t}
\t\t\t.dropship-message p {
\t\t\t\tmargin: 0;
\t\t\t\tcolor: #666;
\t\t\t\tline-height: 1.6;
\t\t\t}
\t\t\t.dropship-modal-footer {
\t\t\t\tpadding: 20px 30px 30px;
\t\t\t\tdisplay: flex;
\t\t\t\tgap: 12px;
\t\t\t\tjustify-content: flex-end;
\t\t\t\tborder-top: 1px solid #f0f0f0;
\t\t\t}
\t\t\t.dropship-modal-footer .btn {
\t\t\t\tpadding: 12px 24px;
\t\t\t\tborder-radius: 8px;
\t\t\t\tfont-weight: 500;
\t\t\t\tborder: none;
\t\t\t\tcursor: pointer;
\t\t\t\ttransition: all 0.2s;
\t\t\t\tfont-size: 15px;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-secondary {
\t\t\t\tbackground: #f0f0f0;
\t\t\t\tcolor: #666;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-secondary:hover {
\t\t\t\tbackground: #e0e0e0;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-primary {
\t\t\t\tbackground: #ffa200;
\t\t\t\tcolor: white;
\t\t\t}
\t\t\t.dropship-modal-footer .btn-primary:hover {
\t\t\t\tbackground: #e8910a;
\t\t\t\ttransform: translateY(-2px);
\t\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.3);
\t\t\t}
\t\t\t.dropship-modal-footer .btn-primary:disabled {
\t\t\t\topacity: 0.6;
\t\t\t\tcursor: not-allowed;
\t\t\t\ttransform: none;
\t\t\t}
\t\t</style>
\t\t<script>
\t\t\t// Afficher le modal automatiquement au chargement de la page
document.addEventListener('DOMContentLoaded', function () {
const dropshipModal = document.getElementById('dropship-modal');
if (dropshipModal) {
setTimeout(function () {
dropshipModal.style.display = 'flex';
document.body.style.overflow = 'hidden';
}, 500); // Délai de 500ms pour une meilleure UX
}
});
function closeDropshipModal () {
const dropshipModal = document.getElementById('dropship-modal');
if (dropshipModal) {
dropshipModal.style.display = 'none';
document.body.style.overflow = 'auto';
}
}
function addToCartFromDropship () {
const addBtn = document.querySelector('.dropship-add-to-cart');
if (! addBtn)
return;
// Désactiver le bouton pendant le traitement
addBtn.disabled = true;
addBtn.innerHTML = '<i class=\"fas fa-spinner fa-spin\"></i> Ajout en cours...';
const productId = {{ product.id }};
const qty = parseInt(document.getElementById('sst') ?. value || '1');
// Utiliser fetch pour ajouter au panier
fetch('{{ path(\"ui_cart_add\") }}', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
},
body: new URLSearchParams(
{productId: productId, qty: qty}
)
}).then(response => response.json()).then(data => {
if (data.ok) { // Afficher un message de succès
const modalBody = document.querySelector('.dropship-modal-body');
if (modalBody) {
modalBody.innerHTML = `
\t\t\t\t\t\t\t\t<div style=\"text-align: center; padding: 30px 20px;\">
\t\t\t\t\t\t\t\t\t<div style=\"width: 80px; height: 80px; margin: 0 auto 20px; background: #d4edda; border-radius: 50%; display: flex; align-items: center; justify-content: center;\">
\t\t\t\t\t\t\t\t\t\t<i class=\"fas fa-check\" style=\"font-size: 40px; color: #28a745;\"></i>
\t\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t\t\t<h3 style=\"color: #28a745; margin-bottom: 10px;\">Produit ajouté avec succès !</h3>
\t\t\t\t\t\t\t\t\t<p style=\"color: #666; margin-bottom: 20px;\">Merci d'avoir utilisé le lien de recommandation de <strong>{{ dropshipReferral.affiliateName }}</strong></p>
\t\t\t\t\t\t\t\t\t<p style=\"color: #666; font-size: 14px;\">Vous pouvez continuer vos achats ou aller directement au panier.</p>
\t\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t`;
}
const modalFooter = document.querySelector('.dropship-modal-footer');
if (modalFooter) {
modalFooter.innerHTML = `
\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" onclick=\"closeDropshipModal()\">
\t\t\t\t\t\t\t\t\tContinuer les achats
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t<a href=\"{{ path('cart') }}\" class=\"btn btn-primary\" style=\"text-decoration: none; display: inline-block;\">
\t\t\t\t\t\t\t\t\t<i class=\"fas fa-shopping-cart\"></i> Voir le panier
\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t`;
}
// Mettre à jour le compteur du panier si présent
const cartCount = document.querySelector('.cart-count, .cart_count, [data-cart-count]');
if (cartCount) {
cartCount.textContent = data.totalQty || 0;
}
} else {
showCustomAlert('Erreur lors de l\\'ajout au panier. Veuillez réessayer.', 'error');
addBtn.disabled = false;
addBtn.innerHTML = '<i class=\"fas fa-shopping-cart\"></i> Ajouter au panier';
}
}).catch(error => {
console.error('Erreur:', error);
showCustomAlert('Une erreur est survenue. Veuillez réessayer.', 'error');
addBtn.disabled = false;
addBtn.innerHTML = '<i class=\"fas fa-shopping-cart\"></i> Ajouter au panier';
});
}
// Fermer le modal en cliquant sur l'overlay
document.addEventListener('DOMContentLoaded', function () {
const dropshipModal = document.getElementById('dropship-modal');
if (dropshipModal) {
const overlay = dropshipModal.querySelector('.dropship-modal-overlay');
if (overlay) {
overlay.addEventListener('click', function () {
closeDropshipModal();
});
}
}
});
\t\t</script>
\t{% endif %}
\t<!-- Modal personnalisé pour remplacer les alert -->
\t<div class=\"modal fade custom-alert-modal\" id=\"customAlertModal\" tabindex=\"-1\" aria-labelledby=\"customAlertModalLabel\" aria-hidden=\"true\">
\t\t<div class=\"modal-dialog modal-dialog-centered\">
\t\t\t<div class=\"modal-content\">
\t\t\t\t<div class=\"modal-header\">
\t\t\t\t\t<h5 class=\"modal-title text-white\" id=\"customAlertModalLabel\">Notification</h5>
\t\t\t\t\t<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>
\t\t\t\t</div>
\t\t\t\t<div class=\"modal-body\">
\t\t\t\t\t<div class=\"alert-icon\" id=\"alertIcon\">
\t\t\t\t\t\t<i class=\"lnr lnr-info-circle\"></i>
\t\t\t\t\t</div>
\t\t\t\t\t<p class=\"alert-message\" id=\"alertMessage\"></p>
\t\t\t\t</div>
\t\t\t\t<div class=\"modal-footer\">
\t\t\t\t\t<button type=\"button\" class=\"btn btn-primary\" data-bs-dismiss=\"modal\">OK</button>
\t\t\t\t</div>
\t\t\t</div>
\t\t</div>
\t</div>
\t<script>
\t\t// Fonction pour remplacer alert()
function showCustomAlert (message, type = 'info') {
const modal = new bootstrap.Modal(document.getElementById('customAlertModal'));
const alertMessage = document.getElementById('alertMessage');
const alertIcon = document.getElementById('alertIcon');
const modalTitle = document.getElementById('customAlertModalLabel');
alertMessage.textContent = message;
// Définir l'icône et le titre selon le type
let iconClass = 'lnr lnr-info-circle';
let title = 'Information';
switch (type) {
case 'success': iconClass = 'lnr lnr-checkmark-circle';
title = 'Succès';
alertIcon.className = 'alert-icon success';
break;
case 'error':
case 'danger': iconClass = 'lnr lnr-warning';
title = 'Erreur';
alertIcon.className = 'alert-icon error';
break;
case 'warning': iconClass = 'lnr lnr-warning';
title = 'Attention';
alertIcon.className = 'alert-icon warning';
break;
default: iconClass = 'lnr lnr-info-circle';
title = 'Information';
alertIcon.className = 'alert-icon info';
}
alertIcon.innerHTML = `<i class=\"\${iconClass}\"></i>`;
modalTitle.textContent = title;
modal.show();
}
// Remplacer window.alert par showCustomAlert
window.alert = showCustomAlert;
\t</script>
{% endblock %}
", "home/single-product.html.twig", "/home/u540977899/domains/maketou-ht.com/public_html/templates/home/single-product.html.twig");
}
}