var/cache/dev/twig/b9/b932b00f9926f3af0cf9914133167a94.php line 58

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\CoreExtension;
  6. use Twig\Extension\SandboxExtension;
  7. use Twig\Markup;
  8. use Twig\Sandbox\SecurityError;
  9. use Twig\Sandbox\SecurityNotAllowedTagError;
  10. use Twig\Sandbox\SecurityNotAllowedFilterError;
  11. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  12. use Twig\Source;
  13. use Twig\Template;
  14. use Twig\TemplateWrapper;
  15. /* Parent/DetailsSejour.html.twig */
  16. class __TwigTemplate_2e4d9af98367fb875e9538af7eac3dac extends Template
  17. {
  18.     private Source $source;
  19.     /**
  20.      * @var array<string, Template>
  21.      */
  22.     private array $macros = [];
  23.     public function __construct(Environment $env)
  24.     {
  25.         parent::__construct($env);
  26.         $this->source $this->getSourceContext();
  27.         $this->blocks = [
  28.             'LinksCss' => [$this'block_LinksCss'],
  29.             'Content' => [$this'block_Content'],
  30.             'Javascript' => [$this'block_Javascript'],
  31.         ];
  32.     }
  33.     protected function doGetParent(array $context): bool|string|Template|TemplateWrapper
  34.     {
  35.         // line 1
  36.         return "Parent/LayoutParent.html.twig";
  37.     }
  38.     protected function doDisplay(array $context, array $blocks = []): iterable
  39.     {
  40.         $macros $this->macros;
  41.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  42.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Parent/DetailsSejour.html.twig"));
  43.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  44.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Parent/DetailsSejour.html.twig"));
  45.         // line 197
  46.         $context["pageMenu"] = CoreExtension::getAttribute($this->env$this->sourceCoreExtension::getAttribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'197$this->source); })()), "session", [], "any"falsefalsefalse197), "get", ["pageMenu"], "method"falsefalsefalse197);
  47.         // line 1
  48.         $this->parent $this->load("Parent/LayoutParent.html.twig"1);
  49.         yield from $this->parent->unwrap()->yield($contextarray_merge($this->blocks$blocks));
  50.         
  51.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  52.         
  53.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  54.     }
  55.     /**
  56.      * @return iterable<null|scalar|\Stringable>
  57.      */
  58.     public function block_LinksCss(array $context, array $blocks = []): iterable
  59.     {
  60.         $macros $this->macros;
  61.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  62.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""LinksCss"));
  63.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  64.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""LinksCss"));
  65.         // line 2
  66.         yield from $this->yieldParentBlock("LinksCss"$context$blocks);
  67.         yield "
  68. <script src=\"https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js\"></script>
  69. <link rel=\"stylesheet\" href=\"";
  70.         // line 5
  71.         yield "/css/Parent/css/premiercnx.css";
  72.         yield "\" />
  73. <link href=\"";
  74.         // line 6
  75.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("css/Parent/css/detailsejour.css"), "html"nulltrue);
  76.         yield "\" type=\"text/css\" rel=\"stylesheet\" />
  77. <link rel=\"stylesheet\" href=\"";
  78.         // line 7
  79.         yield "/css/Accompagnateur/imgzoom.css";
  80.         yield "\" />
  81. <link rel=\"stylesheet\" href=\"";
  82.         // line 8
  83.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("Plugins/css/dropzone.css"), "html"nulltrue);
  84.         yield "\" />
  85. <link rel=\"stylesheet\" href=\"";
  86.         // line 9
  87.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("css/splide.min.css"), "html"nulltrue);
  88.         yield "\" />
  89. <link rel=\"stylesheet\" href=\"";
  90.         // line 10
  91.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("css/favorites-sidebar.css"), "html"nulltrue);
  92.         yield "\" />
  93. ";
  94.         // line 11
  95.         $context["destination"] = "detailsejour";
  96.         // line 12
  97.         yield "<style>
  98. .btn-cmdFav {
  99.   background-color: #F56040;
  100.   color: white;
  101.   padding: 10px 20px;
  102.   border-radius: 6px;
  103.   font-size: 1rem;
  104.   box-shadow: 0 4px 8px rgba(0,0,0,0.15);
  105.   transition: all 0.3s ease;
  106. }
  107. .btn-cmdFav:hover {
  108.   background-color: #e64a30;
  109.   transform: scale(1.05);
  110.   box-shadow: 0 6px 12px rgba(0,0,0,0.2);
  111. }
  112. .filter-badge {
  113.   background-color: #ccc;
  114.   color: white;
  115.   font-size: 12px;
  116.   padding: 2px 10px;
  117.   border-radius: 20px;
  118.   display: flex;
  119.   align-items: center;
  120.   cursor: pointer;
  121.   transition: all 0.3s ease;
  122. }
  123. .filter-badge:hover {
  124.   background-color: #aaa;
  125. }
  126. /* Quand le filtre est actif */
  127. .filter-badge.active {
  128.   background-color: #3BA39B; /* Vert plus vif */
  129.   box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
  130.   font-weight: bold;
  131.   color: white;
  132. }
  133.   .close-btn-purchase {
  134.     position: absolute;
  135.     padding: 2px;
  136.     top: 10px;
  137.     right: 10px;
  138.     background: none;
  139.     border: none;
  140.     font-size: 35px;
  141.     cursor: pointer;
  142.   }
  143.   .close-btn-purchase :hover {
  144.     color: red;
  145.   }
  146.   .rowimag.no-margin {
  147.     display: grid;
  148.     grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  149.     /* auto-fill + minmax ensures they fill the row and wrap automatically */
  150.     gap: 8px; /* spacing between items, optional */
  151.     margin: 0; /* override default margin if you want */
  152.     padding: 0;
  153.   }
  154.   /* Each cell is 200px tall (or pick your own dimension). */
  155.   .photo-item {
  156.     width: 100%;
  157.     height: 250px; /* fixed height: 200px */
  158.     position: relative;
  159.     overflow: hidden; /* hide any overflow if the image is bigger */
  160.     border-radius: 4px; /* optional rounding corners */
  161.     background: #f0f0f0; /* fallback background color while image loads */
  162.     margin-bottom: 20px;
  163.   }
  164.   /* For images, we want them to fill the box and maintain a cover aspect. */
  165.   .photo-item img,
  166.   .photo-item video {
  167.     width: 100%;
  168.     height: 100%;
  169.     object-fit: cover; /* ensures image or video is cropped rather than distorted */
  170.     display: block;
  171.   }
  172.   .fav-button {
  173.     pointer-events: none; /* Makes the entire button unclickable */
  174.   }
  175.   
  176.   /* Enable hover effects only */
  177.   .fav-button * {
  178.     pointer-events: auto; /* Re-enable events for children */
  179.     pointer-events: hover; /* Only allow hover events, not clicks */
  180.   }
  181.   
  182.   /* Add this class to the purchase alert to ensure it remains interactive */
  183.   #purchase-alert {
  184.     pointer-events: auto;
  185.   
  186.   }
  187.   /* Réduit l'espace autour du header */
  188.   .header {
  189.     padding: 15px 15px 5px 15px;
  190.     background: #f9f9f9;
  191.   }
  192.   /* Réduit l'espace sous le titre et le sous-titre */
  193.   .titreDetailSej {
  194.     margin-bottom: 8px;
  195.   }
  196.   .media-counts {
  197.     margin-bottom: 8px;
  198.   }
  199.   /* Centre la navigation des dates */
  200.   .date-navigation {
  201.     display: flex;
  202.     align-items: center;
  203.     justify-content: center;
  204.     gap: 8px;
  205.     width: 100%;
  206.     margin-top: 0;
  207.   }
  208.   /* Centre le conteneur des cartes */
  209.   .date-container {
  210.     display: flex;
  211.     justify-content: center;
  212.     width: 100%;
  213.   }
  214.   .media-list-horizontal {
  215.     gap: 4px;
  216.     font-size: 11px;
  217.     margin-top: 2px;
  218.     display: flex;
  219.     justify-content: center;
  220.     list-style: none;
  221.     margin-bottom: 0;
  222.     padding-left: 0;
  223.   }
  224.   .sejour-title h1 {
  225.     font-size: 1.5rem;
  226.     font-weight: bold;
  227.     color: #3BA39B;
  228.     display: flex;
  229.     align-items: center;
  230.     gap: 10px;
  231.   }
  232.   .sejour-dates {
  233.     font-size: 14px;
  234.     color: #777;
  235.     margin-top: 5px;
  236.   }
  237.   .sejour-medias {
  238.     display: flex;
  239.     gap: 20px;
  240.     align-items: center;
  241.     font-size: 14px;
  242.     color: #555;
  243.   }
  244.   .media-info {
  245.     display: flex;
  246.     align-items: center;
  247.     gap: 5px;
  248.   }
  249.   /* Responsive Mobile */
  250.   @media (max-width: 768px) {
  251.     .sejour-header {
  252.       flex-direction: column;
  253.       align-items: center;
  254.       text-align: center;
  255.     }
  256.     .sejour-medias {
  257.       margin-top: 10px;
  258.       gap: 10px;
  259.     }
  260.   }
  261. </style>
  262. ";
  263.         
  264.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  265.         
  266.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  267.         yield from [];
  268.     }
  269.     // line 197
  270.     /**
  271.      * @return iterable<null|scalar|\Stringable>
  272.      */
  273.     public function block_Content(array $context, array $blocks = []): iterable
  274.     {
  275.         $macros $this->macros;
  276.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  277.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Content"));
  278.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  279.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Content"));
  280.         // line 199
  281.         yield "
  282. <!-- Alerte pour inciter à acheter -->
  283. <div id=\"purchase-alert\" class=\"purchase-alert hidden\" style=\"display: none;\">
  284.   <button class=\"close-btn\" onclick=\"closePurchaseAlert()\">&times;</button>
  285.   <div id=\"purchase-alert-content\">
  286.     <!-- Le contenu de l'alerte sera mis à jour dynamiquement en fonction du nombre de favoris -->
  287.   </div>
  288. </div>
  289. <div
  290.   id=\"verifImg\"
  291.   class=\"modal fade\"
  292.   role=\"dialog\"
  293.   style=\"background-color: rgba(112, 112, 112, 0.56); z-index: 1000000\"
  294. >
  295.   <div class=\"modal-dialog dialogUploadImg\">
  296.     <div class=\"row modal-content no-margin contentdialogNoImg\">
  297.       <div class=\"headerdialogUploadImg\">
  298.         <h1 class=\"titledialogUploadImg\"></h1>
  299.         <img
  300.           src=\"";
  301.         // line 220
  302.         yield "/images/Accompagnateur/CroixFermeture.svg";
  303.         yield "\"
  304.           class=\"closeNOUploadImg\"
  305.           data-dismiss=\"modal\"
  306.         />
  307.       </div>
  308.       <div class=\"ContenudetailsSejour\">
  309.         <div class=\"row no-margin detailsSejour\">
  310.           <div class=\"ContentUpload\">
  311.             <h1 class=\"titleTelechargement\">
  312.               Oulala, patience, avant tout sélectionnez vos photos préférées à
  313.               l'aide de ce bouton
  314.               <i
  315.                 class=\"bi bi-heart\"
  316.                 style=\"font-size: 1.3rem\"
  317.                 title=\"Ajouter à  ma sélection\"
  318.               ></i>
  319.               sous les photos  <br /><br /><a style=\"color: #f09e7a\"
  320.                 >Pensez à commander des tirages... pour leurs offrir un beau
  321.                 souvenir !
  322.               </a>
  323.             </h1>
  324.           </div>
  325.         </div>
  326.       </div>
  327.       <div class=\"BottomNoUploadImg\">
  328.         <button class=\"BtnUploadImg btnAnnulerUpload\" data-dismiss=\"modal\">
  329.           OK
  330.         </button>
  331.       </div>
  332.     </div>
  333.   </div>
  334. </div>
  335. <div class=\"main-content\">
  336.   <div class=\"row no-margin\">
  337.     <!-- Chat button -->
  338.     <div
  339.       class=\"fav-button\"
  340.       onmouseover=\"showSelection()\"
  341.       onmouseout=\"hideSelection()\"
  342.     >
  343.       <i id=\"favoris-icon-Accueilpayment\" class=\"bi bi-heart-fill CoeurEclat\"></i
  344.       ><label
  345.         id=\"likeCount\"
  346.         class=\"labelFavCount\"
  347.         style=\"background-color: #f56040\"
  348.       >
  349.         ";
  350.         // line 268
  351.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), (isset($context["likes"]) || array_key_exists("likes"$context) ? $context["likes"] : (function () { throw new RuntimeError('Variable "likes" does not exist.'268$this->source); })())), "html"nulltrue);
  352.         yield "</label
  353.       >
  354.     </div>
  355.     <div class=\"selection-popover\" id=\"selectionPopover\">
  356.       <h4>Votre sélection</h4>
  357.       <p>Tirages : ";
  358.         // line 273
  359.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), (isset($context["likes"]) || array_key_exists("likes"$context) ? $context["likes"] : (function () { throw new RuntimeError('Variable "likes" does not exist.'273$this->source); })())), "html"nulltrue);
  360.         yield " / 12</p>
  361.       <p>Numériques : ";
  362.         // line 274
  363.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), (isset($context["likes"]) || array_key_exists("likes"$context) ? $context["likes"] : (function () { throw new RuntimeError('Variable "likes" does not exist.'274$this->source); })())), "html"nulltrue);
  364.         yield " / 15</p>
  365.       <p>Album : ";
  366.         // line 275
  367.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::length($this->env->getCharset(), (isset($context["likes"]) || array_key_exists("likes"$context) ? $context["likes"] : (function () { throw new RuntimeError('Variable "likes" does not exist.'275$this->source); })())), "html"nulltrue);
  368.         yield " / 20</p>
  369.       <button class=\"finalize-button\">Finaliser ma commande</button>
  370.     </div>
  371.   </div>
  372.   <div class=\"divSliderModern\">
  373.     <input type=\"hidden\" id=\"nbFavCurrent\" value=\"";
  374.         // line 281
  375.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["nblikes"]) || array_key_exists("nblikes"$context) ? $context["nblikes"] : (function () { throw new RuntimeError('Variable "nblikes" does not exist.'281$this->source); })()), "html"nulltrue);
  376.         yield "\" />
  377.     <div
  378.       class=\"splide no-padding no-margin\"
  379.       id=\"imageSlider\"
  380.       style=\"max-height: 200px\"
  381.     >
  382.       <div class=\"splide__track\">
  383.         <ul class=\"splide__list\">
  384.           <!-- Slide 1 -->
  385.           <li class=\"splide__slide\">
  386.             <div class=\"slider-content\" style=\"background: white\">
  387.               <div class=\"namePRD\" style=\"display: block\">
  388.                 <h4
  389.                   class=\"titleProdbienvenu titleProdbienvenu1\"
  390.                   style=\"color: #41a2aa\"
  391.                 >
  392.                   Ajoutez vos favoris dès maintenant
  393.                 </h4>
  394.                 <h4
  395.                   class=\"titleProdbienvenu titleProdbienvenu2\"
  396.                   style=\"color: #f09e7a\"
  397.                 >
  398.                   et profitez de nos produits souvenirs personnalisés !
  399.                 </h4>
  400.               </div>
  401.               <img
  402.                 src=\"";
  403.         // line 309
  404.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/images/imgSliderEmpty2.png"), "html"nulltrue);
  405.         yield "\"
  406.                 class=\"imgslider\"
  407.                 alt=\"Image 1\"
  408.               />
  409.             </div>
  410.           </li>
  411.           <!-- Slide 2 -->
  412.           <li class=\"splide__slide\">
  413.             <div class=\"slider-content\" style=\"background: white\">
  414.               <div class=\"namePRD\" style=\"display: block\">
  415.                 <h4
  416.                   class=\"titleProdbienvenu titleProdbienvenu1\"
  417.                   style=\"color: #f09e7a\"
  418.                 >
  419.                   Pensez à commander le livre du séjour
  420.                 </h4>
  421.                 <h4
  422.                   class=\"titleProdbienvenu titleProdbienvenu2\"
  423.                   style=\"color: #41a2aa\"
  424.                 >
  425.                   et offrez lui le plus beau des cadeaux !
  426.                 </h4>
  427.               </div>
  428.               <img
  429.                 src=\"";
  430.         // line 333
  431.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/images/imgSliderEmpty1.png"), "html"nulltrue);
  432.         yield "\"
  433.                 class=\"imgslider\"
  434.                 alt=\"Image 2\"
  435.               />
  436.             </div>
  437.           </li>
  438.         </ul>
  439.       </div>
  440.     </div>
  441.   </div>
  442.   <!-- Section de contenu à atteindre après le scroll -->
  443.   <div
  444.     class=\"no-margin\"
  445.     id=\"scrollTarget\"
  446.     style=\"width: 100%; background: #f9f9f9; padding-top: 30px\"
  447.   >
  448.     <div class=\"no-margin\" id=\"scrollTarget\" style=\"width: 100%\">
  449.       <!-- Conteneur principal en ligne -->
  450.       <div
  451.         class=\"header d-flex align-items-center justify-content-between\"
  452.         style=\"padding: 15px;\"
  453.       >
  454.         <!-- Bloc titre -->
  455.         <div class=\"box divInfosSejour\" style=\"width: 95%;\">
  456.           <img
  457.             class=\"imageTitreSej\"
  458.             src=\"/Accueil/imagesAccueil/sejour.png\"
  459.             alt=\"Icône séjour\"
  460.             style=\"width: 40px; height: auto\"
  461.           />
  462.           <h1 class=\"titreDetailSej\">
  463.             Séjour ";
  464.         // line 365
  465.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'365$this->source); })()), "codeSejour", [], "any"falsefalsefalse365), "html"nulltrue);
  466.         yield " ";
  467.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'365$this->source); })()), "themSejour", [], "any"falsefalsefalse365), "html"nulltrue);
  468.         yield "
  469.             <span class=\"spnTitleSej\">
  470.               du
  471.               ";
  472.         // line 369
  473.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::replace($this->extensions['Twig\Extension\CoreExtension']->formatDate(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'369$this->source); })()), "dateDebutSejour", [], "any"falsefalsefalse369), "d M Y"), ["Jan" => "janv.""Feb" => "fév.""Mar" => "mars""Apr" => "avr.""May" => "mai""Jun" => "juin""Jul" => "juil.""Aug" => "août""Sep" => "sept.""Oct." => "oct.""Nov." => "nov.""Dec." => "déc."]), "html"nulltrue);
  474.         yield "
  475.               au
  476.               ";
  477.         // line 371
  478.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::replace($this->extensions['Twig\Extension\CoreExtension']->formatDate(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'371$this->source); })()), "dateFinSejour", [], "any"falsefalsefalse371), "d M Y"), ["Jan" => "janv.""Feb" => "fév.""Mar" => "mars""Apr" => "avr.""May" => "mai""Jun" => "juin""Jul" => "juil.""Aug" => "août""Sep" => "sept.""Oct." => "oct.""Nov." => "nov.""Dec." => "déc."]), "html"nulltrue);
  479.         yield "
  480.             </span>
  481.           </h1>
  482.           <span class=\"spnTitleSej\" style=\"color:black\">
  483.         
  484.             (📷 ";
  485.         // line 376
  486.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["attachementsCount"]) || array_key_exists("attachementsCount"$context) ? $context["attachementsCount"] : (function () { throw new RuntimeError('Variable "attachementsCount" does not exist.'376$this->source); })()), "html"nulltrue);
  487.         yield " Photos/Vidéos | 🎵 ";
  488.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["nbmessages"]) || array_key_exists("nbmessages"$context) ? $context["nbmessages"] : (function () { throw new RuntimeError('Variable "nbmessages" does not exist.'376$this->source); })()), "html"nulltrue);
  489.         yield " Audios  ❤️  <label
  490.         id=\"mesFavCount\" style=\"color:black;margin-right:5px\"
  491.       
  492.     >
  493.     ";
  494.         // line 380
  495.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["nblikes"]) || array_key_exists("nblikes"$context) ? $context["nblikes"] : (function () { throw new RuntimeError('Variable "nblikes" does not exist.'380$this->source); })()), "html"nulltrue);
  496.         yield "   </label> Favoris )
  497.   
  498.           </span>
  499.           <div class=\"date-navigation\">
  500.           
  501.      
  502.             <div class=\"date-container\">
  503.               ";
  504.         // line 389
  505.         $context['_parent'] = $context;
  506.         $context['_seq'] = CoreExtension::ensureTraversable((isset($context["listeattach"]) || array_key_exists("listeattach"$context) ? $context["listeattach"] : (function () { throw new RuntimeError('Variable "listeattach" does not exist.'389$this->source); })()));
  507.         $context['loop'] = [
  508.           'parent' => $context['_parent'],
  509.           'index0' => 0,
  510.           'index'  => 1,
  511.           'first'  => true,
  512.         ];
  513.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  514.             $length count($context['_seq']);
  515.             $context['loop']['revindex0'] = $length 1;
  516.             $context['loop']['revindex'] = $length;
  517.             $context['loop']['length'] = $length;
  518.             $context['loop']['last'] = === $length;
  519.         }
  520.         foreach ($context['_seq'] as $context["x"] => $context["groupAttach"]) {
  521.             // line 390
  522.             yield "                ";
  523.             $context["xDate"] = $this->extensions['Twig\Extension\CoreExtension']->convertDate($context["x"]);
  524.             // line 391
  525.             yield "                ";
  526.             $context["finDate"] = $this->extensions['Twig\Extension\CoreExtension']->convertDate(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'391$this->source); })()), "dateFinSejour", [], "any"falsefalsefalse391));
  527.             // line 392
  528.             yield "                ";
  529.             if (((isset($context["xDate"]) || array_key_exists("xDate"$context) ? $context["xDate"] : (function () { throw new RuntimeError('Variable "xDate" does not exist.'392$this->source); })()) <= (isset($context["finDate"]) || array_key_exists("finDate"$context) ? $context["finDate"] : (function () { throw new RuntimeError('Variable "finDate" does not exist.'392$this->source); })()))) {
  530.                 // line 393
  531.                 yield "                  <div
  532.                     class=\"date-card modern-card ";
  533.                 // line 394
  534.                 if ((CoreExtension::getAttribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse394) && ((isset($context["xDate"]) || array_key_exists("xDate"$context) ? $context["xDate"] : (function () { throw new RuntimeError('Variable "xDate" does not exist.'394$this->source); })()) <= (isset($context["finDate"]) || array_key_exists("finDate"$context) ? $context["finDate"] : (function () { throw new RuntimeError('Variable "finDate" does not exist.'394$this->source); })())))) {
  535.                     yield " active ";
  536.                 }
  537.                 yield "\"
  538.                     data-aos=\"fade-up\"
  539.                     data-bs-toggle=\"collapse\"
  540.                     data-bs-target=\"#demP";
  541.                 // line 397
  542.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse397), "html"nulltrue);
  543.                 yield "\"
  544.                     id=\"iconedemoP";
  545.                 // line 398
  546.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse398), "html"nulltrue);
  547.                 yield "\"
  548.                   >
  549.                     <div class=\"card-content text-center\">
  550.                       <span class=\"day\">
  551.                         ";
  552.                 // line 402
  553.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "isFirstDay", [], "any"falsefalsefalse402) == "yes")) {
  554.                     yield " Premier jour
  555.                         ";
  556.                 } elseif ((CoreExtension::getAttribute($this->env$this->source,                 // line 403
  557. $context["groupAttach"], "isLastDay", [], "any"falsefalsefalse403) == "yes")) {
  558.                     yield " Dernier jour
  559.                         ";
  560.                 } else {
  561.                     // line 405
  562.                     yield "                          ";
  563.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::replace($this->extensions['Twig\Extension\CoreExtension']->formatDate((isset($context["xDate"]) || array_key_exists("xDate"$context) ? $context["xDate"] : (function () { throw new RuntimeError('Variable "xDate" does not exist.'405$this->source); })()), "D"), ["Mon" => "lun.""Tue" => "mar.""Wed" => "mer.""Thu" => "jeu.""Fri" => "ven.""Sat" => "sam.""Sun" => "dim."]), "html"nulltrue);
  564.                     // line 413
  565.                     yield "
  566.                         ";
  567.                 }
  568.                 // line 415
  569.                 yield "                      </span>
  570.                       <span class=\"full-date\">
  571.                         ";
  572.                 // line 417
  573.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::replace($this->extensions['Twig\Extension\CoreExtension']->formatDate((isset($context["xDate"]) || array_key_exists("xDate"$context) ? $context["xDate"] : (function () { throw new RuntimeError('Variable "xDate" does not exist.'417$this->source); })()), "d M Y"), ["Jan" => "janv.""Feb" => "fév.""Mar" => "mars""Apr" => "avr.""May" => "mai""Jun" => "juin""Jul" => "juil.""Aug" => "août""Sep" => "sept.""Oct." => "oct.""Nov." => "nov.""Dec." => "déc."]), "html"nulltrue);
  574.                 // line 430
  575.                 yield "
  576.                       </span>
  577.                       <ul class=\"media-list-horizontal\">
  578.                         ";
  579.                 // line 433
  580.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countPhotos", [], "any"falsefalsefalse433) > 0)) {
  581.                     // line 434
  582.                     yield "                        <li>
  583.                           <i class=\"bi bi-images\" style=\"color: #f56040; font-size: 0.7rem; margin-right: 3px\"></i>
  584.                           ";
  585.                     // line 436
  586.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countPhotos", [], "any"falsefalsefalse436), "html"nulltrue);
  587.                     yield "
  588.                         </li>
  589.                         ";
  590.                 }
  591.                 // line 439
  592.                 yield "                        ";
  593.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countAudio", [], "any"falsefalsefalse439) > 0)) {
  594.                     // line 440
  595.                     yield "                        <li>
  596.                           <i class=\"bi bi-mic-fill\" style=\"color: #ffa500; font-size: 0.7rem; margin-right: 5px\"></i>
  597.                           ";
  598.                     // line 442
  599.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countAudio", [], "any"falsefalsefalse442), "html"nulltrue);
  600.                     yield "
  601.                         </li>
  602.                         ";
  603.                 }
  604.                 // line 445
  605.                 yield "                        ";
  606.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countVideos", [], "any"falsefalsefalse445) > 0)) {
  607.                     // line 446
  608.                     yield "                        <li>
  609.                           <i class=\"bi bi-camera-video-fill\" style=\"color: #41a2aa; font-size: 0.7rem; margin-right: 5px\"></i>
  610.                           ";
  611.                     // line 448
  612.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countVideos", [], "any"falsefalsefalse448), "html"nulltrue);
  613.                     yield "
  614.                         </li>
  615.                         ";
  616.                 }
  617.                 // line 451
  618.                 yield "                      </ul>
  619.                     </div>
  620.                   </div>
  621.                 ";
  622.             }
  623.             // line 455
  624.             yield "              ";
  625.             ++$context['loop']['index0'];
  626.             ++$context['loop']['index'];
  627.             $context['loop']['first'] = false;
  628.             if (isset($context['loop']['revindex0'], $context['loop']['revindex'])) {
  629.                 --$context['loop']['revindex0'];
  630.                 --$context['loop']['revindex'];
  631.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  632.             }
  633.         }
  634.         $_parent $context['_parent'];
  635.         unset($context['_seq'], $context['x'], $context['groupAttach'], $context['_parent'], $context['loop']);
  636.         $context array_intersect_key($context$_parent) + $_parent;
  637.         yield " <div id=\"dynamic-card\" class=\"dynamic-card\">
  638.       <div id=\"dynamic-card-content\" class=\"dynamic-card-content\">
  639.         <!-- Le contenu dynamique (album, pochette, montage vidéo) sera injecté ici -->
  640.       </div>
  641.     </div>
  642.             </div>
  643.           </div>
  644.         </div>
  645.       </div>
  646.     </div>
  647.     <!-- Descriptions and Attachments -->
  648.     <div class=\"container--gallery modern\">
  649.       ";
  650.         // line 468
  651.         $context["lastValidIndex"] = 0;
  652.         // line 469
  653.         yield "      ";
  654.         $context["hasAttachments"] = false;
  655.         // line 470
  656.         yield "      ";
  657.         $context['_parent'] = $context;
  658.         $context['_seq'] = CoreExtension::ensureTraversable((isset($context["listeattach"]) || array_key_exists("listeattach"$context) ? $context["listeattach"] : (function () { throw new RuntimeError('Variable "listeattach" does not exist.'470$this->source); })()));
  659.         $context['loop'] = [
  660.           'parent' => $context['_parent'],
  661.           'index0' => 0,
  662.           'index'  => 1,
  663.           'first'  => true,
  664.         ];
  665.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  666.             $length count($context['_seq']);
  667.             $context['loop']['revindex0'] = $length 1;
  668.             $context['loop']['revindex'] = $length;
  669.             $context['loop']['length'] = $length;
  670.             $context['loop']['last'] = === $length;
  671.         }
  672.         foreach ($context['_seq'] as $context["x"] => $context["groupAttach"]) {
  673.             // line 471
  674.             yield "      ";
  675.             $context["xDate"] = $this->extensions['Twig\Extension\CoreExtension']->convertDate($context["x"]);
  676.             // line 472
  677.             yield "      ";
  678.             $context["finDate"] = $this->extensions['Twig\Extension\CoreExtension']->convertDate(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'472$this->source); })()), "dateFinSejour", [], "any"falsefalsefalse472));
  679.             // line 473
  680.             yield "      ";
  681.             if (((isset($context["xDate"]) || array_key_exists("xDate"$context) ? $context["xDate"] : (function () { throw new RuntimeError('Variable "xDate" does not exist.'473$this->source); })()) <= (isset($context["finDate"]) || array_key_exists("finDate"$context) ? $context["finDate"] : (function () { throw new RuntimeError('Variable "finDate" does not exist.'473$this->source); })()))) {
  682.                 // line 474
  683.                 yield "      ";
  684.                 $context["lastValidIndex"] = CoreExtension::getAttribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse474);
  685.                 // line 475
  686.                 yield "      ";
  687.                 $context["hasAttachments"] = true;
  688.                 // line 476
  689.                 yield "      <div
  690.         id=\"demP";
  691.                 // line 477
  692.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse477), "html"nulltrue);
  693.                 yield "\"
  694.         class=\"collapse ";
  695.                 // line 478
  696.                 if ((CoreExtension::getAttribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse478) && ((isset($context["xDate"]) || array_key_exists("xDate"$context) ? $context["xDate"] : (function () { throw new RuntimeError('Variable "xDate" does not exist.'478$this->source); })()) <= (isset($context["finDate"]) || array_key_exists("finDate"$context) ? $context["finDate"] : (function () { throw new RuntimeError('Variable "finDate" does not exist.'478$this->source); })())))) {
  697.                     yield "show";
  698.                 }
  699.                 yield "\"
  700.         style=\"padding: 2%; padding-top: 0%\"
  701.       >
  702.         <div class=\"journal-entry\">
  703.         <div class=\"entry-header\" style=\"
  704.     display: flex;
  705.     align-items: center;
  706.     justify-content: space-between;
  707.     background: #ffffff;
  708.     padding: 8px 15px;
  709.     border-radius: 10px;
  710.     margin-bottom: 20px;
  711.     box-shadow: 0 2px 8px rgba(0,0,0,0.05);
  712.     border-bottom: 1px solid #eee;
  713.     flex-wrap: wrap;
  714. \">
  715.   <!-- Bouton Jour Précédent -->
  716.   ";
  717.                 // line 496
  718.                 if ((($tmp =  !CoreExtension::getAttribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse496)) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  719.                     // line 497
  720.                     yield "  <button class=\"btn-prev-day\" data-target=\"";
  721.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((CoreExtension::getAttribute($this->env$this->source$context["loop"], "index0", [], "any"falsefalsefalse497) - 1), "html"nulltrue);
  722.                     yield "\" style=\"
  723.       background-color: #3BA39B;
  724.       border: none;
  725.       padding: 5px 10px;
  726.       border-radius: 8px;
  727.       font-weight: bold;
  728.       font-size: 14px;
  729.       height: 36px;
  730.       display: flex;
  731.       align-items: center;
  732.       color: white;
  733.       cursor: pointer;
  734.       transition: all 0.3s ease;
  735.   \">
  736.     <i class=\"bi bi-chevron-left\" style=\"font-size: 18px;\"></i>
  737.   </button>
  738.   ";
  739.                 } else {
  740.                     // line 514
  741.                     yield "  <div style=\"width: 36px;\"></div>
  742.   ";
  743.                 }
  744.                 // line 516
  745.                 yield "
  746.   <!-- Centre : Date + Médias -->
  747.   <div style=\"
  748.       flex-grow: 1;
  749.       display: flex;
  750.       align-items: center;
  751.       justify-content: center;
  752.       flex-wrap: wrap;
  753.       gap: 12px;
  754.   \">
  755.     <!-- Date -->
  756.     <div style=\"font-weight: bold; font-size: 16px; color: #333;\">
  757.       ";
  758.                 // line 528
  759.                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(Twig\Extension\CoreExtension::replace($this->extensions['Twig\Extension\CoreExtension']->formatDate($context["x"], "l d F Y"), ["Monday" => "Lundi""Tuesday" => "Mardi""Wednesday" => "Mercredi""Thursday" => "Jeudi""Friday" => "Vendredi""Saturday" => "Samedi""Sunday" => "Dimanche""January" => "Janvier""February" => "Février""March" => "Mars""April" => "Avril""May" => "Mai""June" => "Juin""July" => "Juillet""August" => "Août""September" => "Septembre""October" => "Octobre""November" => "Novembre""December" => "Décembre"]), "html"nulltrue);
  760.                 // line 536
  761.                 yield "
  762.     </div>
  763.   <!-- Filtres Médias -->
  764. <div class=\"filter-icons\" style=\"display: flex; gap: 8px; flex-wrap: wrap;\">
  765.     <span class=\"filter-badge active\" data-filter=\"all\" title=\"Afficher tout\">
  766.         <i class=\"bi bi-grid-3x3-gap-fill\" style=\"margin-right: 5px; font-size: 14px;\"></i> Tout
  767.     </span>
  768.     ";
  769.                 // line 545
  770.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countPhotos", [], "any"falsefalsefalse545) > 0)) {
  771.                     // line 546
  772.                     yield "    <span class=\"filter-badge\" data-filter=\"photo\" title=\"Filtrer les photos\">
  773.         <i class=\"bi bi-image\" style=\"margin-right: 5px; font-size: 14px;\"></i> ";
  774.                     // line 547
  775.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countPhotos", [], "any"falsefalsefalse547), "html"nulltrue);
  776.                     yield "
  777.     </span>
  778.     ";
  779.                 }
  780.                 // line 550
  781.                 yield "
  782.     ";
  783.                 // line 551
  784.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countVideos", [], "any"falsefalsefalse551) > 0)) {
  785.                     // line 552
  786.                     yield "    <span class=\"filter-badge\" data-filter=\"video\" title=\"Filtrer les vidéos\">
  787.         <i class=\"bi bi-camera-video-fill\" style=\"margin-right: 5px; font-size: 14px;\"></i> ";
  788.                     // line 553
  789.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countVideos", [], "any"falsefalsefalse553), "html"nulltrue);
  790.                     yield "
  791.     </span>
  792.     ";
  793.                 }
  794.                 // line 556
  795.                 yield "
  796.     ";
  797.                 // line 557
  798.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countAudio", [], "any"falsefalsefalse557) > 0)) {
  799.                     // line 558
  800.                     yield "    <span class=\"filter-badge\" data-filter=\"audio\" title=\"Filtrer les messages audio\">
  801.         <i class=\"bi bi-mic-fill\" style=\"margin-right: 5px; font-size: 14px;\"></i> ";
  802.                     // line 559
  803.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countAudio", [], "any"falsefalsefalse559), "html"nulltrue);
  804.                     yield "
  805.     </span>
  806.     ";
  807.                 }
  808.                 // line 562
  809.                 yield "</div>
  810.   </div>
  811.   <!-- Bouton Jour Suivant -->
  812.   ";
  813.                 // line 567
  814.                 if ((($tmp =  !CoreExtension::getAttribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse567)) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  815.                     // line 568
  816.                     yield "  <button class=\"btn-next-day\" data-target=\"";
  817.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((CoreExtension::getAttribute($this->env$this->source$context["loop"], "index0", [], "any"falsefalsefalse568) + 1), "html"nulltrue);
  818.                     yield "\" style=\"
  819.       background-color: #3BA39B;
  820.       border: none;
  821.       padding: 5px 10px;
  822.       border-radius: 8px;
  823.       font-weight: bold;
  824.       font-size: 14px;
  825.       height: 36px;
  826.       display: flex;
  827.       align-items: center;
  828.       color: white;
  829.       cursor: pointer;
  830.       transition: all 0.3s ease;
  831.   \">
  832.     <i class=\"bi bi-chevron-right\" style=\"font-size: 18px;\"></i>
  833.   </button>
  834.   ";
  835.                 } else {
  836.                     // line 585
  837.                     yield "  <div style=\"width: 36px;\"></div>
  838.   ";
  839.                 }
  840.                 // line 587
  841.                 yield "
  842.    
  843.    
  844.         </div>
  845.         <!-- Contenu -->
  846.         <div class=\"entry-content\" id=\"TourContent\">
  847.       
  848.           <p class=\"description\" style=\"margin-left:2%;width:95%;margin-top:1%;margin-bottom:1%;text-align:left\">
  849.             ";
  850.                 // line 597
  851.                 $context['_parent'] = $context;
  852.                 $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'597$this->source); })()), "jourdescripdate", [], "any"falsefalsefalse597));
  853.                 foreach ($context['_seq'] as $context["_key"] => $context["description"]) {
  854.                     yield " ";
  855.                     if (($this->extensions['Twig\Extension\CoreExtension']->formatDate(CoreExtension::getAttribute($this->env$this->source,                     // line 598
  856. $context["description"], "datejourphoto", [], "any"falsefalsefalse598), "m/d/Y") == $this->extensions['Twig\Extension\CoreExtension']->formatDate($context["x"], "m/d/Y"))) {
  857.                         // line 599
  858.                         yield "            ";
  859.                         yield Twig\Extension\CoreExtension::nl2br($this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["description"], "description", [], "any"falsefalsefalse599), "html"nulltrue));
  860.                         yield "
  861.             ";
  862.                     }
  863.                     // line 600
  864.                     yield " ";
  865.                 }
  866.                 $_parent $context['_parent'];
  867.                 unset($context['_seq'], $context['_key'], $context['description'], $context['_parent']);
  868.                 $context array_intersect_key($context$_parent) + $_parent;
  869.                 // line 601
  870.                 yield "          </p>
  871.  
  872.           <!-- Conteneur des photos et vidéos -->
  873.           <div
  874.             class=\"rowimag no-margin\"
  875.             style=\"
  876.               width: 100%;
  877.               display: flex;
  878.               flex-wrap: wrap;
  879.               margin: 0;
  880.               box-sizing: border-box;
  881.             \"
  882.           >
  883.             <!-- Afficher les Photos et Vidéos -->
  884.             ";
  885.                 // line 616
  886.                 $context['_parent'] = $context;
  887.                 $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "attachments", [], "any"falsefalsefalse616));
  888.                 foreach ($context['_seq'] as $context["_key"] => $context["attach"]) {
  889.                     // line 617
  890.                     yield "              ";
  891.                     if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse617) == "photo")) {
  892.                         // line 618
  893.                         yield "           
  894.             <div class=\"column\" data-type=\"";
  895.                         // line 619
  896.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse619), "html"nulltrue);
  897.                         yield "\">
  898.             
  899.               <div class=\"photo-zoom photo-item\">
  900.          
  901.                 <a href=\"";
  902.                         // line 623
  903.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse623), "html"nulltrue);
  904.                         yield "\">
  905.                   <img src=\"";
  906.                         // line 624
  907.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse624), "html"nulltrue);
  908.                         yield "\" alt=\"";
  909.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse624), "html"nulltrue);
  910.                         yield "\" />
  911.                 </a>
  912.                 <!-- Icône du cœur avec logique existante -->
  913.                 <div
  914.                   class=\"heart-icon\"
  915.                   id=\"coeur";
  916.                         // line 630
  917.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "id_attchment", [], "any"falsefalsefalse630), "html"nulltrue);
  918.                         yield "\"
  919.                   data-id=\"";
  920.                         // line 631
  921.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "id_attchment", [], "any"falsefalsefalse631), "html"nulltrue);
  922.                         yield "\"
  923.                   data-sejour-id=\"";
  924.                         // line 632
  925.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'632$this->source); })()), "id", [], "any"falsefalsefalse632), "html"nulltrue);
  926.                         yield "\"
  927.                   data-path=\"";
  928.                         // line 633
  929.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse633), "html"nulltrue);
  930.                         yield "\"
  931.                   data-description=\"";
  932.                         // line 634
  933.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse634), "html"nulltrue);
  934.                         yield "\"
  935.                 >
  936.                   ";
  937.                         // line 636
  938.                         if ((($tmp CoreExtension::getAttribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'636$this->source); })()), "user", [], "any"falsefalsefalse636)) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  939.                             yield " ";
  940.                             if ((($tmp CoreExtension::getAttribute($this->env$this->source$context["attach"], "is_favorite", [], "any"falsefalsefalse636)) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  941.                                 // line 637
  942.                                 yield "                  <i
  943.                     class=\"bi bi-heart-fill\"
  944.                     title=\"Sélectionnée\"
  945.                     style=\"color: #f56040\"
  946.                   ></i>
  947.                   ";
  948.                             } else {
  949.                                 // line 643
  950.                                 yield "                  <i class=\"bi bi-heart\" title=\"Ajouter à ma sélection\"></i>
  951.                   ";
  952.                             }
  953.                             // line 644
  954.                             yield " ";
  955.                         }
  956.                         // line 645
  957.                         yield "                </div>
  958.                 <div class=\"photo-actions\" style=\"display: none\">
  959.                   <button class=\"menu-btn\">⋮</button>
  960.                   <div class=\"menu-options\">
  961.                     <button onclick=\"addToPack('tirage')\">
  962.                       🖨️ Ajouter au tirage
  963.                     </button>
  964.                     <button onclick=\"addToPack('numerique')\">
  965.                       💾 Ajouter au numérique
  966.                     </button>
  967.                   </div>
  968.                 </div>
  969.               
  970.               </div>
  971.               ";
  972.                         // line 659
  973.                         if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse659) != "")) {
  974.                             // line 660
  975.                             yield "              <h4 class=\"description\">";
  976.                             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse660), "html"nulltrue);
  977.                             yield "</h4>
  978.               ";
  979.                         }
  980.                         // line 662
  981.                         yield "            </div>
  982.             ";
  983.                     }
  984.                     // line 666
  985.                     yield 
  986.              ";
  987.                     // line 669
  988.                     if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse669) == "video")) {
  989.                         // line 670
  990.                         yield "           
  991.             <div class=\"column\" data-type=\"";
  992.                         // line 671
  993.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse671), "html"nulltrue);
  994.                         yield "\">
  995.                  
  996.             
  997.                  <div class=\"video-container\" style=\"position: relative; display: inline-block; width: 100%; border-radius: 8px; overflow: hidden;\">
  998.                         <video class=\"photo-zoom\" controls controlslist=\"nodownload noplaybackrate\" style=\"width: 100%;\">
  999.                           <source src=\"";
  1000.                         // line 676
  1001.                         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse676), "html"nulltrue);
  1002.                         yield "\" type=\"video/mp4\" />
  1003.                           Votre navigateur ne supporte pas la lecture vidéo.
  1004.                         </video>
  1005.                       
  1006.                       </div>
  1007.               ";
  1008.                         // line 681
  1009.                         if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse681) != "")) {
  1010.                             // line 682
  1011.                             yield "              <h4 class=\"description\">";
  1012.                             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse682), "html"nulltrue);
  1013.                             yield "</h4>
  1014.               ";
  1015.                         }
  1016.                         // line 684
  1017.                         yield "            </div>
  1018.             ";
  1019.                     }
  1020.                     // line 685
  1021.                     yield 
  1022.             
  1023.             ";
  1024.                 }
  1025.                 $_parent $context['_parent'];
  1026.                 unset($context['_seq'], $context['_key'], $context['attach'], $context['_parent']);
  1027.                 $context array_intersect_key($context$_parent) + $_parent;
  1028.                 // line 688
  1029.                 yield "          </div>
  1030.           <!-- Section séparée pour les messages audio -->
  1031.           ";
  1032.                 // line 691
  1033.                 if ((CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countAudio", [], "any"falsefalsefalse691) > 0)) {
  1034.                     // line 692
  1035.                     yield "          <div class=\"audio-messages-section\" style=\"margin-top:15px; border-top: 1px solid #eee; padding: 30px;\">
  1036.             <h4 style=\"margin-bottom: 15px; color: #555\">
  1037.               <i class=\"bi bi-mic-fill\" style=\"margin-right: 8px; color: #ffa500\"></i>
  1038.               Messages vocaux (";
  1039.                     // line 695
  1040.                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "countAudio", [], "any"falsefalsefalse695), "html"nulltrue);
  1041.                     yield ")
  1042.             </h4>
  1043.             
  1044.             ";
  1045.                     // line 698
  1046.                     if ((Twig\Extension\CoreExtension::slice($this->env->getCharset(), CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'698$this->source); })()), "codeSejour", [], "any"falsefalsefalse698), 02) == "PF")) {
  1047.                         // line 699
  1048.                         yield "              ";
  1049.                         // line 700
  1050.                         yield "              <div class=\"audio-messages-container\" style=\"display: flex; flex-wrap: wrap; gap: 15px\">
  1051.                 ";
  1052.                         // line 701
  1053.                         $context['_parent'] = $context;
  1054.                         $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "attachments", [], "any"falsefalsefalse701));
  1055.                         foreach ($context['_seq'] as $context["_key"] => $context["attach"]) {
  1056.                             // line 702
  1057.                             yield "                  ";
  1058.                             if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse702) == "message")) {
  1059.                                 // line 703
  1060.                                 yield "                    <div class=\"audio-message-item\" style=\"background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;\">
  1061.                       <div class=\"audio-player-container\" style=\"display: flex; align-items: center; margin-bottom: 10px;\">
  1062.                         <i class=\"bi bi-mic-fill\" style=\"font-size: 20px; margin-right: 10px; color: #ffa500\"></i>
  1063.                         <audio controls controlslist=\"nodownload noplaybackrate\" style=\"flex: 1\">
  1064.                           <source src=\"";
  1065.                                 // line 707
  1066.                                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse707), "html"nulltrue);
  1067.                                 yield "\" type=\"audio/mp3\" />
  1068.                           Votre navigateur ne supporte pas la lecture audio.
  1069.                         </audio>
  1070.                       </div>
  1071.                       ";
  1072.                                 // line 711
  1073.                                 if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse711) != "")) {
  1074.                                     // line 712
  1075.                                     yield "                        <div class=\"audio-description\" style=\"padding-left: 30px\">
  1076.                           <p style=\"margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;\">
  1077.                             ";
  1078.                                     // line 714
  1079.                                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse714), "html"nulltrue);
  1080.                                     yield "
  1081.                           </p>
  1082.                         </div>
  1083.                       ";
  1084.                                 }
  1085.                                 // line 718
  1086.                                 yield "                    </div>
  1087.                   ";
  1088.                             }
  1089.                             // line 720
  1090.                             yield "                ";
  1091.                         }
  1092.                         $_parent $context['_parent'];
  1093.                         unset($context['_seq'], $context['_key'], $context['attach'], $context['_parent']);
  1094.                         $context array_intersect_key($context$_parent) + $_parent;
  1095.                         // line 721
  1096.                         yield "              </div>
  1097.             
  1098.             ";
  1099.                     } elseif ((((Twig\Extension\CoreExtension::slice($this->env->getCharset(), CoreExtension::getAttribute($this->env$this->source,                     // line 723
  1100. (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'723$this->source); })()), "codeSejour", [], "any"falsefalsefalse723), 02) == "PP") && (CoreExtension::getAttribute($this->env$this->source, (isset($context["parentsejour"]) || array_key_exists("parentsejour"$context) ? $context["parentsejour"] : (function () { throw new RuntimeError('Variable "parentsejour" does not exist.'723$this->source); })()), "payment", [], "any"falsefalsefalse723) == 1)) || ((Twig\Extension\CoreExtension::slice($this->env->getCharset(), CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'723$this->source); })()), "codeSejour", [], "any"falsefalsefalse723), 02) == "EF") && (CoreExtension::getAttribute($this->env$this->source, (isset($context["parentsejour"]) || array_key_exists("parentsejour"$context) ? $context["parentsejour"] : (function () { throw new RuntimeError('Variable "parentsejour" does not exist.'723$this->source); })()), "payment", [], "any"falsefalsefalse723) == 1)))) {
  1101.                         // line 724
  1102.                         yield "              ";
  1103.                         // line 725
  1104.                         yield "              <div class=\"audio-messages-container\" style=\"display: flex; flex-wrap: wrap; gap: 15px\">
  1105.                 ";
  1106.                         // line 726
  1107.                         $context['_parent'] = $context;
  1108.                         $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "attachments", [], "any"falsefalsefalse726));
  1109.                         foreach ($context['_seq'] as $context["_key"] => $context["attach"]) {
  1110.                             // line 727
  1111.                             yield "                  ";
  1112.                             if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse727) == "message")) {
  1113.                                 // line 728
  1114.                                 yield "                    <div class=\"audio-message-item\" style=\"background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;\">
  1115.                       <div class=\"audio-player-container\" style=\"display: flex; align-items: center; margin-bottom: 10px;\">
  1116.                         <i class=\"bi bi-mic-fill\" style=\"font-size: 20px; margin-right: 10px; color: #ffa500\"></i>
  1117.                         <audio controls controlslist=\"nodownload noplaybackrate\" style=\"flex: 1\">
  1118.                           <source src=\"";
  1119.                                 // line 732
  1120.                                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse732), "html"nulltrue);
  1121.                                 yield "\" type=\"audio/mp3\" />
  1122.                           Votre navigateur ne supporte pas la lecture audio.
  1123.                         </audio>
  1124.                       </div>
  1125.                       ";
  1126.                                 // line 736
  1127.                                 if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse736) != "")) {
  1128.                                     // line 737
  1129.                                     yield "                        <div class=\"audio-description\" style=\"padding-left: 30px\">
  1130.                           <p style=\"margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;\">
  1131.                             ";
  1132.                                     // line 739
  1133.                                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse739), "html"nulltrue);
  1134.                                     yield "
  1135.                           </p>
  1136.                         </div>
  1137.                       ";
  1138.                                 }
  1139.                                 // line 743
  1140.                                 yield "                    </div>
  1141.                   ";
  1142.                             }
  1143.                             // line 745
  1144.                             yield "                ";
  1145.                         }
  1146.                         $_parent $context['_parent'];
  1147.                         unset($context['_seq'], $context['_key'], $context['attach'], $context['_parent']);
  1148.                         $context array_intersect_key($context$_parent) + $_parent;
  1149.                         // line 746
  1150.                         yield "              </div>
  1151.             
  1152.             ";
  1153.                     } elseif ((((Twig\Extension\CoreExtension::slice($this->env->getCharset(), CoreExtension::getAttribute($this->env$this->source,                     // line 748
  1154. (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'748$this->source); })()), "codeSejour", [], "any"falsefalsefalse748), 02) == "PP") && (CoreExtension::getAttribute($this->env$this->source, (isset($context["parentsejour"]) || array_key_exists("parentsejour"$context) ? $context["parentsejour"] : (function () { throw new RuntimeError('Variable "parentsejour" does not exist.'748$this->source); })()), "payment", [], "any"falsefalsefalse748) == 0)) || ((Twig\Extension\CoreExtension::slice($this->env->getCharset(), CoreExtension::getAttribute($this->env$this->source, (isset($context["sejour"]) || array_key_exists("sejour"$context) ? $context["sejour"] : (function () { throw new RuntimeError('Variable "sejour" does not exist.'748$this->source); })()), "codeSejour", [], "any"falsefalsefalse748), 02) == "EF") && (CoreExtension::getAttribute($this->env$this->source, (isset($context["parentsejour"]) || array_key_exists("parentsejour"$context) ? $context["parentsejour"] : (function () { throw new RuntimeError('Variable "parentsejour" does not exist.'748$this->source); })()), "payment", [], "any"falsefalsefalse748) == 0)))) {
  1155.                         // line 749
  1156.                         yield "              ";
  1157.                         // line 750
  1158.                         yield "              <div class=\"audio-messages-container\" style=\"display: flex; flex-wrap: wrap; gap: 15px; opacity: 0.5; pointer-events: none; filter: grayscale(100%);\">
  1159.                 <div class=\"audio-messages-restricted\" style=\"padding: 20px; background: #f0f0f0; border-radius: 8px; text-align: center; margin-bottom: 15px; width: 100%;\">
  1160.                   <i class=\"bi bi-lock-fill\" style=\"font-size: 24px; color: #808080; margin-bottom: 10px;\"></i>
  1161.                   <p style=\"margin: 0; color: #555;\">📢 Les messages vocaux sont disponibles via la boîte vocale premium. Un paiement est requis pour l’activer et y accéder.</p>
  1162.                 </div>
  1163.                 ";
  1164.                         // line 755
  1165.                         $context['_parent'] = $context;
  1166.                         $context['_seq'] = CoreExtension::ensureTraversable(CoreExtension::getAttribute($this->env$this->source$context["groupAttach"], "attachments", [], "any"falsefalsefalse755));
  1167.                         foreach ($context['_seq'] as $context["_key"] => $context["attach"]) {
  1168.                             // line 756
  1169.                             yield "                  ";
  1170.                             if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "libiller", [], "any"falsefalsefalse756) == "message")) {
  1171.                                 // line 757
  1172.                                 yield "                    <div class=\"audio-message-item\" style=\"background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;\">
  1173.                       <div class=\"audio-player-container\" style=\"display: flex; align-items: center; margin-bottom: 10px;\">
  1174.                         <i class=\"bi bi-mic-fill\" style=\"font-size: 20px; margin-right: 10px; color: #ffa500\"></i>
  1175.                         <audio controls controlslist=\"nodownload noplaybackrate\" style=\"flex: 1\" disabled>
  1176.                           <source src=\"";
  1177.                                 // line 761
  1178.                                 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "path", [], "any"falsefalsefalse761), "html"nulltrue);
  1179.                                 yield "\" type=\"audio/mp3\" />
  1180.                           Votre navigateur ne supporte pas la lecture audio.
  1181.                         </audio>
  1182.                       </div>
  1183.                       ";
  1184.                                 // line 765
  1185.                                 if ((CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse765) != "")) {
  1186.                                     // line 766
  1187.                                     yield "                        <div class=\"audio-description\" style=\"padding-left: 30px\">
  1188.                           <p style=\"margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;\">
  1189.                             ";
  1190.                                     // line 768
  1191.                                     yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(CoreExtension::getAttribute($this->env$this->source$context["attach"], "descreption", [], "any"falsefalsefalse768), "html"nulltrue);
  1192.                                     yield "
  1193.                           </p>
  1194.                         </div>
  1195.                       ";
  1196.                                 }
  1197.                                 // line 772
  1198.                                 yield "                    </div>
  1199.                   ";
  1200.                             }
  1201.                             // line 774
  1202.                             yield "                ";
  1203.                         }
  1204.                         $_parent $context['_parent'];
  1205.                         unset($context['_seq'], $context['_key'], $context['attach'], $context['_parent']);
  1206.                         $context array_intersect_key($context$_parent) + $_parent;
  1207.                         // line 775
  1208.                         yield "              </div>
  1209.             ";
  1210.                     }
  1211.                     // line 777
  1212.                     yield "          </div>
  1213.         ";
  1214.                 }
  1215.                 // line 779
  1216.                 yield "        </div>
  1217.       </div>
  1218.     </div>
  1219.     ";
  1220.             }
  1221.             // line 783
  1222.             yield "    ";
  1223.             ++$context['loop']['index0'];
  1224.             ++$context['loop']['index'];
  1225.             $context['loop']['first'] = false;
  1226.             if (isset($context['loop']['revindex0'], $context['loop']['revindex'])) {
  1227.                 --$context['loop']['revindex0'];
  1228.                 --$context['loop']['revindex'];
  1229.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  1230.             }
  1231.         }
  1232.         $_parent $context['_parent'];
  1233.         unset($context['_seq'], $context['x'], $context['groupAttach'], $context['_parent'], $context['loop']);
  1234.         $context array_intersect_key($context$_parent) + $_parent;
  1235.         // line 784
  1236.         yield "    ";
  1237.         if ((($tmp =  !(isset($context["hasAttachments"]) || array_key_exists("hasAttachments"$context) ? $context["hasAttachments"] : (function () { throw new RuntimeError('Variable "hasAttachments" does not exist.'784$this->source); })())) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  1238.             // line 785
  1239.             yield "    <div class=\"welcome-message\" style=\"padding: 50px 20px; text-align: center; background: #f9f9f9; border-radius: 15px; margin: 30px auto; max-width: 800px; box-shadow: 0 5px 15px rgba(0,0,0,0.05);\">
  1240.       <img src=\"/images/welcome-icon.svg\" alt=\"Bienvenue\" style=\"width: 80px; margin-bottom: 20px;\" onerror=\"this.src='/images/Accompagnateur/Picto5sur5.svg'; this.style.width='120px';\">
  1241.       
  1242.       <h2 style=\"color: #41a2aa; margin-bottom: 20px; font-size: 24px;\">Bienvenue sur votre espace séjour !</h2>
  1243.       
  1244.       <p style=\"font-size: 18px; color: #555; margin-bottom: 15px;\">
  1245.         Aucun contenu n'a encore été partagé pour ce séjour.
  1246.       </p>
  1247.       
  1248.       <p style=\"font-size: 16px; color: #666; margin-bottom: 25px;\">
  1249.         L'accompagnateur partagera bientôt des photos, vidéos et messages vocaux.
  1250.         <br>Revenez consulter cette page régulièrement pour suivre les aventures du séjour !
  1251.       </p>
  1252.       
  1253.       <div style=\"display: flex; justify-content: center; gap: 15px; flex-wrap: wrap;\">
  1254.         <div style=\"display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);\">
  1255.           <i class=\"bi bi-images\" style=\"font-size: 24px; color: #f56040; margin-right: 10px;\"></i>
  1256.           <span>Photos du séjour</span>
  1257.         </div>
  1258.         
  1259.         <div style=\"display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);\">
  1260.           <i class=\"bi bi-camera-video-fill\" style=\"font-size: 24px; color: #41a2aa; margin-right: 10px;\"></i>
  1261.           <span>Vidéos des activités</span>
  1262.         </div>
  1263.         
  1264.         <div style=\"display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);\">
  1265.           <i class=\"bi bi-mic-fill\" style=\"font-size: 24px; color: #ffa500; margin-right: 10px;\"></i>
  1266.           <span>Messages vocaux</span>
  1267.         </div>
  1268.       </div>
  1269.     </div>
  1270.     
  1271.     <!-- Espace supplémentaire pour déplacer le footer vers le bas -->
  1272.     <div style=\"height: 300px;\"></div>
  1273.     ";
  1274.         }
  1275.         // line 820
  1276.         yield "    
  1277.     <!-- Make sure we're showing the right content by default if no valid content is marked 'show' -->
  1278.     ";
  1279.         // line 822
  1280.         if (((isset($context["lastValidIndex"]) || array_key_exists("lastValidIndex"$context) ? $context["lastValidIndex"] : (function () { throw new RuntimeError('Variable "lastValidIndex" does not exist.'822$this->source); })()) > 0)) {
  1281.             // line 823
  1282.             yield "    <script>
  1283.       document.addEventListener('DOMContentLoaded', function() {
  1284.         // Check if no content is showing
  1285.         if (document.querySelectorAll('.container--gallery .collapse.show').length === 0) {
  1286.           // Show the content for the last valid date
  1287.           var lastValidContent = document.getElementById('demP";
  1288.             // line 828
  1289.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["lastValidIndex"]) || array_key_exists("lastValidIndex"$context) ? $context["lastValidIndex"] : (function () { throw new RuntimeError('Variable "lastValidIndex" does not exist.'828$this->source); })()), "html"nulltrue);
  1290.             yield "');
  1291.           if (lastValidContent) {
  1292.             lastValidContent.classList.add('show');
  1293.             
  1294.             // Also mark the corresponding date card as active
  1295.             var dateCards = document.querySelectorAll('.date-card');
  1296.             if (dateCards.length >= ";
  1297.             // line 834
  1298.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["lastValidIndex"]) || array_key_exists("lastValidIndex"$context) ? $context["lastValidIndex"] : (function () { throw new RuntimeError('Variable "lastValidIndex" does not exist.'834$this->source); })()), "html"nulltrue);
  1299.             yield ") {
  1300.               dateCards.forEach(card => card.classList.remove('active'));
  1301.               dateCards[";
  1302.             // line 836
  1303.             yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape(((isset($context["lastValidIndex"]) || array_key_exists("lastValidIndex"$context) ? $context["lastValidIndex"] : (function () { throw new RuntimeError('Variable "lastValidIndex" does not exist.'836$this->source); })()) - 1), "html"nulltrue);
  1304.             yield "].classList.add('active');
  1305.             }
  1306.           }
  1307.         }
  1308.       });
  1309.     </script>
  1310.     ";
  1311.         }
  1312.         // line 843
  1313.         yield "  </div>
  1314. </div>
  1315.   ";
  1316.         
  1317.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  1318.         
  1319.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  1320.         yield from [];
  1321.     }
  1322.     // line 846
  1323.     /**
  1324.      * @return iterable<null|scalar|\Stringable>
  1325.      */
  1326.     public function block_Javascript(array $context, array $blocks = []): iterable
  1327.     {
  1328.         $macros $this->macros;
  1329.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  1330.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Javascript"));
  1331.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  1332.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Javascript"));
  1333.         // line 847
  1334.         yield "  ";
  1335.         yield from $this->yieldParentBlock("Javascript"$context$blocks);
  1336.         yield "
  1337.   <script>// Gestion de la sidebar des favoris
  1338. document.addEventListener('DOMContentLoaded', function() {
  1339.     const sidebar = document.getElementById('favorites-sidebar');
  1340.     const openBtn = document.getElementById('openFavoritesSidebar');
  1341.     const closeBtn = document.querySelector('.favorites-close');
  1342.     const favButton = document.querySelector('.fav-button');
  1343.     function openSidebar() {
  1344.         sidebar.classList.add('active');
  1345.         updateFavoritesSidebar();
  1346.     }
  1347.     function closeSidebar() {
  1348.         sidebar.classList.remove('active');
  1349.     }
  1350.     function updateFavoritesSidebar() {
  1351.         const grid = document.getElementById('favorites-grid');
  1352.         const counter = document.getElementById('favorites-counter');
  1353.         const emptyState = document.getElementById('favorites-empty-state');
  1354.         const progress = document.getElementById('favorites-progress');
  1355.         
  1356.         const count = parseInt(document.getElementById('likeCount').textContent);
  1357.         counter.textContent = count +1;
  1358.         
  1359.         if (count === 0) {
  1360.             emptyState.style.display = 'flex';
  1361.             grid.style.display = 'none';
  1362.         } else {
  1363.             emptyState.style.display = 'none';
  1364.             grid.style.display = 'grid';
  1365.             const percentage = (count / 20) * 100;
  1366.             progress.style.width = `\${percentage}%`;
  1367.         }
  1368.     }
  1369.     if (openBtn) {
  1370.         openBtn.addEventListener('click', openSidebar);
  1371.     }
  1372.     if (favButton) {
  1373.         favButton.addEventListener('click', openSidebar);
  1374.     }
  1375.     if (closeBtn) {
  1376.         closeBtn.addEventListener('click', closeSidebar);
  1377.     }
  1378.     document.addEventListener('click', (e) => {
  1379.         if (sidebar.classList.contains('active') && 
  1380.             !sidebar.contains(e.target) && 
  1381.             !favButton.contains(e.target) && 
  1382.             !openBtn.contains(e.target)) {
  1383.             closeSidebar();
  1384.         }
  1385.     });
  1386. });
  1387. // Modification des fonctions existantes
  1388. const originalAddFavoris = window.AddFavoris;
  1389. window.AddFavoris = function(\$id, \$idSejour, \$urlimg, \$description) {
  1390.     if (originalAddFavoris) {
  1391.         originalAddFavoris(\$id, \$idSejour, \$urlimg, \$description);
  1392.     }
  1393.     
  1394.     // Vérifier si la sidebar est ouverte - noter que nous vérifions la valeur CSS right: 0
  1395.     if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  1396.         // Recharger les favoris
  1397.         loadFavorites();
  1398.     }
  1399. };
  1400. const originalSupprimerFavoris = window.supprimerFavoris;
  1401. window.supprimerFavoris = function(\$id, \$idSejour) {
  1402.     if (originalSupprimerFavoris) {
  1403.         originalSupprimerFavoris(\$id, \$idSejour);
  1404.     }
  1405.     
  1406.     // Vérifier si la sidebar est ouverte
  1407.     if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  1408.         // Recharger les favoris
  1409.         loadFavorites();
  1410.     }
  1411. };
  1412. // Variables globales
  1413. let selectedFavorites = [];
  1414. let allFavorites = [];
  1415. // Fonction pour mettre à jour la sidebar
  1416. function loadFavorites() {
  1417.     \$(\"#favorites-grid\").html(\"<div style='text-align:center;padding:20px;'>Chargement...</div>\");
  1418.     
  1419.     \$.ajax({
  1420.         url: \"/Parent/mes-favoris\",
  1421.         type: \"GET\",
  1422.         dataType: \"json\",
  1423.         success: function(data) {
  1424.             \$(\"#favorites-grid\").empty();
  1425.             allFavorites = data.data || [];
  1426.             
  1427.             if (allFavorites.length > 0) {
  1428.                 \$(\"#favorites-empty-state\").hide();
  1429.                 
  1430.                 \$.each(allFavorites, function(i, fav) {
  1431.                     var isSelected = selectedFavorites.includes(fav.id);
  1432.                     
  1433.                     var item = \$(\"<div class='favorite-item' style='position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1;cursor:pointer;'></div>\");
  1434.                     var img = \$(\"<img style='width:100%;height:100%;object-fit:cover;transition:transform 0.3s ease;'>\").attr(\"src\", fav.path).attr(\"alt\", fav.descreption || \"Photo favorite\");
  1435.                     
  1436.                     // Overlay de sélection
  1437.                     var selectionOverlay = \$(\"<div class='selection-overlay' style='position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.3);display:flex;align-items:center;justify-content:center;'></div>\");
  1438.                     
  1439.                     // Icône de sélection
  1440.                     var checkIcon = \$(\"<div style='width:25px;height:25px;border-radius:50%;border:2px solid white;display:flex;align-items:center;justify-content:center;background:\" + (isSelected ? \"#F56040\" : \"transparent\") + \";transition:background 0.2s;'></div>\");
  1441.                     if (isSelected) {
  1442.                         checkIcon.append(\"<i class='bi bi-check' style='color:white;font-size:16px;'></i>\");
  1443.                     }
  1444.                     
  1445.                     selectionOverlay.append(checkIcon);
  1446.                     
  1447.                     // Overlay d'action (bouton supprimer)
  1448.                     var actionOverlay = \$(\"<div class='action-overlay' style='position:absolute;top:5px;right:5px;opacity:0;transition:opacity 0.2s;'></div>\");
  1449.                   
  1450.                     actionOverlay.append(deleteBtn);
  1451.                     
  1452.                     // Ajouter les événements
  1453.                     item.hover(
  1454.                         function() { \$(this).find(\".action-overlay\").css(\"opacity\", \"1\"); },
  1455.                         function() { \$(this).find(\".action-overlay\").css(\"opacity\", \"0\"); }
  1456.                     );
  1457.                     
  1458.                     item.click(function() {
  1459.                         toggleSelection(fav.id, \$(this).find(\".selection-overlay > div\"));
  1460.                     });
  1461.                     
  1462.                     item.append(img).append(selectionOverlay).append(actionOverlay);
  1463.                     \$(\"#favorites-grid\").append(item);
  1464.                 });
  1465.                 
  1466.                 \$(\"#favorites-counter\").text(allFavorites.length);
  1467.                 
  1468.                 // Mettre à jour le compteur sur le bouton également
  1469.                 \$(\"#openFavoritesSidebar span\").text(allFavorites.length);
  1470.                 
  1471.                 // Mettre à jour l'interface produits
  1472.                 updateProductsView();
  1473.                 
  1474.             } else {
  1475.                 \$(\"#favorites-empty-state\").show();
  1476.                 \$(\"#favorites-counter\").text(\"0\");
  1477.                 \$(\"#openFavoritesSidebar span\").text(\"0\");
  1478.                 \$(\"#selection-count\").text(\"0\");
  1479.                 updateProductsView();
  1480.             }
  1481.         },
  1482.         error: function() {
  1483.             \$(\"#favorites-grid\").html(\"<div style='color:red;text-align:center;padding:20px;'>Erreur de chargement</div>\");
  1484.         }
  1485.     });
  1486. }
  1487. // Fonction pour supprimer un favori
  1488. function removeFavorite(id) {
  1489.     \$.ajax({
  1490.         url: \"/Parent/remove-favorite/\" + id,
  1491.         type: \"POST\",
  1492.         success: function() {
  1493.             // Retirer de la sélection si présent
  1494.             selectedFavorites = selectedFavorites.filter(favId => favId != id);
  1495.             
  1496.             // Mettre à jour le compteur de sélection
  1497.             \$(\"#selection-count\").text(selectedFavorites.length);
  1498.             
  1499.             // Recharger les favoris
  1500.             loadFavorites();
  1501.             
  1502.             // Mettre à jour les compteurs globaux
  1503.             var count = parseInt(\$(\"#likeCount\").text());
  1504.             if (!isNaN(count)) {
  1505.                 \$(\"#likeCount\").text(count - 1);
  1506.             }
  1507.             
  1508.             var countFav = parseInt(\$(\"#mesFavCount\").text());
  1509.             if (!isNaN(countFav)) {
  1510.                 \$(\"#mesFavCount\").text(countFav - 1);
  1511.             }
  1512.             
  1513.             // Mettre à jour l'interface produits
  1514.             updateProductsView();
  1515.         },
  1516.         error: function() {
  1517.             alert(\"Erreur lors de la suppression du favori\");
  1518.         }
  1519.     });
  1520. }
  1521. // Fonction pour basculer la sélection d'une photo
  1522. function toggleSelection(id, checkElement) {
  1523.     const index = selectedFavorites.indexOf(id);
  1524.     
  1525.     if (index === -1) {
  1526.         // Ajouter à la sélection
  1527.         selectedFavorites.push(id);
  1528.         checkElement.css(\"background\", \"#F56040\");
  1529.         checkElement.html(\"<i class='bi bi-check' style='color:white;font-size:16px;'></i>\");
  1530.     } else {
  1531.         // Retirer de la sélection
  1532.         selectedFavorites.splice(index, 1);
  1533.         checkElement.css(\"background\", \"transparent\");
  1534.         checkElement.html(\"\");
  1535.     }
  1536.     
  1537.     // Mettre à jour le compteur
  1538.     \$(\"#selection-count\").text(selectedFavorites.length);
  1539.     
  1540.     // Mettre à jour l'interface produits
  1541.     updateProductsView();
  1542. }
  1543. // Fonction pour mettre à jour la vue des produits
  1544. function updateProductsView() {
  1545.     const current = selectedFavorites.length;
  1546.     \$(\"#product-photo-count\").text(current);
  1547.     
  1548.     let remainingForAlbum = Math.max(0, 20 - current);
  1549.     let remainingForPochette = Math.max(0, 12 - current);
  1550.     let remainingForPack = Math.max(0, 12 - current);
  1551.     const progressBar = (count, total, color) => `
  1552.         <div style=\"margin: 5px 0;\">
  1553.             <div style=\"background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;\">
  1554.                 <div style=\"width: \${(count / total) * 100}%; background-color: \${color}; height: 100%;\"></div>
  1555.             </div>
  1556.             <small style=\"font-size: 12px;\">\${count}/\${total} photos</small>
  1557.         </div>
  1558.     `;
  1559.     // Liste des produits
  1560.     const products = [
  1561.         {
  1562.             name: \"Pack numérique (20 photos)\",
  1563.             required: 20,
  1564.             remaining: Math.max(0, 20 - current),
  1565.             image: \"/images/produit/photoNumerique.jpg\",
  1566.             color: \"#4caf50\",
  1567.             link: \"";
  1568.         // line 1093
  1569.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("PackPhotosNumerique_Favoris", ["nbr" => 20]);
  1570.         yield "\",
  1571.         },
  1572.        +
  1573.         {
  1574.             name: \"Pochette photo (12 photos)\",
  1575.             required: 12,
  1576.             remaining: Math.max(0, 12 - current),
  1577.             image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  1578.             color: \"#2196f3\",
  1579.             link: \"";
  1580.         // line 1102
  1581.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("AjoutPochettePhotos_Favoris", ["nbr" => 12]);
  1582.         yield "\",
  1583.         },
  1584.     ].sort((a, b) => a.remaining - b.remaining);
  1585.     const productList = products
  1586.         .map((product) => {
  1587.             const count = current;
  1588.             const total = product.required;
  1589.             const remaining = product.remaining;
  1590.             return `
  1591.                 <li style=\"margin-bottom: 20px;\">
  1592.                     <div style=\"display: flex; align-items: center; gap: 10px;\">
  1593.                         <img src=\"\${product.image}\" alt=\"\${product.name}\" style=\"width: 70px; height: 70px; border-radius: 5px; object-fit: cover;\" />
  1594.                         <div style=\"flex: 1;\">
  1595.                             <strong style=\"font-size: 14px;\">\${product.name}</strong>
  1596.                             \${progressBar(count, total, product.color)}
  1597.                             \${
  1598.                                 `<small style=\"color: \${product.color}; font-size: 12px;\">
  1599.                                     Encore \${remaining} photos pour compléter \${product.name.toLowerCase()}
  1600.                                 </small>
  1601.                                 <button
  1602.                                     style=\"
  1603.                                         margin-top: 5px;
  1604.                                         padding: 6px 12px;
  1605.                                         background-color: \${product.color};
  1606.                                         color: white;
  1607.                                         border: none;
  1608.                                         border-radius: 5px;
  1609.                                         font-size: 13px;
  1610.                                         cursor: pointer;
  1611.                                     \"
  1612.                                     onclick=\"window.location.href='\${product.link}'\"
  1613.                                 >
  1614.                                     Commander
  1615.                                 </button>`
  1616.                             }
  1617.                         </div>
  1618.                     </div>
  1619.                 </li>
  1620.             `;
  1621.         })
  1622.         .join(\"\");
  1623.     const boutiqueButton = `
  1624.         <li style=\"margin-top: 25px; text-align: center;\">
  1625.             <button
  1626.                 style=\"
  1627.                     padding: 8px 15px;
  1628.                     background-color: #F56040;
  1629.                     color: white;
  1630.                     border: none;
  1631.                     border-radius: 5px;
  1632.                     font-size: 14px;
  1633.                     width: 170px;
  1634.                     height: 40px;
  1635.                     cursor: pointer;
  1636.                 \"
  1637.                 onclick=\"window.location.href='";
  1638.         // line 1160
  1639.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("boutique5sur5");
  1640.         yield "'\"
  1641.             >
  1642.                 Voir toute la boutique
  1643.             </button>
  1644.         </li>
  1645.     `;
  1646.     \$(\"#product-list\").html(productList + boutiqueButton);
  1647. }
  1648. // Modifications au script existant
  1649. \$(document).ready(function() {
  1650.     // Fonctions pour ouvrir/fermer la sidebar
  1651.     \$(\"#openFavoritesSidebar\").click(function() {
  1652.         \$(\"#favorites-sidebar\").css(\"right\", \"0\");
  1653.         loadFavorites();
  1654.     });
  1655.     
  1656.     \$(\"#close-favorites-btn\").click(function() {
  1657.         closeFavoritesSidebar();
  1658.     });
  1659.     
  1660.     // Fonction pour fermer la sidebar
  1661.     window.closeFavoritesSidebar = function() {
  1662.         \$(\"#favorites-sidebar\").css(\"right\", \"-500px\");
  1663.     };
  1664.     
  1665.     // Tout sélectionner / Tout désélectionner
  1666.     \$(\"#select-all-btn\").click(function() {
  1667.         if (selectedFavorites.length === allFavorites.length) {
  1668.             // Tout désélectionner
  1669.             selectedFavorites = [];
  1670.             \$(\".selection-overlay > div\").css(\"background\", \"transparent\").html(\"\");
  1671.             \$(this).text(\"Tout sélectionner\");
  1672.         } else {
  1673.             // Tout sélectionner
  1674.             selectedFavorites = allFavorites.map(fav => fav.id);
  1675.             \$(\".selection-overlay > div\").css(\"background\", \"#F56040\").html(\"<i class='bi bi-check' style='color:white;font-size:16px;'></i>\");
  1676.             \$(this).text(\"Tout désélectionner\");
  1677.         }
  1678.         
  1679.         // Mettre à jour le compteur
  1680.         \$(\"#selection-count\").text(selectedFavorites.length);
  1681.         
  1682.         // Mettre à jour l'interface produits
  1683.         updateProductsView();
  1684.     });
  1685.     
  1686.     // Gestion des onglets
  1687.     \$(\".sidebar-tab\").click(function() {
  1688.         \$(\".sidebar-tab\").removeClass(\"active\").css({
  1689.             \"color\": \"#666\",
  1690.             \"border-bottom\": \"none\"
  1691.         });
  1692.         \$(this).addClass(\"active\").css({
  1693.             \"color\": \"#F56040\",
  1694.             \"border-bottom\": \"2px solid #F56040\"
  1695.         });
  1696.         
  1697.         const tabId = \$(this).attr(\"id\");
  1698.         \$(\".tab-content\").hide();
  1699.         
  1700.         if (tabId === \"tab-photos\") {
  1701.             \$(\"#photos-content\").show();
  1702.         } else if (tabId === \"tab-products\") {
  1703.             \$(\"#products-content\").show();
  1704.         }
  1705.     });
  1706.     
  1707.     // Modifier les fonctions existantes pour intercepter l'ajout/suppression de favoris
  1708.     const originalAddFavoris = window.AddFavoris;
  1709.     window.AddFavoris = function(\$id, \$idSejour, \$urlimg, \$description) {
  1710.         if (originalAddFavoris) {
  1711.             originalAddFavoris(\$id, \$idSejour, \$urlimg, \$description);
  1712.         }
  1713.         
  1714.         // Recharger les favoris si la sidebar est ouverte
  1715.         if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  1716.             loadFavorites();
  1717.         }
  1718.     };
  1719.     const originalSupprimerFavoris = window.supprimerFavoris;
  1720.     window.supprimerFavoris = function(\$id, \$idSejour) {
  1721.         if (originalSupprimerFavoris) {
  1722.             originalSupprimerFavoris(\$id, \$idSejour);
  1723.         }
  1724.         
  1725.         // Recharger les favoris si la sidebar est ouverte
  1726.         if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  1727.             // Retirer de la sélection si présent
  1728.             selectedFavorites = selectedFavorites.filter(favId => favId != \$id);
  1729.             loadFavorites();
  1730.         }
  1731.     };
  1732.     
  1733.     // Fermer en cliquant en dehors
  1734.     \$(document).click(function(event) {
  1735.         if (!\$(event.target).closest(\"#favorites-sidebar\").length && 
  1736.             !\$(event.target).closest(\"#openFavoritesSidebar\").length && 
  1737.             \$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  1738.             closeFavoritesSidebar();
  1739.         }
  1740.     });
  1741. });
  1742. // Initialisation de la sidebar
  1743. \$(document).ready(function() {
  1744.     // Fonctions pour ouvrir/fermer la sidebar
  1745.     \$(\"#openFavoritesSidebar\").click(function() {
  1746.         \$(\"#favorites-sidebar\").css(\"right\", \"0\");
  1747.         loadFavorites();
  1748.     });
  1749.     
  1750.     \$(\"#close-favorites-btn\").click(function() {
  1751.         \$(\"#favorites-sidebar\").css(\"right\", \"-500px\");
  1752.     });
  1753.     
  1754.     // Fermer en cliquant en dehors
  1755.     \$(document).click(function(event) {
  1756.         if (!\$(event.target).closest(\"#favorites-sidebar\").length && 
  1757.             !\$(event.target).closest(\"#openFavoritesSidebar\").length && 
  1758.             \$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  1759.             \$(\"#favorites-sidebar\").css(\"right\", \"-500px\");
  1760.         }
  1761.     });
  1762. });
  1763.   </script>
  1764.   <script src=\"";
  1765.         // line 1287
  1766.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("js/splide.min.js"), "html"nulltrue);
  1767.         yield "\"></script>
  1768.    
  1769. <script>
  1770.   document.addEventListener('DOMContentLoaded', function () {
  1771.     const openBtn = document.getElementById('openFavoritesSidebar');
  1772.     const sidebar = document.getElementById('favorites-sidebar');
  1773.     const closeBtn = document.getElementById('favorites-close');
  1774.     if (openBtn && sidebar) {
  1775.       openBtn.addEventListener('click', () => sidebar.classList.add('active'));
  1776.     }
  1777.     if (closeBtn && sidebar) {
  1778.       closeBtn.addEventListener('click', () => sidebar.classList.remove('active'));
  1779.     }
  1780.   });
  1781. </script>
  1782.  
  1783. <script>
  1784. document.addEventListener('DOMContentLoaded', function() {
  1785.   const filterBadges = document.querySelectorAll('.filter-badge');
  1786.   filterBadges.forEach(badge => {
  1787.     badge.addEventListener('click', function() {
  1788.       // Désactiver tous les badges
  1789.       filterBadges.forEach(b => b.classList.remove('active'));
  1790.       // Activer le badge cliqué
  1791.       this.classList.add('active');
  1792.     });
  1793.   });
  1794. });
  1795. </script>
  1796.   <script
  1797.     type=\"text/javascript\"
  1798.     src=\"";
  1799.         // line 1326
  1800.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("Accueil/js/jquery.magnific-popup.min.js"), "html"nulltrue);
  1801.         yield "\"
  1802.   ></script>
  1803.   <script>
  1804. document.addEventListener('DOMContentLoaded', function () {
  1805.   const prevButtons = document.querySelectorAll('.btn-prev-day');
  1806.   const nextButtons = document.querySelectorAll('.btn-next-day');
  1807.   const dateCards = document.querySelectorAll('.date-card.modern-card');
  1808.   const collapseSections = document.querySelectorAll('.collapse');
  1809.   function navigateToDay(index) {
  1810.     if (index >= 0 && index < collapseSections.length) {
  1811.       // Fermer tous les jours
  1812.       collapseSections.forEach(s => s.classList.remove('show'));
  1813.       dateCards.forEach(c => c.classList.remove('active'));
  1814.       // Ouvrir le bon jour
  1815.       const targetCollapse = collapseSections[index];
  1816.       const targetCard = dateCards[index];
  1817.       if (targetCollapse && targetCard) {
  1818.         targetCollapse.classList.add('show');
  1819.         targetCard.classList.add('active');
  1820.       }
  1821.     }
  1822.   }
  1823.   prevButtons.forEach(button => {
  1824.     button.addEventListener('click', function () {
  1825.       const targetIndex = parseInt(this.dataset.target, 10);
  1826.       navigateToDay(targetIndex);
  1827.     });
  1828.   });
  1829.   nextButtons.forEach(button => {
  1830.     button.addEventListener('click', function () {
  1831.       const targetIndex = parseInt(this.dataset.target, 10);
  1832.       navigateToDay(targetIndex);
  1833.     });
  1834.   });
  1835. });
  1836. </script>
  1837.   <script>
  1838.     document.addEventListener('DOMContentLoaded', function() {
  1839.   const style = document.createElement('style');
  1840.   style.textContent = `
  1841.     .hidden {
  1842.       display: none !important;
  1843.     }
  1844.   `;
  1845.   document.head.appendChild(style);
  1846. });
  1847.     document.addEventListener('DOMContentLoaded', function() {
  1848.     // Get the favorite button
  1849.     const favoriteButton = document.querySelector('.fav-button');
  1850.     if (favoriteButton) {
  1851.       // Make it unclickable with JS too (belt and suspenders approach)
  1852.       favoriteButton.style.pointerEvents = 'none';
  1853.       
  1854.       // Override any existing click handlers
  1855.       favoriteButton.onclick = function(e) {
  1856.         e.preventDefault();
  1857.         e.stopPropagation();
  1858.         return false;
  1859.       };
  1860.       
  1861.       // Make sure hover still works
  1862.       favoriteButton.addEventListener('mouseover', function() {
  1863.         document.getElementById('purchase-alert').style.display = 'block';
  1864.       });
  1865.       
  1866.       // Keep any existing hover functionality
  1867.       if (typeof showSelection === 'function') {
  1868.         favoriteButton.onmouseover = showSelection;
  1869.       }
  1870.     }
  1871.     
  1872.     // Make sure the purchase alert remains interactive
  1873.     const purchaseAlert = document.getElementById('purchase-alert');
  1874.     if (purchaseAlert) {
  1875.       purchaseAlert.style.pointerEvents = 'auto';
  1876.     }
  1877.   });
  1878.     // Sélection des éléments
  1879.     const purchaseAlert = document.getElementById(\"purchase-alert\");
  1880.     const alertContent = document.getElementById(\"purchase-alert-content\");
  1881.     const likeCountLabel = document.getElementById(\"likeCount\");
  1882.     const favoriteCount = parseInt(likeCountLabel.textContent.trim(), 10); // Convertir en nombre
  1883.     // Fonction pour mettre à jour le contenu de l'alerte
  1884.     function updatePurchaseAlert(current) {
  1885.   let remainingForAlbum = Math.max(0, 20 - current);
  1886.   let remainingForPochette = Math.max(0, 12 - current);
  1887.   let remainingForPack = Math.max(0, 12 - current);
  1888.   const progressBar = (count, total, color) => `
  1889.   <div style=\"margin: 5px 0;\">
  1890.     <div style=\"background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;\">
  1891.       <div style=\"width: \${
  1892.         (count / total) * 100
  1893.       }%; background-color: \${color}; height: 100%;\"></div>
  1894.     </div>
  1895.     <small style=\"font-size: 12px;\">\${count}/\${total} photos</small>
  1896.   </div>
  1897. `;
  1898.   // Use Twig paths here:
  1899.   const products = [
  1900.       {
  1901.       name: \"Pochette photo (12 photos)\",
  1902.       required: 12,
  1903.       remaining: remainingForPochette,
  1904.       image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  1905.       color: \"#2196f3\",
  1906.       link: \"";
  1907.         // line 1441
  1908.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("AjoutPochettePhotos_Favoris", ["nbr" => 12]);
  1909.         yield "\",
  1910.     },
  1911.        {
  1912.       name: \"Pack numérique (20 photos)\",
  1913.       required: 20,
  1914.       remaining: remainingForAlbum,
  1915.       image: \"/images/produit/photoNumerique.jpg\",
  1916.       color: \"#4caf50\",
  1917.       link: \"";
  1918.         // line 1449
  1919.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("PackPhotosNumerique_Favoris", ["nbr" => 20]);
  1920.         yield "\",
  1921.     }
  1922.   
  1923.   
  1924.     
  1925.   ].sort((a, b) => a.remaining - b.remaining);
  1926.   const productList = products
  1927.     .map((product) => {
  1928.       const count = current;
  1929.       const total = product.required;
  1930.       const remaining = product.remaining;
  1931.       return `
  1932.     <li style=\"margin-bottom: 15px;\">
  1933.       <div style=\"display: flex; align-items: center; gap: 10px;\">
  1934.         <img
  1935.           src=\"\${product.image}\"
  1936.           alt=\"\${product.name}\"
  1937.           style=\"width: 65px; height: 65px; border-radius: 5px; margin-top:-19px\"
  1938.         />
  1939.         <div style=\"flex: 1;\">
  1940.           <strong style=\"font-size: 14px;\">\${product.name}</strong>
  1941.           \${progressBar(count, total, product.color)}
  1942.           \${
  1943.             remaining > 0
  1944.               ? `<small style=\"color: \${product.color}; font-size: 12px;\">
  1945.                    Encore \${remaining} photos ❤️ pour compléter \${product.name.toLowerCase()}
  1946.                  </small>`
  1947.               : `<button
  1948.                   style=\"
  1949.                     margin-top: 5px;
  1950.                     padding: 5px 8px;
  1951.                     background-color: \${product.color};
  1952.                     color: white;
  1953.                     border: none;
  1954.                     border-radius: 5px;
  1955.                     font-size: 12px;
  1956.                     cursor: pointer;
  1957.                   \"
  1958.                   onclick=\"window.location.href='\${product.link}'\"
  1959.                 >
  1960.                   Commander
  1961.                 </button>`
  1962.           }
  1963.         </div>
  1964.       </div>
  1965.     </li>
  1966.   `;
  1967.     })
  1968.     .join(\"\");
  1969.   const plusButton = `
  1970.     <li style=\"margin-bottom: 15px; text-align: center;\">
  1971.       <button
  1972.         style=\"
  1973.           padding: 5px 8px;
  1974.           background-color: #F56040;
  1975.           color: white;
  1976.           border: none;
  1977.           border-radius: 5px;
  1978.           font-size: 14px;
  1979.           line-height: 1;
  1980.           width: 150px;
  1981.           height: 40px;
  1982.           cursor: pointer;
  1983.         \"
  1984.         onclick=\"window.location.href='";
  1985.         // line 1516
  1986.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("boutique5sur5");
  1987.         yield "'\"
  1988.       >
  1989.         Aller à la boutique
  1990.       </button>
  1991.     </li>
  1992.   `;
  1993.   if (current === 0) {
  1994.     alertContent.innerHTML = `
  1995.     <p style=\"font-size: 16px; font-weight: bold; color: #333;\">
  1996.       Vous n'avez pas encore de photos favorites !
  1997.     </p>
  1998.     <p style=\"margin-bottom: 20px; color: #555;\">
  1999.       Commencez à ajouter vos moments préférés pour profiter de nos offres.
  2000.     </p>
  2001.     <ul style=\"list-style-type: none; padding: 0;\">\${productList}\${plusButton}</ul>
  2002.   `;
  2003.   } else {
  2004.     alertContent.innerHTML = `
  2005.     <p style=\"font-size: 16px; font-weight: bold; color: #333;\">
  2006.       Vous avez atteint \${current} photos favorites !
  2007.     </p>
  2008.     <p style=\"margin-bottom: 20px; color: #555;\">
  2009.       Profitez de nos offres spéciales :
  2010.     </p>
  2011.     <ul style=\"list-style-type: none; padding: 0;\">\${productList}\${plusButton}</ul>
  2012.   `;
  2013.   }
  2014.   purchaseAlert.classList.remove(\"hidden\");
  2015.   clearTimeout(purchaseAlertTimeout);
  2016.   purchaseAlertTimeout = setTimeout(() => {
  2017.     if (!purchaseAlert.matches(\":hover\")) {
  2018.       closePurchaseAlert();
  2019.     }
  2020.   }, 5000);
  2021. }
  2022.     // Fonction pour fermer l'alerte
  2023.     function closePurchaseAlert() {
  2024.       purchaseAlert.classList.add(\"hidden\");
  2025.     }
  2026.     // Événement pour mettre à jour le contenu et afficher la popover dynamiquement au hover
  2027.     document.querySelector(\".fav-button\").addEventListener(\"mouseover\", () => {
  2028.       updatePurchaseAlert(favoriteCount);
  2029.       purchaseAlert.classList.remove(\"cachee\"); // Réaffiche la popover
  2030.     });
  2031.     function showSelection() {
  2032.       document.getElementById(\"purchase-alert\").style.display = \"block\";
  2033.     }
  2034.     function hideSelection() {
  2035.       document.getElementById(\"selectionPopover\").style.display = \"none\";
  2036.     }
  2037.     document.addEventListener(\"DOMContentLoaded\", function () {
  2038.       const container = document.querySelector(\".date-container\");
  2039.       // Vérifie si le conteneur existe pour éviter les erreurs
  2040.       if (container) {
  2041.         container.scrollTo({
  2042.           left: container.scrollWidth, // Scroll directement à la position maximale
  2043.           behavior: \"smooth\", // Défilement fluide
  2044.         });
  2045.       }
  2046.     });
  2047.     document.addEventListener(\"DOMContentLoaded\", function () {
  2048.       const container = document.querySelector(\".date-container\");
  2049.       const leftArrow = document.querySelector(\".scroll-btn.left\");
  2050.       const rightArrow = document.querySelector(\".scroll-btn.right\");
  2051.       // Fonction pour vérifier le débordement et activer/désactiver les flèches
  2052.       function updateArrowsVisibility() {
  2053.         const isOverflowing = container.scrollWidth > container.clientWidth; // Vérifie si débordement
  2054.         leftArrow.style.display = isOverflowing ? \"flex\" : \"none\";
  2055.         rightArrow.style.display = isOverflowing ? \"flex\" : \"none\";
  2056.       }
  2057.       // Fonction pour défiler
  2058.       function scrollContainer(direction) {
  2059.         container.scrollBy({
  2060.           left: direction === \"left\" ? -200 : 200, // Défiler à gauche ou à droite
  2061.           behavior: \"smooth\",
  2062.         });
  2063.       }
  2064.       // Ajout des événements de clic pour les flèches
  2065.       leftArrow.addEventListener(\"click\", () => scrollContainer(\"left\"));
  2066.       rightArrow.addEventListener(\"click\", () => scrollContainer(\"right\"));
  2067.       // Vérification initiale et sur redimensionnement de la fenêtre
  2068.       updateArrowsVisibility();
  2069.       window.addEventListener(\"resize\", updateArrowsVisibility);
  2070.     });
  2071.     document.addEventListener(\"DOMContentLoaded\", function () {
  2072.       const container = document.querySelector(\".date-container\");
  2073.       const leftBtn = document.querySelector(\".scroll-btn.left\");
  2074.       const rightBtn = document.querySelector(\".scroll-btn.right\");
  2075.       leftBtn.addEventListener(\"click\", () => {
  2076.         container.scrollBy({
  2077.           left: -200, // Défile vers la gauche
  2078.           behavior: \"smooth\",
  2079.         });
  2080.       });
  2081.       rightBtn.addEventListener(\"click\", () => {
  2082.         container.scrollBy({
  2083.           left: 200, // Défile vers la droite
  2084.           behavior: \"smooth\",
  2085.         });
  2086.       });
  2087.     });
  2088.  document.addEventListener(\"DOMContentLoaded\", function () {
  2089.     // Sélectionnez tous les badges de filtre
  2090.     const filterBadges = document.querySelectorAll(\".filter-badge\");
  2091.     // Sélectionnez tous les éléments de la galerie
  2092.     const galleryItems = document.querySelectorAll(\".column\");
  2093.     // Sélectionnez tous les jours
  2094.     const days = document.querySelectorAll(\".collapse\");
  2095.     // Fonction pour réinitialiser les filtres
  2096.     function resetFilters() {
  2097.         // Réinitialisez tous les éléments de la galerie
  2098.         galleryItems.forEach((item) => {
  2099.             item.style.display = \"block\";
  2100.         });
  2101.         // Réinitialisez les états des badges
  2102.         filterBadges.forEach((badge) => badge.classList.remove(\"active\"));
  2103.     }
  2104.     // Ajoutez un gestionnaire d'événements pour chaque badge
  2105.     filterBadges.forEach((badge) => {
  2106.         badge.addEventListener(\"click\", function () {
  2107.             const filter = this.getAttribute(\"data-filter\");
  2108.             // Réinitialisez l'état actif pour tous les badges
  2109.             filterBadges.forEach((btn) => btn.classList.remove(\"active\"));
  2110.             // Ajoutez l'état actif au badge cliqué
  2111.             this.classList.add(\"active\");
  2112.             // Affichez ou masquez les éléments de la galerie
  2113.             galleryItems.forEach((item) => {
  2114.                 if (filter === \"all\") {
  2115.                     item.style.display = \"block\";
  2116.                 } else if (filter === \"photo\" && item.querySelector(\"img\")) {
  2117.                     item.style.display = \"block\";
  2118.                 } else if (filter === \"video\" && item.querySelector(\"video\")) {
  2119.                     item.style.display = \"block\";
  2120.                 } else if (filter === \"audio\" && item.classList.contains(\"audio-message-item\")) {
  2121.                     item.style.display = \"block\";
  2122.                 } else {
  2123.                     item.style.display = \"none\";
  2124.                 }
  2125.             });
  2126.         });
  2127.     });
  2128.     // Réinitialiser les filtres lors du changement de jour
  2129.     days.forEach((day) => {
  2130.         day.addEventListener(\"show.bs.collapse\", function () {
  2131.             resetFilters();
  2132.         });
  2133.     });
  2134. });
  2135.     \$(document).ready(function () {
  2136.       let zoomCounter = 0; // Initialize zoom counter
  2137.       let currentImageSrc = \"\"; // Track current image source
  2138.       let lastClickPosition = { x: 50, y: 50 }; // Default to center of image
  2139.       \$(\".container--gallery\").magnificPopup({
  2140.         delegate: \"a\",
  2141.         type: \"image\",
  2142.         mainClass: \"mfp-with-zoom mfp-img-mobile\",
  2143.         image: {
  2144.           verticalFit: true,
  2145.         },
  2146.         gallery: {
  2147.           enabled: true,
  2148.           tPrev: \"Previous (Left arrow key)\", // Alt text on left arrow
  2149.           tNext: \"Next (Right arrow key)\", // Alt text on right arrow
  2150.           tCounter: \"%curr% of %total%\", // Markup for \"1 of 7\" counter
  2151.         },
  2152.         zoom: {
  2153.           enabled: true,
  2154.           duration: 300,
  2155.           opener: function (element) {
  2156.             return element.find(\"img\");
  2157.           },
  2158.         },
  2159.         callbacks: {
  2160.           open: function () {
  2161.             // Get current image data from the link that was clicked
  2162.             const currentLink = this.currItem.el;
  2163.             const imageId =
  2164.               currentLink
  2165.                 .closest(\".photo-zoom\")
  2166.                 .find(\".heart-icon\")
  2167.                 .data(\"id\") || \"\";
  2168.             const sejourId =
  2169.               currentLink
  2170.                 .closest(\".photo-zoom\")
  2171.                 .find(\".heart-icon\")
  2172.                 .data(\"sejour-id\") || \"\";
  2173.             const imagePath =
  2174.               currentLink
  2175.                 .closest(\".photo-zoom\")
  2176.                 .find(\".heart-icon\")
  2177.                 .data(\"path\") || \"\";
  2178.             const imageDesc =
  2179.               currentLink
  2180.                 .closest(\".photo-zoom\")
  2181.                 .find(\".heart-icon\")
  2182.                 .data(\"description\") || \"\";
  2183.             const isFavorite = currentLink
  2184.               .closest(\".photo-zoom\")
  2185.               .find(\".heart-icon i\")
  2186.               .hasClass(\"bi-heart-fill\");
  2187.             const favoriteIconClass = isFavorite ? \"bi-heart-fill\" : \"bi-heart\";
  2188.             const favoriteIconColor = isFavorite ? \"#f56040\" : \"white\";
  2189.             const favoriteTooltip = isFavorite
  2190.               ? \"Retirer des favoris\"
  2191.               : \"Ajouter aux favoris\";
  2192.             const zoomControls = `
  2193.           <div class=\"mfp-zoom-controls\">
  2194.             <button class=\"zoom-btn zoom-out\" title=\"Zoom Out\"><i class=\"fa fa-search-minus\"></i></button>
  2195.             <button class=\"zoom-btn zoom-in\" title=\"Zoom In\"><i class=\"fa fa-search-plus\"></i></button>
  2196.           </div>
  2197.           <div class=\"mfp-favorite\">
  2198.             <button class=\"favorite-btn\" 
  2199.                     data-id=\"\${imageId}\" 
  2200.                     data-sejour-id=\"\${sejourId}\" 
  2201.                     data-path=\"\${imagePath}\" 
  2202.                     data-description=\"\${imageDesc}\"
  2203.                     title=\"\${favoriteTooltip}\">
  2204.               <i class=\"bi \${favoriteIconClass}\" style=\"color: \${favoriteIconColor}; text-shadow: 0px 0px 3px rgba(0,0,0,0.5);\"></i>
  2205.             </button>
  2206.           </div>
  2207.           <div class=\"mfp-counter\"></div>
  2208.         `;
  2209.             \$(\".mfp-content\").append(zoomControls);
  2210.             initializeZoomControls();
  2211.             initializeFavoriteButton();
  2212.             const intervalId = setInterval(() => {
  2213.               const newImageSrc = \$(\".mfp-img\").attr(\"src\");
  2214.               if (newImageSrc !== currentImageSrc) {
  2215.                 currentImageSrc = newImageSrc;
  2216.                 zoomCounter = 0;
  2217.                 lastClickPosition = { x: 50, y: 50 }; // Reset to center
  2218.                 attachZoomHandler(); // Reattach zoom handler to new image
  2219.                 \$(\".mfp-img\").css({
  2220.                   \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  2221.                   transform: `scale(1)`,
  2222.                 });
  2223.                 // Update favorite button for the new image
  2224.                 updateFavoriteButton();
  2225.                 initializeZoomControls();
  2226.                 updateCounter();
  2227.               }
  2228.             }, 100);
  2229.             this.content.on(\"mfpClose\", function () {
  2230.               clearInterval(intervalId);
  2231.             });
  2232.             attachZoomHandler();
  2233.           },
  2234.           close: function () {
  2235.             \$(\".mfp-zoom-controls\").remove();
  2236.             \$(\".mfp-favorite\").remove();
  2237.             \$(\".mfp-counter\").remove();
  2238.             zoomCounter = 0;
  2239.           },
  2240.         },
  2241.       });
  2242.       function attachZoomHandler() {
  2243.         \$(\".mfp-img\")
  2244.           .off(\"click\")
  2245.           .on(\"click\", function (event) {
  2246.             event.stopPropagation(); // Prevent default navigation behavior
  2247.             // Calculate click coordinates relative to the image
  2248.             const imgOffset = \$(this).offset();
  2249.             const clickX = event.pageX - imgOffset.left;
  2250.             const clickY = event.pageY - imgOffset.top;
  2251.             const imgWidth = \$(this).width();
  2252.             const imgHeight = \$(this).height();
  2253.             // Calculate transform-origin based on click position
  2254.             lastClickPosition = {
  2255.               x: (clickX / imgWidth) * 100,
  2256.               y: (clickY / imgHeight) * 100,
  2257.             };
  2258.             // Cycle through zoom levels: 1x, 1.5x, 2x
  2259.             zoomCounter = (zoomCounter + 1) % 3;
  2260.             const zoomLevels = [1, 1.5, 2];
  2261.             const zoomLevel = zoomLevels[zoomCounter];
  2262.             \$(this).css({
  2263.               \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  2264.               transform: `scale(\${zoomLevel})`,
  2265.             });
  2266.             updateZoomButtonState();
  2267.           });
  2268.       }
  2269.       function initializeZoomControls() {
  2270.         \$(\".mfp-zoom-controls .zoom-in\")
  2271.           .off(\"click\")
  2272.           .on(\"click\", function (event) {
  2273.             event.stopPropagation();
  2274.             zoomCounter = (zoomCounter + 1) % 3;
  2275.             const zoomLevels = [1, 1.5, 2];
  2276.             const zoomLevel = zoomLevels[zoomCounter];
  2277.             \$(\".mfp-img\").css({
  2278.               \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  2279.               transform: `scale(\${zoomLevel})`,
  2280.             });
  2281.             updateZoomButtonState();
  2282.           });
  2283.         \$(\".mfp-zoom-controls .zoom-out\")
  2284.           .off(\"click\")
  2285.           .on(\"click\", function (event) {
  2286.             event.stopPropagation();
  2287.             if (zoomCounter > 0) {
  2288.               zoomCounter -= 1;
  2289.               const zoomLevels = [1, 1.5, 2];
  2290.               const zoomLevel = zoomLevels[zoomCounter];
  2291.               \$(\".mfp-img\").css({
  2292.                 \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  2293.                 transform: `scale(\${zoomLevel})`,
  2294.               });
  2295.               updateZoomButtonState();
  2296.             } else {
  2297.               \$.magnificPopup.close();
  2298.             }
  2299.           });
  2300.       }
  2301.       function initializeFavoriteButton() {
  2302.         \$(\".mfp-favorite .favorite-btn\")
  2303.           .off(\"click\")
  2304.           .on(\"click\", function (event) {
  2305.             event.stopPropagation();
  2306.             const \$this = \$(this);
  2307.             const imageId = \$this.data(\"id\");
  2308.             const sejourId = \$this.data(\"sejour-id\");
  2309.             // Toggle favorite status
  2310.             const isFavorite = \$this.find(\"i\").hasClass(\"bi-heart-fill\");
  2311.             // Update the button appearance
  2312.             if (isFavorite) {
  2313.               \$this
  2314.                 .find(\"i\")
  2315.                 .removeClass(\"bi-heart-fill\")
  2316.                 .addClass(\"bi-heart\")
  2317.                 .css(\"color\", \"white\");
  2318.               \$this.attr(\"title\", \"Ajouter aux favoris\");
  2319.             } else {
  2320.               \$this
  2321.                 .find(\"i\")
  2322.                 .removeClass(\"bi-heart\")
  2323.                 .addClass(\"bi-heart-fill\")
  2324.                 .css(\"color\", \"#f56040\");
  2325.               \$this.attr(\"title\", \"Retirer des favoris\");
  2326.             }
  2327.             // Update the original heart icon in the gallery
  2328.             const originalHeartIcon = \$(
  2329.               `.heart-icon[data-id=\"\${imageId}\"]`
  2330.             ).find(\"i\");
  2331.             if (isFavorite) {
  2332.               originalHeartIcon
  2333.                 .removeClass(\"bi-heart-fill\")
  2334.                 .addClass(\"bi-heart\")
  2335.                 .css(\"color\", \"\");
  2336.             } else {
  2337.               originalHeartIcon
  2338.                 .removeClass(\"bi-heart\")
  2339.                 .addClass(\"bi-heart-fill\")
  2340.                 .css(\"color\", \"#f56040\");
  2341.             }
  2342.             // Make AJAX call to update favorite status in the backend using Parent routes
  2343.             \$.ajax({
  2344.               url: isFavorite ? \"/Parent/aSupprimerFav\" : \"/Parent/ajouterFav\",
  2345.               type: \"POST\",
  2346.               data: {
  2347.                 id: imageId,
  2348.                 idSejour: sejourId,
  2349.               },
  2350.               success: function (response) {
  2351.                 // Optional: Show a success message or handle response
  2352.                 console.log(\"Favorite status updated\", response);
  2353.               },
  2354.               error: function (error) {
  2355.                 console.error(\"Error updating favorite status\", error);
  2356.                 // Revert the icon change on error
  2357.                 if (isFavorite) {
  2358.                   \$this
  2359.                     .find(\"i\")
  2360.                     .removeClass(\"bi-heart\")
  2361.                     .addClass(\"bi-heart-fill\")
  2362.                     .css(\"color\", \"#f56040\");
  2363.                   originalHeartIcon
  2364.                     .removeClass(\"bi-heart\")
  2365.                     .addClass(\"bi-heart-fill\")
  2366.                     .css(\"color\", \"#f56040\");
  2367.                 } else {
  2368.                   \$this
  2369.                     .find(\"i\")
  2370.                     .removeClass(\"bi-heart-fill\")
  2371.                     .addClass(\"bi-heart\")
  2372.                     .css(\"color\", \"white\");
  2373.                   originalHeartIcon
  2374.                     .removeClass(\"bi-heart-fill\")
  2375.                     .addClass(\"bi-heart\")
  2376.                     .css(\"color\", \"\");
  2377.                 }
  2378.               },
  2379.             });
  2380.           });
  2381.       }
  2382.       function updateFavoriteButton() {
  2383.         // Get current image data from the current slide
  2384.         const currentSlide = \$.magnificPopup.instance.currItem.el;
  2385.         const photoZoom = currentSlide.closest(\".photo-zoom\");
  2386.         if (photoZoom.length) {
  2387.           const heartIcon = photoZoom.find(\".heart-icon\");
  2388.           const imageId = heartIcon.data(\"id\") || \"\";
  2389.           const sejourId = heartIcon.data(\"sejour-id\") || \"\";
  2390.           const imagePath = heartIcon.data(\"path\") || \"\";
  2391.           const imageDesc = heartIcon.data(\"description\") || \"\";
  2392.           const isFavorite = heartIcon.find(\"i\").hasClass(\"bi-heart-fill\");
  2393.           const favoriteIconClass = isFavorite ? \"bi-heart-fill\" : \"bi-heart\";
  2394.           const favoriteIconColor = isFavorite ? \"#f56040\" : \"white\";
  2395.           const favoriteTooltip = isFavorite
  2396.             ? \"Retirer des favoris\"
  2397.             : \"Ajouter aux favoris\";
  2398.           // Update the favorite button
  2399.           const \$favoriteBtn = \$(\".mfp-favorite .favorite-btn\");
  2400.           \$favoriteBtn.data(\"id\", imageId);
  2401.           \$favoriteBtn.data(\"sejour-id\", sejourId);
  2402.           \$favoriteBtn.data(\"path\", imagePath);
  2403.           \$favoriteBtn.data(\"description\", imageDesc);
  2404.           \$favoriteBtn.attr(\"title\", favoriteTooltip);
  2405.           \$favoriteBtn
  2406.             .find(\"i\")
  2407.             .removeClass(\"bi-heart bi-heart-fill\")
  2408.             .addClass(favoriteIconClass)
  2409.             .css(\"color\", favoriteIconColor);
  2410.         }
  2411.       }
  2412.       function updateZoomButtonState() {
  2413.         const zoomLevels = [1, 1.5, 2];
  2414.         const currentZoom = zoomLevels[zoomCounter];
  2415.         \$(\".zoom-in\").prop(\"disabled\", currentZoom === 2);
  2416.         \$(\".zoom-out\").prop(\"disabled\", currentZoom === 1);
  2417.       }
  2418.       function updateCounter() {
  2419.         const counterText = \$(\".mfp-counter\")
  2420.           .closest(\".mfp-content\")
  2421.           .find(\".mfp-counter\")
  2422.           .text();
  2423.         const matches = counterText.match(/(\\d+) of (\\d+)/);
  2424.         if (matches) {
  2425.           const currentIndex = matches[1];
  2426.           const totalImages = matches[2];
  2427.           \$(\".mfp-counter\").text(`\${currentIndex} of \${totalImages}`);
  2428.         }
  2429.       }
  2430.       // Add CSS for the favorite button and rounded image corners
  2431.       \$(\"<style>\")
  2432.         .prop(\"type\", \"text/css\")
  2433.         .html(
  2434.           `
  2435.       .mfp-favorite {
  2436.         position: absolute;
  2437.         top: 15px;
  2438.         left: 15px;
  2439.         z-index: 1046;
  2440.       }
  2441.       .favorite-btn {
  2442.         background: transparent;
  2443.         border: none;
  2444.         font-size: 24px;
  2445.         padding: 5px;
  2446.         cursor: pointer;
  2447.         outline: none;
  2448.       }
  2449.       .favorite-btn i {
  2450.         transition: all 0.3s ease;
  2451.       }
  2452.       .favorite-btn:hover i {
  2453.         transform: scale(1.2);
  2454.       }
  2455.       /* Rounded corners for zoomed images */
  2456.       .mfp-img {
  2457.         border-radius: 8px;
  2458.       }
  2459.       /* Make sure the container doesn't clip the rounded corners */
  2460.       .mfp-figure:after {
  2461.         border-radius: 8px;
  2462.       }
  2463.     `
  2464.         )
  2465.         .appendTo(\"head\");
  2466.     });
  2467.   </script>
  2468. <script>
  2469. document.addEventListener('DOMContentLoaded', function () {
  2470.   const openBtn = document.getElementById('openFavoritesBtn');
  2471.   const closeBtn = document.getElementById('closeSidebarBtn');
  2472.   const sidebar = document.getElementById('favoritesSidebar');
  2473.   const tbody = document.querySelector('#favoritesTable tbody');
  2474.   openBtn.addEventListener('click', async () => {
  2475.     try {
  2476.       const response = await fetch('/Parent/mes-favoris', {
  2477.         headers: {
  2478.           'Accept': 'application/json'
  2479.         }
  2480.       });
  2481.       const result = await response.json();
  2482.       if (!result.success || !Array.isArray(result.data)) {
  2483.         alert('Erreur lors du chargement des favoris.');
  2484.         return;
  2485.       }
  2486.       tbody.innerHTML = '';
  2487.       result.data.forEach((fav, index) => {
  2488.         const row = document.createElement('tr');
  2489.         row.innerHTML = `
  2490.           <td>\${index + 1}</td>
  2491.           <td><img src=\"\${fav.path}\" alt=\"favori\"></td>
  2492.           <td>\${fav.descreption || '—'}</td>
  2493.           <td>\${fav.created_at}</td>
  2494.         `;
  2495.         tbody.appendChild(row);
  2496.       });
  2497.       sidebar.classList.add('active');
  2498.     } catch (e) {
  2499.       console.error('Erreur réseau:', e);
  2500.       alert('Impossible de charger les favoris.');
  2501.     }
  2502.   });
  2503.   closeBtn.addEventListener('click', () => {
  2504.     sidebar.classList.remove('active');
  2505.   });
  2506. });
  2507. </script>
  2508.   <script>
  2509.         // Fonction pour vérifier et afficher l'alerte
  2510.         function checkFavorites() {
  2511.             if (favoriteCount >= 10) {
  2512.                 purchaseAlert.style.display = 'block'; // Affiche l'alerte
  2513.             } else {
  2514.                 purchaseAlert.style.display = 'none'; // Cache l'alerte si le nombre est réduit
  2515.             }
  2516.         }
  2517.         // Ajout d'un favori
  2518.         function addFavorite() {
  2519.             favoriteCount++;
  2520.             likeCountLabel.textContent = favoriteCount;
  2521.             checkFavorites();
  2522.         }
  2523.         // Suppression d'un favori
  2524.         function removeFavorite() {
  2525.             if (favoriteCount > 0) {
  2526.                 favoriteCount--;
  2527.                 likeCountLabel.textContent = favoriteCount;
  2528.                 checkFavorites();
  2529.             }
  2530.         }document.addEventListener('DOMContentLoaded', () => {
  2531.     const favoriteCount = ";
  2532.         // line 2129
  2533.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["nblikes"]) || array_key_exists("nblikes"$context) ? $context["nblikes"] : (function () { throw new RuntimeError('Variable "nblikes" does not exist.'2129$this->source); })()), "html"nulltrue);
  2534.         yield ";
  2535.     updateCardContent(favoriteCount);
  2536. });
  2537. function updateCardContent(favoriteCount) {
  2538.     const card = document.getElementById('dynamic-card');
  2539.     const cardContent = document.getElementById('dynamic-card-content');
  2540.     let produits = [];
  2541.     if (favoriteCount >= 20) {
  2542.         produits.push({
  2543.             titre: \"Album débloqué !\",
  2544.             bouton: \"Commander\",
  2545.             image: \"/images/produit/Album5sur5-3.jpg\",
  2546.             lien: \"";
  2547.         // line 2144
  2548.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("EditionAlbum");
  2549.         yield "\"
  2550.         });
  2551.     }
  2552.     if (favoriteCount >= 12) {
  2553.         produits.push({
  2554.             titre: \"Pochette débloquée !\",
  2555.             bouton: \"Commander\",
  2556.             image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  2557.             lien: \"";
  2558.         // line 2152
  2559.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("AjoutPochettePhotos_Favoris", ["nbr" => 12]);
  2560.         yield "\"
  2561.         });
  2562.     }
  2563.     if (favoriteCount >= 5) {
  2564.         produits.push({
  2565.             titre: \"Pack numérique débloqué !\",
  2566.             bouton: \"Commander\",
  2567.             image: \"/images/produit/photoNumerique.jpg\",
  2568.             lien: \"";
  2569.         // line 2160
  2570.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("PackPhotosNumerique_Favoris", ["nbr" => 15]);
  2571.         yield "\"
  2572.         });
  2573.     }
  2574. if (produits.length === 0) {
  2575.   cardContent.innerHTML = `
  2576.     <div style=\"position: relative; width: 100%; height: 140px; border-radius: 15px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.1);\">
  2577.       <div style=\"background-image: url('/images/produit/CoffretCadeau5sur5-2.jpg'); background-size: cover; background-position: center; width: 100%; height: 100%;\">
  2578.         <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.45); display: flex; align-items: center; justify-content: center; padding: 10px;\">
  2579.           <div style=\"
  2580.     margin-top: 35px;
  2581.     color: white;
  2582.     font-size: 15px;
  2583.     font-weight: bold;
  2584.     text-align: center;
  2585.     line-height: 1;
  2586.     text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);\">
  2587.             Ajoutez des favoris ❤️<br><span style=\"font-size: 16px; font-weight: normal;\">pour débloquer un souvenir à offrir 🎁</span>
  2588.           </div>
  2589.         </div>
  2590.       </div>
  2591.     </div>
  2592.   `;
  2593.         return;
  2594.     }
  2595.     cardContent.innerHTML = `
  2596.     <div class=\"splide\" id=\"dynamicSplide\">
  2597.       <div class=\"splide__track\">
  2598.         <ul class=\"splide__list\">
  2599.           \${produits.map(produit => `
  2600.             <li class=\"splide__slide\" style=\"position: relative;\">
  2601.               <img src=\"\${produit.image}\" alt=\"\${produit.titre}\" style=\"width: 100%; height: 150px; object-fit: cover; border-radius: 8px;\">
  2602.               <div style=\"position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.1); color: white; padding: 10px; text-align: center; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;\">
  2603.                 <div style=\"font-weight: bold; font-size: 14px;\">\${produit.titre}</div>
  2604.                 <button style=\"margin-top: 5px; padding: 5px 8px; background-color: #F56040; color: white; border: none; border-radius: 4px; font-size: 12px; cursor: pointer;\" onclick=\"window.location.href='\${produit.lien}'\">
  2605.                   \${produit.bouton}
  2606.                 </button>
  2607.               </div>
  2608.             </li>
  2609.           `).join('')}
  2610.         </ul>
  2611.       </div>
  2612.     </div>
  2613.     `;
  2614.     // Monte le carrousel
  2615.     new Splide('#dynamicSplide', {
  2616.         type: 'loop',
  2617.         arrows: true,
  2618.         pagination: false,
  2619.         autoplay: true,
  2620.         interval: 4000,
  2621.         speed: 800,
  2622.     }).mount();
  2623. }
  2624.         function supprimerFavoris(\$id, \$idSejour) {
  2625.             // Vider l'élément coeur pour ce favori
  2626.             const coeurElement = \$('#coeur' + \$id);
  2627.             coeurElement.empty();
  2628.             // Ajout d'une animation sur le bouton favori
  2629.             const favoriteButton = document.querySelector('.fav-button');
  2630.             if (favoriteButton) {
  2631.                 favoriteButton.classList.add('active');
  2632.                 // Retirer l'animation après qu'elle soit jouée
  2633.                 setTimeout(() => {
  2634.                     favoriteButton.classList.remove('active');
  2635.                 }, 600); // La durée doit correspondre à celle de l'animation
  2636.             }
  2637.             // Mise à jour de l'icône coeur
  2638.             const clas = \$('.IconImag6').hasClass('active') ? \"IconDelete IconDeletesix\" : \"IconDelete\";
  2639.             coeurElement.html(
  2640.                 `<i class=\"bi bi-heart \${clas}\" onclick=\"AddFavoris(\${\$id}, \${\$idSejour})\"></i>`
  2641.             );
  2642.             // Mettre à jour le compteur des favoris
  2643.             const likeCountLabel = document.getElementById('likeCount');
  2644.            const likeMesFavLabel = document.getElementById('mesFavCount');
  2645.              if (likeMesFavLabel) {
  2646.                 let currentCount = parseInt(likeMesFavLabel.textContent.trim(), 10) || 0;
  2647.                 currentCount = Math.max(0, currentCount - 1); // Empêche le compteur d'aller en dessous de 0
  2648.                 likeMesFavLabel.textContent = currentCount;
  2649.             }
  2650.             if (likeCountLabel) {
  2651.                 let currentCount = parseInt(likeCountLabel.textContent.trim(), 10) || 0;
  2652.                 currentCount = Math.max(0, currentCount - 1); // Empêche le compteur d'aller en dessous de 0
  2653.                 likeCountLabel.textContent = currentCount;
  2654.                 // Mettre à jour la valeur dans l'input hidden
  2655.                 const nbFavCurrentInput = \$('#nbFavCurrent');
  2656.                 if (nbFavCurrentInput.length) {
  2657.                     nbFavCurrentInput.val(currentCount);
  2658.                 }
  2659.             }
  2660.             // Préparation des données pour l'Ajax
  2661.             const \$_data = { 'id': \$id, 'idSejour': \$idSejour };
  2662.             // Appel Ajax pour supprimer le favori
  2663.             \$.ajax({
  2664.                 type: \"POST\",
  2665.                 url: \"";
  2666.         // line 2266
  2667.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("Supprimer_fav");
  2668.         yield "\",
  2669.                 data: \$_data,
  2670.                 success: function () {
  2671.                     // Réactiver les icônes après succès
  2672.                     \$('.IconDelete').each(function () {
  2673.                         \$(this).css('pointer-events', '');
  2674.                     });
  2675.                 },
  2676.                 error: function (xhr, status, error) {
  2677.                     console.error('Erreur lors de la suppression du favori :', error);
  2678.                 }
  2679.             });
  2680.         }
  2681.         function AddFavoris(\$id, \$idSejour, \$urlimg, \$description) {
  2682.            // console.log('Adding favorite:', { attachmentId, sejourId, path, description });
  2683.   \$(\"#close-favorites-btn\").click()
  2684.             favoriteButton.classList.add('active');
  2685.    const likeMesFavLabel = document.getElementById('mesFavCount');
  2686.       
  2687.             const likeCountLabel = document.getElementById('likeCount');
  2688.             if (likeCountLabel) {
  2689.                 let currentCount = parseInt(likeCountLabel.textContent.trim(), 10) || 0;
  2690.                 likeCountLabel.textContent = currentCount + 1;
  2691.                      likeMesFavLabel.textContent = currentCount + 1;
  2692.             }
  2693.         // Retirer l'animation après qu'elle soit jouée
  2694.         setTimeout(() => {
  2695.             favoriteButton.classList.remove('active');
  2696.         }, 600); // La durée doit correspondre à celle de l'animation
  2697.             \$('#coeur' + \$id).empty();
  2698.             var clas = \$('.IconImag6').hasClass('active') ? \"IconDelete IconDeletesix\" : \"IconDelete\";
  2699.             \$('#coeur' + \$id).html(\"<i class=\\\"bi bi-heart-fill favSelect \" + clas + \"\\\" onclick=\\\"supprimerFavoris(\" + \$id + \",\" + \$idSejour + \")\\\"></i>\");
  2700.             var \$total = parseInt(\$(\"#totalLike\").html()) + 1;
  2701.             \$(\"#totalLike\").html(\$total);
  2702.             \$(\"#totalLikeTitle\").html(\$total);
  2703.             \$(\"#totalLikeMobile\").html(\$total);
  2704.             var \$data = { 'id': \$id, 'idSejour': \$idSejour };
  2705.             \$.ajax({
  2706.                 type: \"POST\",
  2707.                 url: \"";
  2708.         // line 2311
  2709.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("Ajouter_fav");
  2710.         yield "\",
  2711.                 data: \$data,
  2712.                 success: function () {
  2713.                     \$('.IconDelete').each(function () {
  2714.                         \$(this).css('pointer-events', '');
  2715.                     });
  2716.                     if (\$description === undefined) {
  2717.                         \$description = ''; // Set it to an empty string
  2718.                     }
  2719.                     \$('.rowMaselection').append(
  2720.                         '<div class=\"column\" id=\"column-' + \$id + '\">'+
  2721.                         '<a style=\"position: relative;\" title=\"Enlever de ma sélection\" onclick=\"supprimerFavoris(' + \$id + ',' + \$idSejour + ')\" class=\"iconeSuppImg\"><i class=\"bi bi-x\" style=\"font-size:17px;cursor:pointer;color:#d30909;float:right;margin-top:-3%;margin-right:2%\"></i></a>'+
  2722.                         '<a class=\"photo-zoom\">'+
  2723.                         '<img data-idAtach=\"'+\$id+'\" id=\"'+\$idSejour+'\" src=\"'+\$urlimg+'\"></a>'+
  2724.                         (\$description ? '<h4 id=\"commint\" class=\"titleHeadPhoto\">'+\$description+'</h4>' : '')+ // Only add the <h4> if \$description is not empty
  2725.                         '</div>'
  2726.                     );
  2727.                     // Directly update nbLikes count in the header
  2728.                     var currentNbLikes = parseInt(\$('#favoris-link-Accueilpayment .nbrpanier').text());
  2729.                     var newNbLikes = currentNbLikes + 1;
  2730.                     \$('#favoris-link-Accueilpayment .nbrpanier').text(newNbLikes);
  2731.                 },
  2732.                 error: function (xhr, status, error) {
  2733.                     console.error('Error:', error);
  2734.                 }
  2735.             });
  2736.         }
  2737.         \$(document).on('click', '.bi-heart, .bi-heart-fill', function () {
  2738.         const heartIcon       = \$(this);
  2739.         const heartContainer  = heartIcon.closest('.heart-icon');
  2740.         // Extract data attributes
  2741.         const attachmentId    = heartContainer.data('id');
  2742.         const sejourId        = heartContainer.data('sejour-id');
  2743.         const path            = heartContainer.data('path');
  2744.         const description     = heartContainer.data('description');
  2745.         const isFavorite      = heartIcon.hasClass('bi-heart-fill');
  2746.         // Get the input that contains the favorite count
  2747.         const likeFavInput    = document.getElementById('nbFavCurrent');
  2748.         let favoriteNb        = parseInt(likeFavInput.value, 10);
  2749.         if (isFavorite) {
  2750.             // Remove from favorites
  2751.             supprimerFavoris(attachmentId, sejourId);
  2752.             favoriteNb = Math.max(0, favoriteNb - 1);
  2753.             likeFavInput.value = favoriteNb;
  2754.             updateCardContent(favoriteNb);
  2755.               updateFavoritesSidebar();
  2756.                  \$(\"#close-favorites-btn\").click()
  2757.         } else {
  2758.             // Add to favorites
  2759.             AddFavoris(attachmentId, sejourId, path, description);
  2760.             favoriteNb = favoriteNb + 1;
  2761.             likeFavInput.value = favoriteNb;
  2762.             updateCardContent(favoriteNb);
  2763.        
  2764.             updateFavoritesSidebar();
  2765.                \$(\"#close-favorites-btn\").click()
  2766.         }
  2767.         // **** SIMPLE STEP: Update the purchase alert ****
  2768.         // This will refresh the progress bars, count, etc.
  2769.         updatePurchaseAlert(favoriteNb);
  2770.     });
  2771.         // Gestion dynamique du clic sur les icônes cœur
  2772.         \$(document).on('click', '.bi-hsddddeart, .bi-hdddeart-fill', function () {
  2773.             const heartIcon = \$(this);
  2774.           //  const heartIcon = \$(this);
  2775.             //const attachmentId = heartIcon.data('id'); // Récupère l'ID directement
  2776.             const attachmentId = heartIcon.closest('.heart-icon').attr('id').replace('coeur', '');
  2777.             const sejourId = heartIcon.data('sejour-id'); // Store the sejour ID in a data attribute
  2778.             const isFavorite = heartIcon.hasClass('bi-heart-fill');
  2779.             // Récupérer l'input contenant le nombre de favoris
  2780.             const likeFavInput = document.getElementById('nbFavCurrent');
  2781.             let favoriteNb = parseInt(likeFavInput.value, 10); // Utiliser .value pour les inputs
  2782.             // Validation pour éviter les NaN
  2783.             if (isNaN(favoriteNb)) {
  2784.                 favoriteNb = 0;
  2785.             }
  2786.             if (isFavorite) {
  2787.                 // Si c'est un favori, le supprimer
  2788.                 supprimerFavoris(attachmentId, sejourId);
  2789.                 // Décrémenter le compteur
  2790.                 favoriteNb = Math.max(0, favoriteNb - 1);
  2791.                 likeFavInput.value = favoriteNb; // Mettre à jour la valeur de l'input
  2792.                 // Mettre à jour dynamiquement le contenu des cartes ou popovers
  2793.                 updateCardContent(favoriteNb);
  2794.             } else {
  2795.                 // Si ce n'est pas un favori, l'ajouter
  2796.                 const path = heartIcon.data('path'); // Path de l'attachement
  2797.                 const description = heartIcon.data('description'); // Description de l'attachement
  2798.                 AddFavoris(attachmentId, sejourId, path, description);
  2799.           // Décrémenter le compteur
  2800.                 favoriteNb = Math.max(0, favoriteNb + 1);
  2801.                 likeFavInput.value = favoriteNb; // Mettre à jour la valeur de l'input
  2802.                 // Incrémenter le compteur
  2803.                 // Mettre à jour dynamiquement le contenu des cartes ou popovers
  2804.                 updateCardContent(favoriteNb);
  2805.             }
  2806.             // Mettre à jour dynamiquement la popover ou d'autres éléments liés
  2807.         });
  2808.         // Ajoutez les événements sur les icônes de cœur
  2809.         document.querySelectorAll('.IconDelete').forEach((icon) => {
  2810.             icon.addEventListener('click', (event) => {
  2811.                 const isFavorite = icon.classList.contains('bi-heart-fill');
  2812.                 if (isFavorite) {
  2813.                     removeFavorite();
  2814.                     icon.classList.remove('bi-heart-fill');
  2815.                     icon.classList.add('bi-heart');
  2816.                 } else {
  2817.                     addFavorite();
  2818.                     icon.classList.remove('bi-heart');
  2819.                     icon.classList.add('bi-heart-fill');
  2820.                 }
  2821.             });
  2822.         });
  2823.         // Vérifie l'état initial
  2824.         checkFavorites();
  2825.   </script>
  2826.   <!-- Initialisation -->
  2827.   <script>
  2828.     AOS.init({
  2829.       duration: 800, // Duration of animations in milliseconds
  2830.       easing: \"ease-in-out\", // Animation timing function
  2831.     });
  2832.     document.addEventListener(\"DOMContentLoaded\", function () {
  2833.       const dateCards = document.querySelectorAll(\".date-card\");
  2834.       const sections = document.querySelectorAll(\".collapse\");
  2835.       dateCards.forEach((card) => {
  2836.         card.addEventListener(\"click\", function () {
  2837.           // Supprimer les classes actives des autres cartes et sections
  2838.           dateCards.forEach((c) => c.classList.remove(\"active\"));
  2839.           sections.forEach((s) => s.classList.remove(\"show\"));
  2840.           // Ajouter la classe active à la carte cliquée
  2841.           this.classList.add(\"active\");
  2842.           // Récupérer la cible et afficher la bonne section
  2843.           const targetId = this.getAttribute(\"data-bs-target\");
  2844.           const targetSection = document.querySelector(targetId);
  2845.           if (targetSection) {
  2846.             targetSection.classList.add(\"show\");
  2847.           }
  2848.         });
  2849.       });
  2850.     });
  2851.     document.addEventListener(\"DOMContentLoaded\", function () {
  2852.       // Initialisation du carrousel Splide
  2853.       var splide = new Splide(\"#imageSlider\", {
  2854.         type: \"loop\",
  2855.         perPage: 1,
  2856.         autoplay: true,
  2857.         interval: 6000,
  2858.         pauseOnHover: false,
  2859.         pauseOnFocus: false,
  2860.         pagination: false, // Désactive la pagination
  2861.         arrows: false,
  2862.       });
  2863.       splide.mount();
  2864.       // Fonction pour faire défiler automatiquement vers la section suivante avec un ajustement personnalisé de la hauteur
  2865.       function scrollToNextSection() {
  2866.         const targetSection = document.getElementById(\"scrollTarget\");
  2867.         if (targetSection) {
  2868.           const targetPosition =
  2869.             targetSection.getBoundingClientRect().top + window.scrollY; // Position de la section
  2870.           const adjustedPosition = targetPosition - 50; // Réduit la hauteur du scroll de 150px (ajustez selon vos besoins)
  2871.           // Scroll vers la position ajustée
  2872.           window.scrollTo({
  2873.             top: adjustedPosition,
  2874.             behavior: \"smooth\",
  2875.           });
  2876.         }
  2877.       }
  2878.       // Démarrer le timer pour le scroll automatique après 10 secondes
  2879.       setTimeout(scrollToNextSection, 5000); // 10 secondes
  2880.     });
  2881.   </script>
  2882.   <script>
  2883.         document.addEventListener('DOMContentLoaded', function () {
  2884.             var myModal = new bootstrap.Modal(document.getElementById('PubProd'));
  2885.             myModal.show();
  2886.         });
  2887.         // Function to close the modal
  2888.     function closeModal() {
  2889.         var myModal = bootstrap.Modal.getInstance(document.getElementById('PubProd'));
  2890.         if (myModal) {
  2891.             myModal.hide();
  2892.         }
  2893.     }
  2894.     const favoriteButton = document.querySelector('.fav-button');
  2895.     favoriteButton.addEventListener('click', () => {
  2896.         // Ajouter la classe 'active' pour déclencher l'éclat
  2897.         favoriteButton.classList.add('active');
  2898.         // Retirer l'animation après qu'elle soit jouée
  2899.         setTimeout(() => {
  2900.             favoriteButton.classList.remove('active');
  2901.         }, 600); // La durée doit correspondre à celle de l'animation
  2902.     });
  2903.     
  2904.     //const HeartAddButton = document.querySelector('.IconDelete');
  2905.     \$(\".IconDelete\").on('click', () => {
  2906.         // Ajouter la classe 'active' pour déclencher l'éclat
  2907.         favoriteButton.classList.add('active');
  2908.         // Retirer l'animation après qu'elle soit jouée
  2909.         setTimeout(() => {
  2910.             favoriteButton.classList.remove('active');
  2911.         }, 600); // La durée doit correspondre à celle de l'animation
  2912.     });
  2913.     \$(document).ready(function() {
  2914.         // Attach click event to collapse triggers
  2915.         const lastCard = \$('.date-card.modern-card.active');
  2916.         const lastTargetId = lastCard.attr('data-bs-target');
  2917.         if (lastTargetId) {
  2918.             \$(lastTargetId).collapse('show'); // Expand the last collapse section
  2919.             LoadImagesCloud(\$(lastTargetId)); // Load images for the last day
  2920.         }
  2921.         \$('[data-bs-toggle=\"collapse\"]').on('click', function() {
  2922.             var targetId = \$(this).attr('data-bs-target'); // Get the target ID
  2923.             \$('.date-card.modern-card').removeClass('active'); // Remove 'active' class from all cards
  2924.             \$(this).addClass('active'); // Add 'active' class to the clicked card
  2925.             LoadImagesCloud(\$(targetId)); // Ensure this function works as expected
  2926.                // Hide all other collapses except the one clicked
  2927.                \$('[data-bs-target]').each(function() {
  2928.                 var currentTargetId = \$(this).attr('data-bs-target');
  2929.                 // If the current collapse is not the one clicked, hide it
  2930.                 if (currentTargetId !== targetId) {
  2931.                     \$(currentTargetId).collapse('hide');
  2932.                     //\$('[data-bs-toggle=\"collapse\"]').removeClass('active'); // Remove active class from all cards
  2933.                     //Modifier leurs style en non active aussi
  2934.                 }
  2935.             });
  2936.         });
  2937.     });
  2938.     function rotateIcone(iconId) {
  2939.         // Use the icon ID to target the specific element
  2940.         var icon = \$('#' + iconId);
  2941.         // Toggle the rotate-right class to apply rotation
  2942.         if (icon.hasClass('rotate-right')) {
  2943.             icon.removeClass('rotate-right'); // Remove rotation class
  2944.         } else {
  2945.             icon.addClass('rotate-right'); // Add rotation class
  2946.         }
  2947.     }
  2948.             \$(document).ready(function () {
  2949.                 \$total1 = parseInt(\$(\"#esphoto\").find('strong').html().replace('(', '').replace(')', ''));
  2950.                 \$('[data-bs-toggle=\"tooltip\"]').tooltip();
  2951.                 ";
  2952.         // line 2613
  2953.         if ((($tmp CoreExtension::getAttribute($this->env$this->sourceCoreExtension::getAttribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'2613$this->source); })()), "session", [], "any"falsefalsefalse2613), "get", ["paymentmoniteco"], "method"falsefalsefalse2613)) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  2954.             // line 2614
  2955.             yield "                ";
  2956.             if ((CoreExtension::getAttribute($this->env$this->sourceCoreExtension::getAttribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'2614$this->source); })()), "session", [], "any"falsefalsefalse2614), "get", ["paymentmoniteco"], "method"falsefalsefalse2614) == "succses")) {
  2957.                 // line 2615
  2958.                 yield "
  2959.                 Swal.fire({
  2960.                     icon: 'success',
  2961.                     title: ' succès ',
  2962.                     text: 'votre commande est validée'
  2963.                 });
  2964.                 ";
  2965.             }
  2966.             // line 2625
  2967.             yield "                ";
  2968.         }
  2969.         // line 2626
  2970.         yield "
  2971.                 if (\$total1 > 0) {
  2972.                     \$('.iconeFleche').first().click();
  2973.                     //  \$([document.documentElement, document.body]).animate({
  2974.                     //  scrollTop: \$('.iconeFleche').last().offset().top
  2975.                     //  }, );
  2976.                 }
  2977.                 else {
  2978.                     \$(window).scrollTop(0);
  2979.                 }
  2980.                 var slider = \$('.responsive').slick({
  2981.                     infinite: true,
  2982.                     slidesToShow: 1,
  2983.                     slidesToScroll: 1,
  2984.                     autoplay: true,
  2985.                     autoplaySpeed: 4000,
  2986.                     pauseOnFocus: false,
  2987.                     pauseOnHover: false,
  2988.                     draggable: false,
  2989.                     fade: true
  2990.                 });
  2991.                 \$('.responsive').css('display', 'block');
  2992.                 \$('.namePRD').css('display', 'block');
  2993.                 var currSlide = 0;
  2994.                 var nextSlide = 0;
  2995.                 slider.on('afterChange', function (event, slick, currentSlide) {
  2996.                     console.log(typeof (\$('.slick-active .slick-current').find('.imgproduit2')) != \"undefined\");
  2997.                     if (typeof (\$('.slick-active .slick-current').find('.imgproduit2')) != \"undefined\") {
  2998.                         setTimeout(function () {
  2999.                             \$('.slick-active .imgproduit1').removeClass('animated fadeIn');
  3000.                             \$('.slick-active .imgproduit1').addClass('animated fadeOut');
  3001.                             \$('.slick-active .imgproduit1').css('display', 'none');
  3002.                             \$('.slick-active .imgproduit2').css('display', 'block');
  3003.                             \$('.slick-active .imgproduit2').removeClass('animated fadeOut');
  3004.                             \$('.slick-active .imgproduit2').addClass('animated fadeIn');
  3005.                         }, 2000);
  3006.                     }
  3007.                 });
  3008.                 slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
  3009.                     currSlide = currentSlide;
  3010.                     \$('.imgproduit2').each(function () {
  3011.                         \$(this).removeClass('animated fadeIn');
  3012.                         \$(this).addClass('animated fadeOut');
  3013.                         \$(this).css('display', 'none');
  3014.                     });
  3015.                     \$('.imgproduit1').each(function () {
  3016.                         \$(this).css('display', 'block');
  3017.                         \$(this).removeClass('animated fadeOut');
  3018.                         \$(this).addClass('animated fadeIn');
  3019.                     });
  3020.                 });
  3021.                 \$('.columnPub').each(function () {
  3022.                     \$(this).slick({
  3023.                         infinite: true,
  3024.                         speed: 50,
  3025.                         fade: true,
  3026.                         slidesToShow: 1,
  3027.                         slidesToScroll: 1,
  3028.                         autoplay: true,
  3029.                         pauseOnFocus: false,
  3030.                         pauseOnHover: false,
  3031.                         draggable: false
  3032.                     });
  3033.                     \$(this).css('display', 'block');
  3034.                 });
  3035.                 \$(\"#offrePack\").click();
  3036.                 ";
  3037.         // line 2700
  3038.         if ((CoreExtension::getAttribute($this->env$this->sourceCoreExtension::getAttribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'2700$this->source); })()), "user", [], "any"falsefalsefalse2700), "showpubprod", [], "any"falsefalsefalse2700) != "false")) {
  3039.             // line 2701
  3040.             yield "                \$('#btnPubProd').click();
  3041.                 \$('.modal-backdrop').css('background-color', 'rgba(0, 0, 0, 0.2)');
  3042.                 ";
  3043.         }
  3044.         // line 2704
  3045.         yield "            });
  3046.             \$(\"#closeImage\").click(function () {
  3047.                 \$('#myModalImage').css('display', \"none\");
  3048.             });
  3049.             \$.ajax({
  3050.                 type: \"POST\",
  3051.                 url: \"";
  3052.         // line 2710
  3053.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("delateSession_parent");
  3054.         yield "\",
  3055.                 success: function () { }
  3056.             });
  3057.             function afficheDiv(elem) {
  3058.                 \$('.nav-link').each(function () {
  3059.                     \$(this).removeClass('active');
  3060.                 });
  3061.                 elem.addClass('active');
  3062.                 if (elem.attr('id') === \"esphoto\" || elem.attr('id') === \"esphotoMobile\") {
  3063.                     \$(\"#espacphoto\").show();
  3064.                     \$(\"#espacemessage\").hide();
  3065.                     \$(\"#espaceMa_selection\").hide();
  3066.                     pageMenu = 'MonSejour'
  3067.                     \$(this).addClass('active');
  3068.                    \$('#imageActifphoto').css('display', 'block');
  3069.                      \$('#imagenoActifphoto').css('display', 'none');
  3070.                    \$('#VocalActivee').css('display', 'none');
  3071.                      \$('#noActifVocal').css('display', 'block');
  3072.                 }
  3073.                 if (elem.attr('id') === \"esmessage\" || elem.attr('id') === \"esmessageMobile\") {
  3074.                     \$(\"#espacphoto\").hide();
  3075.                     \$(\"#espaceMa_selection\").hide();
  3076.                     \$(\"#espacemessage\").show();
  3077.                     pageMenu = 'BoiteVocale'
  3078.                     \$(\"#espaceMa_selection\").hide();
  3079.                     \$(this).addClass('active');
  3080.                   \$('#imageActifphoto').css('display', 'none');
  3081.                      \$('#imagenoActifphoto').css('display', 'block');
  3082.                    \$('#VocalActivee').css('display', 'block');
  3083.                      \$('#noActifVocal').css('display', 'none');
  3084.                 }
  3085.                 if (elem.attr('id') === \"esselection\" || elem.attr('id') === \"esselectionMobile\") {
  3086.                     \$(\"#espacphoto\").hide();
  3087.                     \$(\"#espacemessage\").hide();
  3088.                     \$(\"#espaceMa_selection\").show();
  3089.                     \$(homeNavmob).removeClass('bi bi-house-door-fill');
  3090.                     \$(homeNavmob).addClass('bi bi-house-door');
  3091.                     \$(micromob).removeClass('bi bi-mic-fill');
  3092.                     \$(micromob).addClass('bi bi-mic');
  3093.                     \$(selecNavmob).removeClass('bi bi-heart');
  3094.                     \$(selecNavmob).addClass('bi bi-heart-fill');
  3095.                 }
  3096.             }
  3097.             function LoadImagesCloud(\$element) {
  3098.                 \$element.find('.photo-zoom img').each(function (\$this) {
  3099.                     if (\$(this).attr('data-src') != \$(this).attr('src')) {
  3100.                         \$(this).attr('src', \$(this).attr('data-src'));
  3101.                     }
  3102.                 });
  3103.             }
  3104.       function afficheDivFooterMobile(elem) {
  3105.              if(elem =='esphotoMobile') {
  3106.                    \$(\"#espacphoto\").show();
  3107.                     \$(\"#espacemessage\").hide();
  3108.                     \$(\"#espaceMa_selection\").hide();
  3109.                     \$(\"#storevide\").hide();
  3110.                     \$(\"#storefull\").show();
  3111.                     \$(\"#fullphoto\").show();
  3112.                     \$(\"#videphoto\").hide()
  3113.                     \$(\"#vocalfull\").hide();
  3114.                     \$(\"#vocalvide\").show();
  3115.                 }
  3116.                 if (elem === \"esmessageMobile\" ) {
  3117.                     \$(\"#espacphoto\").hide();
  3118.                     \$(\"#espacemessage\").show();
  3119.                     \$(\"#espaceMa_selection\").hide();
  3120.                     \$(\"#storefull\").hide();
  3121.                     \$(\"#storevide\").show();
  3122.                     \$(\"#fullphoto\").hide();
  3123.                     \$(\"#videphoto\").show()
  3124.                     \$(\"#vocalfull\").show();
  3125.                     \$(\"#vocalvide\").hide();
  3126.                 }
  3127.             }
  3128.             function permutation(elem) {
  3129.                 \$(\".IconImag\").each(function () {
  3130.                     \$(this).removeClass('active');
  3131.                 });
  3132.                 elem.addClass(\"active\");
  3133.             }
  3134.             function per(elem) {
  3135.                 \$(\".list-group-item \").each(function () {
  3136.                     \$(this).removeClass('show');
  3137.                 });
  3138.                 elem.addClass(\"active\");
  3139.                 \$(\"#iconeFleche\").addClass('active');
  3140.             }
  3141.            function setidattach(id) {
  3142.                 \$(\"#idattachipmut\").val(id)
  3143.             }
  3144.             var ParentAjouterALL_fav = \"";
  3145.         // line 2821
  3146.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ParentAjouterALL_fav");
  3147.         yield "\";
  3148.             function AllFavoris(\$idSejour) {
  3149.                 \$('#SelectALL').html('Désélectionner tout');
  3150.                 \$('#SelectALL').css('pointer-events', 'none');
  3151.                 \$('#SelectALL').css('opacity', '0.5');
  3152.                 \$('#SelectALL').css('cursor', 'no-drop');
  3153.                 \$('#SelectALL1').html('Désélectionner tout');
  3154.                 \$('#SelectALL1').css('pointer-events', 'none');
  3155.                 \$('#SelectALL1').css('opacity', '0.5');
  3156.                 \$('#SelectALL1').css('cursor', 'no-drop');
  3157.                 \$data = { 'idSejour': \$idSejour }
  3158.                 \$.ajax({
  3159.                     type: \"POST\",
  3160.                     url: \"";
  3161.         // line 2834
  3162.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ParentAjouterALL_fav");
  3163.         yield "\",
  3164.                     data: \$data,
  3165.                     success: function () {
  3166.                         location.reload();
  3167.                     }
  3168.                 });
  3169.             }
  3170.             function RemoveAllFavoris(\$idSejour) {
  3171.                 \$('#SelectALL').html('Sélectionner tout');
  3172.                 \$('#SelectALL').css('pointer-events', 'none');
  3173.                 \$('#SelectALL').css('opacity', '0.5');
  3174.                 \$('#SelectALL').css('cursor', 'no-drop');
  3175.                 \$('#SelectALL1').html('Sélectionner tout');
  3176.                 \$('#SelectALL1').css('pointer-events', 'none');
  3177.                 \$('#SelectALL1').css('opacity', '0.5');
  3178.                 \$('#SelectALL1').css('cursor', 'no-drop');
  3179.                 \$data = { 'idSejour': \$idSejour }
  3180.                 \$.ajax({
  3181.                     type: \"POST\",
  3182.                     url: \"";
  3183.         // line 2854
  3184.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("ParentSupprimer_ALLfav");
  3185.         yield "\",
  3186.                     data: \$data,
  3187.                     success: function () {
  3188.                         location.reload();
  3189.                     }
  3190.                 });
  3191.             }
  3192.             // Get the elements with class=\"column\"
  3193.             var elements = document.getElementsByClassName(\"column\");
  3194.             // Declare a \"loop\" variable
  3195.             var i;
  3196.             // Full-width images
  3197.             function Four() {
  3198.                 for (i = 0; i < elements.length; i++) {
  3199.                     elements[i].style.flex = \"0 0 25%\";
  3200.                 }
  3201.                 \$('.IconDelete').attr('class', 'IconDelete ');
  3202.                 \$('.photo-zoom ').attr('class', 'photo-zoom');
  3203.                 \$('.localistaion').css('visibility', 'visible');
  3204.                 \$('.localistaion').attr('class', 'localistaion');
  3205.                 \$('.legend').css('visibility', 'visible');
  3206.                 \$('.columnPub').each(function () {
  3207.                     \$(this).css('max-width', '25%');
  3208.                     \$(this).find('.slick-list').removeClass('miniature');
  3209.                     \$(this).find('.single_service').removeClass('miniature');
  3210.                     \$(this).find('.bottomdivpub').removeClass('miniature');
  3211.                 });
  3212.             }
  3213.             // Two images side by side
  3214.             function six() {
  3215.                 for (i = 0; i < elements.length; i++) {
  3216.                     elements[i].style.flex = \"0 0 15%\";
  3217.                 }
  3218.                 \$('.column').css('padding', '0px 10px 0px 0px');
  3219.                 \$('.localistaion').attr('class', 'localistaion localistaionsix');
  3220.                 \$('.IconDelete').attr('class', 'IconDelete IconDeletesix');
  3221.                 \$('.legend').css('visibility', 'visible');
  3222.                 \$('.photo-zoom ').attr('class', 'photo-zoom heightimg');
  3223.                 \$('.columnPub').each(function () {
  3224.                     \$(this).css('max-width', '15%');
  3225.                     \$(this).find('.slick-list').addClass('miniature');
  3226.                     \$(this).find('.single_service').addClass('miniature');
  3227.                     \$(this).find('.bottomdivpub').addClass('miniature');
  3228.                 });
  3229.             }
  3230.             // Four images side by side
  3231.             function two() {
  3232.                 for (i = 0; i < elements.length; i++) {
  3233.                     elements[i].style.flex = \"0 0 40%\";
  3234.                 }
  3235.                 \$('.column').css('padding', '14px 10px');
  3236.                 \$('.column').css('max-width', '40%');
  3237.                 \$('.localistaion').css('visibility', 'visible');
  3238.                 \$('.legend').css('visibility', 'visible');
  3239.                 \$('.photo-zoom ').attr('class', 'photo-zoom');
  3240.                 \$('.localistaion').attr('class', 'localistaion localistaiontwo');
  3241.                 \$('.IconDelete').attr('class', 'IconDelete IconDeletetwo');
  3242.                 \$('.legend').attr('class', 'legend legendtwo');
  3243.                 \$('.columnPub').each(function () {
  3244.                     \$(this).css('max-width', '40%');
  3245.                     \$(this).find('.slick-list').removeClass('miniature');
  3246.                     \$(this).find('.single_service').removeClass('miniature');
  3247.                     \$(this).find('.bottomdivpub').removeClass('miniature');
  3248.                 });
  3249.             }
  3250.             function hidePopPub() {
  3251.                 \$('.modal-backdrop').css('background-color', 'rgb(0, 0, 0)');
  3252.             }
  3253.             function changeHref(elem, newhref) {
  3254.                 \$(elem).parent().attr('href', newhref);
  3255.             }
  3256.             function VerifNbLikes(nblikes) {
  3257.                 \$('#allerAlaBoutique').click();
  3258.             }
  3259.     function handleMenuClick(menuId, pageMenu) {
  3260.         // Reset all icons
  3261.         document.getElementById('imagenoActifphoto').style.display = 'block';
  3262.         document.getElementById('imageActifphoto').style.display = 'none';
  3263.         document.getElementById('nofavorisVocal').style.display = 'block';
  3264.         document.getElementById('favorisActive').style.display = 'none';
  3265.         document.getElementById('noActifVocal').style.display = 'block';
  3266.         document.getElementById('VocalActivee').style.display = 'none';
  3267.         // Set selected icon
  3268.         if (menuId === 'photo') {
  3269.             document.getElementById('imagenoActifphoto').style.display = 'none';
  3270.             document.getElementById('imageActifphoto').style.display = 'block';
  3271.         } else if (menuId === 'selection') {
  3272.             document.getElementById('nofavorisVocal').style.display = 'none';
  3273.             document.getElementById('favorisActive').style.display = 'block';
  3274.         } else if (menuId === 'message') {
  3275.             document.getElementById('noActifVocal').style.display = 'none';
  3276.             document.getElementById('VocalActivee').style.display = 'block';
  3277.         }
  3278.         // Handle any other necessary logic
  3279.         \$('#list-tab-photo').removeClass('show');
  3280.         \$('#list-tab-message').removeClass('show');
  3281.         afficheDiv(\$(`#\${menuId}`));
  3282.     }
  3283.   </script>
  3284.   <script>
  3285.     \$(document).ready(function () {
  3286.       \$(\"#PubProd\").on(\"hidden.bs.modal\", function () {
  3287.         \$(document).trigger(\"modalClosed\");
  3288.       });
  3289.     });
  3290.   </script>
  3291.   <script>
  3292.     \$(document).ready(function () {
  3293.       \$(\"#noShow\").on(\"change\", function () {
  3294.         if (\$(this).is(\":checked\")) {
  3295.           \$.ajax({
  3296.             url: \"/Parent/showpub\",
  3297.             type: \"POST\",
  3298.             dataType: \"json\",
  3299.             success: function (response) {
  3300.               if (response.status === \"success\") {
  3301.                 console.log(\"User showpubprod updated successfully.\");
  3302.               } else {
  3303.                 console.log(\"Error:\", response.message);
  3304.               }
  3305.             },
  3306.             error: function (xhr, status, error) {
  3307.               console.log(\"AJAX Error:\", error);
  3308.             },
  3309.           });
  3310.         }
  3311.       });
  3312.     });
  3313.   </script>
  3314. </div>
  3315. <!-- Script pour la sidebar des favoris -->
  3316. <script>
  3317.   \$(document).ready(function() {
  3318.     // Ouvrir la sidebar
  3319.     \$(\"#openFavoritesSidebar\").click(function() {
  3320.       \$(\".favorites-sidebar\").addClass(\"open\");
  3321.       loadFavorites();
  3322.     });
  3323.     
  3324.     // Fermer la sidebar
  3325.     \$(\".favorites-close\").click(function() {
  3326.       \$(\".favorites-sidebar\").removeClass(\"open\");
  3327.     });
  3328.     
  3329.     // Charger les favoris
  3330.     function loadFavorites() {
  3331.       \$.ajax({
  3332.         url: \"/Parent/mes-favoris\",
  3333.         type: \"GET\",
  3334.         dataType: \"json\",
  3335.         beforeSend: function() {
  3336.           \$(\"#favorites-grid\").html(\"<div style='text-align:center'>Chargement...</div>\");
  3337.         },
  3338.         success: function(data) {
  3339.           \$(\"#favorites-grid\").empty();
  3340.           
  3341.           if (data.data && data.data.length > 0) {
  3342.             \$(\"#favorites-empty-state\").hide();
  3343.             
  3344.             \$.each(data.data, function(i, fav) {
  3345.               var item = \$(\"<div class='favorite-item'></div>\");
  3346.               var img = \$(\"<img>\").attr(\"src\", fav.path).attr(\"alt\", fav.descreption || \"Photo favorite\");
  3347.               var overlay = \$(\"<div class='favorite-overlay'></div>\");
  3348.         
  3349.               
  3350.               btn.click(function(e) {
  3351.                 e.preventDefault();
  3352.                 e.stopPropagation();
  3353.                 removeFavorite(fav.id);
  3354.               });
  3355.               
  3356.               overlay.append(btn);
  3357.               item.append(img).append(overlay);
  3358.               \$(\"#favorites-grid\").append(item);
  3359.             });
  3360.             
  3361.             \$(\"#favorites-counter\").text(data.data.length);
  3362.             var percentage = (data.data.length / 10) * 100;
  3363.             \$(\"#favorites-progress\").css(\"width\", percentage + \"%\");
  3364.             
  3365.           } else {
  3366.             \$(\"#favorites-empty-state\").show();
  3367.             \$(\"#favorites-counter\").text(\"0\");
  3368.             \$(\"#favorites-progress\").css(\"width\", \"0%\");
  3369.           }
  3370.         },
  3371.         error: function() {
  3372.           \$(\"#favorites-grid\").html(\"<div style='color:red;text-align:center'>Erreur de chargement</div>\");
  3373.         }
  3374.       });
  3375.     }
  3376.     
  3377.     // Supprimer un favori
  3378.     function removeFavorite(id) {
  3379.       \$.ajax({
  3380.         url: \"/Parent/remove-favorite/\" + id,
  3381.         type: \"POST\",
  3382.         success: function() {
  3383.           loadFavorites();
  3384.           
  3385.           // Mettre à jour le compteur global
  3386.           var count = parseInt(\$(\"#likeCount\").text());
  3387.           if (!isNaN(count)) {
  3388.             \$(\"#likeCount\").text(count - 1);
  3389.           }
  3390.           
  3391.           var countFav = parseInt(\$(\"#mesFavCount\").text());
  3392.           if (!isNaN(countFav)) {
  3393.             \$(\"#mesFavCount\").text(countFav - 1);
  3394.           }
  3395.         },
  3396.         error: function() {
  3397.           alert(\"Erreur lors de la suppression du favori\");
  3398.         }
  3399.       });
  3400.     }
  3401.   });
  3402. </script>
  3403. <!-- Script pour la sidebar des favoris -->
  3404. <script>
  3405. \$(document).ready(function() {
  3406.     // Fonctions pour ouvrir/fermer la sidebar
  3407.     \$(\"#openFavoritesSidebar\").click(function() {
  3408.         \$(\"#favorites-sidebar\").css(\"right\", \"0\");
  3409.         loadFavorites();
  3410.     });
  3411.     
  3412.     \$(\"#close-favorites-btn\").click(function() {
  3413.         \$(\"#favorites-sidebar\").css(\"right\", \"-400px\");
  3414.     });
  3415.     
  3416.     // Fermer en cliquant en dehors
  3417.     \$(document).click(function(event) {
  3418.         if (!\$(event.target).closest(\"#favorites-sidebar\").length && 
  3419.             !\$(event.target).closest(\"#openFavoritesSidebar\").length && 
  3420.             \$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  3421.             \$(\"#favorites-sidebar\").css(\"right\", \"-400px\");
  3422.         }
  3423.     });
  3424.     
  3425.    // Variables globales
  3426. let selectedFavorites = [];
  3427. let allFavorites = [];
  3428. let coverPhotoId = null; // ID de la photo de couverture
  3429. // Fonction pour mettre à jour la sidebar
  3430. function loadFavorites() {
  3431.     \$(\"#favorites-grid\").html(\"<div style='text-align:center;padding:20px;'>Chargement...</div>\");
  3432.     
  3433.     \$.ajax({
  3434.         url: \"/Parent/mes-favoris\",
  3435.         type: \"GET\",
  3436.         dataType: \"json\",
  3437.         success: function(data) {
  3438.             \$(\"#favorites-grid\").empty();
  3439.             allFavorites = data.data || [];
  3440.             
  3441.             if (allFavorites.length > 0) {
  3442.                 \$(\"#favorites-empty-state\").hide();
  3443.                 
  3444.                 // Ajouter l'option de photo de couverture au-dessus de la grille
  3445.                 if (!\$(\"#cover-photo-section\").length) {
  3446.                     const coverSection = \$(`
  3447.                         <div id=\"cover-photo-section\" style=\"margin-bottom:15px;\">
  3448.                             <div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;\">
  3449.                                 <h4 style=\"margin:0;font-size:15px;color:#333;\">Photo de couverture</h4>
  3450.                                 <span style=\"font-size:12px;color:#777;\">Pour la personnalisation des produits</span>
  3451.                             </div>
  3452.                             <div id=\"cover-photo-container\" style=\"height:120px;background:#f5f5f5;border-radius:8px;display:flex;align-items:center;justify-content:center;overflow:hidden;position:relative;border:1px dashed #ccc;\">
  3453.                                 <div id=\"cover-photo-placeholder\" style=\"text-align:center;padding:15px;color:#777;\">
  3454.                                     <i class=\"bi bi-image\" style=\"font-size:24px;display:block;margin-bottom:8px;\"></i>
  3455.                                     <p style=\"margin:0;font-size:13px;\">Sélectionnez une photo comme couverture</p>
  3456.                                 </div>
  3457.                                 <div id=\"cover-photo-preview\" style=\"display:none;width:100%;height:100%;position:relative;\">
  3458.                                     <img src=\"\" style=\"width:100%;height:100%;object-fit:cover;\" />
  3459.                                     <button id=\"remove-cover-photo\" style=\"position:absolute;top:5px;right:5px;background:#F56040;color:white;border:none;width:24px;height:24px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;\">
  3460.                                         <i class=\"bi bi-x\"></i>
  3461.                                     </button>
  3462.                                 </div>
  3463.                             </div>
  3464.                         </div>
  3465.                     `);
  3466.                     
  3467.                     \$(\"#photos-content\").prepend(coverSection);
  3468.                     
  3469.                     // Événement pour retirer la photo de couverture
  3470.                     \$(\"#remove-cover-photo\").click(function(e) {
  3471.                         e.stopPropagation();
  3472.                         setCoverPhoto(null);
  3473.                     });
  3474.                 }
  3475.                 
  3476.                 // Mettre à jour l'affichage de la photo de couverture
  3477.                 updateCoverPhotoDisplay();
  3478.                 
  3479.                 // Générer la grille de photos
  3480.                 \$.each(allFavorites, function(i, fav) {
  3481.                     var isSelected = selectedFavorites.includes(fav.id);
  3482.                     var isCoverPhoto = (coverPhotoId === fav.id);
  3483.                     
  3484.                     // Conteneur principal avec styles conditionnels
  3485.                     var item = \$(\"<div class='favorite-item' data-id='\" + fav.id + \"' style='position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1;cursor:pointer;transition:all 0.2s;border:3px solid \" + (isSelected ? \"#F56040\" : (isCoverPhoto ? \"#4CAF50\" : \"transparent\")) + \";'></div>\");
  3486.                     
  3487.                     var img = \$(\"<img style='width:100%;height:100%;object-fit:cover;'>\").attr(\"src\", fav.path).attr(\"alt\", fav.descreption || \"Photo favorite\");
  3488.                     
  3489.                     // Badge de sélection
  3490.                     var selectionBadge = \$(\"<div class='selection-badge' style='position:absolute;top:5px;right:5px;width:22px;height:22px;border-radius:50%;background:#F56040;display:\" + (isSelected ? \"flex\" : \"none\") + \";align-items:center;justify-content:center;color:white;font-size:12px;z-index:10;'><i class='bi bi-check'></i></div>\");
  3491.                     
  3492.                     // Badge de photo de couverture
  3493.                     var coverBadge = \$(\"<div class='cover-badge' style='position:absolute;top:5px;left:5px;padding:2px 6px;background:#4CAF50;color:white;font-size:10px;border-radius:3px;display:\" + (isCoverPhoto ? \"block\" : \"none\") + \";z-index:10;'><i class='bi bi-star-fill' style='margin-right:3px;font-size:8px;'></i>Couverture</div>\");
  3494.                     
  3495.                     // Overlay simple pour effet au survol
  3496.                     var hoverOverlay = \$(\"<div class='hover-overlay' style='position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.2);opacity:0;transition:opacity 0.2s;z-index:5;'></div>\");
  3497.                     
  3498.                     // Actions sur hover
  3499.                     var actionsOverlay = \$(\"<div class='actions-overlay' style='position:absolute;bottom:5px;left:5px;right:5px;display:flex;justify-content:center;gap:8px;opacity:0;transition:opacity 0.2s;z-index:15;'></div>\");
  3500.                     
  3501.                     // Bouton pour définir comme photo de couverture
  3502.                     var setCoverBtn = \$(\"<button style='background:\" + (isCoverPhoto ? \"#4CAF50\" : \"rgba(255,255,255,0.8)\") + \";color:\" + (isCoverPhoto ? \"white\" : \"#333\") + \";border:none;border-radius:3px;font-size:11px;padding:5px 8px;cursor:pointer;'><i class='bi bi-star\" + (isCoverPhoto ? \"-fill\" : \"\") + \"' style='margin-right:3px;'></i>Couverture</button>\");
  3503.                     
  3504.                     setCoverBtn.click(function(e) {
  3505.                         e.stopPropagation();
  3506.                         if (isCoverPhoto) {
  3507.                             setCoverPhoto(null);
  3508.                         } else {
  3509.                             setCoverPhoto(fav.id);
  3510.                         }
  3511.                     });
  3512.                     
  3513.                     actionsOverlay.append(setCoverBtn);
  3514.                     
  3515.                     // Ajouter effet de survol
  3516.                     item.hover(
  3517.                         function() { 
  3518.                             \$(this).find(\".hover-overlay\").css(\"opacity\", \"1\");
  3519.                             \$(this).find(\".actions-overlay\").css(\"opacity\", \"1\");
  3520.                         },
  3521.                         function() { 
  3522.                             \$(this).find(\".hover-overlay\").css(\"opacity\", \"0\");
  3523.                             \$(this).find(\".actions-overlay\").css(\"opacity\", \"0\");
  3524.                         }
  3525.                     );
  3526.                     
  3527.                     // Gérer le clic pour la sélection
  3528.                     item.click(function(e) {
  3529.                         e.stopPropagation();
  3530.                         toggleSelection(\$(this).data('id'));
  3531.                     });
  3532.                     
  3533.                     item.append(img).append(hoverOverlay).append(selectionBadge).append(coverBadge).append(actionsOverlay);
  3534.                     
  3535.                     // Ajouter explicitement une classe pour le style
  3536.                     item.addClass(\"no-trash-button\");
  3537.                     
  3538.                     \$(\"#favorites-grid\").append(item);
  3539.                 });
  3540.                 
  3541.                 // Supprimer tout bouton de suppression qui pourrait être ajouté dynamiquement
  3542.                 setTimeout(function() {
  3543.                     \$(\".favorite-item .remove-favorite, .favorite-item button:has(.bi-trash), .favorite-overlay button\").remove();
  3544.                 }, 100);
  3545.                 
  3546.                 \$(\"#favorites-counter\").text(allFavorites.length);
  3547.                 \$(\"#openFavoritesSidebar span\").text(allFavorites.length);
  3548.                 updateProductsView();
  3549.                 
  3550.             } else {
  3551.                 \$(\"#favorites-empty-state\").show();
  3552.                 \$(\"#favorites-counter\").text(\"0\");
  3553.                 \$(\"#openFavoritesSidebar span\").text(\"0\");
  3554.                 \$(\"#selection-count\").text(\"0\");
  3555.                 updateProductsView();
  3556.             }
  3557.         },
  3558.         error: function() {
  3559.             \$(\"#favorites-grid\").html(\"<div style='color:red;text-align:center;padding:20px;'>Erreur de chargement</div>\");
  3560.         }
  3561.     });
  3562. }
  3563. // Fonction pour définir la photo de couverture
  3564. function setCoverPhoto(id) {
  3565.     coverPhotoId = id;
  3566.     
  3567.     // Mettre à jour l'affichage
  3568.     updateCoverPhotoDisplay();
  3569.     
  3570.     // Mettre à jour le style des photos dans la grille
  3571.     \$(\".favorite-item\").each(function() {
  3572.         const itemId = \$(this).data('id');
  3573.         const isSelected = selectedFavorites.includes(itemId);
  3574.         const isCover = (itemId === coverPhotoId);
  3575.         
  3576.         // Mettre à jour la bordure
  3577.         \$(this).css(\"border\", \"3px solid \" + (isSelected ? \"#F56040\" : (isCover ? \"#4CAF50\" : \"transparent\")));
  3578.         
  3579.         // Mettre à jour le badge de couverture
  3580.         \$(this).find(\".cover-badge\").css(\"display\", isCover ? \"block\" : \"none\");
  3581.         
  3582.         // Mettre à jour le bouton de couverture
  3583.         const coverBtn = \$(this).find(\".actions-overlay button:first\");
  3584.         coverBtn.css({
  3585.             \"background\": isCover ? \"#4CAF50\" : \"rgba(255,255,255,0.8)\",
  3586.             \"color\": isCover ? \"white\" : \"#333\"
  3587.         });
  3588.         coverBtn.find(\"i\").attr(\"class\", \"bi bi-star\" + (isCover ? \"-fill\" : \"\"));
  3589.     });
  3590.     
  3591.     // Enregistrer l'ID de la photo de couverture (si nécessaire pour le backend)
  3592.     if (id) {
  3593.         console.log(\"Photo de couverture définie avec l'ID:\", id);
  3594.         // Ici vous pouvez ajouter une requête AJAX pour enregistrer ce choix sur le serveur
  3595.         
  3596.         // Ajouter automatiquement la photo de couverture à la sélection si elle n'y est pas déjà
  3597.         if (!selectedFavorites.includes(id)) {
  3598.             toggleSelection(id);
  3599.         }
  3600.     } else {
  3601.         console.log(\"Photo de couverture supprimée\");
  3602.     }
  3603. }
  3604. // Mettre à jour l'affichage de la photo de couverture
  3605. function updateCoverPhotoDisplay() {
  3606.     if (coverPhotoId) {
  3607.         // Trouver la photo correspondante
  3608.         const coverPhoto = allFavorites.find(fav => fav.id === coverPhotoId);
  3609.         if (coverPhoto) {
  3610.             \$(\"#cover-photo-placeholder\").hide();
  3611.             \$(\"#cover-photo-preview\").show();
  3612.             \$(\"#cover-photo-preview img\").attr(\"src\", coverPhoto.path);
  3613.         } else {
  3614.             // Si l'ID ne correspond à aucune photo (cas rare)
  3615.             coverPhotoId = null;
  3616.             \$(\"#cover-photo-placeholder\").show();
  3617.             \$(\"#cover-photo-preview\").hide();
  3618.         }
  3619.     } else {
  3620.         \$(\"#cover-photo-placeholder\").show();
  3621.         \$(\"#cover-photo-preview\").hide();
  3622.     }
  3623. }
  3624. // Modifier la fonction updateProductsView pour tenir compte de la photo de couverture
  3625. function updateProductsView() {
  3626.     const current = selectedFavorites.length;
  3627.     const hasCoverPhoto = coverPhotoId !== null;
  3628.     
  3629.     \$(\"#product-photo-count\").text(current);
  3630.     
  3631.     let remainingForAlbum = Math.max(0, 20 - current);
  3632.     let remainingForPochette = Math.max(0, 12 - current);
  3633.     let remainingForPack = Math.max(0, 12 - current);
  3634.     const progressBar = (count, total, color) => `
  3635.         <div style=\"margin: 5px 0;\">
  3636.             <div style=\"background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;\">
  3637.                 <div style=\"width: \${(count / total) * 100}%; background-color: \${color}; height: 100%;\"></div>
  3638.             </div>
  3639.             <small style=\"font-size: 12px;\">\${count}/\${total} photos</small>
  3640.         </div>
  3641.     `;
  3642.     // Liste des produits
  3643.     const products = [
  3644.         {
  3645.             name: \"Pochette photo (12 photos)\",
  3646.             required: 12,
  3647.             remaining: Math.max(0, 12 - current),
  3648.             image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  3649.             color: \"#2196f3\",
  3650.             link: \"";
  3651.         // line 3339
  3652.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("AjoutPochettePhotos_Favoris", ["nbr" => 12]);
  3653.         yield "\",
  3654.             needsCover: true
  3655.         },
  3656.         {
  3657.             name: \"Pack numérique (20 photos)\",
  3658.             required: 20,
  3659.             remaining: Math.max(0, 20 - current),
  3660.             image: \"/images/produit/photoNumerique.jpg\",
  3661.             color: \"#4caf50\",
  3662.             link: \"";
  3663.         // line 3348
  3664.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("PackPhotosNumerique_Favoris", ["nbr" => 20]);
  3665.         yield "\",
  3666.             needsCover: false
  3667.         },
  3668.        
  3669.       
  3670.     ].sort((a, b) => a.remaining - b.remaining);
  3671.     const productList = products
  3672.         .map((product) => {
  3673.             const count = current;
  3674.             const total = product.required;
  3675.             const remaining = product.remaining;
  3676.             const coverRequired = product.needsCover && !hasCoverPhoto;
  3677.             return `
  3678.                 <li style=\"margin-bottom: 20px; position: relative;\">
  3679.                     \${coverRequired ? `<div style=\"position: absolute; top: 0; right: 0; background: #FFC107; color: #333; font-size: 10px; padding: 2px 6px; border-radius: 3px; z-index: 5;\">
  3680.                         <i class=\"bi bi-exclamation-triangle\"></i> Photo de couverture requise
  3681.                     </div>` : ''}
  3682.                     <div style=\"display: flex; align-items: center; gap: 10px;\">
  3683.                         <img src=\"\${product.image}\" alt=\"\${product.name}\" style=\"width: 70px; height: 70px; border-radius: 5px; object-fit: cover;\" />
  3684.                         <div style=\"flex: 1;\">
  3685.                             <strong style=\"font-size: 14px;\">\${product.name}</strong>
  3686.                             \${progressBar(count, total, product.color)}
  3687.                             \${
  3688.                                 remaining > 0
  3689.                                 ? `<small style=\"color: \${product.color}; font-size: 12px;\">
  3690.                                     Encore \${remaining} photos pour compléter \${product.name.toLowerCase()}
  3691.                                 </small>`
  3692.                                 : coverRequired
  3693.                                 ? `<button
  3694.                                     style=\"
  3695.                                         margin-top: 5px;
  3696.                                         padding: 6px 12px;
  3697.                                         background-color: #FFC107;
  3698.                                         color: #333;
  3699.                                         border: none;
  3700.                                         border-radius: 5px;
  3701.                                         font-size: 13px;
  3702.                                         cursor: pointer;
  3703.                                     \"
  3704.                                     onclick=\"\$('#tab-photos').click(); /* Rediriger vers l'onglet photos */\"
  3705.                                 >
  3706.                                     Choisir une couverture
  3707.                                 </button>`
  3708.                                 : `<button
  3709.                                     style=\"
  3710.                                         margin-top: 5px;
  3711.                                         padding: 6px 12px;
  3712.                                         background-color: \${product.color};
  3713.                                         color: white;
  3714.                                         border: none;
  3715.                                         border-radius: 5px;
  3716.                                         font-size: 13px;
  3717.                                         cursor: pointer;
  3718.                                     \"
  3719.                                     onclick=\"window.location.href='\${product.link}'\"
  3720.                                 >
  3721.                                     Commander
  3722.                                 </button>`
  3723.                             }
  3724.                         </div>
  3725.                     </div>
  3726.                 </li>
  3727.             `;
  3728.         })
  3729.         .join(\"\");
  3730.     const boutiqueButton = `
  3731.         <li style=\"margin-top: 25px; text-align: center;\">
  3732.             <button
  3733.                 style=\"
  3734.                     padding: 8px 15px;
  3735.                     background-color: #F56040;
  3736.                     color: white;
  3737.                     border: none;
  3738.                     border-radius: 5px;
  3739.                     font-size: 14px;
  3740.                     width: 170px;
  3741.                     height: 40px;
  3742.                     cursor: pointer;
  3743.                 \"
  3744.                 onclick=\"window.location.href='";
  3745.         // line 3430
  3746.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("boutique5sur5");
  3747.         yield "'\"
  3748.             >
  3749.                 Voir toute la boutique
  3750.             </button>
  3751.         </li>
  3752.     `;
  3753.     \$(\"#product-list\").html(productList + boutiqueButton);
  3754. }
  3755. });
  3756. </script>
  3757. ";
  3758.         
  3759.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  3760.         
  3761.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  3762.         yield from [];
  3763.     }
  3764.     /**
  3765.      * @codeCoverageIgnore
  3766.      */
  3767.     public function getTemplateName(): string
  3768.     {
  3769.         return "Parent/DetailsSejour.html.twig";
  3770.     }
  3771.     /**
  3772.      * @codeCoverageIgnore
  3773.      */
  3774.     public function isTraitable(): bool
  3775.     {
  3776.         return false;
  3777.     }
  3778.     /**
  3779.      * @codeCoverageIgnore
  3780.      */
  3781.     public function getDebugInfo(): array
  3782.     {
  3783.         return array (  4068 => 3430,  3983 => 3348,  3971 => 3339,  3483 => 2854,  3460 => 2834,  3444 => 2821,  3330 => 2710,  3322 => 2704,  3317 => 2701,  3315 => 2700,  3239 => 2626,  3236 => 2625,  3224 => 2615,  3221 => 2614,  3219 => 2613,  2914 => 2311,  2866 => 2266,  2757 => 2160,  2746 => 2152,  2735 => 2144,  2717 => 2129,  2101 => 1516,  2031 => 1449,  2020 => 1441,  1902 => 1326,  1860 => 1287,  1730 => 1160,  1669 => 1102,  1657 => 1093,  1407 => 847,  1394 => 846,  1380 => 843,  1370 => 836,  1365 => 834,  1356 => 828,  1349 => 823,  1347 => 822,  1343 => 820,  1306 => 785,  1303 => 784,  1289 => 783,  1283 => 779,  1279 => 777,  1275 => 775,  1269 => 774,  1265 => 772,  1258 => 768,  1254 => 766,  1252 => 765,  1245 => 761,  1239 => 757,  1236 => 756,  1232 => 755,  1225 => 750,  1223 => 749,  1221 => 748,  1217 => 746,  1211 => 745,  1207 => 743,  1200 => 739,  1196 => 737,  1194 => 736,  1187 => 732,  1181 => 728,  1178 => 727,  1174 => 726,  1171 => 725,  1169 => 724,  1167 => 723,  1163 => 721,  1157 => 720,  1153 => 718,  1146 => 714,  1142 => 712,  1140 => 711,  1133 => 707,  1127 => 703,  1124 => 702,  1120 => 701,  1117 => 700,  1115 => 699,  1113 => 698,  1107 => 695,  1102 => 692,  1100 => 691,  1095 => 688,  1087 => 685,  1083 => 684,  1077 => 682,  1075 => 681,  1067 => 676,  1059 => 671,  1056 => 670,  1054 => 669,  1049 => 666,  1042 => 662,  1036 => 660,  1034 => 659,  1018 => 645,  1015 => 644,  1011 => 643,  1003 => 637,  999 => 636,  994 => 634,  990 => 633,  986 => 632,  982 => 631,  978 => 630,  967 => 624,  963 => 623,  956 => 619,  953 => 618,  950 => 617,  946 => 616,  929 => 601,  923 => 600,  917 => 599,  915 => 598,  910 => 597,  898 => 587,  894 => 585,  873 => 568,  871 => 567,  864 => 562,  858 => 559,  855 => 558,  853 => 557,  850 => 556,  844 => 553,  841 => 552,  839 => 551,  836 => 550,  830 => 547,  827 => 546,  825 => 545,  814 => 536,  812 => 528,  798 => 516,  794 => 514,  773 => 497,  771 => 496,  748 => 478,  744 => 477,  741 => 476,  738 => 475,  735 => 474,  732 => 473,  729 => 472,  726 => 471,  708 => 470,  705 => 469,  703 => 468,  675 => 455,  669 => 451,  663 => 448,  659 => 446,  656 => 445,  650 => 442,  646 => 440,  643 => 439,  637 => 436,  633 => 434,  631 => 433,  626 => 430,  624 => 417,  620 => 415,  616 => 413,  613 => 405,  608 => 403,  604 => 402,  597 => 398,  593 => 397,  585 => 394,  582 => 393,  579 => 392,  576 => 391,  573 => 390,  556 => 389,  544 => 380,  535 => 376,  527 => 371,  522 => 369,  513 => 365,  478 => 333,  451 => 309,  420 => 281,  411 => 275,  407 => 274,  403 => 273,  395 => 268,  344 => 220,  321 => 199,  308 => 197,  112 => 12,  110 => 11,  106 => 10,  102 => 9,  98 => 8,  94 => 7,  90 => 6,  86 => 5,  80 => 2,  57 => 1,  55 => 197,  42 => 1,);
  3784.     }
  3785.     public function getSourceContext(): Source
  3786.     {
  3787.         return new Source("{% extends \"Parent/LayoutParent.html.twig\" %} {% block LinksCss %}
  3788. {{ parent() }}
  3789. <script src=\"https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js\"></script>
  3790. <link rel=\"stylesheet\" href=\"{{ '/css/Parent/css/premiercnx.css' }}\" />
  3791. <link href=\"{{ asset('css/Parent/css/detailsejour.css') }}\" type=\"text/css\" rel=\"stylesheet\" />
  3792. <link rel=\"stylesheet\" href=\"{{ '/css/Accompagnateur/imgzoom.css' }}\" />
  3793. <link rel=\"stylesheet\" href=\"{{ asset('Plugins/css/dropzone.css') }}\" />
  3794. <link rel=\"stylesheet\" href=\"{{ asset('css/splide.min.css') }}\" />
  3795. <link rel=\"stylesheet\" href=\"{{ asset('css/favorites-sidebar.css') }}\" />
  3796. {% set destination = \"detailsejour\" %}
  3797. <style>
  3798. .btn-cmdFav {
  3799.   background-color: #F56040;
  3800.   color: white;
  3801.   padding: 10px 20px;
  3802.   border-radius: 6px;
  3803.   font-size: 1rem;
  3804.   box-shadow: 0 4px 8px rgba(0,0,0,0.15);
  3805.   transition: all 0.3s ease;
  3806. }
  3807. .btn-cmdFav:hover {
  3808.   background-color: #e64a30;
  3809.   transform: scale(1.05);
  3810.   box-shadow: 0 6px 12px rgba(0,0,0,0.2);
  3811. }
  3812. .filter-badge {
  3813.   background-color: #ccc;
  3814.   color: white;
  3815.   font-size: 12px;
  3816.   padding: 2px 10px;
  3817.   border-radius: 20px;
  3818.   display: flex;
  3819.   align-items: center;
  3820.   cursor: pointer;
  3821.   transition: all 0.3s ease;
  3822. }
  3823. .filter-badge:hover {
  3824.   background-color: #aaa;
  3825. }
  3826. /* Quand le filtre est actif */
  3827. .filter-badge.active {
  3828.   background-color: #3BA39B; /* Vert plus vif */
  3829.   box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
  3830.   font-weight: bold;
  3831.   color: white;
  3832. }
  3833.   .close-btn-purchase {
  3834.     position: absolute;
  3835.     padding: 2px;
  3836.     top: 10px;
  3837.     right: 10px;
  3838.     background: none;
  3839.     border: none;
  3840.     font-size: 35px;
  3841.     cursor: pointer;
  3842.   }
  3843.   .close-btn-purchase :hover {
  3844.     color: red;
  3845.   }
  3846.   .rowimag.no-margin {
  3847.     display: grid;
  3848.     grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  3849.     /* auto-fill + minmax ensures they fill the row and wrap automatically */
  3850.     gap: 8px; /* spacing between items, optional */
  3851.     margin: 0; /* override default margin if you want */
  3852.     padding: 0;
  3853.   }
  3854.   /* Each cell is 200px tall (or pick your own dimension). */
  3855.   .photo-item {
  3856.     width: 100%;
  3857.     height: 250px; /* fixed height: 200px */
  3858.     position: relative;
  3859.     overflow: hidden; /* hide any overflow if the image is bigger */
  3860.     border-radius: 4px; /* optional rounding corners */
  3861.     background: #f0f0f0; /* fallback background color while image loads */
  3862.     margin-bottom: 20px;
  3863.   }
  3864.   /* For images, we want them to fill the box and maintain a cover aspect. */
  3865.   .photo-item img,
  3866.   .photo-item video {
  3867.     width: 100%;
  3868.     height: 100%;
  3869.     object-fit: cover; /* ensures image or video is cropped rather than distorted */
  3870.     display: block;
  3871.   }
  3872.   .fav-button {
  3873.     pointer-events: none; /* Makes the entire button unclickable */
  3874.   }
  3875.   
  3876.   /* Enable hover effects only */
  3877.   .fav-button * {
  3878.     pointer-events: auto; /* Re-enable events for children */
  3879.     pointer-events: hover; /* Only allow hover events, not clicks */
  3880.   }
  3881.   
  3882.   /* Add this class to the purchase alert to ensure it remains interactive */
  3883.   #purchase-alert {
  3884.     pointer-events: auto;
  3885.   
  3886.   }
  3887.   /* Réduit l'espace autour du header */
  3888.   .header {
  3889.     padding: 15px 15px 5px 15px;
  3890.     background: #f9f9f9;
  3891.   }
  3892.   /* Réduit l'espace sous le titre et le sous-titre */
  3893.   .titreDetailSej {
  3894.     margin-bottom: 8px;
  3895.   }
  3896.   .media-counts {
  3897.     margin-bottom: 8px;
  3898.   }
  3899.   /* Centre la navigation des dates */
  3900.   .date-navigation {
  3901.     display: flex;
  3902.     align-items: center;
  3903.     justify-content: center;
  3904.     gap: 8px;
  3905.     width: 100%;
  3906.     margin-top: 0;
  3907.   }
  3908.   /* Centre le conteneur des cartes */
  3909.   .date-container {
  3910.     display: flex;
  3911.     justify-content: center;
  3912.     width: 100%;
  3913.   }
  3914.   .media-list-horizontal {
  3915.     gap: 4px;
  3916.     font-size: 11px;
  3917.     margin-top: 2px;
  3918.     display: flex;
  3919.     justify-content: center;
  3920.     list-style: none;
  3921.     margin-bottom: 0;
  3922.     padding-left: 0;
  3923.   }
  3924.   .sejour-title h1 {
  3925.     font-size: 1.5rem;
  3926.     font-weight: bold;
  3927.     color: #3BA39B;
  3928.     display: flex;
  3929.     align-items: center;
  3930.     gap: 10px;
  3931.   }
  3932.   .sejour-dates {
  3933.     font-size: 14px;
  3934.     color: #777;
  3935.     margin-top: 5px;
  3936.   }
  3937.   .sejour-medias {
  3938.     display: flex;
  3939.     gap: 20px;
  3940.     align-items: center;
  3941.     font-size: 14px;
  3942.     color: #555;
  3943.   }
  3944.   .media-info {
  3945.     display: flex;
  3946.     align-items: center;
  3947.     gap: 5px;
  3948.   }
  3949.   /* Responsive Mobile */
  3950.   @media (max-width: 768px) {
  3951.     .sejour-header {
  3952.       flex-direction: column;
  3953.       align-items: center;
  3954.       text-align: center;
  3955.     }
  3956.     .sejour-medias {
  3957.       margin-top: 10px;
  3958.       gap: 10px;
  3959.     }
  3960.   }
  3961. </style>
  3962. {% endblock %} {% set pageMenu = app.session.get('pageMenu') %} {% block Content
  3963. %}
  3964. <!-- Alerte pour inciter à acheter -->
  3965. <div id=\"purchase-alert\" class=\"purchase-alert hidden\" style=\"display: none;\">
  3966.   <button class=\"close-btn\" onclick=\"closePurchaseAlert()\">&times;</button>
  3967.   <div id=\"purchase-alert-content\">
  3968.     <!-- Le contenu de l'alerte sera mis à jour dynamiquement en fonction du nombre de favoris -->
  3969.   </div>
  3970. </div>
  3971. <div
  3972.   id=\"verifImg\"
  3973.   class=\"modal fade\"
  3974.   role=\"dialog\"
  3975.   style=\"background-color: rgba(112, 112, 112, 0.56); z-index: 1000000\"
  3976. >
  3977.   <div class=\"modal-dialog dialogUploadImg\">
  3978.     <div class=\"row modal-content no-margin contentdialogNoImg\">
  3979.       <div class=\"headerdialogUploadImg\">
  3980.         <h1 class=\"titledialogUploadImg\"></h1>
  3981.         <img
  3982.           src=\"{{ '/images/Accompagnateur/CroixFermeture.svg' }}\"
  3983.           class=\"closeNOUploadImg\"
  3984.           data-dismiss=\"modal\"
  3985.         />
  3986.       </div>
  3987.       <div class=\"ContenudetailsSejour\">
  3988.         <div class=\"row no-margin detailsSejour\">
  3989.           <div class=\"ContentUpload\">
  3990.             <h1 class=\"titleTelechargement\">
  3991.               Oulala, patience, avant tout sélectionnez vos photos préférées à
  3992.               l'aide de ce bouton
  3993.               <i
  3994.                 class=\"bi bi-heart\"
  3995.                 style=\"font-size: 1.3rem\"
  3996.                 title=\"Ajouter à  ma sélection\"
  3997.               ></i>
  3998.               sous les photos  <br /><br /><a style=\"color: #f09e7a\"
  3999.                 >Pensez à commander des tirages... pour leurs offrir un beau
  4000.                 souvenir !
  4001.               </a>
  4002.             </h1>
  4003.           </div>
  4004.         </div>
  4005.       </div>
  4006.       <div class=\"BottomNoUploadImg\">
  4007.         <button class=\"BtnUploadImg btnAnnulerUpload\" data-dismiss=\"modal\">
  4008.           OK
  4009.         </button>
  4010.       </div>
  4011.     </div>
  4012.   </div>
  4013. </div>
  4014. <div class=\"main-content\">
  4015.   <div class=\"row no-margin\">
  4016.     <!-- Chat button -->
  4017.     <div
  4018.       class=\"fav-button\"
  4019.       onmouseover=\"showSelection()\"
  4020.       onmouseout=\"hideSelection()\"
  4021.     >
  4022.       <i id=\"favoris-icon-Accueilpayment\" class=\"bi bi-heart-fill CoeurEclat\"></i
  4023.       ><label
  4024.         id=\"likeCount\"
  4025.         class=\"labelFavCount\"
  4026.         style=\"background-color: #f56040\"
  4027.       >
  4028.         {{ likes | length }}</label
  4029.       >
  4030.     </div>
  4031.     <div class=\"selection-popover\" id=\"selectionPopover\">
  4032.       <h4>Votre sélection</h4>
  4033.       <p>Tirages : {{ likes | length }} / 12</p>
  4034.       <p>Numériques : {{ likes | length }} / 15</p>
  4035.       <p>Album : {{ likes | length }} / 20</p>
  4036.       <button class=\"finalize-button\">Finaliser ma commande</button>
  4037.     </div>
  4038.   </div>
  4039.   <div class=\"divSliderModern\">
  4040.     <input type=\"hidden\" id=\"nbFavCurrent\" value=\"{{ nblikes }}\" />
  4041.     <div
  4042.       class=\"splide no-padding no-margin\"
  4043.       id=\"imageSlider\"
  4044.       style=\"max-height: 200px\"
  4045.     >
  4046.       <div class=\"splide__track\">
  4047.         <ul class=\"splide__list\">
  4048.           <!-- Slide 1 -->
  4049.           <li class=\"splide__slide\">
  4050.             <div class=\"slider-content\" style=\"background: white\">
  4051.               <div class=\"namePRD\" style=\"display: block\">
  4052.                 <h4
  4053.                   class=\"titleProdbienvenu titleProdbienvenu1\"
  4054.                   style=\"color: #41a2aa\"
  4055.                 >
  4056.                   Ajoutez vos favoris dès maintenant
  4057.                 </h4>
  4058.                 <h4
  4059.                   class=\"titleProdbienvenu titleProdbienvenu2\"
  4060.                   style=\"color: #f09e7a\"
  4061.                 >
  4062.                   et profitez de nos produits souvenirs personnalisés !
  4063.                 </h4>
  4064.               </div>
  4065.               <img
  4066.                 src=\"{{ asset('/images/imgSliderEmpty2.png') }}\"
  4067.                 class=\"imgslider\"
  4068.                 alt=\"Image 1\"
  4069.               />
  4070.             </div>
  4071.           </li>
  4072.           <!-- Slide 2 -->
  4073.           <li class=\"splide__slide\">
  4074.             <div class=\"slider-content\" style=\"background: white\">
  4075.               <div class=\"namePRD\" style=\"display: block\">
  4076.                 <h4
  4077.                   class=\"titleProdbienvenu titleProdbienvenu1\"
  4078.                   style=\"color: #f09e7a\"
  4079.                 >
  4080.                   Pensez à commander le livre du séjour
  4081.                 </h4>
  4082.                 <h4
  4083.                   class=\"titleProdbienvenu titleProdbienvenu2\"
  4084.                   style=\"color: #41a2aa\"
  4085.                 >
  4086.                   et offrez lui le plus beau des cadeaux !
  4087.                 </h4>
  4088.               </div>
  4089.               <img
  4090.                 src=\"{{ asset('/images/imgSliderEmpty1.png') }}\"
  4091.                 class=\"imgslider\"
  4092.                 alt=\"Image 2\"
  4093.               />
  4094.             </div>
  4095.           </li>
  4096.         </ul>
  4097.       </div>
  4098.     </div>
  4099.   </div>
  4100.   <!-- Section de contenu à atteindre après le scroll -->
  4101.   <div
  4102.     class=\"no-margin\"
  4103.     id=\"scrollTarget\"
  4104.     style=\"width: 100%; background: #f9f9f9; padding-top: 30px\"
  4105.   >
  4106.     <div class=\"no-margin\" id=\"scrollTarget\" style=\"width: 100%\">
  4107.       <!-- Conteneur principal en ligne -->
  4108.       <div
  4109.         class=\"header d-flex align-items-center justify-content-between\"
  4110.         style=\"padding: 15px;\"
  4111.       >
  4112.         <!-- Bloc titre -->
  4113.         <div class=\"box divInfosSejour\" style=\"width: 95%;\">
  4114.           <img
  4115.             class=\"imageTitreSej\"
  4116.             src=\"/Accueil/imagesAccueil/sejour.png\"
  4117.             alt=\"Icône séjour\"
  4118.             style=\"width: 40px; height: auto\"
  4119.           />
  4120.           <h1 class=\"titreDetailSej\">
  4121.             Séjour {{sejour.codeSejour}} {{ sejour.themSejour }}
  4122.             <span class=\"spnTitleSej\">
  4123.               du
  4124.               {{ sejour.dateDebutSejour|date(\"d M Y\")|replace({\"Jan\": \"janv.\", \"Feb\": \"fév.\", \"Mar\": \"mars\", \"Apr\": \"avr.\", \"May\": \"mai\", \"Jun\": \"juin\", \"Jul\": \"juil.\", \"Aug\": \"août\", \"Sep\": \"sept.\", \"Oct.\": \"oct.\", \"Nov.\": \"nov.\", \"Dec.\": \"déc.\"}) }}
  4125.               au
  4126.               {{ sejour.dateFinSejour|date(\"d M Y\")|replace({\"Jan\": \"janv.\", \"Feb\": \"fév.\", \"Mar\": \"mars\", \"Apr\": \"avr.\", \"May\": \"mai\", \"Jun\": \"juin\", \"Jul\": \"juil.\", \"Aug\": \"août\", \"Sep\": \"sept.\", \"Oct.\": \"oct.\", \"Nov.\": \"nov.\", \"Dec.\": \"déc.\"}) }}
  4127.             </span>
  4128.           </h1>
  4129.           <span class=\"spnTitleSej\" style=\"color:black\">
  4130.         
  4131.             (📷 {{ attachementsCount }} Photos/Vidéos | 🎵 {{ nbmessages }} Audios  ❤️  <label
  4132.         id=\"mesFavCount\" style=\"color:black;margin-right:5px\"
  4133.       
  4134.     >
  4135.     {{ nblikes }}   </label> Favoris )
  4136.   
  4137.           </span>
  4138.           <div class=\"date-navigation\">
  4139.           
  4140.      
  4141.             <div class=\"date-container\">
  4142.               {% for x, groupAttach in listeattach %}
  4143.                 {% set xDate = date(x) %}
  4144.                 {% set finDate = date(sejour.dateFinSejour) %}
  4145.                 {% if xDate <= finDate %}
  4146.                   <div
  4147.                     class=\"date-card modern-card {% if loop.last and xDate <= finDate %} active {% endif %}\"
  4148.                     data-aos=\"fade-up\"
  4149.                     data-bs-toggle=\"collapse\"
  4150.                     data-bs-target=\"#demP{{ loop.index }}\"
  4151.                     id=\"iconedemoP{{ loop.index }}\"
  4152.                   >
  4153.                     <div class=\"card-content text-center\">
  4154.                       <span class=\"day\">
  4155.                         {% if groupAttach.isFirstDay == \"yes\" %} Premier jour
  4156.                         {% elseif groupAttach.isLastDay == \"yes\" %} Dernier jour
  4157.                         {% else %}
  4158.                           {{ xDate|date(\"D\")|replace({
  4159.                             \"Mon\": \"lun.\",
  4160.                             \"Tue\": \"mar.\",
  4161.                             \"Wed\": \"mer.\",
  4162.                             \"Thu\": \"jeu.\",
  4163.                             \"Fri\": \"ven.\",
  4164.                             \"Sat\": \"sam.\",
  4165.                             \"Sun\": \"dim.\"
  4166.                           }) }}
  4167.                         {% endif %}
  4168.                       </span>
  4169.                       <span class=\"full-date\">
  4170.                         {{ xDate|date(\"d M Y\")|replace({
  4171.                           \"Jan\": \"janv.\",
  4172.                           \"Feb\": \"fév.\",
  4173.                           \"Mar\": \"mars\",
  4174.                           \"Apr\": \"avr.\",
  4175.                           \"May\": \"mai\",
  4176.                           \"Jun\": \"juin\",
  4177.                           \"Jul\": \"juil.\",
  4178.                           \"Aug\": \"août\",
  4179.                           \"Sep\": \"sept.\",
  4180.                           \"Oct.\": \"oct.\",
  4181.                           \"Nov.\": \"nov.\",
  4182.                           \"Dec.\": \"déc.\"
  4183.                         }) }}
  4184.                       </span>
  4185.                       <ul class=\"media-list-horizontal\">
  4186.                         {% if groupAttach.countPhotos > 0 %}
  4187.                         <li>
  4188.                           <i class=\"bi bi-images\" style=\"color: #f56040; font-size: 0.7rem; margin-right: 3px\"></i>
  4189.                           {{ groupAttach.countPhotos }}
  4190.                         </li>
  4191.                         {% endif %}
  4192.                         {% if groupAttach.countAudio > 0 %}
  4193.                         <li>
  4194.                           <i class=\"bi bi-mic-fill\" style=\"color: #ffa500; font-size: 0.7rem; margin-right: 5px\"></i>
  4195.                           {{ groupAttach.countAudio }}
  4196.                         </li>
  4197.                         {% endif %}
  4198.                         {% if groupAttach.countVideos > 0 %}
  4199.                         <li>
  4200.                           <i class=\"bi bi-camera-video-fill\" style=\"color: #41a2aa; font-size: 0.7rem; margin-right: 5px\"></i>
  4201.                           {{ groupAttach.countVideos }}
  4202.                         </li>
  4203.                         {% endif %}
  4204.                       </ul>
  4205.                     </div>
  4206.                   </div>
  4207.                 {% endif %}
  4208.               {% endfor %} <div id=\"dynamic-card\" class=\"dynamic-card\">
  4209.       <div id=\"dynamic-card-content\" class=\"dynamic-card-content\">
  4210.         <!-- Le contenu dynamique (album, pochette, montage vidéo) sera injecté ici -->
  4211.       </div>
  4212.     </div>
  4213.             </div>
  4214.           </div>
  4215.         </div>
  4216.       </div>
  4217.     </div>
  4218.     <!-- Descriptions and Attachments -->
  4219.     <div class=\"container--gallery modern\">
  4220.       {% set lastValidIndex = 0 %}
  4221.       {% set hasAttachments = false %}
  4222.       {% for x, groupAttach in listeattach %}
  4223.       {% set xDate = date(x) %}
  4224.       {% set finDate = date(sejour.dateFinSejour) %}
  4225.       {% if xDate <= finDate %}
  4226.       {% set lastValidIndex = loop.index %}
  4227.       {% set hasAttachments = true %}
  4228.       <div
  4229.         id=\"demP{{ loop.index }}\"
  4230.         class=\"collapse {% if loop.last and xDate <= finDate %}show{% endif %}\"
  4231.         style=\"padding: 2%; padding-top: 0%\"
  4232.       >
  4233.         <div class=\"journal-entry\">
  4234.         <div class=\"entry-header\" style=\"
  4235.     display: flex;
  4236.     align-items: center;
  4237.     justify-content: space-between;
  4238.     background: #ffffff;
  4239.     padding: 8px 15px;
  4240.     border-radius: 10px;
  4241.     margin-bottom: 20px;
  4242.     box-shadow: 0 2px 8px rgba(0,0,0,0.05);
  4243.     border-bottom: 1px solid #eee;
  4244.     flex-wrap: wrap;
  4245. \">
  4246.   <!-- Bouton Jour Précédent -->
  4247.   {% if not loop.first %}
  4248.   <button class=\"btn-prev-day\" data-target=\"{{ loop.index0 - 1 }}\" style=\"
  4249.       background-color: #3BA39B;
  4250.       border: none;
  4251.       padding: 5px 10px;
  4252.       border-radius: 8px;
  4253.       font-weight: bold;
  4254.       font-size: 14px;
  4255.       height: 36px;
  4256.       display: flex;
  4257.       align-items: center;
  4258.       color: white;
  4259.       cursor: pointer;
  4260.       transition: all 0.3s ease;
  4261.   \">
  4262.     <i class=\"bi bi-chevron-left\" style=\"font-size: 18px;\"></i>
  4263.   </button>
  4264.   {% else %}
  4265.   <div style=\"width: 36px;\"></div>
  4266.   {% endif %}
  4267.   <!-- Centre : Date + Médias -->
  4268.   <div style=\"
  4269.       flex-grow: 1;
  4270.       display: flex;
  4271.       align-items: center;
  4272.       justify-content: center;
  4273.       flex-wrap: wrap;
  4274.       gap: 12px;
  4275.   \">
  4276.     <!-- Date -->
  4277.     <div style=\"font-weight: bold; font-size: 16px; color: #333;\">
  4278.       {{ x|date(\"l d F Y\")|replace({
  4279.           \"Monday\": \"Lundi\", \"Tuesday\": \"Mardi\", \"Wednesday\": \"Mercredi\",
  4280.           \"Thursday\": \"Jeudi\", \"Friday\": \"Vendredi\", \"Saturday\": \"Samedi\",
  4281.           \"Sunday\": \"Dimanche\",
  4282.           \"January\": \"Janvier\", \"February\": \"Février\", \"March\": \"Mars\",
  4283.           \"April\": \"Avril\", \"May\": \"Mai\", \"June\": \"Juin\",
  4284.           \"July\": \"Juillet\", \"August\": \"Août\", \"September\": \"Septembre\",
  4285.           \"October\": \"Octobre\", \"November\": \"Novembre\", \"December\": \"Décembre\"
  4286.       }) }}
  4287.     </div>
  4288.   <!-- Filtres Médias -->
  4289. <div class=\"filter-icons\" style=\"display: flex; gap: 8px; flex-wrap: wrap;\">
  4290.     <span class=\"filter-badge active\" data-filter=\"all\" title=\"Afficher tout\">
  4291.         <i class=\"bi bi-grid-3x3-gap-fill\" style=\"margin-right: 5px; font-size: 14px;\"></i> Tout
  4292.     </span>
  4293.     {% if groupAttach.countPhotos > 0 %}
  4294.     <span class=\"filter-badge\" data-filter=\"photo\" title=\"Filtrer les photos\">
  4295.         <i class=\"bi bi-image\" style=\"margin-right: 5px; font-size: 14px;\"></i> {{ groupAttach.countPhotos }}
  4296.     </span>
  4297.     {% endif %}
  4298.     {% if groupAttach.countVideos > 0 %}
  4299.     <span class=\"filter-badge\" data-filter=\"video\" title=\"Filtrer les vidéos\">
  4300.         <i class=\"bi bi-camera-video-fill\" style=\"margin-right: 5px; font-size: 14px;\"></i> {{ groupAttach.countVideos }}
  4301.     </span>
  4302.     {% endif %}
  4303.     {% if groupAttach.countAudio > 0 %}
  4304.     <span class=\"filter-badge\" data-filter=\"audio\" title=\"Filtrer les messages audio\">
  4305.         <i class=\"bi bi-mic-fill\" style=\"margin-right: 5px; font-size: 14px;\"></i> {{ groupAttach.countAudio }}
  4306.     </span>
  4307.     {% endif %}
  4308. </div>
  4309.   </div>
  4310.   <!-- Bouton Jour Suivant -->
  4311.   {% if not loop.last %}
  4312.   <button class=\"btn-next-day\" data-target=\"{{ loop.index0 + 1 }}\" style=\"
  4313.       background-color: #3BA39B;
  4314.       border: none;
  4315.       padding: 5px 10px;
  4316.       border-radius: 8px;
  4317.       font-weight: bold;
  4318.       font-size: 14px;
  4319.       height: 36px;
  4320.       display: flex;
  4321.       align-items: center;
  4322.       color: white;
  4323.       cursor: pointer;
  4324.       transition: all 0.3s ease;
  4325.   \">
  4326.     <i class=\"bi bi-chevron-right\" style=\"font-size: 18px;\"></i>
  4327.   </button>
  4328.   {% else %}
  4329.   <div style=\"width: 36px;\"></div>
  4330.   {% endif %}
  4331.    
  4332.    
  4333.         </div>
  4334.         <!-- Contenu -->
  4335.         <div class=\"entry-content\" id=\"TourContent\">
  4336.       
  4337.           <p class=\"description\" style=\"margin-left:2%;width:95%;margin-top:1%;margin-bottom:1%;text-align:left\">
  4338.             {% for description in sejour.jourdescripdate %} {% if
  4339.             description.datejourphoto|date(\"m/d/Y\") == x|date(\"m/d/Y\") %}
  4340.             {{ description.description | nl2br }}
  4341.             {% endif %} {% endfor %}
  4342.           </p>
  4343.  
  4344.           <!-- Conteneur des photos et vidéos -->
  4345.           <div
  4346.             class=\"rowimag no-margin\"
  4347.             style=\"
  4348.               width: 100%;
  4349.               display: flex;
  4350.               flex-wrap: wrap;
  4351.               margin: 0;
  4352.               box-sizing: border-box;
  4353.             \"
  4354.           >
  4355.             <!-- Afficher les Photos et Vidéos -->
  4356.             {% for attach in groupAttach.attachments %}
  4357.               {% if attach.libiller == 'photo' %}
  4358.            
  4359.             <div class=\"column\" data-type=\"{{ attach.libiller }}\">
  4360.             
  4361.               <div class=\"photo-zoom photo-item\">
  4362.          
  4363.                 <a href=\"{{ attach.path }}\">
  4364.                   <img src=\"{{ attach.path }}\" alt=\"{{ attach.descreption }}\" />
  4365.                 </a>
  4366.                 <!-- Icône du cœur avec logique existante -->
  4367.                 <div
  4368.                   class=\"heart-icon\"
  4369.                   id=\"coeur{{ attach.id_attchment }}\"
  4370.                   data-id=\"{{ attach.id_attchment }}\"
  4371.                   data-sejour-id=\"{{ sejour.id }}\"
  4372.                   data-path=\"{{ attach.path }}\"
  4373.                   data-description=\"{{ attach.descreption }}\"
  4374.                 >
  4375.                   {% if app.user %} {% if attach.is_favorite %}
  4376.                   <i
  4377.                     class=\"bi bi-heart-fill\"
  4378.                     title=\"Sélectionnée\"
  4379.                     style=\"color: #f56040\"
  4380.                   ></i>
  4381.                   {% else %}
  4382.                   <i class=\"bi bi-heart\" title=\"Ajouter à ma sélection\"></i>
  4383.                   {% endif %} {% endif %}
  4384.                 </div>
  4385.                 <div class=\"photo-actions\" style=\"display: none\">
  4386.                   <button class=\"menu-btn\">⋮</button>
  4387.                   <div class=\"menu-options\">
  4388.                     <button onclick=\"addToPack('tirage')\">
  4389.                       🖨️ Ajouter au tirage
  4390.                     </button>
  4391.                     <button onclick=\"addToPack('numerique')\">
  4392.                       💾 Ajouter au numérique
  4393.                     </button>
  4394.                   </div>
  4395.                 </div>
  4396.               
  4397.               </div>
  4398.               {% if attach.descreption != \"\" %}
  4399.               <h4 class=\"description\">{{ attach.descreption }}</h4>
  4400.               {% endif %}
  4401.             </div>
  4402.             {% endif %} 
  4403.              {% if attach.libiller == 'video' %}
  4404.            
  4405.             <div class=\"column\" data-type=\"{{ attach.libiller }}\">
  4406.                  
  4407.             
  4408.                  <div class=\"video-container\" style=\"position: relative; display: inline-block; width: 100%; border-radius: 8px; overflow: hidden;\">
  4409.                         <video class=\"photo-zoom\" controls controlslist=\"nodownload noplaybackrate\" style=\"width: 100%;\">
  4410.                           <source src=\"{{ attach.path }}\" type=\"video/mp4\" />
  4411.                           Votre navigateur ne supporte pas la lecture vidéo.
  4412.                         </video>
  4413.                       
  4414.                       </div>
  4415.               {% if attach.descreption != \"\" %}
  4416.               <h4 class=\"description\">{{ attach.descreption }}</h4>
  4417.               {% endif %}
  4418.             </div>
  4419.             {% endif %} 
  4420.             
  4421.             {% endfor %}
  4422.           </div>
  4423.           <!-- Section séparée pour les messages audio -->
  4424.           {% if groupAttach.countAudio > 0 %}
  4425.           <div class=\"audio-messages-section\" style=\"margin-top:15px; border-top: 1px solid #eee; padding: 30px;\">
  4426.             <h4 style=\"margin-bottom: 15px; color: #555\">
  4427.               <i class=\"bi bi-mic-fill\" style=\"margin-right: 8px; color: #ffa500\"></i>
  4428.               Messages vocaux ({{ groupAttach.countAudio }})
  4429.             </h4>
  4430.             
  4431.             {% if sejour.codeSejour|slice(0, 2) == 'PF' %}
  4432.               {# Les séjours commençant par PF ont toujours accès #}
  4433.               <div class=\"audio-messages-container\" style=\"display: flex; flex-wrap: wrap; gap: 15px\">
  4434.                 {% for attach in groupAttach.attachments %}
  4435.                   {% if attach.libiller == 'message' %}
  4436.                     <div class=\"audio-message-item\" style=\"background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;\">
  4437.                       <div class=\"audio-player-container\" style=\"display: flex; align-items: center; margin-bottom: 10px;\">
  4438.                         <i class=\"bi bi-mic-fill\" style=\"font-size: 20px; margin-right: 10px; color: #ffa500\"></i>
  4439.                         <audio controls controlslist=\"nodownload noplaybackrate\" style=\"flex: 1\">
  4440.                           <source src=\"{{ attach.path }}\" type=\"audio/mp3\" />
  4441.                           Votre navigateur ne supporte pas la lecture audio.
  4442.                         </audio>
  4443.                       </div>
  4444.                       {% if attach.descreption != \"\" %}
  4445.                         <div class=\"audio-description\" style=\"padding-left: 30px\">
  4446.                           <p style=\"margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;\">
  4447.                             {{ attach.descreption }}
  4448.                           </p>
  4449.                         </div>
  4450.                       {% endif %}
  4451.                     </div>
  4452.                   {% endif %}
  4453.                 {% endfor %}
  4454.               </div>
  4455.             
  4456.             {% elseif sejour.codeSejour|slice(0, 2) == 'PP' and parentsejour.payment  == 1 or sejour.codeSejour|slice(0, 2) == 'EF' and parentsejour.payment  == 1 %}
  4457.               {# PP ou EF avec paiement effectué #}
  4458.               <div class=\"audio-messages-container\" style=\"display: flex; flex-wrap: wrap; gap: 15px\">
  4459.                 {% for attach in groupAttach.attachments %}
  4460.                   {% if attach.libiller == 'message' %}
  4461.                     <div class=\"audio-message-item\" style=\"background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;\">
  4462.                       <div class=\"audio-player-container\" style=\"display: flex; align-items: center; margin-bottom: 10px;\">
  4463.                         <i class=\"bi bi-mic-fill\" style=\"font-size: 20px; margin-right: 10px; color: #ffa500\"></i>
  4464.                         <audio controls controlslist=\"nodownload noplaybackrate\" style=\"flex: 1\">
  4465.                           <source src=\"{{ attach.path }}\" type=\"audio/mp3\" />
  4466.                           Votre navigateur ne supporte pas la lecture audio.
  4467.                         </audio>
  4468.                       </div>
  4469.                       {% if attach.descreption != \"\" %}
  4470.                         <div class=\"audio-description\" style=\"padding-left: 30px\">
  4471.                           <p style=\"margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;\">
  4472.                             {{ attach.descreption }}
  4473.                           </p>
  4474.                         </div>
  4475.                       {% endif %}
  4476.                     </div>
  4477.                   {% endif %}
  4478.                 {% endfor %}
  4479.               </div>
  4480.             
  4481.             {% elseif sejour.codeSejour|slice(0, 2) == 'PP' and parentsejour.payment == 0 or sejour.codeSejour|slice(0, 2) == 'EF' and parentsejour.payment == 0 %}
  4482.               {# PP ou EF sans paiement - message d'accès limité et audio désactivés #}
  4483.               <div class=\"audio-messages-container\" style=\"display: flex; flex-wrap: wrap; gap: 15px; opacity: 0.5; pointer-events: none; filter: grayscale(100%);\">
  4484.                 <div class=\"audio-messages-restricted\" style=\"padding: 20px; background: #f0f0f0; border-radius: 8px; text-align: center; margin-bottom: 15px; width: 100%;\">
  4485.                   <i class=\"bi bi-lock-fill\" style=\"font-size: 24px; color: #808080; margin-bottom: 10px;\"></i>
  4486.                   <p style=\"margin: 0; color: #555;\">📢 Les messages vocaux sont disponibles via la boîte vocale premium. Un paiement est requis pour l’activer et y accéder.</p>
  4487.                 </div>
  4488.                 {% for attach in groupAttach.attachments %}
  4489.                   {% if attach.libiller == 'message' %}
  4490.                     <div class=\"audio-message-item\" style=\"background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;\">
  4491.                       <div class=\"audio-player-container\" style=\"display: flex; align-items: center; margin-bottom: 10px;\">
  4492.                         <i class=\"bi bi-mic-fill\" style=\"font-size: 20px; margin-right: 10px; color: #ffa500\"></i>
  4493.                         <audio controls controlslist=\"nodownload noplaybackrate\" style=\"flex: 1\" disabled>
  4494.                           <source src=\"{{ attach.path }}\" type=\"audio/mp3\" />
  4495.                           Votre navigateur ne supporte pas la lecture audio.
  4496.                         </audio>
  4497.                       </div>
  4498.                       {% if attach.descreption != \"\" %}
  4499.                         <div class=\"audio-description\" style=\"padding-left: 30px\">
  4500.                           <p style=\"margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;\">
  4501.                             {{ attach.descreption }}
  4502.                           </p>
  4503.                         </div>
  4504.                       {% endif %}
  4505.                     </div>
  4506.                   {% endif %}
  4507.                 {% endfor %}
  4508.               </div>
  4509.             {% endif %}
  4510.           </div>
  4511.         {% endif %}
  4512.         </div>
  4513.       </div>
  4514.     </div>
  4515.     {% endif %}
  4516.     {% endfor %}
  4517.     {% if not hasAttachments %}
  4518.     <div class=\"welcome-message\" style=\"padding: 50px 20px; text-align: center; background: #f9f9f9; border-radius: 15px; margin: 30px auto; max-width: 800px; box-shadow: 0 5px 15px rgba(0,0,0,0.05);\">
  4519.       <img src=\"/images/welcome-icon.svg\" alt=\"Bienvenue\" style=\"width: 80px; margin-bottom: 20px;\" onerror=\"this.src='/images/Accompagnateur/Picto5sur5.svg'; this.style.width='120px';\">
  4520.       
  4521.       <h2 style=\"color: #41a2aa; margin-bottom: 20px; font-size: 24px;\">Bienvenue sur votre espace séjour !</h2>
  4522.       
  4523.       <p style=\"font-size: 18px; color: #555; margin-bottom: 15px;\">
  4524.         Aucun contenu n'a encore été partagé pour ce séjour.
  4525.       </p>
  4526.       
  4527.       <p style=\"font-size: 16px; color: #666; margin-bottom: 25px;\">
  4528.         L'accompagnateur partagera bientôt des photos, vidéos et messages vocaux.
  4529.         <br>Revenez consulter cette page régulièrement pour suivre les aventures du séjour !
  4530.       </p>
  4531.       
  4532.       <div style=\"display: flex; justify-content: center; gap: 15px; flex-wrap: wrap;\">
  4533.         <div style=\"display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);\">
  4534.           <i class=\"bi bi-images\" style=\"font-size: 24px; color: #f56040; margin-right: 10px;\"></i>
  4535.           <span>Photos du séjour</span>
  4536.         </div>
  4537.         
  4538.         <div style=\"display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);\">
  4539.           <i class=\"bi bi-camera-video-fill\" style=\"font-size: 24px; color: #41a2aa; margin-right: 10px;\"></i>
  4540.           <span>Vidéos des activités</span>
  4541.         </div>
  4542.         
  4543.         <div style=\"display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);\">
  4544.           <i class=\"bi bi-mic-fill\" style=\"font-size: 24px; color: #ffa500; margin-right: 10px;\"></i>
  4545.           <span>Messages vocaux</span>
  4546.         </div>
  4547.       </div>
  4548.     </div>
  4549.     
  4550.     <!-- Espace supplémentaire pour déplacer le footer vers le bas -->
  4551.     <div style=\"height: 300px;\"></div>
  4552.     {% endif %}
  4553.     
  4554.     <!-- Make sure we're showing the right content by default if no valid content is marked 'show' -->
  4555.     {% if lastValidIndex > 0 %}
  4556.     <script>
  4557.       document.addEventListener('DOMContentLoaded', function() {
  4558.         // Check if no content is showing
  4559.         if (document.querySelectorAll('.container--gallery .collapse.show').length === 0) {
  4560.           // Show the content for the last valid date
  4561.           var lastValidContent = document.getElementById('demP{{ lastValidIndex }}');
  4562.           if (lastValidContent) {
  4563.             lastValidContent.classList.add('show');
  4564.             
  4565.             // Also mark the corresponding date card as active
  4566.             var dateCards = document.querySelectorAll('.date-card');
  4567.             if (dateCards.length >= {{ lastValidIndex }}) {
  4568.               dateCards.forEach(card => card.classList.remove('active'));
  4569.               dateCards[{{ lastValidIndex - 1 }}].classList.add('active');
  4570.             }
  4571.           }
  4572.         }
  4573.       });
  4574.     </script>
  4575.     {% endif %}
  4576.   </div>
  4577. </div>
  4578.   {% endblock %} {% block Javascript %}
  4579.   {{ parent() }}
  4580.   <script>// Gestion de la sidebar des favoris
  4581. document.addEventListener('DOMContentLoaded', function() {
  4582.     const sidebar = document.getElementById('favorites-sidebar');
  4583.     const openBtn = document.getElementById('openFavoritesSidebar');
  4584.     const closeBtn = document.querySelector('.favorites-close');
  4585.     const favButton = document.querySelector('.fav-button');
  4586.     function openSidebar() {
  4587.         sidebar.classList.add('active');
  4588.         updateFavoritesSidebar();
  4589.     }
  4590.     function closeSidebar() {
  4591.         sidebar.classList.remove('active');
  4592.     }
  4593.     function updateFavoritesSidebar() {
  4594.         const grid = document.getElementById('favorites-grid');
  4595.         const counter = document.getElementById('favorites-counter');
  4596.         const emptyState = document.getElementById('favorites-empty-state');
  4597.         const progress = document.getElementById('favorites-progress');
  4598.         
  4599.         const count = parseInt(document.getElementById('likeCount').textContent);
  4600.         counter.textContent = count +1;
  4601.         
  4602.         if (count === 0) {
  4603.             emptyState.style.display = 'flex';
  4604.             grid.style.display = 'none';
  4605.         } else {
  4606.             emptyState.style.display = 'none';
  4607.             grid.style.display = 'grid';
  4608.             const percentage = (count / 20) * 100;
  4609.             progress.style.width = `\${percentage}%`;
  4610.         }
  4611.     }
  4612.     if (openBtn) {
  4613.         openBtn.addEventListener('click', openSidebar);
  4614.     }
  4615.     if (favButton) {
  4616.         favButton.addEventListener('click', openSidebar);
  4617.     }
  4618.     if (closeBtn) {
  4619.         closeBtn.addEventListener('click', closeSidebar);
  4620.     }
  4621.     document.addEventListener('click', (e) => {
  4622.         if (sidebar.classList.contains('active') && 
  4623.             !sidebar.contains(e.target) && 
  4624.             !favButton.contains(e.target) && 
  4625.             !openBtn.contains(e.target)) {
  4626.             closeSidebar();
  4627.         }
  4628.     });
  4629. });
  4630. // Modification des fonctions existantes
  4631. const originalAddFavoris = window.AddFavoris;
  4632. window.AddFavoris = function(\$id, \$idSejour, \$urlimg, \$description) {
  4633.     if (originalAddFavoris) {
  4634.         originalAddFavoris(\$id, \$idSejour, \$urlimg, \$description);
  4635.     }
  4636.     
  4637.     // Vérifier si la sidebar est ouverte - noter que nous vérifions la valeur CSS right: 0
  4638.     if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  4639.         // Recharger les favoris
  4640.         loadFavorites();
  4641.     }
  4642. };
  4643. const originalSupprimerFavoris = window.supprimerFavoris;
  4644. window.supprimerFavoris = function(\$id, \$idSejour) {
  4645.     if (originalSupprimerFavoris) {
  4646.         originalSupprimerFavoris(\$id, \$idSejour);
  4647.     }
  4648.     
  4649.     // Vérifier si la sidebar est ouverte
  4650.     if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  4651.         // Recharger les favoris
  4652.         loadFavorites();
  4653.     }
  4654. };
  4655. // Variables globales
  4656. let selectedFavorites = [];
  4657. let allFavorites = [];
  4658. // Fonction pour mettre à jour la sidebar
  4659. function loadFavorites() {
  4660.     \$(\"#favorites-grid\").html(\"<div style='text-align:center;padding:20px;'>Chargement...</div>\");
  4661.     
  4662.     \$.ajax({
  4663.         url: \"/Parent/mes-favoris\",
  4664.         type: \"GET\",
  4665.         dataType: \"json\",
  4666.         success: function(data) {
  4667.             \$(\"#favorites-grid\").empty();
  4668.             allFavorites = data.data || [];
  4669.             
  4670.             if (allFavorites.length > 0) {
  4671.                 \$(\"#favorites-empty-state\").hide();
  4672.                 
  4673.                 \$.each(allFavorites, function(i, fav) {
  4674.                     var isSelected = selectedFavorites.includes(fav.id);
  4675.                     
  4676.                     var item = \$(\"<div class='favorite-item' style='position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1;cursor:pointer;'></div>\");
  4677.                     var img = \$(\"<img style='width:100%;height:100%;object-fit:cover;transition:transform 0.3s ease;'>\").attr(\"src\", fav.path).attr(\"alt\", fav.descreption || \"Photo favorite\");
  4678.                     
  4679.                     // Overlay de sélection
  4680.                     var selectionOverlay = \$(\"<div class='selection-overlay' style='position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.3);display:flex;align-items:center;justify-content:center;'></div>\");
  4681.                     
  4682.                     // Icône de sélection
  4683.                     var checkIcon = \$(\"<div style='width:25px;height:25px;border-radius:50%;border:2px solid white;display:flex;align-items:center;justify-content:center;background:\" + (isSelected ? \"#F56040\" : \"transparent\") + \";transition:background 0.2s;'></div>\");
  4684.                     if (isSelected) {
  4685.                         checkIcon.append(\"<i class='bi bi-check' style='color:white;font-size:16px;'></i>\");
  4686.                     }
  4687.                     
  4688.                     selectionOverlay.append(checkIcon);
  4689.                     
  4690.                     // Overlay d'action (bouton supprimer)
  4691.                     var actionOverlay = \$(\"<div class='action-overlay' style='position:absolute;top:5px;right:5px;opacity:0;transition:opacity 0.2s;'></div>\");
  4692.                   
  4693.                     actionOverlay.append(deleteBtn);
  4694.                     
  4695.                     // Ajouter les événements
  4696.                     item.hover(
  4697.                         function() { \$(this).find(\".action-overlay\").css(\"opacity\", \"1\"); },
  4698.                         function() { \$(this).find(\".action-overlay\").css(\"opacity\", \"0\"); }
  4699.                     );
  4700.                     
  4701.                     item.click(function() {
  4702.                         toggleSelection(fav.id, \$(this).find(\".selection-overlay > div\"));
  4703.                     });
  4704.                     
  4705.                     item.append(img).append(selectionOverlay).append(actionOverlay);
  4706.                     \$(\"#favorites-grid\").append(item);
  4707.                 });
  4708.                 
  4709.                 \$(\"#favorites-counter\").text(allFavorites.length);
  4710.                 
  4711.                 // Mettre à jour le compteur sur le bouton également
  4712.                 \$(\"#openFavoritesSidebar span\").text(allFavorites.length);
  4713.                 
  4714.                 // Mettre à jour l'interface produits
  4715.                 updateProductsView();
  4716.                 
  4717.             } else {
  4718.                 \$(\"#favorites-empty-state\").show();
  4719.                 \$(\"#favorites-counter\").text(\"0\");
  4720.                 \$(\"#openFavoritesSidebar span\").text(\"0\");
  4721.                 \$(\"#selection-count\").text(\"0\");
  4722.                 updateProductsView();
  4723.             }
  4724.         },
  4725.         error: function() {
  4726.             \$(\"#favorites-grid\").html(\"<div style='color:red;text-align:center;padding:20px;'>Erreur de chargement</div>\");
  4727.         }
  4728.     });
  4729. }
  4730. // Fonction pour supprimer un favori
  4731. function removeFavorite(id) {
  4732.     \$.ajax({
  4733.         url: \"/Parent/remove-favorite/\" + id,
  4734.         type: \"POST\",
  4735.         success: function() {
  4736.             // Retirer de la sélection si présent
  4737.             selectedFavorites = selectedFavorites.filter(favId => favId != id);
  4738.             
  4739.             // Mettre à jour le compteur de sélection
  4740.             \$(\"#selection-count\").text(selectedFavorites.length);
  4741.             
  4742.             // Recharger les favoris
  4743.             loadFavorites();
  4744.             
  4745.             // Mettre à jour les compteurs globaux
  4746.             var count = parseInt(\$(\"#likeCount\").text());
  4747.             if (!isNaN(count)) {
  4748.                 \$(\"#likeCount\").text(count - 1);
  4749.             }
  4750.             
  4751.             var countFav = parseInt(\$(\"#mesFavCount\").text());
  4752.             if (!isNaN(countFav)) {
  4753.                 \$(\"#mesFavCount\").text(countFav - 1);
  4754.             }
  4755.             
  4756.             // Mettre à jour l'interface produits
  4757.             updateProductsView();
  4758.         },
  4759.         error: function() {
  4760.             alert(\"Erreur lors de la suppression du favori\");
  4761.         }
  4762.     });
  4763. }
  4764. // Fonction pour basculer la sélection d'une photo
  4765. function toggleSelection(id, checkElement) {
  4766.     const index = selectedFavorites.indexOf(id);
  4767.     
  4768.     if (index === -1) {
  4769.         // Ajouter à la sélection
  4770.         selectedFavorites.push(id);
  4771.         checkElement.css(\"background\", \"#F56040\");
  4772.         checkElement.html(\"<i class='bi bi-check' style='color:white;font-size:16px;'></i>\");
  4773.     } else {
  4774.         // Retirer de la sélection
  4775.         selectedFavorites.splice(index, 1);
  4776.         checkElement.css(\"background\", \"transparent\");
  4777.         checkElement.html(\"\");
  4778.     }
  4779.     
  4780.     // Mettre à jour le compteur
  4781.     \$(\"#selection-count\").text(selectedFavorites.length);
  4782.     
  4783.     // Mettre à jour l'interface produits
  4784.     updateProductsView();
  4785. }
  4786. // Fonction pour mettre à jour la vue des produits
  4787. function updateProductsView() {
  4788.     const current = selectedFavorites.length;
  4789.     \$(\"#product-photo-count\").text(current);
  4790.     
  4791.     let remainingForAlbum = Math.max(0, 20 - current);
  4792.     let remainingForPochette = Math.max(0, 12 - current);
  4793.     let remainingForPack = Math.max(0, 12 - current);
  4794.     const progressBar = (count, total, color) => `
  4795.         <div style=\"margin: 5px 0;\">
  4796.             <div style=\"background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;\">
  4797.                 <div style=\"width: \${(count / total) * 100}%; background-color: \${color}; height: 100%;\"></div>
  4798.             </div>
  4799.             <small style=\"font-size: 12px;\">\${count}/\${total} photos</small>
  4800.         </div>
  4801.     `;
  4802.     // Liste des produits
  4803.     const products = [
  4804.         {
  4805.             name: \"Pack numérique (20 photos)\",
  4806.             required: 20,
  4807.             remaining: Math.max(0, 20 - current),
  4808.             image: \"/images/produit/photoNumerique.jpg\",
  4809.             color: \"#4caf50\",
  4810.             link: \"{{ path('PackPhotosNumerique_Favoris', {'nbr':20}) }}\",
  4811.         },
  4812.        +
  4813.         {
  4814.             name: \"Pochette photo (12 photos)\",
  4815.             required: 12,
  4816.             remaining: Math.max(0, 12 - current),
  4817.             image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  4818.             color: \"#2196f3\",
  4819.             link: \"{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}\",
  4820.         },
  4821.     ].sort((a, b) => a.remaining - b.remaining);
  4822.     const productList = products
  4823.         .map((product) => {
  4824.             const count = current;
  4825.             const total = product.required;
  4826.             const remaining = product.remaining;
  4827.             return `
  4828.                 <li style=\"margin-bottom: 20px;\">
  4829.                     <div style=\"display: flex; align-items: center; gap: 10px;\">
  4830.                         <img src=\"\${product.image}\" alt=\"\${product.name}\" style=\"width: 70px; height: 70px; border-radius: 5px; object-fit: cover;\" />
  4831.                         <div style=\"flex: 1;\">
  4832.                             <strong style=\"font-size: 14px;\">\${product.name}</strong>
  4833.                             \${progressBar(count, total, product.color)}
  4834.                             \${
  4835.                                 `<small style=\"color: \${product.color}; font-size: 12px;\">
  4836.                                     Encore \${remaining} photos pour compléter \${product.name.toLowerCase()}
  4837.                                 </small>
  4838.                                 <button
  4839.                                     style=\"
  4840.                                         margin-top: 5px;
  4841.                                         padding: 6px 12px;
  4842.                                         background-color: \${product.color};
  4843.                                         color: white;
  4844.                                         border: none;
  4845.                                         border-radius: 5px;
  4846.                                         font-size: 13px;
  4847.                                         cursor: pointer;
  4848.                                     \"
  4849.                                     onclick=\"window.location.href='\${product.link}'\"
  4850.                                 >
  4851.                                     Commander
  4852.                                 </button>`
  4853.                             }
  4854.                         </div>
  4855.                     </div>
  4856.                 </li>
  4857.             `;
  4858.         })
  4859.         .join(\"\");
  4860.     const boutiqueButton = `
  4861.         <li style=\"margin-top: 25px; text-align: center;\">
  4862.             <button
  4863.                 style=\"
  4864.                     padding: 8px 15px;
  4865.                     background-color: #F56040;
  4866.                     color: white;
  4867.                     border: none;
  4868.                     border-radius: 5px;
  4869.                     font-size: 14px;
  4870.                     width: 170px;
  4871.                     height: 40px;
  4872.                     cursor: pointer;
  4873.                 \"
  4874.                 onclick=\"window.location.href='{{ path('boutique5sur5') }}'\"
  4875.             >
  4876.                 Voir toute la boutique
  4877.             </button>
  4878.         </li>
  4879.     `;
  4880.     \$(\"#product-list\").html(productList + boutiqueButton);
  4881. }
  4882. // Modifications au script existant
  4883. \$(document).ready(function() {
  4884.     // Fonctions pour ouvrir/fermer la sidebar
  4885.     \$(\"#openFavoritesSidebar\").click(function() {
  4886.         \$(\"#favorites-sidebar\").css(\"right\", \"0\");
  4887.         loadFavorites();
  4888.     });
  4889.     
  4890.     \$(\"#close-favorites-btn\").click(function() {
  4891.         closeFavoritesSidebar();
  4892.     });
  4893.     
  4894.     // Fonction pour fermer la sidebar
  4895.     window.closeFavoritesSidebar = function() {
  4896.         \$(\"#favorites-sidebar\").css(\"right\", \"-500px\");
  4897.     };
  4898.     
  4899.     // Tout sélectionner / Tout désélectionner
  4900.     \$(\"#select-all-btn\").click(function() {
  4901.         if (selectedFavorites.length === allFavorites.length) {
  4902.             // Tout désélectionner
  4903.             selectedFavorites = [];
  4904.             \$(\".selection-overlay > div\").css(\"background\", \"transparent\").html(\"\");
  4905.             \$(this).text(\"Tout sélectionner\");
  4906.         } else {
  4907.             // Tout sélectionner
  4908.             selectedFavorites = allFavorites.map(fav => fav.id);
  4909.             \$(\".selection-overlay > div\").css(\"background\", \"#F56040\").html(\"<i class='bi bi-check' style='color:white;font-size:16px;'></i>\");
  4910.             \$(this).text(\"Tout désélectionner\");
  4911.         }
  4912.         
  4913.         // Mettre à jour le compteur
  4914.         \$(\"#selection-count\").text(selectedFavorites.length);
  4915.         
  4916.         // Mettre à jour l'interface produits
  4917.         updateProductsView();
  4918.     });
  4919.     
  4920.     // Gestion des onglets
  4921.     \$(\".sidebar-tab\").click(function() {
  4922.         \$(\".sidebar-tab\").removeClass(\"active\").css({
  4923.             \"color\": \"#666\",
  4924.             \"border-bottom\": \"none\"
  4925.         });
  4926.         \$(this).addClass(\"active\").css({
  4927.             \"color\": \"#F56040\",
  4928.             \"border-bottom\": \"2px solid #F56040\"
  4929.         });
  4930.         
  4931.         const tabId = \$(this).attr(\"id\");
  4932.         \$(\".tab-content\").hide();
  4933.         
  4934.         if (tabId === \"tab-photos\") {
  4935.             \$(\"#photos-content\").show();
  4936.         } else if (tabId === \"tab-products\") {
  4937.             \$(\"#products-content\").show();
  4938.         }
  4939.     });
  4940.     
  4941.     // Modifier les fonctions existantes pour intercepter l'ajout/suppression de favoris
  4942.     const originalAddFavoris = window.AddFavoris;
  4943.     window.AddFavoris = function(\$id, \$idSejour, \$urlimg, \$description) {
  4944.         if (originalAddFavoris) {
  4945.             originalAddFavoris(\$id, \$idSejour, \$urlimg, \$description);
  4946.         }
  4947.         
  4948.         // Recharger les favoris si la sidebar est ouverte
  4949.         if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  4950.             loadFavorites();
  4951.         }
  4952.     };
  4953.     const originalSupprimerFavoris = window.supprimerFavoris;
  4954.     window.supprimerFavoris = function(\$id, \$idSejour) {
  4955.         if (originalSupprimerFavoris) {
  4956.             originalSupprimerFavoris(\$id, \$idSejour);
  4957.         }
  4958.         
  4959.         // Recharger les favoris si la sidebar est ouverte
  4960.         if (\$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  4961.             // Retirer de la sélection si présent
  4962.             selectedFavorites = selectedFavorites.filter(favId => favId != \$id);
  4963.             loadFavorites();
  4964.         }
  4965.     };
  4966.     
  4967.     // Fermer en cliquant en dehors
  4968.     \$(document).click(function(event) {
  4969.         if (!\$(event.target).closest(\"#favorites-sidebar\").length && 
  4970.             !\$(event.target).closest(\"#openFavoritesSidebar\").length && 
  4971.             \$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  4972.             closeFavoritesSidebar();
  4973.         }
  4974.     });
  4975. });
  4976. // Initialisation de la sidebar
  4977. \$(document).ready(function() {
  4978.     // Fonctions pour ouvrir/fermer la sidebar
  4979.     \$(\"#openFavoritesSidebar\").click(function() {
  4980.         \$(\"#favorites-sidebar\").css(\"right\", \"0\");
  4981.         loadFavorites();
  4982.     });
  4983.     
  4984.     \$(\"#close-favorites-btn\").click(function() {
  4985.         \$(\"#favorites-sidebar\").css(\"right\", \"-500px\");
  4986.     });
  4987.     
  4988.     // Fermer en cliquant en dehors
  4989.     \$(document).click(function(event) {
  4990.         if (!\$(event.target).closest(\"#favorites-sidebar\").length && 
  4991.             !\$(event.target).closest(\"#openFavoritesSidebar\").length && 
  4992.             \$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  4993.             \$(\"#favorites-sidebar\").css(\"right\", \"-500px\");
  4994.         }
  4995.     });
  4996. });
  4997.   </script>
  4998.   <script src=\"{{ asset('js/splide.min.js') }}\"></script>
  4999.    
  5000. <script>
  5001.   document.addEventListener('DOMContentLoaded', function () {
  5002.     const openBtn = document.getElementById('openFavoritesSidebar');
  5003.     const sidebar = document.getElementById('favorites-sidebar');
  5004.     const closeBtn = document.getElementById('favorites-close');
  5005.     if (openBtn && sidebar) {
  5006.       openBtn.addEventListener('click', () => sidebar.classList.add('active'));
  5007.     }
  5008.     if (closeBtn && sidebar) {
  5009.       closeBtn.addEventListener('click', () => sidebar.classList.remove('active'));
  5010.     }
  5011.   });
  5012. </script>
  5013.  
  5014. <script>
  5015. document.addEventListener('DOMContentLoaded', function() {
  5016.   const filterBadges = document.querySelectorAll('.filter-badge');
  5017.   filterBadges.forEach(badge => {
  5018.     badge.addEventListener('click', function() {
  5019.       // Désactiver tous les badges
  5020.       filterBadges.forEach(b => b.classList.remove('active'));
  5021.       // Activer le badge cliqué
  5022.       this.classList.add('active');
  5023.     });
  5024.   });
  5025. });
  5026. </script>
  5027.   <script
  5028.     type=\"text/javascript\"
  5029.     src=\"{{ asset('Accueil/js/jquery.magnific-popup.min.js') }}\"
  5030.   ></script>
  5031.   <script>
  5032. document.addEventListener('DOMContentLoaded', function () {
  5033.   const prevButtons = document.querySelectorAll('.btn-prev-day');
  5034.   const nextButtons = document.querySelectorAll('.btn-next-day');
  5035.   const dateCards = document.querySelectorAll('.date-card.modern-card');
  5036.   const collapseSections = document.querySelectorAll('.collapse');
  5037.   function navigateToDay(index) {
  5038.     if (index >= 0 && index < collapseSections.length) {
  5039.       // Fermer tous les jours
  5040.       collapseSections.forEach(s => s.classList.remove('show'));
  5041.       dateCards.forEach(c => c.classList.remove('active'));
  5042.       // Ouvrir le bon jour
  5043.       const targetCollapse = collapseSections[index];
  5044.       const targetCard = dateCards[index];
  5045.       if (targetCollapse && targetCard) {
  5046.         targetCollapse.classList.add('show');
  5047.         targetCard.classList.add('active');
  5048.       }
  5049.     }
  5050.   }
  5051.   prevButtons.forEach(button => {
  5052.     button.addEventListener('click', function () {
  5053.       const targetIndex = parseInt(this.dataset.target, 10);
  5054.       navigateToDay(targetIndex);
  5055.     });
  5056.   });
  5057.   nextButtons.forEach(button => {
  5058.     button.addEventListener('click', function () {
  5059.       const targetIndex = parseInt(this.dataset.target, 10);
  5060.       navigateToDay(targetIndex);
  5061.     });
  5062.   });
  5063. });
  5064. </script>
  5065.   <script>
  5066.     document.addEventListener('DOMContentLoaded', function() {
  5067.   const style = document.createElement('style');
  5068.   style.textContent = `
  5069.     .hidden {
  5070.       display: none !important;
  5071.     }
  5072.   `;
  5073.   document.head.appendChild(style);
  5074. });
  5075.     document.addEventListener('DOMContentLoaded', function() {
  5076.     // Get the favorite button
  5077.     const favoriteButton = document.querySelector('.fav-button');
  5078.     if (favoriteButton) {
  5079.       // Make it unclickable with JS too (belt and suspenders approach)
  5080.       favoriteButton.style.pointerEvents = 'none';
  5081.       
  5082.       // Override any existing click handlers
  5083.       favoriteButton.onclick = function(e) {
  5084.         e.preventDefault();
  5085.         e.stopPropagation();
  5086.         return false;
  5087.       };
  5088.       
  5089.       // Make sure hover still works
  5090.       favoriteButton.addEventListener('mouseover', function() {
  5091.         document.getElementById('purchase-alert').style.display = 'block';
  5092.       });
  5093.       
  5094.       // Keep any existing hover functionality
  5095.       if (typeof showSelection === 'function') {
  5096.         favoriteButton.onmouseover = showSelection;
  5097.       }
  5098.     }
  5099.     
  5100.     // Make sure the purchase alert remains interactive
  5101.     const purchaseAlert = document.getElementById('purchase-alert');
  5102.     if (purchaseAlert) {
  5103.       purchaseAlert.style.pointerEvents = 'auto';
  5104.     }
  5105.   });
  5106.     // Sélection des éléments
  5107.     const purchaseAlert = document.getElementById(\"purchase-alert\");
  5108.     const alertContent = document.getElementById(\"purchase-alert-content\");
  5109.     const likeCountLabel = document.getElementById(\"likeCount\");
  5110.     const favoriteCount = parseInt(likeCountLabel.textContent.trim(), 10); // Convertir en nombre
  5111.     // Fonction pour mettre à jour le contenu de l'alerte
  5112.     function updatePurchaseAlert(current) {
  5113.   let remainingForAlbum = Math.max(0, 20 - current);
  5114.   let remainingForPochette = Math.max(0, 12 - current);
  5115.   let remainingForPack = Math.max(0, 12 - current);
  5116.   const progressBar = (count, total, color) => `
  5117.   <div style=\"margin: 5px 0;\">
  5118.     <div style=\"background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;\">
  5119.       <div style=\"width: \${
  5120.         (count / total) * 100
  5121.       }%; background-color: \${color}; height: 100%;\"></div>
  5122.     </div>
  5123.     <small style=\"font-size: 12px;\">\${count}/\${total} photos</small>
  5124.   </div>
  5125. `;
  5126.   // Use Twig paths here:
  5127.   const products = [
  5128.       {
  5129.       name: \"Pochette photo (12 photos)\",
  5130.       required: 12,
  5131.       remaining: remainingForPochette,
  5132.       image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  5133.       color: \"#2196f3\",
  5134.       link: \"{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}\",
  5135.     },
  5136.        {
  5137.       name: \"Pack numérique (20 photos)\",
  5138.       required: 20,
  5139.       remaining: remainingForAlbum,
  5140.       image: \"/images/produit/photoNumerique.jpg\",
  5141.       color: \"#4caf50\",
  5142.       link: \"{{ path('PackPhotosNumerique_Favoris', {'nbr': 20}) }}\",
  5143.     }
  5144.   
  5145.   
  5146.     
  5147.   ].sort((a, b) => a.remaining - b.remaining);
  5148.   const productList = products
  5149.     .map((product) => {
  5150.       const count = current;
  5151.       const total = product.required;
  5152.       const remaining = product.remaining;
  5153.       return `
  5154.     <li style=\"margin-bottom: 15px;\">
  5155.       <div style=\"display: flex; align-items: center; gap: 10px;\">
  5156.         <img
  5157.           src=\"\${product.image}\"
  5158.           alt=\"\${product.name}\"
  5159.           style=\"width: 65px; height: 65px; border-radius: 5px; margin-top:-19px\"
  5160.         />
  5161.         <div style=\"flex: 1;\">
  5162.           <strong style=\"font-size: 14px;\">\${product.name}</strong>
  5163.           \${progressBar(count, total, product.color)}
  5164.           \${
  5165.             remaining > 0
  5166.               ? `<small style=\"color: \${product.color}; font-size: 12px;\">
  5167.                    Encore \${remaining} photos ❤️ pour compléter \${product.name.toLowerCase()}
  5168.                  </small>`
  5169.               : `<button
  5170.                   style=\"
  5171.                     margin-top: 5px;
  5172.                     padding: 5px 8px;
  5173.                     background-color: \${product.color};
  5174.                     color: white;
  5175.                     border: none;
  5176.                     border-radius: 5px;
  5177.                     font-size: 12px;
  5178.                     cursor: pointer;
  5179.                   \"
  5180.                   onclick=\"window.location.href='\${product.link}'\"
  5181.                 >
  5182.                   Commander
  5183.                 </button>`
  5184.           }
  5185.         </div>
  5186.       </div>
  5187.     </li>
  5188.   `;
  5189.     })
  5190.     .join(\"\");
  5191.   const plusButton = `
  5192.     <li style=\"margin-bottom: 15px; text-align: center;\">
  5193.       <button
  5194.         style=\"
  5195.           padding: 5px 8px;
  5196.           background-color: #F56040;
  5197.           color: white;
  5198.           border: none;
  5199.           border-radius: 5px;
  5200.           font-size: 14px;
  5201.           line-height: 1;
  5202.           width: 150px;
  5203.           height: 40px;
  5204.           cursor: pointer;
  5205.         \"
  5206.         onclick=\"window.location.href='{{ path('boutique5sur5') }}'\"
  5207.       >
  5208.         Aller à la boutique
  5209.       </button>
  5210.     </li>
  5211.   `;
  5212.   if (current === 0) {
  5213.     alertContent.innerHTML = `
  5214.     <p style=\"font-size: 16px; font-weight: bold; color: #333;\">
  5215.       Vous n'avez pas encore de photos favorites !
  5216.     </p>
  5217.     <p style=\"margin-bottom: 20px; color: #555;\">
  5218.       Commencez à ajouter vos moments préférés pour profiter de nos offres.
  5219.     </p>
  5220.     <ul style=\"list-style-type: none; padding: 0;\">\${productList}\${plusButton}</ul>
  5221.   `;
  5222.   } else {
  5223.     alertContent.innerHTML = `
  5224.     <p style=\"font-size: 16px; font-weight: bold; color: #333;\">
  5225.       Vous avez atteint \${current} photos favorites !
  5226.     </p>
  5227.     <p style=\"margin-bottom: 20px; color: #555;\">
  5228.       Profitez de nos offres spéciales :
  5229.     </p>
  5230.     <ul style=\"list-style-type: none; padding: 0;\">\${productList}\${plusButton}</ul>
  5231.   `;
  5232.   }
  5233.   purchaseAlert.classList.remove(\"hidden\");
  5234.   clearTimeout(purchaseAlertTimeout);
  5235.   purchaseAlertTimeout = setTimeout(() => {
  5236.     if (!purchaseAlert.matches(\":hover\")) {
  5237.       closePurchaseAlert();
  5238.     }
  5239.   }, 5000);
  5240. }
  5241.     // Fonction pour fermer l'alerte
  5242.     function closePurchaseAlert() {
  5243.       purchaseAlert.classList.add(\"hidden\");
  5244.     }
  5245.     // Événement pour mettre à jour le contenu et afficher la popover dynamiquement au hover
  5246.     document.querySelector(\".fav-button\").addEventListener(\"mouseover\", () => {
  5247.       updatePurchaseAlert(favoriteCount);
  5248.       purchaseAlert.classList.remove(\"cachee\"); // Réaffiche la popover
  5249.     });
  5250.     function showSelection() {
  5251.       document.getElementById(\"purchase-alert\").style.display = \"block\";
  5252.     }
  5253.     function hideSelection() {
  5254.       document.getElementById(\"selectionPopover\").style.display = \"none\";
  5255.     }
  5256.     document.addEventListener(\"DOMContentLoaded\", function () {
  5257.       const container = document.querySelector(\".date-container\");
  5258.       // Vérifie si le conteneur existe pour éviter les erreurs
  5259.       if (container) {
  5260.         container.scrollTo({
  5261.           left: container.scrollWidth, // Scroll directement à la position maximale
  5262.           behavior: \"smooth\", // Défilement fluide
  5263.         });
  5264.       }
  5265.     });
  5266.     document.addEventListener(\"DOMContentLoaded\", function () {
  5267.       const container = document.querySelector(\".date-container\");
  5268.       const leftArrow = document.querySelector(\".scroll-btn.left\");
  5269.       const rightArrow = document.querySelector(\".scroll-btn.right\");
  5270.       // Fonction pour vérifier le débordement et activer/désactiver les flèches
  5271.       function updateArrowsVisibility() {
  5272.         const isOverflowing = container.scrollWidth > container.clientWidth; // Vérifie si débordement
  5273.         leftArrow.style.display = isOverflowing ? \"flex\" : \"none\";
  5274.         rightArrow.style.display = isOverflowing ? \"flex\" : \"none\";
  5275.       }
  5276.       // Fonction pour défiler
  5277.       function scrollContainer(direction) {
  5278.         container.scrollBy({
  5279.           left: direction === \"left\" ? -200 : 200, // Défiler à gauche ou à droite
  5280.           behavior: \"smooth\",
  5281.         });
  5282.       }
  5283.       // Ajout des événements de clic pour les flèches
  5284.       leftArrow.addEventListener(\"click\", () => scrollContainer(\"left\"));
  5285.       rightArrow.addEventListener(\"click\", () => scrollContainer(\"right\"));
  5286.       // Vérification initiale et sur redimensionnement de la fenêtre
  5287.       updateArrowsVisibility();
  5288.       window.addEventListener(\"resize\", updateArrowsVisibility);
  5289.     });
  5290.     document.addEventListener(\"DOMContentLoaded\", function () {
  5291.       const container = document.querySelector(\".date-container\");
  5292.       const leftBtn = document.querySelector(\".scroll-btn.left\");
  5293.       const rightBtn = document.querySelector(\".scroll-btn.right\");
  5294.       leftBtn.addEventListener(\"click\", () => {
  5295.         container.scrollBy({
  5296.           left: -200, // Défile vers la gauche
  5297.           behavior: \"smooth\",
  5298.         });
  5299.       });
  5300.       rightBtn.addEventListener(\"click\", () => {
  5301.         container.scrollBy({
  5302.           left: 200, // Défile vers la droite
  5303.           behavior: \"smooth\",
  5304.         });
  5305.       });
  5306.     });
  5307.  document.addEventListener(\"DOMContentLoaded\", function () {
  5308.     // Sélectionnez tous les badges de filtre
  5309.     const filterBadges = document.querySelectorAll(\".filter-badge\");
  5310.     // Sélectionnez tous les éléments de la galerie
  5311.     const galleryItems = document.querySelectorAll(\".column\");
  5312.     // Sélectionnez tous les jours
  5313.     const days = document.querySelectorAll(\".collapse\");
  5314.     // Fonction pour réinitialiser les filtres
  5315.     function resetFilters() {
  5316.         // Réinitialisez tous les éléments de la galerie
  5317.         galleryItems.forEach((item) => {
  5318.             item.style.display = \"block\";
  5319.         });
  5320.         // Réinitialisez les états des badges
  5321.         filterBadges.forEach((badge) => badge.classList.remove(\"active\"));
  5322.     }
  5323.     // Ajoutez un gestionnaire d'événements pour chaque badge
  5324.     filterBadges.forEach((badge) => {
  5325.         badge.addEventListener(\"click\", function () {
  5326.             const filter = this.getAttribute(\"data-filter\");
  5327.             // Réinitialisez l'état actif pour tous les badges
  5328.             filterBadges.forEach((btn) => btn.classList.remove(\"active\"));
  5329.             // Ajoutez l'état actif au badge cliqué
  5330.             this.classList.add(\"active\");
  5331.             // Affichez ou masquez les éléments de la galerie
  5332.             galleryItems.forEach((item) => {
  5333.                 if (filter === \"all\") {
  5334.                     item.style.display = \"block\";
  5335.                 } else if (filter === \"photo\" && item.querySelector(\"img\")) {
  5336.                     item.style.display = \"block\";
  5337.                 } else if (filter === \"video\" && item.querySelector(\"video\")) {
  5338.                     item.style.display = \"block\";
  5339.                 } else if (filter === \"audio\" && item.classList.contains(\"audio-message-item\")) {
  5340.                     item.style.display = \"block\";
  5341.                 } else {
  5342.                     item.style.display = \"none\";
  5343.                 }
  5344.             });
  5345.         });
  5346.     });
  5347.     // Réinitialiser les filtres lors du changement de jour
  5348.     days.forEach((day) => {
  5349.         day.addEventListener(\"show.bs.collapse\", function () {
  5350.             resetFilters();
  5351.         });
  5352.     });
  5353. });
  5354.     \$(document).ready(function () {
  5355.       let zoomCounter = 0; // Initialize zoom counter
  5356.       let currentImageSrc = \"\"; // Track current image source
  5357.       let lastClickPosition = { x: 50, y: 50 }; // Default to center of image
  5358.       \$(\".container--gallery\").magnificPopup({
  5359.         delegate: \"a\",
  5360.         type: \"image\",
  5361.         mainClass: \"mfp-with-zoom mfp-img-mobile\",
  5362.         image: {
  5363.           verticalFit: true,
  5364.         },
  5365.         gallery: {
  5366.           enabled: true,
  5367.           tPrev: \"Previous (Left arrow key)\", // Alt text on left arrow
  5368.           tNext: \"Next (Right arrow key)\", // Alt text on right arrow
  5369.           tCounter: \"%curr% of %total%\", // Markup for \"1 of 7\" counter
  5370.         },
  5371.         zoom: {
  5372.           enabled: true,
  5373.           duration: 300,
  5374.           opener: function (element) {
  5375.             return element.find(\"img\");
  5376.           },
  5377.         },
  5378.         callbacks: {
  5379.           open: function () {
  5380.             // Get current image data from the link that was clicked
  5381.             const currentLink = this.currItem.el;
  5382.             const imageId =
  5383.               currentLink
  5384.                 .closest(\".photo-zoom\")
  5385.                 .find(\".heart-icon\")
  5386.                 .data(\"id\") || \"\";
  5387.             const sejourId =
  5388.               currentLink
  5389.                 .closest(\".photo-zoom\")
  5390.                 .find(\".heart-icon\")
  5391.                 .data(\"sejour-id\") || \"\";
  5392.             const imagePath =
  5393.               currentLink
  5394.                 .closest(\".photo-zoom\")
  5395.                 .find(\".heart-icon\")
  5396.                 .data(\"path\") || \"\";
  5397.             const imageDesc =
  5398.               currentLink
  5399.                 .closest(\".photo-zoom\")
  5400.                 .find(\".heart-icon\")
  5401.                 .data(\"description\") || \"\";
  5402.             const isFavorite = currentLink
  5403.               .closest(\".photo-zoom\")
  5404.               .find(\".heart-icon i\")
  5405.               .hasClass(\"bi-heart-fill\");
  5406.             const favoriteIconClass = isFavorite ? \"bi-heart-fill\" : \"bi-heart\";
  5407.             const favoriteIconColor = isFavorite ? \"#f56040\" : \"white\";
  5408.             const favoriteTooltip = isFavorite
  5409.               ? \"Retirer des favoris\"
  5410.               : \"Ajouter aux favoris\";
  5411.             const zoomControls = `
  5412.           <div class=\"mfp-zoom-controls\">
  5413.             <button class=\"zoom-btn zoom-out\" title=\"Zoom Out\"><i class=\"fa fa-search-minus\"></i></button>
  5414.             <button class=\"zoom-btn zoom-in\" title=\"Zoom In\"><i class=\"fa fa-search-plus\"></i></button>
  5415.           </div>
  5416.           <div class=\"mfp-favorite\">
  5417.             <button class=\"favorite-btn\" 
  5418.                     data-id=\"\${imageId}\" 
  5419.                     data-sejour-id=\"\${sejourId}\" 
  5420.                     data-path=\"\${imagePath}\" 
  5421.                     data-description=\"\${imageDesc}\"
  5422.                     title=\"\${favoriteTooltip}\">
  5423.               <i class=\"bi \${favoriteIconClass}\" style=\"color: \${favoriteIconColor}; text-shadow: 0px 0px 3px rgba(0,0,0,0.5);\"></i>
  5424.             </button>
  5425.           </div>
  5426.           <div class=\"mfp-counter\"></div>
  5427.         `;
  5428.             \$(\".mfp-content\").append(zoomControls);
  5429.             initializeZoomControls();
  5430.             initializeFavoriteButton();
  5431.             const intervalId = setInterval(() => {
  5432.               const newImageSrc = \$(\".mfp-img\").attr(\"src\");
  5433.               if (newImageSrc !== currentImageSrc) {
  5434.                 currentImageSrc = newImageSrc;
  5435.                 zoomCounter = 0;
  5436.                 lastClickPosition = { x: 50, y: 50 }; // Reset to center
  5437.                 attachZoomHandler(); // Reattach zoom handler to new image
  5438.                 \$(\".mfp-img\").css({
  5439.                   \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  5440.                   transform: `scale(1)`,
  5441.                 });
  5442.                 // Update favorite button for the new image
  5443.                 updateFavoriteButton();
  5444.                 initializeZoomControls();
  5445.                 updateCounter();
  5446.               }
  5447.             }, 100);
  5448.             this.content.on(\"mfpClose\", function () {
  5449.               clearInterval(intervalId);
  5450.             });
  5451.             attachZoomHandler();
  5452.           },
  5453.           close: function () {
  5454.             \$(\".mfp-zoom-controls\").remove();
  5455.             \$(\".mfp-favorite\").remove();
  5456.             \$(\".mfp-counter\").remove();
  5457.             zoomCounter = 0;
  5458.           },
  5459.         },
  5460.       });
  5461.       function attachZoomHandler() {
  5462.         \$(\".mfp-img\")
  5463.           .off(\"click\")
  5464.           .on(\"click\", function (event) {
  5465.             event.stopPropagation(); // Prevent default navigation behavior
  5466.             // Calculate click coordinates relative to the image
  5467.             const imgOffset = \$(this).offset();
  5468.             const clickX = event.pageX - imgOffset.left;
  5469.             const clickY = event.pageY - imgOffset.top;
  5470.             const imgWidth = \$(this).width();
  5471.             const imgHeight = \$(this).height();
  5472.             // Calculate transform-origin based on click position
  5473.             lastClickPosition = {
  5474.               x: (clickX / imgWidth) * 100,
  5475.               y: (clickY / imgHeight) * 100,
  5476.             };
  5477.             // Cycle through zoom levels: 1x, 1.5x, 2x
  5478.             zoomCounter = (zoomCounter + 1) % 3;
  5479.             const zoomLevels = [1, 1.5, 2];
  5480.             const zoomLevel = zoomLevels[zoomCounter];
  5481.             \$(this).css({
  5482.               \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  5483.               transform: `scale(\${zoomLevel})`,
  5484.             });
  5485.             updateZoomButtonState();
  5486.           });
  5487.       }
  5488.       function initializeZoomControls() {
  5489.         \$(\".mfp-zoom-controls .zoom-in\")
  5490.           .off(\"click\")
  5491.           .on(\"click\", function (event) {
  5492.             event.stopPropagation();
  5493.             zoomCounter = (zoomCounter + 1) % 3;
  5494.             const zoomLevels = [1, 1.5, 2];
  5495.             const zoomLevel = zoomLevels[zoomCounter];
  5496.             \$(\".mfp-img\").css({
  5497.               \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  5498.               transform: `scale(\${zoomLevel})`,
  5499.             });
  5500.             updateZoomButtonState();
  5501.           });
  5502.         \$(\".mfp-zoom-controls .zoom-out\")
  5503.           .off(\"click\")
  5504.           .on(\"click\", function (event) {
  5505.             event.stopPropagation();
  5506.             if (zoomCounter > 0) {
  5507.               zoomCounter -= 1;
  5508.               const zoomLevels = [1, 1.5, 2];
  5509.               const zoomLevel = zoomLevels[zoomCounter];
  5510.               \$(\".mfp-img\").css({
  5511.                 \"transform-origin\": `\${lastClickPosition.x}% \${lastClickPosition.y}%`,
  5512.                 transform: `scale(\${zoomLevel})`,
  5513.               });
  5514.               updateZoomButtonState();
  5515.             } else {
  5516.               \$.magnificPopup.close();
  5517.             }
  5518.           });
  5519.       }
  5520.       function initializeFavoriteButton() {
  5521.         \$(\".mfp-favorite .favorite-btn\")
  5522.           .off(\"click\")
  5523.           .on(\"click\", function (event) {
  5524.             event.stopPropagation();
  5525.             const \$this = \$(this);
  5526.             const imageId = \$this.data(\"id\");
  5527.             const sejourId = \$this.data(\"sejour-id\");
  5528.             // Toggle favorite status
  5529.             const isFavorite = \$this.find(\"i\").hasClass(\"bi-heart-fill\");
  5530.             // Update the button appearance
  5531.             if (isFavorite) {
  5532.               \$this
  5533.                 .find(\"i\")
  5534.                 .removeClass(\"bi-heart-fill\")
  5535.                 .addClass(\"bi-heart\")
  5536.                 .css(\"color\", \"white\");
  5537.               \$this.attr(\"title\", \"Ajouter aux favoris\");
  5538.             } else {
  5539.               \$this
  5540.                 .find(\"i\")
  5541.                 .removeClass(\"bi-heart\")
  5542.                 .addClass(\"bi-heart-fill\")
  5543.                 .css(\"color\", \"#f56040\");
  5544.               \$this.attr(\"title\", \"Retirer des favoris\");
  5545.             }
  5546.             // Update the original heart icon in the gallery
  5547.             const originalHeartIcon = \$(
  5548.               `.heart-icon[data-id=\"\${imageId}\"]`
  5549.             ).find(\"i\");
  5550.             if (isFavorite) {
  5551.               originalHeartIcon
  5552.                 .removeClass(\"bi-heart-fill\")
  5553.                 .addClass(\"bi-heart\")
  5554.                 .css(\"color\", \"\");
  5555.             } else {
  5556.               originalHeartIcon
  5557.                 .removeClass(\"bi-heart\")
  5558.                 .addClass(\"bi-heart-fill\")
  5559.                 .css(\"color\", \"#f56040\");
  5560.             }
  5561.             // Make AJAX call to update favorite status in the backend using Parent routes
  5562.             \$.ajax({
  5563.               url: isFavorite ? \"/Parent/aSupprimerFav\" : \"/Parent/ajouterFav\",
  5564.               type: \"POST\",
  5565.               data: {
  5566.                 id: imageId,
  5567.                 idSejour: sejourId,
  5568.               },
  5569.               success: function (response) {
  5570.                 // Optional: Show a success message or handle response
  5571.                 console.log(\"Favorite status updated\", response);
  5572.               },
  5573.               error: function (error) {
  5574.                 console.error(\"Error updating favorite status\", error);
  5575.                 // Revert the icon change on error
  5576.                 if (isFavorite) {
  5577.                   \$this
  5578.                     .find(\"i\")
  5579.                     .removeClass(\"bi-heart\")
  5580.                     .addClass(\"bi-heart-fill\")
  5581.                     .css(\"color\", \"#f56040\");
  5582.                   originalHeartIcon
  5583.                     .removeClass(\"bi-heart\")
  5584.                     .addClass(\"bi-heart-fill\")
  5585.                     .css(\"color\", \"#f56040\");
  5586.                 } else {
  5587.                   \$this
  5588.                     .find(\"i\")
  5589.                     .removeClass(\"bi-heart-fill\")
  5590.                     .addClass(\"bi-heart\")
  5591.                     .css(\"color\", \"white\");
  5592.                   originalHeartIcon
  5593.                     .removeClass(\"bi-heart-fill\")
  5594.                     .addClass(\"bi-heart\")
  5595.                     .css(\"color\", \"\");
  5596.                 }
  5597.               },
  5598.             });
  5599.           });
  5600.       }
  5601.       function updateFavoriteButton() {
  5602.         // Get current image data from the current slide
  5603.         const currentSlide = \$.magnificPopup.instance.currItem.el;
  5604.         const photoZoom = currentSlide.closest(\".photo-zoom\");
  5605.         if (photoZoom.length) {
  5606.           const heartIcon = photoZoom.find(\".heart-icon\");
  5607.           const imageId = heartIcon.data(\"id\") || \"\";
  5608.           const sejourId = heartIcon.data(\"sejour-id\") || \"\";
  5609.           const imagePath = heartIcon.data(\"path\") || \"\";
  5610.           const imageDesc = heartIcon.data(\"description\") || \"\";
  5611.           const isFavorite = heartIcon.find(\"i\").hasClass(\"bi-heart-fill\");
  5612.           const favoriteIconClass = isFavorite ? \"bi-heart-fill\" : \"bi-heart\";
  5613.           const favoriteIconColor = isFavorite ? \"#f56040\" : \"white\";
  5614.           const favoriteTooltip = isFavorite
  5615.             ? \"Retirer des favoris\"
  5616.             : \"Ajouter aux favoris\";
  5617.           // Update the favorite button
  5618.           const \$favoriteBtn = \$(\".mfp-favorite .favorite-btn\");
  5619.           \$favoriteBtn.data(\"id\", imageId);
  5620.           \$favoriteBtn.data(\"sejour-id\", sejourId);
  5621.           \$favoriteBtn.data(\"path\", imagePath);
  5622.           \$favoriteBtn.data(\"description\", imageDesc);
  5623.           \$favoriteBtn.attr(\"title\", favoriteTooltip);
  5624.           \$favoriteBtn
  5625.             .find(\"i\")
  5626.             .removeClass(\"bi-heart bi-heart-fill\")
  5627.             .addClass(favoriteIconClass)
  5628.             .css(\"color\", favoriteIconColor);
  5629.         }
  5630.       }
  5631.       function updateZoomButtonState() {
  5632.         const zoomLevels = [1, 1.5, 2];
  5633.         const currentZoom = zoomLevels[zoomCounter];
  5634.         \$(\".zoom-in\").prop(\"disabled\", currentZoom === 2);
  5635.         \$(\".zoom-out\").prop(\"disabled\", currentZoom === 1);
  5636.       }
  5637.       function updateCounter() {
  5638.         const counterText = \$(\".mfp-counter\")
  5639.           .closest(\".mfp-content\")
  5640.           .find(\".mfp-counter\")
  5641.           .text();
  5642.         const matches = counterText.match(/(\\d+) of (\\d+)/);
  5643.         if (matches) {
  5644.           const currentIndex = matches[1];
  5645.           const totalImages = matches[2];
  5646.           \$(\".mfp-counter\").text(`\${currentIndex} of \${totalImages}`);
  5647.         }
  5648.       }
  5649.       // Add CSS for the favorite button and rounded image corners
  5650.       \$(\"<style>\")
  5651.         .prop(\"type\", \"text/css\")
  5652.         .html(
  5653.           `
  5654.       .mfp-favorite {
  5655.         position: absolute;
  5656.         top: 15px;
  5657.         left: 15px;
  5658.         z-index: 1046;
  5659.       }
  5660.       .favorite-btn {
  5661.         background: transparent;
  5662.         border: none;
  5663.         font-size: 24px;
  5664.         padding: 5px;
  5665.         cursor: pointer;
  5666.         outline: none;
  5667.       }
  5668.       .favorite-btn i {
  5669.         transition: all 0.3s ease;
  5670.       }
  5671.       .favorite-btn:hover i {
  5672.         transform: scale(1.2);
  5673.       }
  5674.       /* Rounded corners for zoomed images */
  5675.       .mfp-img {
  5676.         border-radius: 8px;
  5677.       }
  5678.       /* Make sure the container doesn't clip the rounded corners */
  5679.       .mfp-figure:after {
  5680.         border-radius: 8px;
  5681.       }
  5682.     `
  5683.         )
  5684.         .appendTo(\"head\");
  5685.     });
  5686.   </script>
  5687. <script>
  5688. document.addEventListener('DOMContentLoaded', function () {
  5689.   const openBtn = document.getElementById('openFavoritesBtn');
  5690.   const closeBtn = document.getElementById('closeSidebarBtn');
  5691.   const sidebar = document.getElementById('favoritesSidebar');
  5692.   const tbody = document.querySelector('#favoritesTable tbody');
  5693.   openBtn.addEventListener('click', async () => {
  5694.     try {
  5695.       const response = await fetch('/Parent/mes-favoris', {
  5696.         headers: {
  5697.           'Accept': 'application/json'
  5698.         }
  5699.       });
  5700.       const result = await response.json();
  5701.       if (!result.success || !Array.isArray(result.data)) {
  5702.         alert('Erreur lors du chargement des favoris.');
  5703.         return;
  5704.       }
  5705.       tbody.innerHTML = '';
  5706.       result.data.forEach((fav, index) => {
  5707.         const row = document.createElement('tr');
  5708.         row.innerHTML = `
  5709.           <td>\${index + 1}</td>
  5710.           <td><img src=\"\${fav.path}\" alt=\"favori\"></td>
  5711.           <td>\${fav.descreption || '—'}</td>
  5712.           <td>\${fav.created_at}</td>
  5713.         `;
  5714.         tbody.appendChild(row);
  5715.       });
  5716.       sidebar.classList.add('active');
  5717.     } catch (e) {
  5718.       console.error('Erreur réseau:', e);
  5719.       alert('Impossible de charger les favoris.');
  5720.     }
  5721.   });
  5722.   closeBtn.addEventListener('click', () => {
  5723.     sidebar.classList.remove('active');
  5724.   });
  5725. });
  5726. </script>
  5727.   <script>
  5728.         // Fonction pour vérifier et afficher l'alerte
  5729.         function checkFavorites() {
  5730.             if (favoriteCount >= 10) {
  5731.                 purchaseAlert.style.display = 'block'; // Affiche l'alerte
  5732.             } else {
  5733.                 purchaseAlert.style.display = 'none'; // Cache l'alerte si le nombre est réduit
  5734.             }
  5735.         }
  5736.         // Ajout d'un favori
  5737.         function addFavorite() {
  5738.             favoriteCount++;
  5739.             likeCountLabel.textContent = favoriteCount;
  5740.             checkFavorites();
  5741.         }
  5742.         // Suppression d'un favori
  5743.         function removeFavorite() {
  5744.             if (favoriteCount > 0) {
  5745.                 favoriteCount--;
  5746.                 likeCountLabel.textContent = favoriteCount;
  5747.                 checkFavorites();
  5748.             }
  5749.         }document.addEventListener('DOMContentLoaded', () => {
  5750.     const favoriteCount = {{ nblikes }};
  5751.     updateCardContent(favoriteCount);
  5752. });
  5753. function updateCardContent(favoriteCount) {
  5754.     const card = document.getElementById('dynamic-card');
  5755.     const cardContent = document.getElementById('dynamic-card-content');
  5756.     let produits = [];
  5757.     if (favoriteCount >= 20) {
  5758.         produits.push({
  5759.             titre: \"Album débloqué !\",
  5760.             bouton: \"Commander\",
  5761.             image: \"/images/produit/Album5sur5-3.jpg\",
  5762.             lien: \"{{ path('EditionAlbum') }}\"
  5763.         });
  5764.     }
  5765.     if (favoriteCount >= 12) {
  5766.         produits.push({
  5767.             titre: \"Pochette débloquée !\",
  5768.             bouton: \"Commander\",
  5769.             image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  5770.             lien: \"{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}\"
  5771.         });
  5772.     }
  5773.     if (favoriteCount >= 5) {
  5774.         produits.push({
  5775.             titre: \"Pack numérique débloqué !\",
  5776.             bouton: \"Commander\",
  5777.             image: \"/images/produit/photoNumerique.jpg\",
  5778.             lien: \"{{ path('PackPhotosNumerique_Favoris', {'nbr': 15}) }}\"
  5779.         });
  5780.     }
  5781. if (produits.length === 0) {
  5782.   cardContent.innerHTML = `
  5783.     <div style=\"position: relative; width: 100%; height: 140px; border-radius: 15px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.1);\">
  5784.       <div style=\"background-image: url('/images/produit/CoffretCadeau5sur5-2.jpg'); background-size: cover; background-position: center; width: 100%; height: 100%;\">
  5785.         <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.45); display: flex; align-items: center; justify-content: center; padding: 10px;\">
  5786.           <div style=\"
  5787.     margin-top: 35px;
  5788.     color: white;
  5789.     font-size: 15px;
  5790.     font-weight: bold;
  5791.     text-align: center;
  5792.     line-height: 1;
  5793.     text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);\">
  5794.             Ajoutez des favoris ❤️<br><span style=\"font-size: 16px; font-weight: normal;\">pour débloquer un souvenir à offrir 🎁</span>
  5795.           </div>
  5796.         </div>
  5797.       </div>
  5798.     </div>
  5799.   `;
  5800.         return;
  5801.     }
  5802.     cardContent.innerHTML = `
  5803.     <div class=\"splide\" id=\"dynamicSplide\">
  5804.       <div class=\"splide__track\">
  5805.         <ul class=\"splide__list\">
  5806.           \${produits.map(produit => `
  5807.             <li class=\"splide__slide\" style=\"position: relative;\">
  5808.               <img src=\"\${produit.image}\" alt=\"\${produit.titre}\" style=\"width: 100%; height: 150px; object-fit: cover; border-radius: 8px;\">
  5809.               <div style=\"position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.1); color: white; padding: 10px; text-align: center; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;\">
  5810.                 <div style=\"font-weight: bold; font-size: 14px;\">\${produit.titre}</div>
  5811.                 <button style=\"margin-top: 5px; padding: 5px 8px; background-color: #F56040; color: white; border: none; border-radius: 4px; font-size: 12px; cursor: pointer;\" onclick=\"window.location.href='\${produit.lien}'\">
  5812.                   \${produit.bouton}
  5813.                 </button>
  5814.               </div>
  5815.             </li>
  5816.           `).join('')}
  5817.         </ul>
  5818.       </div>
  5819.     </div>
  5820.     `;
  5821.     // Monte le carrousel
  5822.     new Splide('#dynamicSplide', {
  5823.         type: 'loop',
  5824.         arrows: true,
  5825.         pagination: false,
  5826.         autoplay: true,
  5827.         interval: 4000,
  5828.         speed: 800,
  5829.     }).mount();
  5830. }
  5831.         function supprimerFavoris(\$id, \$idSejour) {
  5832.             // Vider l'élément coeur pour ce favori
  5833.             const coeurElement = \$('#coeur' + \$id);
  5834.             coeurElement.empty();
  5835.             // Ajout d'une animation sur le bouton favori
  5836.             const favoriteButton = document.querySelector('.fav-button');
  5837.             if (favoriteButton) {
  5838.                 favoriteButton.classList.add('active');
  5839.                 // Retirer l'animation après qu'elle soit jouée
  5840.                 setTimeout(() => {
  5841.                     favoriteButton.classList.remove('active');
  5842.                 }, 600); // La durée doit correspondre à celle de l'animation
  5843.             }
  5844.             // Mise à jour de l'icône coeur
  5845.             const clas = \$('.IconImag6').hasClass('active') ? \"IconDelete IconDeletesix\" : \"IconDelete\";
  5846.             coeurElement.html(
  5847.                 `<i class=\"bi bi-heart \${clas}\" onclick=\"AddFavoris(\${\$id}, \${\$idSejour})\"></i>`
  5848.             );
  5849.             // Mettre à jour le compteur des favoris
  5850.             const likeCountLabel = document.getElementById('likeCount');
  5851.            const likeMesFavLabel = document.getElementById('mesFavCount');
  5852.              if (likeMesFavLabel) {
  5853.                 let currentCount = parseInt(likeMesFavLabel.textContent.trim(), 10) || 0;
  5854.                 currentCount = Math.max(0, currentCount - 1); // Empêche le compteur d'aller en dessous de 0
  5855.                 likeMesFavLabel.textContent = currentCount;
  5856.             }
  5857.             if (likeCountLabel) {
  5858.                 let currentCount = parseInt(likeCountLabel.textContent.trim(), 10) || 0;
  5859.                 currentCount = Math.max(0, currentCount - 1); // Empêche le compteur d'aller en dessous de 0
  5860.                 likeCountLabel.textContent = currentCount;
  5861.                 // Mettre à jour la valeur dans l'input hidden
  5862.                 const nbFavCurrentInput = \$('#nbFavCurrent');
  5863.                 if (nbFavCurrentInput.length) {
  5864.                     nbFavCurrentInput.val(currentCount);
  5865.                 }
  5866.             }
  5867.             // Préparation des données pour l'Ajax
  5868.             const \$_data = { 'id': \$id, 'idSejour': \$idSejour };
  5869.             // Appel Ajax pour supprimer le favori
  5870.             \$.ajax({
  5871.                 type: \"POST\",
  5872.                 url: \"{{ path('Supprimer_fav') }}\",
  5873.                 data: \$_data,
  5874.                 success: function () {
  5875.                     // Réactiver les icônes après succès
  5876.                     \$('.IconDelete').each(function () {
  5877.                         \$(this).css('pointer-events', '');
  5878.                     });
  5879.                 },
  5880.                 error: function (xhr, status, error) {
  5881.                     console.error('Erreur lors de la suppression du favori :', error);
  5882.                 }
  5883.             });
  5884.         }
  5885.         function AddFavoris(\$id, \$idSejour, \$urlimg, \$description) {
  5886.            // console.log('Adding favorite:', { attachmentId, sejourId, path, description });
  5887.   \$(\"#close-favorites-btn\").click()
  5888.             favoriteButton.classList.add('active');
  5889.    const likeMesFavLabel = document.getElementById('mesFavCount');
  5890.       
  5891.             const likeCountLabel = document.getElementById('likeCount');
  5892.             if (likeCountLabel) {
  5893.                 let currentCount = parseInt(likeCountLabel.textContent.trim(), 10) || 0;
  5894.                 likeCountLabel.textContent = currentCount + 1;
  5895.                      likeMesFavLabel.textContent = currentCount + 1;
  5896.             }
  5897.         // Retirer l'animation après qu'elle soit jouée
  5898.         setTimeout(() => {
  5899.             favoriteButton.classList.remove('active');
  5900.         }, 600); // La durée doit correspondre à celle de l'animation
  5901.             \$('#coeur' + \$id).empty();
  5902.             var clas = \$('.IconImag6').hasClass('active') ? \"IconDelete IconDeletesix\" : \"IconDelete\";
  5903.             \$('#coeur' + \$id).html(\"<i class=\\\"bi bi-heart-fill favSelect \" + clas + \"\\\" onclick=\\\"supprimerFavoris(\" + \$id + \",\" + \$idSejour + \")\\\"></i>\");
  5904.             var \$total = parseInt(\$(\"#totalLike\").html()) + 1;
  5905.             \$(\"#totalLike\").html(\$total);
  5906.             \$(\"#totalLikeTitle\").html(\$total);
  5907.             \$(\"#totalLikeMobile\").html(\$total);
  5908.             var \$data = { 'id': \$id, 'idSejour': \$idSejour };
  5909.             \$.ajax({
  5910.                 type: \"POST\",
  5911.                 url: \"{{ path('Ajouter_fav') }}\",
  5912.                 data: \$data,
  5913.                 success: function () {
  5914.                     \$('.IconDelete').each(function () {
  5915.                         \$(this).css('pointer-events', '');
  5916.                     });
  5917.                     if (\$description === undefined) {
  5918.                         \$description = ''; // Set it to an empty string
  5919.                     }
  5920.                     \$('.rowMaselection').append(
  5921.                         '<div class=\"column\" id=\"column-' + \$id + '\">'+
  5922.                         '<a style=\"position: relative;\" title=\"Enlever de ma sélection\" onclick=\"supprimerFavoris(' + \$id + ',' + \$idSejour + ')\" class=\"iconeSuppImg\"><i class=\"bi bi-x\" style=\"font-size:17px;cursor:pointer;color:#d30909;float:right;margin-top:-3%;margin-right:2%\"></i></a>'+
  5923.                         '<a class=\"photo-zoom\">'+
  5924.                         '<img data-idAtach=\"'+\$id+'\" id=\"'+\$idSejour+'\" src=\"'+\$urlimg+'\"></a>'+
  5925.                         (\$description ? '<h4 id=\"commint\" class=\"titleHeadPhoto\">'+\$description+'</h4>' : '')+ // Only add the <h4> if \$description is not empty
  5926.                         '</div>'
  5927.                     );
  5928.                     // Directly update nbLikes count in the header
  5929.                     var currentNbLikes = parseInt(\$('#favoris-link-Accueilpayment .nbrpanier').text());
  5930.                     var newNbLikes = currentNbLikes + 1;
  5931.                     \$('#favoris-link-Accueilpayment .nbrpanier').text(newNbLikes);
  5932.                 },
  5933.                 error: function (xhr, status, error) {
  5934.                     console.error('Error:', error);
  5935.                 }
  5936.             });
  5937.         }
  5938.         \$(document).on('click', '.bi-heart, .bi-heart-fill', function () {
  5939.         const heartIcon       = \$(this);
  5940.         const heartContainer  = heartIcon.closest('.heart-icon');
  5941.         // Extract data attributes
  5942.         const attachmentId    = heartContainer.data('id');
  5943.         const sejourId        = heartContainer.data('sejour-id');
  5944.         const path            = heartContainer.data('path');
  5945.         const description     = heartContainer.data('description');
  5946.         const isFavorite      = heartIcon.hasClass('bi-heart-fill');
  5947.         // Get the input that contains the favorite count
  5948.         const likeFavInput    = document.getElementById('nbFavCurrent');
  5949.         let favoriteNb        = parseInt(likeFavInput.value, 10);
  5950.         if (isFavorite) {
  5951.             // Remove from favorites
  5952.             supprimerFavoris(attachmentId, sejourId);
  5953.             favoriteNb = Math.max(0, favoriteNb - 1);
  5954.             likeFavInput.value = favoriteNb;
  5955.             updateCardContent(favoriteNb);
  5956.               updateFavoritesSidebar();
  5957.                  \$(\"#close-favorites-btn\").click()
  5958.         } else {
  5959.             // Add to favorites
  5960.             AddFavoris(attachmentId, sejourId, path, description);
  5961.             favoriteNb = favoriteNb + 1;
  5962.             likeFavInput.value = favoriteNb;
  5963.             updateCardContent(favoriteNb);
  5964.        
  5965.             updateFavoritesSidebar();
  5966.                \$(\"#close-favorites-btn\").click()
  5967.         }
  5968.         // **** SIMPLE STEP: Update the purchase alert ****
  5969.         // This will refresh the progress bars, count, etc.
  5970.         updatePurchaseAlert(favoriteNb);
  5971.     });
  5972.         // Gestion dynamique du clic sur les icônes cœur
  5973.         \$(document).on('click', '.bi-hsddddeart, .bi-hdddeart-fill', function () {
  5974.             const heartIcon = \$(this);
  5975.           //  const heartIcon = \$(this);
  5976.             //const attachmentId = heartIcon.data('id'); // Récupère l'ID directement
  5977.             const attachmentId = heartIcon.closest('.heart-icon').attr('id').replace('coeur', '');
  5978.             const sejourId = heartIcon.data('sejour-id'); // Store the sejour ID in a data attribute
  5979.             const isFavorite = heartIcon.hasClass('bi-heart-fill');
  5980.             // Récupérer l'input contenant le nombre de favoris
  5981.             const likeFavInput = document.getElementById('nbFavCurrent');
  5982.             let favoriteNb = parseInt(likeFavInput.value, 10); // Utiliser .value pour les inputs
  5983.             // Validation pour éviter les NaN
  5984.             if (isNaN(favoriteNb)) {
  5985.                 favoriteNb = 0;
  5986.             }
  5987.             if (isFavorite) {
  5988.                 // Si c'est un favori, le supprimer
  5989.                 supprimerFavoris(attachmentId, sejourId);
  5990.                 // Décrémenter le compteur
  5991.                 favoriteNb = Math.max(0, favoriteNb - 1);
  5992.                 likeFavInput.value = favoriteNb; // Mettre à jour la valeur de l'input
  5993.                 // Mettre à jour dynamiquement le contenu des cartes ou popovers
  5994.                 updateCardContent(favoriteNb);
  5995.             } else {
  5996.                 // Si ce n'est pas un favori, l'ajouter
  5997.                 const path = heartIcon.data('path'); // Path de l'attachement
  5998.                 const description = heartIcon.data('description'); // Description de l'attachement
  5999.                 AddFavoris(attachmentId, sejourId, path, description);
  6000.           // Décrémenter le compteur
  6001.                 favoriteNb = Math.max(0, favoriteNb + 1);
  6002.                 likeFavInput.value = favoriteNb; // Mettre à jour la valeur de l'input
  6003.                 // Incrémenter le compteur
  6004.                 // Mettre à jour dynamiquement le contenu des cartes ou popovers
  6005.                 updateCardContent(favoriteNb);
  6006.             }
  6007.             // Mettre à jour dynamiquement la popover ou d'autres éléments liés
  6008.         });
  6009.         // Ajoutez les événements sur les icônes de cœur
  6010.         document.querySelectorAll('.IconDelete').forEach((icon) => {
  6011.             icon.addEventListener('click', (event) => {
  6012.                 const isFavorite = icon.classList.contains('bi-heart-fill');
  6013.                 if (isFavorite) {
  6014.                     removeFavorite();
  6015.                     icon.classList.remove('bi-heart-fill');
  6016.                     icon.classList.add('bi-heart');
  6017.                 } else {
  6018.                     addFavorite();
  6019.                     icon.classList.remove('bi-heart');
  6020.                     icon.classList.add('bi-heart-fill');
  6021.                 }
  6022.             });
  6023.         });
  6024.         // Vérifie l'état initial
  6025.         checkFavorites();
  6026.   </script>
  6027.   <!-- Initialisation -->
  6028.   <script>
  6029.     AOS.init({
  6030.       duration: 800, // Duration of animations in milliseconds
  6031.       easing: \"ease-in-out\", // Animation timing function
  6032.     });
  6033.     document.addEventListener(\"DOMContentLoaded\", function () {
  6034.       const dateCards = document.querySelectorAll(\".date-card\");
  6035.       const sections = document.querySelectorAll(\".collapse\");
  6036.       dateCards.forEach((card) => {
  6037.         card.addEventListener(\"click\", function () {
  6038.           // Supprimer les classes actives des autres cartes et sections
  6039.           dateCards.forEach((c) => c.classList.remove(\"active\"));
  6040.           sections.forEach((s) => s.classList.remove(\"show\"));
  6041.           // Ajouter la classe active à la carte cliquée
  6042.           this.classList.add(\"active\");
  6043.           // Récupérer la cible et afficher la bonne section
  6044.           const targetId = this.getAttribute(\"data-bs-target\");
  6045.           const targetSection = document.querySelector(targetId);
  6046.           if (targetSection) {
  6047.             targetSection.classList.add(\"show\");
  6048.           }
  6049.         });
  6050.       });
  6051.     });
  6052.     document.addEventListener(\"DOMContentLoaded\", function () {
  6053.       // Initialisation du carrousel Splide
  6054.       var splide = new Splide(\"#imageSlider\", {
  6055.         type: \"loop\",
  6056.         perPage: 1,
  6057.         autoplay: true,
  6058.         interval: 6000,
  6059.         pauseOnHover: false,
  6060.         pauseOnFocus: false,
  6061.         pagination: false, // Désactive la pagination
  6062.         arrows: false,
  6063.       });
  6064.       splide.mount();
  6065.       // Fonction pour faire défiler automatiquement vers la section suivante avec un ajustement personnalisé de la hauteur
  6066.       function scrollToNextSection() {
  6067.         const targetSection = document.getElementById(\"scrollTarget\");
  6068.         if (targetSection) {
  6069.           const targetPosition =
  6070.             targetSection.getBoundingClientRect().top + window.scrollY; // Position de la section
  6071.           const adjustedPosition = targetPosition - 50; // Réduit la hauteur du scroll de 150px (ajustez selon vos besoins)
  6072.           // Scroll vers la position ajustée
  6073.           window.scrollTo({
  6074.             top: adjustedPosition,
  6075.             behavior: \"smooth\",
  6076.           });
  6077.         }
  6078.       }
  6079.       // Démarrer le timer pour le scroll automatique après 10 secondes
  6080.       setTimeout(scrollToNextSection, 5000); // 10 secondes
  6081.     });
  6082.   </script>
  6083.   <script>
  6084.         document.addEventListener('DOMContentLoaded', function () {
  6085.             var myModal = new bootstrap.Modal(document.getElementById('PubProd'));
  6086.             myModal.show();
  6087.         });
  6088.         // Function to close the modal
  6089.     function closeModal() {
  6090.         var myModal = bootstrap.Modal.getInstance(document.getElementById('PubProd'));
  6091.         if (myModal) {
  6092.             myModal.hide();
  6093.         }
  6094.     }
  6095.     const favoriteButton = document.querySelector('.fav-button');
  6096.     favoriteButton.addEventListener('click', () => {
  6097.         // Ajouter la classe 'active' pour déclencher l'éclat
  6098.         favoriteButton.classList.add('active');
  6099.         // Retirer l'animation après qu'elle soit jouée
  6100.         setTimeout(() => {
  6101.             favoriteButton.classList.remove('active');
  6102.         }, 600); // La durée doit correspondre à celle de l'animation
  6103.     });
  6104.     
  6105.     //const HeartAddButton = document.querySelector('.IconDelete');
  6106.     \$(\".IconDelete\").on('click', () => {
  6107.         // Ajouter la classe 'active' pour déclencher l'éclat
  6108.         favoriteButton.classList.add('active');
  6109.         // Retirer l'animation après qu'elle soit jouée
  6110.         setTimeout(() => {
  6111.             favoriteButton.classList.remove('active');
  6112.         }, 600); // La durée doit correspondre à celle de l'animation
  6113.     });
  6114.     \$(document).ready(function() {
  6115.         // Attach click event to collapse triggers
  6116.         const lastCard = \$('.date-card.modern-card.active');
  6117.         const lastTargetId = lastCard.attr('data-bs-target');
  6118.         if (lastTargetId) {
  6119.             \$(lastTargetId).collapse('show'); // Expand the last collapse section
  6120.             LoadImagesCloud(\$(lastTargetId)); // Load images for the last day
  6121.         }
  6122.         \$('[data-bs-toggle=\"collapse\"]').on('click', function() {
  6123.             var targetId = \$(this).attr('data-bs-target'); // Get the target ID
  6124.             \$('.date-card.modern-card').removeClass('active'); // Remove 'active' class from all cards
  6125.             \$(this).addClass('active'); // Add 'active' class to the clicked card
  6126.             LoadImagesCloud(\$(targetId)); // Ensure this function works as expected
  6127.                // Hide all other collapses except the one clicked
  6128.                \$('[data-bs-target]').each(function() {
  6129.                 var currentTargetId = \$(this).attr('data-bs-target');
  6130.                 // If the current collapse is not the one clicked, hide it
  6131.                 if (currentTargetId !== targetId) {
  6132.                     \$(currentTargetId).collapse('hide');
  6133.                     //\$('[data-bs-toggle=\"collapse\"]').removeClass('active'); // Remove active class from all cards
  6134.                     //Modifier leurs style en non active aussi
  6135.                 }
  6136.             });
  6137.         });
  6138.     });
  6139.     function rotateIcone(iconId) {
  6140.         // Use the icon ID to target the specific element
  6141.         var icon = \$('#' + iconId);
  6142.         // Toggle the rotate-right class to apply rotation
  6143.         if (icon.hasClass('rotate-right')) {
  6144.             icon.removeClass('rotate-right'); // Remove rotation class
  6145.         } else {
  6146.             icon.addClass('rotate-right'); // Add rotation class
  6147.         }
  6148.     }
  6149.             \$(document).ready(function () {
  6150.                 \$total1 = parseInt(\$(\"#esphoto\").find('strong').html().replace('(', '').replace(')', ''));
  6151.                 \$('[data-bs-toggle=\"tooltip\"]').tooltip();
  6152.                 {% if app.session.get(\"paymentmoniteco\") %}
  6153.                 {% if app.session.get(\"paymentmoniteco\") == \"succses\" %}
  6154.                 Swal.fire({
  6155.                     icon: 'success',
  6156.                     title: ' succès ',
  6157.                     text: 'votre commande est validée'
  6158.                 });
  6159.                 {% endif %}
  6160.                 {% endif %}
  6161.                 if (\$total1 > 0) {
  6162.                     \$('.iconeFleche').first().click();
  6163.                     //  \$([document.documentElement, document.body]).animate({
  6164.                     //  scrollTop: \$('.iconeFleche').last().offset().top
  6165.                     //  }, );
  6166.                 }
  6167.                 else {
  6168.                     \$(window).scrollTop(0);
  6169.                 }
  6170.                 var slider = \$('.responsive').slick({
  6171.                     infinite: true,
  6172.                     slidesToShow: 1,
  6173.                     slidesToScroll: 1,
  6174.                     autoplay: true,
  6175.                     autoplaySpeed: 4000,
  6176.                     pauseOnFocus: false,
  6177.                     pauseOnHover: false,
  6178.                     draggable: false,
  6179.                     fade: true
  6180.                 });
  6181.                 \$('.responsive').css('display', 'block');
  6182.                 \$('.namePRD').css('display', 'block');
  6183.                 var currSlide = 0;
  6184.                 var nextSlide = 0;
  6185.                 slider.on('afterChange', function (event, slick, currentSlide) {
  6186.                     console.log(typeof (\$('.slick-active .slick-current').find('.imgproduit2')) != \"undefined\");
  6187.                     if (typeof (\$('.slick-active .slick-current').find('.imgproduit2')) != \"undefined\") {
  6188.                         setTimeout(function () {
  6189.                             \$('.slick-active .imgproduit1').removeClass('animated fadeIn');
  6190.                             \$('.slick-active .imgproduit1').addClass('animated fadeOut');
  6191.                             \$('.slick-active .imgproduit1').css('display', 'none');
  6192.                             \$('.slick-active .imgproduit2').css('display', 'block');
  6193.                             \$('.slick-active .imgproduit2').removeClass('animated fadeOut');
  6194.                             \$('.slick-active .imgproduit2').addClass('animated fadeIn');
  6195.                         }, 2000);
  6196.                     }
  6197.                 });
  6198.                 slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
  6199.                     currSlide = currentSlide;
  6200.                     \$('.imgproduit2').each(function () {
  6201.                         \$(this).removeClass('animated fadeIn');
  6202.                         \$(this).addClass('animated fadeOut');
  6203.                         \$(this).css('display', 'none');
  6204.                     });
  6205.                     \$('.imgproduit1').each(function () {
  6206.                         \$(this).css('display', 'block');
  6207.                         \$(this).removeClass('animated fadeOut');
  6208.                         \$(this).addClass('animated fadeIn');
  6209.                     });
  6210.                 });
  6211.                 \$('.columnPub').each(function () {
  6212.                     \$(this).slick({
  6213.                         infinite: true,
  6214.                         speed: 50,
  6215.                         fade: true,
  6216.                         slidesToShow: 1,
  6217.                         slidesToScroll: 1,
  6218.                         autoplay: true,
  6219.                         pauseOnFocus: false,
  6220.                         pauseOnHover: false,
  6221.                         draggable: false
  6222.                     });
  6223.                     \$(this).css('display', 'block');
  6224.                 });
  6225.                 \$(\"#offrePack\").click();
  6226.                 {%if app.user.showpubprod != 'false' %}
  6227.                 \$('#btnPubProd').click();
  6228.                 \$('.modal-backdrop').css('background-color', 'rgba(0, 0, 0, 0.2)');
  6229.                 {% endif %}
  6230.             });
  6231.             \$(\"#closeImage\").click(function () {
  6232.                 \$('#myModalImage').css('display', \"none\");
  6233.             });
  6234.             \$.ajax({
  6235.                 type: \"POST\",
  6236.                 url: \"{{ path(\"delateSession_parent\") }}\",
  6237.                 success: function () { }
  6238.             });
  6239.             function afficheDiv(elem) {
  6240.                 \$('.nav-link').each(function () {
  6241.                     \$(this).removeClass('active');
  6242.                 });
  6243.                 elem.addClass('active');
  6244.                 if (elem.attr('id') === \"esphoto\" || elem.attr('id') === \"esphotoMobile\") {
  6245.                     \$(\"#espacphoto\").show();
  6246.                     \$(\"#espacemessage\").hide();
  6247.                     \$(\"#espaceMa_selection\").hide();
  6248.                     pageMenu = 'MonSejour'
  6249.                     \$(this).addClass('active');
  6250.                    \$('#imageActifphoto').css('display', 'block');
  6251.                      \$('#imagenoActifphoto').css('display', 'none');
  6252.                    \$('#VocalActivee').css('display', 'none');
  6253.                      \$('#noActifVocal').css('display', 'block');
  6254.                 }
  6255.                 if (elem.attr('id') === \"esmessage\" || elem.attr('id') === \"esmessageMobile\") {
  6256.                     \$(\"#espacphoto\").hide();
  6257.                     \$(\"#espaceMa_selection\").hide();
  6258.                     \$(\"#espacemessage\").show();
  6259.                     pageMenu = 'BoiteVocale'
  6260.                     \$(\"#espaceMa_selection\").hide();
  6261.                     \$(this).addClass('active');
  6262.                   \$('#imageActifphoto').css('display', 'none');
  6263.                      \$('#imagenoActifphoto').css('display', 'block');
  6264.                    \$('#VocalActivee').css('display', 'block');
  6265.                      \$('#noActifVocal').css('display', 'none');
  6266.                 }
  6267.                 if (elem.attr('id') === \"esselection\" || elem.attr('id') === \"esselectionMobile\") {
  6268.                     \$(\"#espacphoto\").hide();
  6269.                     \$(\"#espacemessage\").hide();
  6270.                     \$(\"#espaceMa_selection\").show();
  6271.                     \$(homeNavmob).removeClass('bi bi-house-door-fill');
  6272.                     \$(homeNavmob).addClass('bi bi-house-door');
  6273.                     \$(micromob).removeClass('bi bi-mic-fill');
  6274.                     \$(micromob).addClass('bi bi-mic');
  6275.                     \$(selecNavmob).removeClass('bi bi-heart');
  6276.                     \$(selecNavmob).addClass('bi bi-heart-fill');
  6277.                 }
  6278.             }
  6279.             function LoadImagesCloud(\$element) {
  6280.                 \$element.find('.photo-zoom img').each(function (\$this) {
  6281.                     if (\$(this).attr('data-src') != \$(this).attr('src')) {
  6282.                         \$(this).attr('src', \$(this).attr('data-src'));
  6283.                     }
  6284.                 });
  6285.             }
  6286.       function afficheDivFooterMobile(elem) {
  6287.              if(elem =='esphotoMobile') {
  6288.                    \$(\"#espacphoto\").show();
  6289.                     \$(\"#espacemessage\").hide();
  6290.                     \$(\"#espaceMa_selection\").hide();
  6291.                     \$(\"#storevide\").hide();
  6292.                     \$(\"#storefull\").show();
  6293.                     \$(\"#fullphoto\").show();
  6294.                     \$(\"#videphoto\").hide()
  6295.                     \$(\"#vocalfull\").hide();
  6296.                     \$(\"#vocalvide\").show();
  6297.                 }
  6298.                 if (elem === \"esmessageMobile\" ) {
  6299.                     \$(\"#espacphoto\").hide();
  6300.                     \$(\"#espacemessage\").show();
  6301.                     \$(\"#espaceMa_selection\").hide();
  6302.                     \$(\"#storefull\").hide();
  6303.                     \$(\"#storevide\").show();
  6304.                     \$(\"#fullphoto\").hide();
  6305.                     \$(\"#videphoto\").show()
  6306.                     \$(\"#vocalfull\").show();
  6307.                     \$(\"#vocalvide\").hide();
  6308.                 }
  6309.             }
  6310.             function permutation(elem) {
  6311.                 \$(\".IconImag\").each(function () {
  6312.                     \$(this).removeClass('active');
  6313.                 });
  6314.                 elem.addClass(\"active\");
  6315.             }
  6316.             function per(elem) {
  6317.                 \$(\".list-group-item \").each(function () {
  6318.                     \$(this).removeClass('show');
  6319.                 });
  6320.                 elem.addClass(\"active\");
  6321.                 \$(\"#iconeFleche\").addClass('active');
  6322.             }
  6323.            function setidattach(id) {
  6324.                 \$(\"#idattachipmut\").val(id)
  6325.             }
  6326.             var ParentAjouterALL_fav = \"{{ path('ParentAjouterALL_fav') }}\";
  6327.             function AllFavoris(\$idSejour) {
  6328.                 \$('#SelectALL').html('Désélectionner tout');
  6329.                 \$('#SelectALL').css('pointer-events', 'none');
  6330.                 \$('#SelectALL').css('opacity', '0.5');
  6331.                 \$('#SelectALL').css('cursor', 'no-drop');
  6332.                 \$('#SelectALL1').html('Désélectionner tout');
  6333.                 \$('#SelectALL1').css('pointer-events', 'none');
  6334.                 \$('#SelectALL1').css('opacity', '0.5');
  6335.                 \$('#SelectALL1').css('cursor', 'no-drop');
  6336.                 \$data = { 'idSejour': \$idSejour }
  6337.                 \$.ajax({
  6338.                     type: \"POST\",
  6339.                     url: \"{{ path('ParentAjouterALL_fav') }}\",
  6340.                     data: \$data,
  6341.                     success: function () {
  6342.                         location.reload();
  6343.                     }
  6344.                 });
  6345.             }
  6346.             function RemoveAllFavoris(\$idSejour) {
  6347.                 \$('#SelectALL').html('Sélectionner tout');
  6348.                 \$('#SelectALL').css('pointer-events', 'none');
  6349.                 \$('#SelectALL').css('opacity', '0.5');
  6350.                 \$('#SelectALL').css('cursor', 'no-drop');
  6351.                 \$('#SelectALL1').html('Sélectionner tout');
  6352.                 \$('#SelectALL1').css('pointer-events', 'none');
  6353.                 \$('#SelectALL1').css('opacity', '0.5');
  6354.                 \$('#SelectALL1').css('cursor', 'no-drop');
  6355.                 \$data = { 'idSejour': \$idSejour }
  6356.                 \$.ajax({
  6357.                     type: \"POST\",
  6358.                     url: \"{{ path('ParentSupprimer_ALLfav') }}\",
  6359.                     data: \$data,
  6360.                     success: function () {
  6361.                         location.reload();
  6362.                     }
  6363.                 });
  6364.             }
  6365.             // Get the elements with class=\"column\"
  6366.             var elements = document.getElementsByClassName(\"column\");
  6367.             // Declare a \"loop\" variable
  6368.             var i;
  6369.             // Full-width images
  6370.             function Four() {
  6371.                 for (i = 0; i < elements.length; i++) {
  6372.                     elements[i].style.flex = \"0 0 25%\";
  6373.                 }
  6374.                 \$('.IconDelete').attr('class', 'IconDelete ');
  6375.                 \$('.photo-zoom ').attr('class', 'photo-zoom');
  6376.                 \$('.localistaion').css('visibility', 'visible');
  6377.                 \$('.localistaion').attr('class', 'localistaion');
  6378.                 \$('.legend').css('visibility', 'visible');
  6379.                 \$('.columnPub').each(function () {
  6380.                     \$(this).css('max-width', '25%');
  6381.                     \$(this).find('.slick-list').removeClass('miniature');
  6382.                     \$(this).find('.single_service').removeClass('miniature');
  6383.                     \$(this).find('.bottomdivpub').removeClass('miniature');
  6384.                 });
  6385.             }
  6386.             // Two images side by side
  6387.             function six() {
  6388.                 for (i = 0; i < elements.length; i++) {
  6389.                     elements[i].style.flex = \"0 0 15%\";
  6390.                 }
  6391.                 \$('.column').css('padding', '0px 10px 0px 0px');
  6392.                 \$('.localistaion').attr('class', 'localistaion localistaionsix');
  6393.                 \$('.IconDelete').attr('class', 'IconDelete IconDeletesix');
  6394.                 \$('.legend').css('visibility', 'visible');
  6395.                 \$('.photo-zoom ').attr('class', 'photo-zoom heightimg');
  6396.                 \$('.columnPub').each(function () {
  6397.                     \$(this).css('max-width', '15%');
  6398.                     \$(this).find('.slick-list').addClass('miniature');
  6399.                     \$(this).find('.single_service').addClass('miniature');
  6400.                     \$(this).find('.bottomdivpub').addClass('miniature');
  6401.                 });
  6402.             }
  6403.             // Four images side by side
  6404.             function two() {
  6405.                 for (i = 0; i < elements.length; i++) {
  6406.                     elements[i].style.flex = \"0 0 40%\";
  6407.                 }
  6408.                 \$('.column').css('padding', '14px 10px');
  6409.                 \$('.column').css('max-width', '40%');
  6410.                 \$('.localistaion').css('visibility', 'visible');
  6411.                 \$('.legend').css('visibility', 'visible');
  6412.                 \$('.photo-zoom ').attr('class', 'photo-zoom');
  6413.                 \$('.localistaion').attr('class', 'localistaion localistaiontwo');
  6414.                 \$('.IconDelete').attr('class', 'IconDelete IconDeletetwo');
  6415.                 \$('.legend').attr('class', 'legend legendtwo');
  6416.                 \$('.columnPub').each(function () {
  6417.                     \$(this).css('max-width', '40%');
  6418.                     \$(this).find('.slick-list').removeClass('miniature');
  6419.                     \$(this).find('.single_service').removeClass('miniature');
  6420.                     \$(this).find('.bottomdivpub').removeClass('miniature');
  6421.                 });
  6422.             }
  6423.             function hidePopPub() {
  6424.                 \$('.modal-backdrop').css('background-color', 'rgb(0, 0, 0)');
  6425.             }
  6426.             function changeHref(elem, newhref) {
  6427.                 \$(elem).parent().attr('href', newhref);
  6428.             }
  6429.             function VerifNbLikes(nblikes) {
  6430.                 \$('#allerAlaBoutique').click();
  6431.             }
  6432.     function handleMenuClick(menuId, pageMenu) {
  6433.         // Reset all icons
  6434.         document.getElementById('imagenoActifphoto').style.display = 'block';
  6435.         document.getElementById('imageActifphoto').style.display = 'none';
  6436.         document.getElementById('nofavorisVocal').style.display = 'block';
  6437.         document.getElementById('favorisActive').style.display = 'none';
  6438.         document.getElementById('noActifVocal').style.display = 'block';
  6439.         document.getElementById('VocalActivee').style.display = 'none';
  6440.         // Set selected icon
  6441.         if (menuId === 'photo') {
  6442.             document.getElementById('imagenoActifphoto').style.display = 'none';
  6443.             document.getElementById('imageActifphoto').style.display = 'block';
  6444.         } else if (menuId === 'selection') {
  6445.             document.getElementById('nofavorisVocal').style.display = 'none';
  6446.             document.getElementById('favorisActive').style.display = 'block';
  6447.         } else if (menuId === 'message') {
  6448.             document.getElementById('noActifVocal').style.display = 'none';
  6449.             document.getElementById('VocalActivee').style.display = 'block';
  6450.         }
  6451.         // Handle any other necessary logic
  6452.         \$('#list-tab-photo').removeClass('show');
  6453.         \$('#list-tab-message').removeClass('show');
  6454.         afficheDiv(\$(`#\${menuId}`));
  6455.     }
  6456.   </script>
  6457.   <script>
  6458.     \$(document).ready(function () {
  6459.       \$(\"#PubProd\").on(\"hidden.bs.modal\", function () {
  6460.         \$(document).trigger(\"modalClosed\");
  6461.       });
  6462.     });
  6463.   </script>
  6464.   <script>
  6465.     \$(document).ready(function () {
  6466.       \$(\"#noShow\").on(\"change\", function () {
  6467.         if (\$(this).is(\":checked\")) {
  6468.           \$.ajax({
  6469.             url: \"/Parent/showpub\",
  6470.             type: \"POST\",
  6471.             dataType: \"json\",
  6472.             success: function (response) {
  6473.               if (response.status === \"success\") {
  6474.                 console.log(\"User showpubprod updated successfully.\");
  6475.               } else {
  6476.                 console.log(\"Error:\", response.message);
  6477.               }
  6478.             },
  6479.             error: function (xhr, status, error) {
  6480.               console.log(\"AJAX Error:\", error);
  6481.             },
  6482.           });
  6483.         }
  6484.       });
  6485.     });
  6486.   </script>
  6487. </div>
  6488. <!-- Script pour la sidebar des favoris -->
  6489. <script>
  6490.   \$(document).ready(function() {
  6491.     // Ouvrir la sidebar
  6492.     \$(\"#openFavoritesSidebar\").click(function() {
  6493.       \$(\".favorites-sidebar\").addClass(\"open\");
  6494.       loadFavorites();
  6495.     });
  6496.     
  6497.     // Fermer la sidebar
  6498.     \$(\".favorites-close\").click(function() {
  6499.       \$(\".favorites-sidebar\").removeClass(\"open\");
  6500.     });
  6501.     
  6502.     // Charger les favoris
  6503.     function loadFavorites() {
  6504.       \$.ajax({
  6505.         url: \"/Parent/mes-favoris\",
  6506.         type: \"GET\",
  6507.         dataType: \"json\",
  6508.         beforeSend: function() {
  6509.           \$(\"#favorites-grid\").html(\"<div style='text-align:center'>Chargement...</div>\");
  6510.         },
  6511.         success: function(data) {
  6512.           \$(\"#favorites-grid\").empty();
  6513.           
  6514.           if (data.data && data.data.length > 0) {
  6515.             \$(\"#favorites-empty-state\").hide();
  6516.             
  6517.             \$.each(data.data, function(i, fav) {
  6518.               var item = \$(\"<div class='favorite-item'></div>\");
  6519.               var img = \$(\"<img>\").attr(\"src\", fav.path).attr(\"alt\", fav.descreption || \"Photo favorite\");
  6520.               var overlay = \$(\"<div class='favorite-overlay'></div>\");
  6521.         
  6522.               
  6523.               btn.click(function(e) {
  6524.                 e.preventDefault();
  6525.                 e.stopPropagation();
  6526.                 removeFavorite(fav.id);
  6527.               });
  6528.               
  6529.               overlay.append(btn);
  6530.               item.append(img).append(overlay);
  6531.               \$(\"#favorites-grid\").append(item);
  6532.             });
  6533.             
  6534.             \$(\"#favorites-counter\").text(data.data.length);
  6535.             var percentage = (data.data.length / 10) * 100;
  6536.             \$(\"#favorites-progress\").css(\"width\", percentage + \"%\");
  6537.             
  6538.           } else {
  6539.             \$(\"#favorites-empty-state\").show();
  6540.             \$(\"#favorites-counter\").text(\"0\");
  6541.             \$(\"#favorites-progress\").css(\"width\", \"0%\");
  6542.           }
  6543.         },
  6544.         error: function() {
  6545.           \$(\"#favorites-grid\").html(\"<div style='color:red;text-align:center'>Erreur de chargement</div>\");
  6546.         }
  6547.       });
  6548.     }
  6549.     
  6550.     // Supprimer un favori
  6551.     function removeFavorite(id) {
  6552.       \$.ajax({
  6553.         url: \"/Parent/remove-favorite/\" + id,
  6554.         type: \"POST\",
  6555.         success: function() {
  6556.           loadFavorites();
  6557.           
  6558.           // Mettre à jour le compteur global
  6559.           var count = parseInt(\$(\"#likeCount\").text());
  6560.           if (!isNaN(count)) {
  6561.             \$(\"#likeCount\").text(count - 1);
  6562.           }
  6563.           
  6564.           var countFav = parseInt(\$(\"#mesFavCount\").text());
  6565.           if (!isNaN(countFav)) {
  6566.             \$(\"#mesFavCount\").text(countFav - 1);
  6567.           }
  6568.         },
  6569.         error: function() {
  6570.           alert(\"Erreur lors de la suppression du favori\");
  6571.         }
  6572.       });
  6573.     }
  6574.   });
  6575. </script>
  6576. <!-- Script pour la sidebar des favoris -->
  6577. <script>
  6578. \$(document).ready(function() {
  6579.     // Fonctions pour ouvrir/fermer la sidebar
  6580.     \$(\"#openFavoritesSidebar\").click(function() {
  6581.         \$(\"#favorites-sidebar\").css(\"right\", \"0\");
  6582.         loadFavorites();
  6583.     });
  6584.     
  6585.     \$(\"#close-favorites-btn\").click(function() {
  6586.         \$(\"#favorites-sidebar\").css(\"right\", \"-400px\");
  6587.     });
  6588.     
  6589.     // Fermer en cliquant en dehors
  6590.     \$(document).click(function(event) {
  6591.         if (!\$(event.target).closest(\"#favorites-sidebar\").length && 
  6592.             !\$(event.target).closest(\"#openFavoritesSidebar\").length && 
  6593.             \$(\"#favorites-sidebar\").css(\"right\") === \"0px\") {
  6594.             \$(\"#favorites-sidebar\").css(\"right\", \"-400px\");
  6595.         }
  6596.     });
  6597.     
  6598.    // Variables globales
  6599. let selectedFavorites = [];
  6600. let allFavorites = [];
  6601. let coverPhotoId = null; // ID de la photo de couverture
  6602. // Fonction pour mettre à jour la sidebar
  6603. function loadFavorites() {
  6604.     \$(\"#favorites-grid\").html(\"<div style='text-align:center;padding:20px;'>Chargement...</div>\");
  6605.     
  6606.     \$.ajax({
  6607.         url: \"/Parent/mes-favoris\",
  6608.         type: \"GET\",
  6609.         dataType: \"json\",
  6610.         success: function(data) {
  6611.             \$(\"#favorites-grid\").empty();
  6612.             allFavorites = data.data || [];
  6613.             
  6614.             if (allFavorites.length > 0) {
  6615.                 \$(\"#favorites-empty-state\").hide();
  6616.                 
  6617.                 // Ajouter l'option de photo de couverture au-dessus de la grille
  6618.                 if (!\$(\"#cover-photo-section\").length) {
  6619.                     const coverSection = \$(`
  6620.                         <div id=\"cover-photo-section\" style=\"margin-bottom:15px;\">
  6621.                             <div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;\">
  6622.                                 <h4 style=\"margin:0;font-size:15px;color:#333;\">Photo de couverture</h4>
  6623.                                 <span style=\"font-size:12px;color:#777;\">Pour la personnalisation des produits</span>
  6624.                             </div>
  6625.                             <div id=\"cover-photo-container\" style=\"height:120px;background:#f5f5f5;border-radius:8px;display:flex;align-items:center;justify-content:center;overflow:hidden;position:relative;border:1px dashed #ccc;\">
  6626.                                 <div id=\"cover-photo-placeholder\" style=\"text-align:center;padding:15px;color:#777;\">
  6627.                                     <i class=\"bi bi-image\" style=\"font-size:24px;display:block;margin-bottom:8px;\"></i>
  6628.                                     <p style=\"margin:0;font-size:13px;\">Sélectionnez une photo comme couverture</p>
  6629.                                 </div>
  6630.                                 <div id=\"cover-photo-preview\" style=\"display:none;width:100%;height:100%;position:relative;\">
  6631.                                     <img src=\"\" style=\"width:100%;height:100%;object-fit:cover;\" />
  6632.                                     <button id=\"remove-cover-photo\" style=\"position:absolute;top:5px;right:5px;background:#F56040;color:white;border:none;width:24px;height:24px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;\">
  6633.                                         <i class=\"bi bi-x\"></i>
  6634.                                     </button>
  6635.                                 </div>
  6636.                             </div>
  6637.                         </div>
  6638.                     `);
  6639.                     
  6640.                     \$(\"#photos-content\").prepend(coverSection);
  6641.                     
  6642.                     // Événement pour retirer la photo de couverture
  6643.                     \$(\"#remove-cover-photo\").click(function(e) {
  6644.                         e.stopPropagation();
  6645.                         setCoverPhoto(null);
  6646.                     });
  6647.                 }
  6648.                 
  6649.                 // Mettre à jour l'affichage de la photo de couverture
  6650.                 updateCoverPhotoDisplay();
  6651.                 
  6652.                 // Générer la grille de photos
  6653.                 \$.each(allFavorites, function(i, fav) {
  6654.                     var isSelected = selectedFavorites.includes(fav.id);
  6655.                     var isCoverPhoto = (coverPhotoId === fav.id);
  6656.                     
  6657.                     // Conteneur principal avec styles conditionnels
  6658.                     var item = \$(\"<div class='favorite-item' data-id='\" + fav.id + \"' style='position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1;cursor:pointer;transition:all 0.2s;border:3px solid \" + (isSelected ? \"#F56040\" : (isCoverPhoto ? \"#4CAF50\" : \"transparent\")) + \";'></div>\");
  6659.                     
  6660.                     var img = \$(\"<img style='width:100%;height:100%;object-fit:cover;'>\").attr(\"src\", fav.path).attr(\"alt\", fav.descreption || \"Photo favorite\");
  6661.                     
  6662.                     // Badge de sélection
  6663.                     var selectionBadge = \$(\"<div class='selection-badge' style='position:absolute;top:5px;right:5px;width:22px;height:22px;border-radius:50%;background:#F56040;display:\" + (isSelected ? \"flex\" : \"none\") + \";align-items:center;justify-content:center;color:white;font-size:12px;z-index:10;'><i class='bi bi-check'></i></div>\");
  6664.                     
  6665.                     // Badge de photo de couverture
  6666.                     var coverBadge = \$(\"<div class='cover-badge' style='position:absolute;top:5px;left:5px;padding:2px 6px;background:#4CAF50;color:white;font-size:10px;border-radius:3px;display:\" + (isCoverPhoto ? \"block\" : \"none\") + \";z-index:10;'><i class='bi bi-star-fill' style='margin-right:3px;font-size:8px;'></i>Couverture</div>\");
  6667.                     
  6668.                     // Overlay simple pour effet au survol
  6669.                     var hoverOverlay = \$(\"<div class='hover-overlay' style='position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.2);opacity:0;transition:opacity 0.2s;z-index:5;'></div>\");
  6670.                     
  6671.                     // Actions sur hover
  6672.                     var actionsOverlay = \$(\"<div class='actions-overlay' style='position:absolute;bottom:5px;left:5px;right:5px;display:flex;justify-content:center;gap:8px;opacity:0;transition:opacity 0.2s;z-index:15;'></div>\");
  6673.                     
  6674.                     // Bouton pour définir comme photo de couverture
  6675.                     var setCoverBtn = \$(\"<button style='background:\" + (isCoverPhoto ? \"#4CAF50\" : \"rgba(255,255,255,0.8)\") + \";color:\" + (isCoverPhoto ? \"white\" : \"#333\") + \";border:none;border-radius:3px;font-size:11px;padding:5px 8px;cursor:pointer;'><i class='bi bi-star\" + (isCoverPhoto ? \"-fill\" : \"\") + \"' style='margin-right:3px;'></i>Couverture</button>\");
  6676.                     
  6677.                     setCoverBtn.click(function(e) {
  6678.                         e.stopPropagation();
  6679.                         if (isCoverPhoto) {
  6680.                             setCoverPhoto(null);
  6681.                         } else {
  6682.                             setCoverPhoto(fav.id);
  6683.                         }
  6684.                     });
  6685.                     
  6686.                     actionsOverlay.append(setCoverBtn);
  6687.                     
  6688.                     // Ajouter effet de survol
  6689.                     item.hover(
  6690.                         function() { 
  6691.                             \$(this).find(\".hover-overlay\").css(\"opacity\", \"1\");
  6692.                             \$(this).find(\".actions-overlay\").css(\"opacity\", \"1\");
  6693.                         },
  6694.                         function() { 
  6695.                             \$(this).find(\".hover-overlay\").css(\"opacity\", \"0\");
  6696.                             \$(this).find(\".actions-overlay\").css(\"opacity\", \"0\");
  6697.                         }
  6698.                     );
  6699.                     
  6700.                     // Gérer le clic pour la sélection
  6701.                     item.click(function(e) {
  6702.                         e.stopPropagation();
  6703.                         toggleSelection(\$(this).data('id'));
  6704.                     });
  6705.                     
  6706.                     item.append(img).append(hoverOverlay).append(selectionBadge).append(coverBadge).append(actionsOverlay);
  6707.                     
  6708.                     // Ajouter explicitement une classe pour le style
  6709.                     item.addClass(\"no-trash-button\");
  6710.                     
  6711.                     \$(\"#favorites-grid\").append(item);
  6712.                 });
  6713.                 
  6714.                 // Supprimer tout bouton de suppression qui pourrait être ajouté dynamiquement
  6715.                 setTimeout(function() {
  6716.                     \$(\".favorite-item .remove-favorite, .favorite-item button:has(.bi-trash), .favorite-overlay button\").remove();
  6717.                 }, 100);
  6718.                 
  6719.                 \$(\"#favorites-counter\").text(allFavorites.length);
  6720.                 \$(\"#openFavoritesSidebar span\").text(allFavorites.length);
  6721.                 updateProductsView();
  6722.                 
  6723.             } else {
  6724.                 \$(\"#favorites-empty-state\").show();
  6725.                 \$(\"#favorites-counter\").text(\"0\");
  6726.                 \$(\"#openFavoritesSidebar span\").text(\"0\");
  6727.                 \$(\"#selection-count\").text(\"0\");
  6728.                 updateProductsView();
  6729.             }
  6730.         },
  6731.         error: function() {
  6732.             \$(\"#favorites-grid\").html(\"<div style='color:red;text-align:center;padding:20px;'>Erreur de chargement</div>\");
  6733.         }
  6734.     });
  6735. }
  6736. // Fonction pour définir la photo de couverture
  6737. function setCoverPhoto(id) {
  6738.     coverPhotoId = id;
  6739.     
  6740.     // Mettre à jour l'affichage
  6741.     updateCoverPhotoDisplay();
  6742.     
  6743.     // Mettre à jour le style des photos dans la grille
  6744.     \$(\".favorite-item\").each(function() {
  6745.         const itemId = \$(this).data('id');
  6746.         const isSelected = selectedFavorites.includes(itemId);
  6747.         const isCover = (itemId === coverPhotoId);
  6748.         
  6749.         // Mettre à jour la bordure
  6750.         \$(this).css(\"border\", \"3px solid \" + (isSelected ? \"#F56040\" : (isCover ? \"#4CAF50\" : \"transparent\")));
  6751.         
  6752.         // Mettre à jour le badge de couverture
  6753.         \$(this).find(\".cover-badge\").css(\"display\", isCover ? \"block\" : \"none\");
  6754.         
  6755.         // Mettre à jour le bouton de couverture
  6756.         const coverBtn = \$(this).find(\".actions-overlay button:first\");
  6757.         coverBtn.css({
  6758.             \"background\": isCover ? \"#4CAF50\" : \"rgba(255,255,255,0.8)\",
  6759.             \"color\": isCover ? \"white\" : \"#333\"
  6760.         });
  6761.         coverBtn.find(\"i\").attr(\"class\", \"bi bi-star\" + (isCover ? \"-fill\" : \"\"));
  6762.     });
  6763.     
  6764.     // Enregistrer l'ID de la photo de couverture (si nécessaire pour le backend)
  6765.     if (id) {
  6766.         console.log(\"Photo de couverture définie avec l'ID:\", id);
  6767.         // Ici vous pouvez ajouter une requête AJAX pour enregistrer ce choix sur le serveur
  6768.         
  6769.         // Ajouter automatiquement la photo de couverture à la sélection si elle n'y est pas déjà
  6770.         if (!selectedFavorites.includes(id)) {
  6771.             toggleSelection(id);
  6772.         }
  6773.     } else {
  6774.         console.log(\"Photo de couverture supprimée\");
  6775.     }
  6776. }
  6777. // Mettre à jour l'affichage de la photo de couverture
  6778. function updateCoverPhotoDisplay() {
  6779.     if (coverPhotoId) {
  6780.         // Trouver la photo correspondante
  6781.         const coverPhoto = allFavorites.find(fav => fav.id === coverPhotoId);
  6782.         if (coverPhoto) {
  6783.             \$(\"#cover-photo-placeholder\").hide();
  6784.             \$(\"#cover-photo-preview\").show();
  6785.             \$(\"#cover-photo-preview img\").attr(\"src\", coverPhoto.path);
  6786.         } else {
  6787.             // Si l'ID ne correspond à aucune photo (cas rare)
  6788.             coverPhotoId = null;
  6789.             \$(\"#cover-photo-placeholder\").show();
  6790.             \$(\"#cover-photo-preview\").hide();
  6791.         }
  6792.     } else {
  6793.         \$(\"#cover-photo-placeholder\").show();
  6794.         \$(\"#cover-photo-preview\").hide();
  6795.     }
  6796. }
  6797. // Modifier la fonction updateProductsView pour tenir compte de la photo de couverture
  6798. function updateProductsView() {
  6799.     const current = selectedFavorites.length;
  6800.     const hasCoverPhoto = coverPhotoId !== null;
  6801.     
  6802.     \$(\"#product-photo-count\").text(current);
  6803.     
  6804.     let remainingForAlbum = Math.max(0, 20 - current);
  6805.     let remainingForPochette = Math.max(0, 12 - current);
  6806.     let remainingForPack = Math.max(0, 12 - current);
  6807.     const progressBar = (count, total, color) => `
  6808.         <div style=\"margin: 5px 0;\">
  6809.             <div style=\"background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;\">
  6810.                 <div style=\"width: \${(count / total) * 100}%; background-color: \${color}; height: 100%;\"></div>
  6811.             </div>
  6812.             <small style=\"font-size: 12px;\">\${count}/\${total} photos</small>
  6813.         </div>
  6814.     `;
  6815.     // Liste des produits
  6816.     const products = [
  6817.         {
  6818.             name: \"Pochette photo (12 photos)\",
  6819.             required: 12,
  6820.             remaining: Math.max(0, 12 - current),
  6821.             image: \"/images/produit/PochettePhoto5sur5-2.jpg\",
  6822.             color: \"#2196f3\",
  6823.             link: \"{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}\",
  6824.             needsCover: true
  6825.         },
  6826.         {
  6827.             name: \"Pack numérique (20 photos)\",
  6828.             required: 20,
  6829.             remaining: Math.max(0, 20 - current),
  6830.             image: \"/images/produit/photoNumerique.jpg\",
  6831.             color: \"#4caf50\",
  6832.             link: \"{{ path('PackPhotosNumerique_Favoris', {'nbr': 20}) }}\",
  6833.             needsCover: false
  6834.         },
  6835.        
  6836.       
  6837.     ].sort((a, b) => a.remaining - b.remaining);
  6838.     const productList = products
  6839.         .map((product) => {
  6840.             const count = current;
  6841.             const total = product.required;
  6842.             const remaining = product.remaining;
  6843.             const coverRequired = product.needsCover && !hasCoverPhoto;
  6844.             return `
  6845.                 <li style=\"margin-bottom: 20px; position: relative;\">
  6846.                     \${coverRequired ? `<div style=\"position: absolute; top: 0; right: 0; background: #FFC107; color: #333; font-size: 10px; padding: 2px 6px; border-radius: 3px; z-index: 5;\">
  6847.                         <i class=\"bi bi-exclamation-triangle\"></i> Photo de couverture requise
  6848.                     </div>` : ''}
  6849.                     <div style=\"display: flex; align-items: center; gap: 10px;\">
  6850.                         <img src=\"\${product.image}\" alt=\"\${product.name}\" style=\"width: 70px; height: 70px; border-radius: 5px; object-fit: cover;\" />
  6851.                         <div style=\"flex: 1;\">
  6852.                             <strong style=\"font-size: 14px;\">\${product.name}</strong>
  6853.                             \${progressBar(count, total, product.color)}
  6854.                             \${
  6855.                                 remaining > 0
  6856.                                 ? `<small style=\"color: \${product.color}; font-size: 12px;\">
  6857.                                     Encore \${remaining} photos pour compléter \${product.name.toLowerCase()}
  6858.                                 </small>`
  6859.                                 : coverRequired
  6860.                                 ? `<button
  6861.                                     style=\"
  6862.                                         margin-top: 5px;
  6863.                                         padding: 6px 12px;
  6864.                                         background-color: #FFC107;
  6865.                                         color: #333;
  6866.                                         border: none;
  6867.                                         border-radius: 5px;
  6868.                                         font-size: 13px;
  6869.                                         cursor: pointer;
  6870.                                     \"
  6871.                                     onclick=\"\$('#tab-photos').click(); /* Rediriger vers l'onglet photos */\"
  6872.                                 >
  6873.                                     Choisir une couverture
  6874.                                 </button>`
  6875.                                 : `<button
  6876.                                     style=\"
  6877.                                         margin-top: 5px;
  6878.                                         padding: 6px 12px;
  6879.                                         background-color: \${product.color};
  6880.                                         color: white;
  6881.                                         border: none;
  6882.                                         border-radius: 5px;
  6883.                                         font-size: 13px;
  6884.                                         cursor: pointer;
  6885.                                     \"
  6886.                                     onclick=\"window.location.href='\${product.link}'\"
  6887.                                 >
  6888.                                     Commander
  6889.                                 </button>`
  6890.                             }
  6891.                         </div>
  6892.                     </div>
  6893.                 </li>
  6894.             `;
  6895.         })
  6896.         .join(\"\");
  6897.     const boutiqueButton = `
  6898.         <li style=\"margin-top: 25px; text-align: center;\">
  6899.             <button
  6900.                 style=\"
  6901.                     padding: 8px 15px;
  6902.                     background-color: #F56040;
  6903.                     color: white;
  6904.                     border: none;
  6905.                     border-radius: 5px;
  6906.                     font-size: 14px;
  6907.                     width: 170px;
  6908.                     height: 40px;
  6909.                     cursor: pointer;
  6910.                 \"
  6911.                 onclick=\"window.location.href='{{ path('boutique5sur5') }}'\"
  6912.             >
  6913.                 Voir toute la boutique
  6914.             </button>
  6915.         </li>
  6916.     `;
  6917.     \$(\"#product-list\").html(productList + boutiqueButton);
  6918. }
  6919. });
  6920. </script>
  6921. {% endblock %}
  6922. ""Parent/DetailsSejour.html.twig""/var/www/5sur5sejour/templates/Parent/DetailsSejour.html.twig");
  6923.     }
  6924. }