<?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_aae7211b9c474856cd179227db62caa6 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 d'actions */
\t\t.card_area {
\t\t\tmargin-top: 20px;
\t\t\tgap: 12px;
\t\t}
\t\t.card_area .primary-btn {
\t\t\tbackground: #ffa200;
\t\t\tborder: none;
\t\t\tpadding: 0 30px;
\t\t\theight: 50px;
\t\t\tdisplay: inline-flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tborder-radius: 8px;
\t\t\tcolor: white;
\t\t\tfont-weight: 600;
\t\t\tfont-size: 16px;
\t\t\ttransition: all 0.3s ease;
\t\t\ttext-decoration: none;
\t\t\tgap: 8px;
\t\t\tflex: 1;
\t\t\tmax-width: 250px;
\t\t}
\t\t.card_area .primary-btn i {
\t\t\tfont-size: 20px;
\t\t}
\t\t.card_area .primary-btn:hover {
\t\t\tbackground: #e8910a;
\t\t\ttransform: translateY(-2px);
\t\t\tbox-shadow: 0 4px 15px rgba(255, 162, 0, 0.3);
\t\t\tcolor: white;
\t\t}
\t\t.card_area .icon_btn {
\t\t\tdisplay: inline-flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\twidth: 50px;
\t\t\theight: 50px;
\t\t\tborder-radius: 8px;
\t\t\tbackground: #fff;
\t\t\tcolor: #333;
\t\t\tborder: 1px solid #ddd;
\t\t\ttransition: all 0.3s ease;
\t\t\ttext-decoration: none;
\t\t}
\t\t.card_area .icon_btn i {
\t\t\tfont-size: 22px;
\t\t}
\t\t.card_area .icon_btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tcolor: white;
\t\t\tborder-color: #ffa200;
\t\t\ttransform: translateY(-2px);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.2);
\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\talign-items: stretch;
\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\theight: auto;
\t\t}
\t\t/* Les boutons sont toujours visibles (meilleur pour le mobile et l'UX) */
\t\t.thumbnails-container .thumbnail-nav-btn {
\t\t\ttransition: all 0.2s ease;
\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\tflex: 1;
\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\tpadding: 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: #fff;
\t\t\tborder-bottom: 2px solid #e0e0e0;
\t\t\tflex-shrink: 0;
\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;
\t\t\ttransition: transform 0.3s ease;
\t\t}
\t\t.thumbnail-item:hover img {
\t\t\ttransform: scale(1.1);
\t\t}
\t\t.thumbnail-item.active img {
\t\t\ttransform: scale(1.1);
\t\t}
\t\t.product-main-image-wrapper {
\t\t\tflex: 1;
\t\t\tposition: relative;
\t\t\tbackground: #fff;
\t\t\tborder-radius: 12px;
\t\t\toverflow: hidden;
\t\t\tborder: 1px solid #e0e0e0;
\t\t\tcursor: crosshair;
\t\t}
\t\t.product-main-image {
\t\t\tposition: relative;
\t\t\twidth: 100%;
\t\t\tpadding-top: 100%;
\t\t\toverflow: hidden;
\t\t\tbackground: #f8f9fa;
\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;
\t\t\ttransition: transform 0.15s ease-out;
\t\t\ttransform-origin: center center;
\t\t}
\t\t/* Supprimer le scale basique, géré en JS */
\t\t/* .product-main-image:hover img {
\t\t\ttransform: scale(1.05);
\t\t} */
\t\t.image-overlay-icons {
\t\t\tposition: absolute;
\t\t\ttop: 15px;
\t\t\tright: 15px;
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\tgap: 10px;
\t\t\tz-index: 20;
\t\t\tpointer-events: none;
\t\t}
\t\t.icon-btn {
\t\t\tpointer-events: all;
\t\t\twidth: 45px;
\t\t\theight: 45px;
\t\t\tborder-radius: 50%;
\t\t\tbackground: rgba(255, 255, 255, 0.95);
\t\t\tborder: none;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tpadding: 0;
\t\t\tcursor: pointer;
\t\t\ttransition: all 0.3s ease;
\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
\t\t\tcolor: #333;
\t\t}
\t\t.icon-btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tcolor: white;
\t\t\ttransform: scale(1.1);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.4);
\t\t}
\t\t.icon-btn i {
\t\t\tfont-size: 18px;
\t\t}
\t\t.favorite-btn.active {
\t\t\tbackground: #ff6b6b;
\t\t\tcolor: white;
\t\t}
\t\t.image-counter {
\t\t\tposition: absolute;
\t\t\tbottom: 15px;
\t\t\tright: 15px;
\t\t\tbackground: rgba(0, 0, 0, 0.7);
\t\t\tcolor: white;
\t\t\tpadding: 6px 12px;
\t\t\tborder-radius: 20px;
\t\t\tfont-size: 13px;
\t\t\tfont-weight: 600;
\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;
\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/* Boutons de navigation sur l'image principale */
\t\t.main-image-nav {
\t\t\tposition: absolute;
\t\t\ttop: 0;
\t\t\tbottom: 0;
\t\t\tleft: 0;
\t\t\tright: 0;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: space-between;
\t\t\tpadding: 0 15px;
\t\t\tpointer-events: none;
\t\t\tz-index: 15;
\t\t}
\t\t.main-image-nav-btn {
\t\t\tpointer-events: all;
\t\t\twidth: 44px;
\t\t\theight: 44px;
\t\t\tborder-radius: 50%;
\t\t\tbackground: rgba(255, 255, 255, 0.95);
\t\t\tborder: 2px solid #e0e0e0;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tpadding: 0;
\t\t\tbox-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
\t\t\tcolor: #333;
\t\t\ttransition: all 0.2s ease;
\t\t}
\t\t.main-image-nav-btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tborder-color: #ffa200;
\t\t\tcolor: #fff;
\t\t\ttransform: scale(1.08);
\t\t}
\t\t.main-image-nav-btn:active {
\t\t\ttransform: scale(0.95);
\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.image-overlay-icons {
\t\t\t\topacity: 1;
\t\t\t}
\t\t}
\t</style>
";
$__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
$__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
yield from [];
}
// line 657
/**
* @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 658
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 691
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", true, true, false, 691) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 691)) > 0))) {
// line 692
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), "images", [], "any", false, false, false, 692));
$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 693
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, 693)) && $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, 693), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t\t\t\t<img src=\"";
// line 694
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, 694), "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, 694), "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 697
yield "\t\t\t\t\t\t\t\t\t";
} else {
// line 698
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 699
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, 699), "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 702
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 712
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", true, true, false, 712) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 712)) > 0))) {
// line 713
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 = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 713)) && 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, 713), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t";
} else {
// line 715
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, 715), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t";
}
// line 717
yield "\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Overlay avec icônes -->
\t\t\t\t\t\t\t<div class=\"image-overlay-icons\">
\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<i class=\"lnr lnr-magnifier\"></i>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t\t<button class=\"icon-btn favorite-btn\" ";
// line 724
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 724)) && $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, 724), "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, 724), "html", null, true);
yield "\">
\t\t\t\t\t\t\t\t\t<i class=\"lnr lnr-heart\"></i>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Navigation sur l'image principale -->
\t\t\t\t\t\t\t<div class=\"main-image-nav\">
\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<i class=\"lnr lnr-chevron-left\"></i>
\t\t\t\t\t\t\t\t</button>
\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<i class=\"lnr lnr-chevron-right\"></i>
\t\t\t\t\t\t\t\t</button>
\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<span id=\"total-images\">";
// line 743
yield ((Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 743))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 743)), "html", null, true)) : (1));
yield "</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</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 750
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 750), "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 752
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, 752), 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 760
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, 760), "name", [], "any", false, false, false, 760), "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 766
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 766), "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<p>";
// line 769
yield Twig\Extension\CoreExtension::nl2br($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, 769)), "html", null, true));
yield "</p>
\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 776
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "shop", [], "any", true, true, false, 776) && CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "shop", [], "any", false, false, false, 776))) {
// line 777
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, 777), "slug", [], "any", false, false, false, 777)]), "html", null, true);
yield "\" class=\"shop-link\">
\t\t\t\t\t\t\t\t\t\t";
// line 778
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, 778), "name", [], "any", false, false, false, 778), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t</a>
\t\t\t\t\t\t\t\t";
} else {
// line 781
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 783
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<input type=\"text\" name=\"qty\" id=\"sst\" maxlength=\"12\" value=\"1\" title=\"Quantité:\" class=\"input-text qty\" max=\"";
// line 788
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", true, true, false, 788) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 788)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 788), "html", null, true)) : (99));
yield "\">
\t\t\t\t\t\t\t<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst < ";
// line 789
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", true, true, false, 789) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 789)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 789), "html", null, true)) : (99));
yield ") result.value++;return false;\" class=\"increase items-count\" type=\"button\">
\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<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst > 1 ) result.value--;return false;\" class=\"reduced items-count\" type=\"button\">
\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<input
\t\t\t\t\t\ttype=\"hidden\" id=\"unit-price-input\" value=\"";
// line 798
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, 798), 2, ".", ""), "html", null, true);
yield "\"/>
\t\t\t\t\t\t";
// line 801
yield "\t\t\t\t\t\t";
$context["tierPrices"] = [];
// line 802
yield "\t\t\t\t\t\t";
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "tierPrices", [], "any", true, true, false, 802) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "tierPrices", [], "any", false, false, false, 802)) > 0))) {
// line 803
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, 803));
foreach ($context['_seq'] as $context["_key"] => $context["tier"]) {
// line 804
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"], "minQty", [], "any", false, false, false, 804), "price" => CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "price", [], "any", false, false, false, 804)]]);
// line 805
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 806
yield "\t\t\t\t\t\t";
} else {
// line 807
yield "\t\t\t\t\t\t\t";
// line 808
yield "\t\t\t\t\t\t\t";
$context["tierPrices"] = [["min" => 1, "price" => CoreExtension::getAttribute($this->env, $this->source, // line 809
($context["product"] ?? null), "price", [], "any", false, false, false, 809)], ["min" => 5, "price" => Twig\Extension\CoreExtension::round((CoreExtension::getAttribute($this->env, $this->source, // line 810
($context["product"] ?? null), "price", [], "any", false, false, false, 810) * 0.98), 2, "floor")], ["min" => 10, "price" => Twig\Extension\CoreExtension::round((CoreExtension::getAttribute($this->env, $this->source, // line 811
($context["product"] ?? null), "price", [], "any", false, false, false, 811) * 0.95), 2, "floor")], ["min" => 20, "price" => Twig\Extension\CoreExtension::round((CoreExtension::getAttribute($this->env, $this->source, // line 812
($context["product"] ?? null), "price", [], "any", false, false, false, 812) * 0.92), 2, "floor")]];
// line 814
yield "\t\t\t\t\t\t";
}
// line 815
yield "
\t\t\t\t\t\t<div id=\"bulk-pricing\" class=\"mt-3\" data-tiers='";
// line 816
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(json_encode(($context["tierPrices"] ?? null)), "html_attr");
yield "'>
\t\t\t\t\t\t\t<div class=\"d-flex align-items-center mb-2\">
\t\t\t\t\t\t\t\t<strong class=\"me-2\">Prix unitaire selon quantité :</strong>
\t\t\t\t\t\t\t\t<span id=\"unit-price-value\">";
// line 819
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, 819), 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\t<div class=\"table-responsive\">
\t\t\t\t\t\t\t\t<table class=\"table table-sm mb-2\" style=\"border:1px solid #eee;\">
\t\t\t\t\t\t\t\t\t<thead class=\"table-light\">
\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t<th>Quantité min.</th>
\t\t\t\t\t\t\t\t\t\t\t<th>Prix unitaire (HTG)</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 831
$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, 831) <=> CoreExtension::getAttribute($this->env, $this->source, ($context["b"] ?? null), "min", [], "any", false, false, false, 831)); }));
foreach ($context['_seq'] as $context["_key"] => $context["tier"]) {
// line 832
yield "\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, 832), "html", null, true);
yield "\">
\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";
// line 834
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, $context["tier"], "min", [], "any", false, false, false, 834), "html", null, true);
yield "</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>";
// line 835
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, 835), 2, ".", " "), "html", null, true);
yield "</td>
\t\t\t\t\t\t\t\t\t\t\t</tr>
\t\t\t\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 838
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<div class=\"d-flex flex-wrap gap-3 align-items-baseline mb-2\">
\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<span id=\"total-price-value\">";
// line 844
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, 844), 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<small class=\"text-muted\">Le prix et le total s’adaptent automatiquement selon la quantité.</small>
\t\t\t\t\t\t</div>
\t\t\t\t\t\t<!-- Stock disponible -->
\t\t\t\t\t\t";
// line 858
if (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", true, true, false, 858)) {
// line 859
yield "\t\t\t\t\t\t\t<small class=\"text-muted\">Stock disponible :
\t\t\t\t\t\t\t\t";
// line 860
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 860), "html", null, true);
yield "
\t\t\t\t\t\t\t\tunités</small>
\t\t\t\t\t\t";
}
// line 863
yield "
\t\t\t\t\t\t<!-- Statistiques du produit -->
\t\t\t\t\t\t";
// line 865
if (array_key_exists("productStats", $context)) {
// line 866
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 870
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["productStats"] ?? null), "totalViews", [], "any", false, false, false, 870), "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 876
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["productStats"] ?? null), "salesCount", [], "any", false, false, false, 876), "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 882
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["productStats"] ?? null), "conversionRate", [], "any", false, false, false, 882), "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 889
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 891
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 891), "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 895
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 895), "html", null, true);
yield "\" ";
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 895)) && $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, 895), "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 898
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 898), "html", null, true);
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, 898), "html", null, true);
yield ", this); return false;\">
\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 930
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", true, true, false, 930) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 930)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 930), "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 936
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 936)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 937
yield "\t\t\t\t\t\t\t<div class=\"product-description-content\">
\t\t\t\t\t\t\t\t";
// line 938
yield Twig\Extension\CoreExtension::nl2br(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "description", [], "any", false, false, false, 938));
yield "
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t";
} else {
// line 941
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 943
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 947
if (((((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "weight", [], "any", false, false, false, 947) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "length", [], "any", false, false, false, 947)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 947)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 947)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "attributes", [], "any", false, false, false, 947))) {
// line 948
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 951
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "sku", [], "any", false, false, false, 951)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 952
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 957
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "sku", [], "any", false, false, false, 957), "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 961
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, 961)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 962
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 967
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "barcode", [], "any", false, false, false, 967), "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 971
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, 971)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 972
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 977
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, 977), "name", [], "any", false, false, false, 977), "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 981
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, 981)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 982
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 987
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, 987), "name", [], "any", false, false, false, 987), "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 991
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, 991)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 992
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 997
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "weight", [], "any", false, false, false, 997), "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 1002
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, 1002) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 1002)) || CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 1002))) {
// line 1003
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 1009
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "length", [], "any", false, false, false, 1009)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1010
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, 1010), "html", null, true);
yield "cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1012
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, 1012)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1013
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 1014
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "width", [], "any", false, false, false, 1014), "html", null, true);
yield "cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1016
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, 1016)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1017
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 1018
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "height", [], "any", false, false, false, 1018), "html", null, true);
yield "cm
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1020
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 1024
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, 1024))) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1025
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 1030
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stock", [], "any", false, false, false, 1030), "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 1035
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, 1035)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1036
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 1042
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1042) == "in_stock")) {
// line 1043
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 1044
($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1044) == "out_of_stock")) {
// line 1045
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 1046
($context["product"] ?? null), "stockStatus", [], "any", false, false, false, 1046) == "backorder")) {
// line 1047
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 1049
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, 1049), "html", null, true);
yield "
\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
}
// line 1051
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 1055
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, 1055)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1056
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 1067
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, 1067))) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1068
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, 1068));
foreach ($context['_seq'] as $context["key"] => $context["value"]) {
// line 1069
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 1071
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 1074
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 1078
yield "\t\t\t\t\t\t\t\t\t\t";
}
// line 1079
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 1083
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 1085
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 1093
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1093)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1094
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 1108
yield "\t\t\t\t\t\t\t<p class=\"text-center\">
\t\t\t\t\t\t\t\t<a href=\"";
// line 1109
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 1113
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 1123
yield (((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1123)) && $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, 1123), 1, ".", ","), "html", null, true)) : ("0.0"));
yield "</h4>
\t\t\t\t\t\t\t\t\t\t\t<h6>(";
// line 1124
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", true, true, false, 1124) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1124)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1124), "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 1131
yield (((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", true, true, false, 1131) && !(null === CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1131)))) ? ($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1131), "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 1134
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "averageRating", [], "any", false, false, false, 1134)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1135
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 1136
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(range(1, 5));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
// line 1137
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, 1137))) {
} 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 1139
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, 1139), 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 1143
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 1145
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 1150
if ((CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1150) && (CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1150) > 0))) {
// line 1151
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 1155
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, 1155), 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 1157
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "reviewCount", [], "any", false, false, false, 1157), "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 1161
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 1166
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 1171
if ((($tmp = CoreExtension::getAttribute($this->env, $this->source, ($context["app"] ?? null), "user", [], "any", false, false, false, 1171)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 1172
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 1178
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(range(5, 1));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
// line 1179
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 1180
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 1184
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 1197
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 1198
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 1202
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// 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</script>
\t";
// line 1293
if ((Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["youMightAlsoLike"] ?? null)) > 0)) {
// line 1294
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 1305
$context['_parent'] = $context;
$context['_seq'] = CoreExtension::ensureTraversable(($context["youMightAlsoLike"] ?? 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["relatedProduct"]) {
// line 1306
yield "\t\t\t\t\t\t<div class=\"col-xl-3 col-lg-4 col-md-6 col-sm-6 mb-4 d-flex align-items-stretch\">
\t\t\t\t\t\t\t";
// line 1307
yield from $this->load("home/_single_product_card.html.twig", 1307)->unwrap()->yield(CoreExtension::merge($context, ["product" => $context["relatedProduct"]]));
// line 1308
yield "\t\t\t\t\t\t</div>
\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['relatedProduct'], $context['_parent'], $context['loop']);
$context = array_intersect_key($context, $_parent) + $_parent;
// line 1310
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;
\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\t</style>
\t\t<script>
\t\t\t// Gestion des boutons d'ajout au panier (principal et section \"Vous pourriez aussi aimer\")
\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
\t\t\t\tconst addToCartButtons = document.querySelectorAll('.btn-add-to-cart');
\t\t\t\t
\t\t\t\taddToCartButtons.forEach(button => {
\t\t\t\t\tbutton.addEventListener('click', function(e) {
\t\t\t\t\t\te.preventDefault();
\t\t\t\t\t\te.stopPropagation();
\t\t\t\t\t\t
\t\t\t\t\t\tconst productId = this.getAttribute('data-product-id');
\t\t\t\t\t\t
\t\t\t\t\t\t// Pour le bouton principal, récupérer la quantité depuis l'input sst si disponible
\t\t\t\t\t\tlet qty = this.getAttribute('data-qty') || '1';
\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\tconst qtyInput = document.getElementById('sst');
\t\t\t\t\t\t\tif (qtyInput) {
\t\t\t\t\t\t\t\tqty = parseInt(qtyInput.value) || 1;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\tif (!productId) {
\t\t\t\t\t\t\tconsole.error('Product ID manquant');
\t\t\t\t\t\t\treturn false;
\t\t\t\t\t\t}
\t\t\t\t\t\t// Sauvegarder le contenu original
\t\t\t\t\t\tconst originalContent = this.innerHTML;
\t\t\t\t\t\t
\t\t\t\t\t\t// Désactiver le bouton et afficher le loading
\t\t\t\t\t\tthis.classList.add('loading');
\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\tthis.style.pointerEvents = 'none';
\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"lnr lnr-spinner\"></i> Ajout en cours...';
\t\t\t\t\t\t} else {
\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"ti ti-loader-2\"></i> <span>Ajout...</span>';
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\t// Construire le body de la requête
\t\t\t\t\t\tlet body = 'productId=' + encodeURIComponent(productId) + '&qty=' + encodeURIComponent(qty);
\t\t\t\t\t\t
\t\t\t\t\t\t// Pour le bouton principal, vérifier aussi le prix unitaire pour les prix de gros
\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\tconst unitPriceInput = document.getElementById('unit-price-input');
\t\t\t\t\t\t\tconst unitPrice = unitPriceInput ? unitPriceInput.value : '';
\t\t\t\t\t\t\tif (unitPrice) {
\t\t\t\t\t\t\t\tbody += '&unitPrice=' + encodeURIComponent(unitPrice);
\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// Faire la requête AJAX
\t\t\t\t\t\tfetch('";
// line 1643
yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ui_cart_add");
yield "', {
\t\t\t\t\t\t\tmethod: 'POST',
\t\t\t\t\t\t\theaders: {
\t\t\t\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',
\t\t\t\t\t\t\t\t'X-Requested-With': 'XMLHttpRequest'
\t\t\t\t\t\t\t},
\t\t\t\t\t\t\tbody: body
\t\t\t\t\t\t})
\t\t\t\t\t\t.then(response => {
\t\t\t\t\t\t\tif (!response.ok) {
\t\t\t\t\t\t\t\tthrow new Error('Erreur réseau: ' + response.status);
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\treturn response.json();
\t\t\t\t\t\t})
\t\t\t\t\t\t.then(data => {
\t\t\t\t\t\t\tif (data.ok || data.success) {
\t\t\t\t\t\t\t\t// Succès - Afficher l'animation de succès
\t\t\t\t\t\t\t\tthis.classList.remove('loading');
\t\t\t\t\t\t\t\tthis.classList.add('success');
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\t\tthis.style.background = 'linear-gradient(135deg, #28a745 0%, #20c997 100%)';
\t\t\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"lnr lnr-checkmark-circle\"></i> Ajouté !';
\t\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t\t// Afficher le message de confirmation si présent
\t\t\t\t\t\t\t\t\tconst cartMessage = document.getElementById('cart-message');
\t\t\t\t\t\t\t\t\tif (cartMessage) {
\t\t\t\t\t\t\t\t\t\tcartMessage.style.display = 'block';
\t\t\t\t\t\t\t\t\t\tsetTimeout(() => {
\t\t\t\t\t\t\t\t\t\t\tcartMessage.style.display = 'none';
\t\t\t\t\t\t\t\t\t\t}, 3000);
\t\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"ti ti-check\"></i> <span>Ajouté !</span>';
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t// Mettre à jour le compteur du panier si présent
\t\t\t\t\t\t\t\tconst cartBadge = document.querySelector('.cart-badge');
\t\t\t\t\t\t\t\tif (cartBadge) {
\t\t\t\t\t\t\t\t\tcartBadge.textContent = data.totalQty || data.quantity || 0;
\t\t\t\t\t\t\t\t\t// Animation du badge
\t\t\t\t\t\t\t\t\tcartBadge.style.transform = 'scale(1.2)';
\t\t\t\t\t\t\t\t\tsetTimeout(() => {
\t\t\t\t\t\t\t\t\t\tcartBadge.style.transform = 'scale(1)';
\t\t\t\t\t\t\t\t\t}, 300);
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t// Afficher une notification si la fonction existe
\t\t\t\t\t\t\t\tif (typeof showCustomAlert === 'function') {
\t\t\t\t\t\t\t\t\tshowCustomAlert('Produit ajouté au panier avec succès !', 'success');
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t// Restaurer le bouton après 2 secondes
\t\t\t\t\t\t\t\tsetTimeout(() => {
\t\t\t\t\t\t\t\t\tthis.classList.remove('success');
\t\t\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\t\t\tthis.style.background = '';
\t\t\t\t\t\t\t\t\t\tthis.style.pointerEvents = 'auto';
\t\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t\tthis.innerHTML = originalContent;
\t\t\t\t\t\t\t\t}, 2000);
\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\t// Erreur
\t\t\t\t\t\t\t\tthis.classList.remove('loading');
\t\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\t\tthis.style.pointerEvents = 'auto';
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\tthis.innerHTML = originalContent;
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\tconst message = data.message || 'Erreur lors de l\\'ajout au panier';
\t\t\t\t\t\t\t\tif (typeof showCustomAlert === 'function') {
\t\t\t\t\t\t\t\t\tshowCustomAlert(message, 'error');
\t\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\t\talert(message);
\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.catch(error => {
\t\t\t\t\t\t\tconsole.error('Erreur:', error);
\t\t\t\t\t\t\tthis.classList.remove('loading');
\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\tthis.style.pointerEvents = 'auto';
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\tthis.innerHTML = originalContent;
\t\t\t\t\t\t\t
\t\t\t\t\t\t\tif (typeof showCustomAlert === 'function') {
\t\t\t\t\t\t\t\tshowCustomAlert('Erreur lors de l\\'ajout au panier. Veuillez réessayer.', 'error');
\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\talert('Erreur lors de l\\'ajout au panier. Veuillez réessayer.');
\t\t\t\t\t\t\t}
\t\t\t\t\t\t});
\t\t\t\t\t\t
\t\t\t\t\t\treturn false;
\t\t\t\t\t});
\t\t\t\t});
\t\t\t});
\t\t</script>
\t";
}
// line 1741
yield "
\t<script src=\"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=\"js/vendor/bootstrap.min.js\"></script>
\t<script src=\"js/jquery.ajaxchimp.min.js\"></script>
\t<script src=\"js/jquery.nice-select.min.js\"></script>
\t<script src=\"js/jquery.sticky.js\"></script>
\t<script src=\"js/nouislider.min.js\"></script>
\t<script src=\"js/jquery.magnific-popup.min.js\"></script>
\t<script src=\"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=\"js/gmaps.min.js\"></script>
\t<script src=\"js/main.js\"></script>
\t<script>
\t\t// Le gestionnaire d'événements pour les boutons d'ajout au panier est déjà défini
\t\t// dans la section \"Vous pourriez aussi aimer\" et gère maintenant aussi le bouton principal
// Gestion de la galerie d'images
document.addEventListener('DOMContentLoaded', function () {
const thumbnails = document.querySelectorAll('.thumbnail-item');
const mainImage = document.getElementById('main-product-image');
const currentIndex = document.getElementById('current-image-index');
const totalImages = document.getElementById('total-images');
// Fonction pour changer l'image principale
function changeMainImage(thumbnail, index) {
const imageUrl = thumbnail.getAttribute('data-image');
if (mainImage && imageUrl) {
mainImage.style.opacity = '0';
setTimeout(() => {
mainImage.src = imageUrl;
mainImage.style.opacity = '1';
// Reset zoom
mainImage.style.transform = 'scale(1)';
mainImage.style.transformOrigin = 'center center';
}, 150);
}
// Mettre à jour l'indicateur
if (currentIndex) {
currentIndex.textContent = index + 1;
}
}
// Ajouter le zoom sur l'image principale au survol
const mainImageContainer = document.querySelector('.product-main-image-wrapper');
if (mainImageContainer && mainImage) {
\tmainImageContainer.addEventListener('mousemove', function(e) {
\t\tconst rect = mainImageContainer.getBoundingClientRect();
\t\tconst x = e.clientX - rect.left;
\t\tconst y = e.clientY - rect.top;
\t\t
\t\tconst xPercent = (x / rect.width) * 100;
\t\tconst yPercent = (y / rect.height) * 100;
\t\t
\t\tmainImage.style.transformOrigin = `\${xPercent}% \${yPercent}%`;
\t\tmainImage.style.transform = 'scale(2.2)'; // Zoom Alibaba-style
\t});
\t
\tmainImageContainer.addEventListener('mouseleave', function() {
\t\tmainImage.style.transformOrigin = 'center center';
\t\tmainImage.style.transform = 'scale(1)';
\t});
}
// Gérer le survol sur les miniatures (sélection permanente au survol)
thumbnails.forEach((thumbnail, index) => {
thumbnail.addEventListener('mouseenter', function () { // Retirer toutes les sélections permanentes
thumbnails.forEach(t => {
t.classList.remove('active', 'permanently-active');
});
// Ajouter active et permanently-active à la miniature survolée
thumbnail.classList.add('active', 'permanently-active');
// Changer l'image principale
changeMainImage(thumbnail, index);
});
});
// Gérer le clic sur les miniatures (sélection permanente)
thumbnails.forEach((thumbnail, index) => {
thumbnail.addEventListener('click', function () { // Retirer la classe active et permanently-active de toutes les miniatures
thumbnails.forEach(t => {
t.classList.remove('active', 'permanently-active');
});
// Ajouter les classes active et permanently-active à la miniature cliquée
thumbnail.classList.add('active', 'permanently-active');
// Changer l'image principale
changeMainImage(thumbnail, index);
});
});
// 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');
return idxAttr ? parseInt(idxAttr, 10) : Math.max(0, thumbnailItems.indexOf(current));
}
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');
changeMainImage(target, newIndex);
// 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);
}
// Navigation sur l'image principale
const mainPrev = document.getElementById('main-image-prev');
const mainNext = document.getElementById('main-image-next');
if(mainPrev) {
mainPrev.addEventListener('click', function (e) {
e.preventDefault();
const idx = getCurrentIndex();
selectThumbnailByIndex(idx - 1);
});
}
if(mainNext) {
mainNext.addEventListener('click', function (e) {
e.preventDefault();
const idx = getCurrentIndex();
selectThumbnailByIndex(idx + 1);
});
}
}
);
// --- 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 ---
// 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 2222
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 2222), "html", null, true);
yield "\">
\t\t</div>
\t</div>
\t";
// line 2226
if ((($tmp = ($context["dropshipReferral"] ?? null)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
// line 2227
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 2239
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["dropshipReferral"] ?? null), "affiliateName", [], "any", false, false, false, 2239), "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 2244
if ((Twig\Extension\CoreExtension::length($this->env->getCharset(), CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 2244)) > 0)) {
// line 2245
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((($_v1 = CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "images", [], "any", false, false, false, 2245)) && is_array($_v1) || $_v1 instanceof ArrayAccess ? ($_v1[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, 2245), "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 2250
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 2254
yield "\t\t\t\t\t\t<div class=\"dropship-product-details\">
\t\t\t\t\t\t\t<h4>";
// line 2255
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "name", [], "any", false, false, false, 2255), "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 2257
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, 2257), 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 2264
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["dropshipReferral"] ?? null), "affiliateName", [], "any", false, false, false, 2264), "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 2515
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["product"] ?? null), "id", [], "any", false, false, false, 2515), "html", null, true);
yield ";
const qty = parseInt(document.getElementById('sst') ?. value || '1');
// Utiliser fetch pour ajouter au panier
fetch('";
// line 2519
yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("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 2538
yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env, $this->source, ($context["dropshipReferral"] ?? null), "affiliateName", [], "any", false, false, false, 2538), "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 2550
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 2588
yield "
\t<!-- Le Modal personnalisé et showCustomAlert ont été déplacés dans base_home.html.twig pour une portée globale -->
\t<script>
\t\t// Remplacer window.alert par showCustomAlert
\t\twindow.alert = window.showCustomAlert || function(message) { console.log(\"Alert:\", message); };
\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 ( 3218 => 2588, 3177 => 2550, 3162 => 2538, 3140 => 2519, 3133 => 2515, 2879 => 2264, 2869 => 2257, 2864 => 2255, 2861 => 2254, 2855 => 2250, 2844 => 2245, 2842 => 2244, 2834 => 2239, 2820 => 2227, 2818 => 2226, 2811 => 2222, 2328 => 1741, 2227 => 1643, 1892 => 1310, 1877 => 1308, 1875 => 1307, 1872 => 1306, 1855 => 1305, 1842 => 1294, 1840 => 1293, 1747 => 1202, 1740 => 1198, 1737 => 1197, 1722 => 1184, 1712 => 1180, 1705 => 1179, 1701 => 1178, 1693 => 1172, 1691 => 1171, 1684 => 1166, 1677 => 1161, 1670 => 1157, 1665 => 1155, 1659 => 1151, 1657 => 1150, 1650 => 1145, 1646 => 1143, 1638 => 1139, 1626 => 1137, 1622 => 1136, 1619 => 1135, 1617 => 1134, 1611 => 1131, 1601 => 1124, 1597 => 1123, 1585 => 1113, 1578 => 1109, 1575 => 1108, 1559 => 1094, 1557 => 1093, 1547 => 1085, 1543 => 1083, 1537 => 1079, 1534 => 1078, 1524 => 1074, 1518 => 1071, 1514 => 1069, 1509 => 1068, 1506 => 1067, 1493 => 1056, 1490 => 1055, 1484 => 1051, 1478 => 1049, 1474 => 1047, 1472 => 1046, 1469 => 1045, 1467 => 1044, 1464 => 1043, 1462 => 1042, 1454 => 1036, 1451 => 1035, 1443 => 1030, 1436 => 1025, 1433 => 1024, 1427 => 1020, 1422 => 1018, 1419 => 1017, 1416 => 1016, 1411 => 1014, 1408 => 1013, 1405 => 1012, 1399 => 1010, 1397 => 1009, 1389 => 1003, 1386 => 1002, 1378 => 997, 1371 => 992, 1368 => 991, 1361 => 987, 1354 => 982, 1351 => 981, 1344 => 977, 1337 => 972, 1334 => 971, 1327 => 967, 1320 => 962, 1317 => 961, 1310 => 957, 1303 => 952, 1301 => 951, 1296 => 948, 1294 => 947, 1288 => 943, 1284 => 941, 1278 => 938, 1275 => 937, 1273 => 936, 1264 => 930, 1227 => 898, 1213 => 895, 1206 => 891, 1202 => 889, 1192 => 882, 1183 => 876, 1174 => 870, 1168 => 866, 1166 => 865, 1162 => 863, 1156 => 860, 1153 => 859, 1151 => 858, 1134 => 844, 1126 => 838, 1117 => 835, 1113 => 834, 1107 => 832, 1103 => 831, 1088 => 819, 1082 => 816, 1079 => 815, 1076 => 814, 1074 => 812, 1073 => 811, 1072 => 810, 1071 => 809, 1069 => 808, 1067 => 807, 1064 => 806, 1058 => 805, 1055 => 804, 1050 => 803, 1047 => 802, 1044 => 801, 1039 => 798, 1027 => 789, 1023 => 788, 1016 => 783, 1012 => 781, 1006 => 778, 1001 => 777, 999 => 776, 989 => 769, 983 => 766, 974 => 760, 963 => 752, 958 => 750, 948 => 743, 918 => 724, 909 => 717, 901 => 715, 893 => 713, 891 => 712, 879 => 702, 871 => 699, 866 => 698, 863 => 697, 842 => 694, 831 => 693, 813 => 692, 811 => 691, 776 => 658, 763 => 657, 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 d'actions */
\t\t.card_area {
\t\t\tmargin-top: 20px;
\t\t\tgap: 12px;
\t\t}
\t\t.card_area .primary-btn {
\t\t\tbackground: #ffa200;
\t\t\tborder: none;
\t\t\tpadding: 0 30px;
\t\t\theight: 50px;
\t\t\tdisplay: inline-flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tborder-radius: 8px;
\t\t\tcolor: white;
\t\t\tfont-weight: 600;
\t\t\tfont-size: 16px;
\t\t\ttransition: all 0.3s ease;
\t\t\ttext-decoration: none;
\t\t\tgap: 8px;
\t\t\tflex: 1;
\t\t\tmax-width: 250px;
\t\t}
\t\t.card_area .primary-btn i {
\t\t\tfont-size: 20px;
\t\t}
\t\t.card_area .primary-btn:hover {
\t\t\tbackground: #e8910a;
\t\t\ttransform: translateY(-2px);
\t\t\tbox-shadow: 0 4px 15px rgba(255, 162, 0, 0.3);
\t\t\tcolor: white;
\t\t}
\t\t.card_area .icon_btn {
\t\t\tdisplay: inline-flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\twidth: 50px;
\t\t\theight: 50px;
\t\t\tborder-radius: 8px;
\t\t\tbackground: #fff;
\t\t\tcolor: #333;
\t\t\tborder: 1px solid #ddd;
\t\t\ttransition: all 0.3s ease;
\t\t\ttext-decoration: none;
\t\t}
\t\t.card_area .icon_btn i {
\t\t\tfont-size: 22px;
\t\t}
\t\t.card_area .icon_btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tcolor: white;
\t\t\tborder-color: #ffa200;
\t\t\ttransform: translateY(-2px);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.2);
\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\talign-items: stretch;
\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\theight: auto;
\t\t}
\t\t/* Les boutons sont toujours visibles (meilleur pour le mobile et l'UX) */
\t\t.thumbnails-container .thumbnail-nav-btn {
\t\t\ttransition: all 0.2s ease;
\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\tflex: 1;
\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\tpadding: 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: #fff;
\t\t\tborder-bottom: 2px solid #e0e0e0;
\t\t\tflex-shrink: 0;
\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;
\t\t\ttransition: transform 0.3s ease;
\t\t}
\t\t.thumbnail-item:hover img {
\t\t\ttransform: scale(1.1);
\t\t}
\t\t.thumbnail-item.active img {
\t\t\ttransform: scale(1.1);
\t\t}
\t\t.product-main-image-wrapper {
\t\t\tflex: 1;
\t\t\tposition: relative;
\t\t\tbackground: #fff;
\t\t\tborder-radius: 12px;
\t\t\toverflow: hidden;
\t\t\tborder: 1px solid #e0e0e0;
\t\t\tcursor: crosshair;
\t\t}
\t\t.product-main-image {
\t\t\tposition: relative;
\t\t\twidth: 100%;
\t\t\tpadding-top: 100%;
\t\t\toverflow: hidden;
\t\t\tbackground: #f8f9fa;
\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;
\t\t\ttransition: transform 0.15s ease-out;
\t\t\ttransform-origin: center center;
\t\t}
\t\t/* Supprimer le scale basique, géré en JS */
\t\t/* .product-main-image:hover img {
\t\t\ttransform: scale(1.05);
\t\t} */
\t\t.image-overlay-icons {
\t\t\tposition: absolute;
\t\t\ttop: 15px;
\t\t\tright: 15px;
\t\t\tdisplay: flex;
\t\t\tflex-direction: column;
\t\t\tgap: 10px;
\t\t\tz-index: 20;
\t\t\tpointer-events: none;
\t\t}
\t\t.icon-btn {
\t\t\tpointer-events: all;
\t\t\twidth: 45px;
\t\t\theight: 45px;
\t\t\tborder-radius: 50%;
\t\t\tbackground: rgba(255, 255, 255, 0.95);
\t\t\tborder: none;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tpadding: 0;
\t\t\tcursor: pointer;
\t\t\ttransition: all 0.3s ease;
\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
\t\t\tcolor: #333;
\t\t}
\t\t.icon-btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tcolor: white;
\t\t\ttransform: scale(1.1);
\t\t\tbox-shadow: 0 4px 12px rgba(255, 162, 0, 0.4);
\t\t}
\t\t.icon-btn i {
\t\t\tfont-size: 18px;
\t\t}
\t\t.favorite-btn.active {
\t\t\tbackground: #ff6b6b;
\t\t\tcolor: white;
\t\t}
\t\t.image-counter {
\t\t\tposition: absolute;
\t\t\tbottom: 15px;
\t\t\tright: 15px;
\t\t\tbackground: rgba(0, 0, 0, 0.7);
\t\t\tcolor: white;
\t\t\tpadding: 6px 12px;
\t\t\tborder-radius: 20px;
\t\t\tfont-size: 13px;
\t\t\tfont-weight: 600;
\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;
\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/* Boutons de navigation sur l'image principale */
\t\t.main-image-nav {
\t\t\tposition: absolute;
\t\t\ttop: 0;
\t\t\tbottom: 0;
\t\t\tleft: 0;
\t\t\tright: 0;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: space-between;
\t\t\tpadding: 0 15px;
\t\t\tpointer-events: none;
\t\t\tz-index: 15;
\t\t}
\t\t.main-image-nav-btn {
\t\t\tpointer-events: all;
\t\t\twidth: 44px;
\t\t\theight: 44px;
\t\t\tborder-radius: 50%;
\t\t\tbackground: rgba(255, 255, 255, 0.95);
\t\t\tborder: 2px solid #e0e0e0;
\t\t\tdisplay: flex;
\t\t\talign-items: center;
\t\t\tjustify-content: center;
\t\t\tpadding: 0;
\t\t\tbox-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
\t\t\tcolor: #333;
\t\t\ttransition: all 0.2s ease;
\t\t}
\t\t.main-image-nav-btn:hover {
\t\t\tbackground: #ffa200;
\t\t\tborder-color: #ffa200;
\t\t\tcolor: #fff;
\t\t\ttransform: scale(1.08);
\t\t}
\t\t.main-image-nav-btn:active {
\t\t\ttransform: scale(0.95);
\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.image-overlay-icons {
\t\t\t\topacity: 1;
\t\t\t}
\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{% if product.images is defined and product.images|length > 0 %}
\t\t\t\t\t\t\t\t\t\t{% for img in product.images %}
\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{% if product.images is defined and product.images|length > 0 %}
\t\t\t\t\t\t\t\t\t<img id=\"main-product-image\" src=\"{{ asset(product.images[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</div>
\t\t\t\t\t\t\t<!-- Overlay avec icônes -->
\t\t\t\t\t\t\t<div class=\"image-overlay-icons\">
\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<i class=\"lnr lnr-magnifier\"></i>
\t\t\t\t\t\t\t\t</button>
\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<i class=\"lnr lnr-heart\"></i>
\t\t\t\t\t\t\t\t</button>
\t\t\t\t\t\t\t</div>
\t\t\t\t\t\t\t<!-- Navigation sur l'image principale -->
\t\t\t\t\t\t\t<div class=\"main-image-nav\">
\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<i class=\"lnr lnr-chevron-left\"></i>
\t\t\t\t\t\t\t\t</button>
\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<i class=\"lnr lnr-chevron-right\"></i>
\t\t\t\t\t\t\t\t</button>
\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<span id=\"total-images\">{{ (product.images|length) ?: 1 }}</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</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<p>{{ product.description|raw|striptags|nl2br }}</p>
\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<input type=\"text\" name=\"qty\" id=\"sst\" maxlength=\"12\" value=\"1\" title=\"Quantité:\" class=\"input-text qty\" max=\"{{ product.stock ?? 99 }}\">
\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=\"increase items-count\" type=\"button\">
\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<button onclick=\"var result = document.getElementById('sst'); var sst = result.value; if( !isNaN( sst ) && sst > 1 ) result.value--;return false;\" class=\"reduced items-count\" type=\"button\">
\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<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) #}
\t\t\t\t\t\t{% set tierPrices = [] %}
\t\t\t\t\t\t{% if product.tierPrices is defined and product.tierPrices|length > 0 %}
\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.minQty, 'price': tier.price }]) %}
\t\t\t\t\t\t\t{% endfor %}
\t\t\t\t\t\t{% else %}
\t\t\t\t\t\t\t{# Facultatif: exemple si pas de data backend #}
\t\t\t\t\t\t\t{% set tierPrices = [
\t\t\t\t\t\t\t\t{ 'min': 1, 'price': product.price },
\t\t\t\t\t\t\t\t{ 'min': 5, 'price': (product.price * 0.98)|round(2, 'floor') },
\t\t\t\t\t\t\t\t{ 'min': 10, 'price': (product.price * 0.95)|round(2, 'floor') },
\t\t\t\t\t\t\t\t{ 'min': 20, 'price': (product.price * 0.92)|round(2, 'floor') }
\t\t\t\t\t\t\t] %}
\t\t\t\t\t\t{% endif %}
\t\t\t\t\t\t<div id=\"bulk-pricing\" class=\"mt-3\" data-tiers='{{ tierPrices|json_encode|e('html_attr') }}'>
\t\t\t\t\t\t\t<div class=\"d-flex align-items-center mb-2\">
\t\t\t\t\t\t\t\t<strong class=\"me-2\">Prix unitaire selon quantité :</strong>
\t\t\t\t\t\t\t\t<span id=\"unit-price-value\">{{ 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\t<div class=\"table-responsive\">
\t\t\t\t\t\t\t\t<table class=\"table table-sm mb-2\" style=\"border:1px solid #eee;\">
\t\t\t\t\t\t\t\t\t<thead class=\"table-light\">
\t\t\t\t\t\t\t\t\t\t<tr>
\t\t\t\t\t\t\t\t\t\t\t<th>Quantité min.</th>
\t\t\t\t\t\t\t\t\t\t\t<th>Prix unitaire (HTG)</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<tr data-min=\"{{ tier.min }}\">
\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{{ tier.min }}</td>
\t\t\t\t\t\t\t\t\t\t\t\t<td>{{ tier.price|number_format(2, '.', ' ') }}</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<div class=\"d-flex flex-wrap gap-3 align-items-baseline mb-2\">
\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<span id=\"total-price-value\">{{ 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<small class=\"text-muted\">Le prix et le total s’adaptent automatiquement selon la quantité.</small>
\t\t\t\t\t\t</div>
\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 }}\" onclick=\"toggleComparison({{ product.id }}, this); return false;\">
\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|nl2br }}
\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.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// 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</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-xl-3 col-lg-4 col-md-6 col-sm-6 mb-4 d-flex align-items-stretch\">
\t\t\t\t\t\t\t{% include 'home/_single_product_card.html.twig' with {'product': relatedProduct} %}
\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;
\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\t</style>
\t\t<script>
\t\t\t// Gestion des boutons d'ajout au panier (principal et section \"Vous pourriez aussi aimer\")
\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
\t\t\t\tconst addToCartButtons = document.querySelectorAll('.btn-add-to-cart');
\t\t\t\t
\t\t\t\taddToCartButtons.forEach(button => {
\t\t\t\t\tbutton.addEventListener('click', function(e) {
\t\t\t\t\t\te.preventDefault();
\t\t\t\t\t\te.stopPropagation();
\t\t\t\t\t\t
\t\t\t\t\t\tconst productId = this.getAttribute('data-product-id');
\t\t\t\t\t\t
\t\t\t\t\t\t// Pour le bouton principal, récupérer la quantité depuis l'input sst si disponible
\t\t\t\t\t\tlet qty = this.getAttribute('data-qty') || '1';
\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\tconst qtyInput = document.getElementById('sst');
\t\t\t\t\t\t\tif (qtyInput) {
\t\t\t\t\t\t\t\tqty = parseInt(qtyInput.value) || 1;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\tif (!productId) {
\t\t\t\t\t\t\tconsole.error('Product ID manquant');
\t\t\t\t\t\t\treturn false;
\t\t\t\t\t\t}
\t\t\t\t\t\t// Sauvegarder le contenu original
\t\t\t\t\t\tconst originalContent = this.innerHTML;
\t\t\t\t\t\t
\t\t\t\t\t\t// Désactiver le bouton et afficher le loading
\t\t\t\t\t\tthis.classList.add('loading');
\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\tthis.style.pointerEvents = 'none';
\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"lnr lnr-spinner\"></i> Ajout en cours...';
\t\t\t\t\t\t} else {
\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"ti ti-loader-2\"></i> <span>Ajout...</span>';
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\t// Construire le body de la requête
\t\t\t\t\t\tlet body = 'productId=' + encodeURIComponent(productId) + '&qty=' + encodeURIComponent(qty);
\t\t\t\t\t\t
\t\t\t\t\t\t// Pour le bouton principal, vérifier aussi le prix unitaire pour les prix de gros
\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\tconst unitPriceInput = document.getElementById('unit-price-input');
\t\t\t\t\t\t\tconst unitPrice = unitPriceInput ? unitPriceInput.value : '';
\t\t\t\t\t\t\tif (unitPrice) {
\t\t\t\t\t\t\t\tbody += '&unitPrice=' + encodeURIComponent(unitPrice);
\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// Faire la requête AJAX
\t\t\t\t\t\tfetch('{{ path(\"ui_cart_add\") }}', {
\t\t\t\t\t\t\tmethod: 'POST',
\t\t\t\t\t\t\theaders: {
\t\t\t\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',
\t\t\t\t\t\t\t\t'X-Requested-With': 'XMLHttpRequest'
\t\t\t\t\t\t\t},
\t\t\t\t\t\t\tbody: body
\t\t\t\t\t\t})
\t\t\t\t\t\t.then(response => {
\t\t\t\t\t\t\tif (!response.ok) {
\t\t\t\t\t\t\t\tthrow new Error('Erreur réseau: ' + response.status);
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\treturn response.json();
\t\t\t\t\t\t})
\t\t\t\t\t\t.then(data => {
\t\t\t\t\t\t\tif (data.ok || data.success) {
\t\t\t\t\t\t\t\t// Succès - Afficher l'animation de succès
\t\t\t\t\t\t\t\tthis.classList.remove('loading');
\t\t\t\t\t\t\t\tthis.classList.add('success');
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\t\tthis.style.background = 'linear-gradient(135deg, #28a745 0%, #20c997 100%)';
\t\t\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"lnr lnr-checkmark-circle\"></i> Ajouté !';
\t\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t\t// Afficher le message de confirmation si présent
\t\t\t\t\t\t\t\t\tconst cartMessage = document.getElementById('cart-message');
\t\t\t\t\t\t\t\t\tif (cartMessage) {
\t\t\t\t\t\t\t\t\t\tcartMessage.style.display = 'block';
\t\t\t\t\t\t\t\t\t\tsetTimeout(() => {
\t\t\t\t\t\t\t\t\t\t\tcartMessage.style.display = 'none';
\t\t\t\t\t\t\t\t\t\t}, 3000);
\t\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\t\tthis.innerHTML = '<i class=\"ti ti-check\"></i> <span>Ajouté !</span>';
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t// Mettre à jour le compteur du panier si présent
\t\t\t\t\t\t\t\tconst cartBadge = document.querySelector('.cart-badge');
\t\t\t\t\t\t\t\tif (cartBadge) {
\t\t\t\t\t\t\t\t\tcartBadge.textContent = data.totalQty || data.quantity || 0;
\t\t\t\t\t\t\t\t\t// Animation du badge
\t\t\t\t\t\t\t\t\tcartBadge.style.transform = 'scale(1.2)';
\t\t\t\t\t\t\t\t\tsetTimeout(() => {
\t\t\t\t\t\t\t\t\t\tcartBadge.style.transform = 'scale(1)';
\t\t\t\t\t\t\t\t\t}, 300);
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t// Afficher une notification si la fonction existe
\t\t\t\t\t\t\t\tif (typeof showCustomAlert === 'function') {
\t\t\t\t\t\t\t\t\tshowCustomAlert('Produit ajouté au panier avec succès !', 'success');
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t// Restaurer le bouton après 2 secondes
\t\t\t\t\t\t\t\tsetTimeout(() => {
\t\t\t\t\t\t\t\t\tthis.classList.remove('success');
\t\t\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\t\t\tthis.style.background = '';
\t\t\t\t\t\t\t\t\t\tthis.style.pointerEvents = 'auto';
\t\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\t\tthis.innerHTML = originalContent;
\t\t\t\t\t\t\t\t}, 2000);
\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\t// Erreur
\t\t\t\t\t\t\t\tthis.classList.remove('loading');
\t\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\t\tthis.style.pointerEvents = 'auto';
\t\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t\tthis.innerHTML = originalContent;
\t\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\tconst message = data.message || 'Erreur lors de l\\'ajout au panier';
\t\t\t\t\t\t\t\tif (typeof showCustomAlert === 'function') {
\t\t\t\t\t\t\t\t\tshowCustomAlert(message, 'error');
\t\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\t\talert(message);
\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.catch(error => {
\t\t\t\t\t\t\tconsole.error('Erreur:', error);
\t\t\t\t\t\t\tthis.classList.remove('loading');
\t\t\t\t\t\t\tif (this.id === 'add-to-cart-btn') {
\t\t\t\t\t\t\t\tthis.style.pointerEvents = 'auto';
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\tthis.innerHTML = originalContent;
\t\t\t\t\t\t\t
\t\t\t\t\t\t\tif (typeof showCustomAlert === 'function') {
\t\t\t\t\t\t\t\tshowCustomAlert('Erreur lors de l\\'ajout au panier. Veuillez réessayer.', 'error');
\t\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t\talert('Erreur lors de l\\'ajout au panier. Veuillez réessayer.');
\t\t\t\t\t\t\t}
\t\t\t\t\t\t});
\t\t\t\t\t\t
\t\t\t\t\t\treturn false;
\t\t\t\t\t});
\t\t\t\t});
\t\t\t});
\t\t</script>
\t{% endif %}
\t<script src=\"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=\"js/vendor/bootstrap.min.js\"></script>
\t<script src=\"js/jquery.ajaxchimp.min.js\"></script>
\t<script src=\"js/jquery.nice-select.min.js\"></script>
\t<script src=\"js/jquery.sticky.js\"></script>
\t<script src=\"js/nouislider.min.js\"></script>
\t<script src=\"js/jquery.magnific-popup.min.js\"></script>
\t<script src=\"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=\"js/gmaps.min.js\"></script>
\t<script src=\"js/main.js\"></script>
\t<script>
\t\t// Le gestionnaire d'événements pour les boutons d'ajout au panier est déjà défini
\t\t// dans la section \"Vous pourriez aussi aimer\" et gère maintenant aussi le bouton principal
// Gestion de la galerie d'images
document.addEventListener('DOMContentLoaded', function () {
const thumbnails = document.querySelectorAll('.thumbnail-item');
const mainImage = document.getElementById('main-product-image');
const currentIndex = document.getElementById('current-image-index');
const totalImages = document.getElementById('total-images');
// Fonction pour changer l'image principale
function changeMainImage(thumbnail, index) {
const imageUrl = thumbnail.getAttribute('data-image');
if (mainImage && imageUrl) {
mainImage.style.opacity = '0';
setTimeout(() => {
mainImage.src = imageUrl;
mainImage.style.opacity = '1';
// Reset zoom
mainImage.style.transform = 'scale(1)';
mainImage.style.transformOrigin = 'center center';
}, 150);
}
// Mettre à jour l'indicateur
if (currentIndex) {
currentIndex.textContent = index + 1;
}
}
// Ajouter le zoom sur l'image principale au survol
const mainImageContainer = document.querySelector('.product-main-image-wrapper');
if (mainImageContainer && mainImage) {
\tmainImageContainer.addEventListener('mousemove', function(e) {
\t\tconst rect = mainImageContainer.getBoundingClientRect();
\t\tconst x = e.clientX - rect.left;
\t\tconst y = e.clientY - rect.top;
\t\t
\t\tconst xPercent = (x / rect.width) * 100;
\t\tconst yPercent = (y / rect.height) * 100;
\t\t
\t\tmainImage.style.transformOrigin = `\${xPercent}% \${yPercent}%`;
\t\tmainImage.style.transform = 'scale(2.2)'; // Zoom Alibaba-style
\t});
\t
\tmainImageContainer.addEventListener('mouseleave', function() {
\t\tmainImage.style.transformOrigin = 'center center';
\t\tmainImage.style.transform = 'scale(1)';
\t});
}
// Gérer le survol sur les miniatures (sélection permanente au survol)
thumbnails.forEach((thumbnail, index) => {
thumbnail.addEventListener('mouseenter', function () { // Retirer toutes les sélections permanentes
thumbnails.forEach(t => {
t.classList.remove('active', 'permanently-active');
});
// Ajouter active et permanently-active à la miniature survolée
thumbnail.classList.add('active', 'permanently-active');
// Changer l'image principale
changeMainImage(thumbnail, index);
});
});
// Gérer le clic sur les miniatures (sélection permanente)
thumbnails.forEach((thumbnail, index) => {
thumbnail.addEventListener('click', function () { // Retirer la classe active et permanently-active de toutes les miniatures
thumbnails.forEach(t => {
t.classList.remove('active', 'permanently-active');
});
// Ajouter les classes active et permanently-active à la miniature cliquée
thumbnail.classList.add('active', 'permanently-active');
// Changer l'image principale
changeMainImage(thumbnail, index);
});
});
// 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');
return idxAttr ? parseInt(idxAttr, 10) : Math.max(0, thumbnailItems.indexOf(current));
}
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');
changeMainImage(target, newIndex);
// 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);
}
// Navigation sur l'image principale
const mainPrev = document.getElementById('main-image-prev');
const mainNext = document.getElementById('main-image-next');
if(mainPrev) {
mainPrev.addEventListener('click', function (e) {
e.preventDefault();
const idx = getCurrentIndex();
selectThumbnailByIndex(idx - 1);
});
}
if(mainNext) {
mainNext.addEventListener('click', function (e) {
e.preventDefault();
const idx = getCurrentIndex();
selectThumbnailByIndex(idx + 1);
});
}
}
);
// --- 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 ---
// 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(\"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<!-- Le Modal personnalisé et showCustomAlert ont été déplacés dans base_home.html.twig pour une portée globale -->
\t<script>
\t\t// Remplacer window.alert par showCustomAlert
\t\twindow.alert = window.showCustomAlert || function(message) { console.log(\"Alert:\", message); };
\t</script>
{% endblock %}
", "home/single-product.html.twig", "/home/u540977899/domains/maketou-ht.com/public_html/templates/home/single-product.html.twig");
}
}