templates/Parent/headerParent.html.twig line 1

Open in your IDE?
  1. {#/*
  2. * Role:Header
  3. *
  4. */#}
  5. {%set codeSejParent = app.session.get('Sejour') %}
  6.     {% set pageMenu = app.session.get('pageMenu') %}
  7. <!-- header-start -->
  8. <!-- Navbar-->
  9.  <style>
  10.     /* Animation pour l'icône du panier */
  11. @keyframes bounce {
  12.     0%, 100% {
  13.         transform: translateY(0);
  14.     }
  15.     30% {
  16.         transform: translateY(-10px);
  17.     }
  18.     50% {
  19.         transform: translateY(5px);
  20.     }
  21.     70% {
  22.         transform: translateY(-5px);
  23.     }
  24. }
  25. .cart-bounce {
  26.     animation: bounce 0.6s ease-out;
  27. }
  28.         .popover-header {
  29.             display: flex;
  30.             justify-content: space-between;
  31.             align-items: center;
  32.         }
  33.         .close {
  34.             margin: -0.5rem -0.5rem -0.5rem auto;
  35.         }
  36.         .custom-button {
  37.             background-color: #f09e7a;
  38.             color: #fff; /* Text color always white */
  39.             font-family: 'Montserrat-SemiBold', sans-serif;
  40.             border-radius: 22px;
  41.             font-size: 11px;
  42.             box-shadow: none !important;
  43.             border: none !important;
  44.             margin-top: 8px;
  45.             margin-left: 75px;
  46.             transition: background-color 0.3s ease; /* Smooth transition for background color */
  47.         }
  48.         .custom-button:hover,
  49.         .custom-button:focus,
  50.         .custom-button:active {
  51.             background-color: #41a2aa; /* Background color on hover, focus, and active */
  52.             color: #fff; /* Text color on hover, focus, and active */
  53.         }
  54.         .custom-button:visited {
  55.             color: #fff; /* Text color for visited link */
  56.         }
  57.         .disabled-section {
  58.             pointer-events: none;   /* Disable all interactions */
  59.             opacity: 0.6;           /* Reduce opacity */
  60.         }
  61.         .disabled-element {
  62.             pointer-events: none;
  63.             color: #999;           /* Gray text */
  64.             opacity: 0.6;
  65.         }
  66.       /* Hide the mobile logo by default */
  67.       .mobile-only {
  68.     display: none !important;
  69. }
  70. /* Show the desktop logo by default */
  71. .desktop-only {
  72.     display: block !important;
  73. }
  74. /* Media query for mobile view */
  75. @media (max-width: 767px) {
  76.     /* Show the mobile logo */
  77.     .mobile-only {
  78.         display: block !important;
  79.     }
  80.     /* Hide the desktop logo */
  81.     .desktop-only {
  82.         display: none !important;
  83.     }
  84. }
  85. @media only screen and (max-width: 768px) {
  86.   .help-icon {
  87.     display: none;
  88.   }
  89. }
  90. .vocal-trigger-btn {
  91.       background-color: #3CA9AB;
  92.       color: white;
  93.       border: none;
  94.       padding: 10px 20px;
  95.       border-radius: 4px;
  96.       font-weight: bold;
  97.       cursor: pointer;
  98.       display: flex;
  99.       align-items: center;
  100.       gap: 8px;
  101.     }
  102.     
  103.     .vocal-modal-overlay {
  104.       position: fixed;
  105.       top: 0;
  106.       left: 0;
  107.       width: 100%;
  108.       height: 100%;
  109.       background-color: rgba(0, 0, 0, 0.5);
  110.       display: none;
  111.       justify-content: center;
  112.       align-items: center;
  113.       z-index: 1000;
  114.     }
  115.     
  116.     .vocal-modal {
  117.       font-family: Arial, sans-serif;
  118.       width: 420px;
  119.       max-width: 90%;
  120.       background-color: white;
  121.       border-radius: 8px;
  122.       box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  123.       overflow: hidden;
  124.       position: relative;
  125.       z-index: 1001;
  126.     }
  127.     
  128.     .vocal-modal-content {
  129.       padding: 15px;
  130.     }
  131.     
  132.     .vocal-feature {
  133.       display: flex;
  134.       margin-bottom: 12px;
  135.       align-items: flex-start;
  136.     }
  137.     
  138.     .vocal-feature-icon {
  139.       margin-right: 10px;
  140.       flex-shrink: 0;
  141.       width: 20px;
  142.       height: 20px;
  143.       display: flex;
  144.       align-items: center;
  145.       justify-content: center;
  146.     }
  147.     
  148.     .vocal-feature-text {
  149.       flex: 1;
  150.     }
  151.     
  152.     .vocal-feature-title {
  153.       font-weight: bold;
  154.       margin-bottom: 2px;
  155.       font-size: 14px;
  156.     }
  157.     
  158.     .vocal-feature-desc {
  159.       color: #555;
  160.       font-size: 12px;
  161.       line-height: 1.3;
  162.       margin: 0 0 2px 0;
  163.     }
  164.     
  165.     .vocal-modal-buttons {
  166.       display: flex;
  167.       justify-content: flex-end;
  168.       padding: 10px 15px;
  169.       background-color: #f5f5f5;
  170.       border-top: 1px solid #e0e0e0;
  171.     }
  172.     
  173.     .vocal-btn {
  174.       padding: 8px 16px;
  175.       border-radius: 4px;
  176.       font-weight: bold;
  177.       cursor: pointer;
  178.       border: none;
  179.       font-size: 13px;
  180.     }
  181.     
  182.     .vocal-btn-cancel {
  183.       background-color: #f1f1f1;
  184.       color: #666;
  185.       margin-right: 10px;
  186.     }
  187.     
  188.     .vocal-btn-confirm {
  189.       background-color: #E9553B;
  190.       color: white;
  191.     }
  192.     
  193.     /* Animation */
  194.     .vocal-fade-in {
  195.       animation: vocalFadeIn 0.3s ease-in-out;
  196.     }
  197.     
  198.     @keyframes vocalFadeIn {
  199.       from { opacity: 0; }
  200.       to { opacity: 1; }
  201.     }
  202.     @media (max-width: 991px) {
  203.   /* Mobile adjustments */
  204.   .mobile-only {
  205.     display: flex !important;
  206.     margin-right: 8px;
  207.   }
  208.   
  209.   .VMobileBrend {
  210.     margin-top: 0 !important;
  211.     margin-right: 10px;
  212.   }
  213.   
  214.   .mobile-help-btn {
  215.     margin-left: 5px;
  216.     margin-right: 10px;
  217.   }
  218.   
  219.   .mobile-nav-menu {
  220.     margin-left: auto;
  221.     margin-right: auto;
  222.   }
  223.   
  224.   .mobile-nav-item {
  225.     text-align: center;
  226.     padding: 0 10px;
  227.   }
  228.   
  229.   .mobile-nav-item a {
  230.     display: flex;
  231.     flex-direction: column;
  232.     align-items: center;
  233.     font-size: 0.8rem;
  234.   }
  235.   
  236.   .mobile-nav-item i {
  237.     font-size: 1.5rem;
  238.     margin-bottom: 3px;
  239.   }
  240.   
  241.   /* Custom dropdown for mobile menu */
  242.   .mobile-menu-custom-dropdown {
  243.     position: absolute;
  244.     right: 0;
  245.     left: auto;
  246.     top: 100%;
  247.     width: 280px;
  248.     background: white;
  249.     border-radius: 8px;
  250.     box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  251.     z-index: 1000;
  252.     padding: 10px 0;
  253.     display: none;
  254.     list-style: none;
  255.     margin: 0;
  256.     transform: translateX(0); /* Remove the negative transform to position on right */
  257.   }
  258.   
  259.   /* Container for the navbar items in the dropdown */
  260.   .mobile-menu-navbar-item {
  261.     display: inline-block;
  262.     margin: 0 5px;
  263.   }
  264.   
  265.   /* Preserve original navbar item styling in the dropdown */
  266.   .mobile-menu-navbar-item .gaucheitems {
  267.     position: relative;
  268.     display: inline-block;
  269.   }
  270.   
  271.   /* Container spacing */
  272.   .container-fluid {
  273.     padding-left: 8px;
  274.     padding-right: 8px;
  275.   }
  276. }
  277.     </style>
  278.     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/shepherd.js@8.3.1/dist/css/shepherd.css">   
  279.     <nav class="navbar navbar-expand-lg parents_Nav sticky-top" id="sticky-header">
  280.       <div class="container-fluid justify-content-between">
  281.         <!-- Left elements -->
  282.         <div class="d-flex align-items-center">
  283.           <!-- Brand -->
  284.           <a class="navbar-brand me-2 mb-1 d-flex align-items-center desktop-only" onclick='location.href = "{{ path('AccueilParent') }}";'>
  285.             <img class="logo5sur5Header"
  286.                  src="{{ asset('Accueil/imagesAccueil/logoHeader.svg') }}" 
  287.                  alt="5sur5sejour"
  288.                  loading="lazy"
  289.             />
  290.           </a>
  291.         
  292.           <!-- Mobile logo repositioned more to the right -->
  293.           <a class="navbar-brand VMobileBrend mobile-only" onclick='location.href = "{{ path('AccueilParent') }}";'>
  294.             <img class="logo5sur5HeaderMobile"
  295.                  src="{{ asset('Accueil/imagesAccueil/Picto5sur5.svg') }}" 
  296.                  alt="5sur5sejour"
  297.                  loading="lazy"
  298.                  style="height:47px; margin-left:10px; margin-top:-10px"
  299.             />
  300.           </a>
  301.           
  302.           <!-- Help button positioned to the right of logo in mobile -->
  303.           <a class="navbar-brand me-2 mb-1 d-none d-lg-flex align-items-center" style="cursor: pointer;margin-left: 9%;margin-top: 9%;" onclick="loadAndStartTourBasedOnRoute()">
  304.             <i class="bi bi-question-circle" style="color:#41a2aa;font-size:1.5rem"></i>
  305.           </a>
  306.         </div>
  307.         <!-- Left elements -->
  308.      
  309.         <!-- Center elements -->
  310.         <ul class="navbar-nav flex-row d-none d-lg-flex">
  311.           <li class="list-inline-item btn_mainMenuparent me-3 me-lg-1 Nav-lism">
  312.             <a {% if app.session.get("Sejour")!="" %}href="{{path('AccueilParent')}}"{% else %} href="{{path('SejourParent')}}" {% endif %}>
  313.               <img class="NewImgHeader" src="/Accueil/imagesAccueil/sejour.png">
  314.               <h3 class="textBtnManuLeft txtBtnSnSej">Séjour  {{ sejour.codeSejour }}</h3>
  315.             </a>
  316.           </li>
  317.           
  318.           <li class="list-inline-item btn_mainMenuparent me-3 me-lg-1 infosSejourHeader" style="display:none">
  319.             <a style="margin-top: 9px;" {% if app.session.get("Sejour")!="" %}href="{{path('SejourParent')}}"{% else %} href="{{path('SejourParent')}}" {% endif %}>
  320.               <h3 class="txtBtnSnSej" style="top: 11%; color: #41a2aa !important;"> Séjour : </h3>
  321.               <h5 class="datesejourHeader" style=""> du {{ sejour.dateDebutSejour|date("d/m/Y") }} au {{ sejour.dateFinSejour|date("d/m/Y") }} </h5>
  322.             </a>
  323.           </li>
  324.           
  325.           <li class="list-inline-item btn_mainMenuparent no-padding me-3 me-lg-1" onclick='location.href = "{{ path('boutique5sur5') }}"'>
  326.             <a href = "{{ path('boutique5sur5') }}">     
  327.               <img class="NewImgHeader" src="/Accueil/imagesAccueil/boutique.png">
  328.               <h3 class="textBtnManuLeft txtBtnSnSej"> Nos produits </h3>
  329.             </a>
  330.           </li> 
  331.           
  332.           {% if albumAcc !=null %} 
  333.           <li class="list-inline-item btn_mainMenuparent no-padding d-none d-lg-flex albumsejour">
  334.             <a style="margin-top: -10px;" href = '{{ path('Album_du_Sejour') }}' title="Vous pouvez désormais commander votre album séjour">
  335.               <i class="bi bi-book-half" id="selecNav" style="font-size:27px;color:#F09E7A"></i>
  336.               <h3 class="textBtnManuLeft txtBtnSnSej"> Album du séjour </h3>
  337.               <label class="nbrVocal blink"><i class="bi bi-basket" style="color:white"></i></label>
  338.             </a> 
  339.           </li> 
  340.           {% endif %}
  341.           
  342.           <li class="list-inline-item btn_mainMenuparent no-padding Nav-lism" onclick='location.href = "{{ path('Besoindaide_5sur5') }}"'>
  343.             <a>     
  344.               <img class="NewImgHeader" style="width: 30px;" src="/Accueil/imagesAccueil/iconcasque.png">
  345.               <h3 class="textBtnManuLeft txtBtnSnSej">Besoin d'aide </h3>
  346.             </a>
  347.           </li> 
  348.           
  349.           {% if sejour.codeSejour|slice(0, 2) == "EF" and payment == 1 %}
  350.     <input hidden value="{{nbLikes}}">
  351.     <div>
  352.         <li class="list-inline-item btn_mainMenuparent no-padding d-none d-lg-flex albumsejour" id="packOffertSection">
  353.             <a  id="offrePack" href="{{ path('PackPhotosNumerique_Offert', {'nbr': 15}) }}">
  354.                 <i class="bi bi-images" id="selecNav" style="font-size:27px;color:#41a2aa"></i>
  355.                 <h3 class="textBtnManuLeft txtBtnSnSej">Pack offert</h3>
  356.                 <label class="nbrVocal blink"><i class="bi bi-gift" style="color:white;"></i></label>
  357.             </a>
  358.         </li>
  359.     </div>
  360. {% endif %}
  361.         </ul>
  362.         <!-- Center elements -->
  363.     
  364.         <!-- Mobile Navigation Items -->
  365.         <ul class="navbar-nav flex-row d-flex d-lg-none mobile-nav-menu">
  366.           <!-- Nos produits - Always visible in mobile -->
  367.           <li class="list-inline-item btn_mainMenuparent no-padding me-3 me-lg-1" onclick='location.href = "{{ path('boutique5sur5') }}"'>
  368.             <a href = "{{ path('boutique5sur5') }}">     
  369.               <img class="NewImgHeader" src="/Accueil/imagesAccueil/boutique.png">
  370.               <h3 class="textBtnManuLeft txtBtnSnSej"> Nos produits </h3>
  371.             </a>
  372.           </li> 
  373.         </ul>
  374.     
  375.         <!-- Right elements -->
  376.         <ul class="navbar-nav flex-row align-items-center">
  377.           <!-- Service client (hidden) -->
  378.           <li style="display:none" class="list-inline-item menuGaucheHeaderli helpdesk" title="Service client">
  379.             <a style="cursor:pointer" class="gaucheitems" onclick='location.href = "{{path('ServiceClient_Parent')}}";'>
  380.               <i class="bi bi-headset"></i>
  381.             </a>
  382.           </li>
  383.        
  384.           {% if app.user %}{% if app.session.get('Sejour') %}
  385.           <!-- Help button (desktop only) -->
  386.        
  387.           
  388.      
  389.           
  390.           <!-- Vocal Messages (desktop only) -->
  391.           <li class="list-inline-item menuGaucheHeaderli d-none d-lg-block" title="Messages vocaux" style="margin-right:40px">
  392.             {% if code_sejour|slice(0, 2) == 'PF' %}
  393.               <a style="cursor:pointer" class="gaucheitems">
  394.                 <img src="/images/300ppi/ICvocal.png" style="width:30px">
  395.                 <label class="nbrpanier" style="background-color: #f54240" id="">{{nbvocal}}</label>
  396.               </a>
  397.             {% elseif code_sejour|slice(0, 2) == 'PP' and payment == 1 %}
  398.               <a style="cursor:pointer" class="gaucheitems">
  399.                 <img src="/images/300ppi/ICvocal.png" style="width:30px">
  400.                 <label class="nbrpanier" style="background-color: #f54240" id="">{{nbvocal}}</label>
  401.               </a>
  402.             {% elseif code_sejour|slice(0, 2) == 'EF' and payment == 1 %}
  403.               <a  style="cursor:pointer" class="gaucheitems">
  404.                 <img src="/images/300ppi/ICvocal.png" style="width:30px">
  405.                 <label class="nbrpanier" style="background-color: #f54240" id="">{{nbvocal}}</label>
  406.               </a>
  407.             {% elseif code_sejour|slice(0, 2) == 'PP' and payment == 0 %}
  408.               <span style="cursor:not-allowed;opacity:0.5" class="gaucheitems">
  409.                 <img src="/images/300ppi/ICvocal.png" style="width:30px;filter:grayscale(100%)">
  410.                 <label class="nbrpanier" style="background-color: #808080" id="">{{nbvocal}}</label>
  411.               </span>
  412.             {% elseif code_sejour|slice(0, 2) == 'EF' and payment == 0 %}
  413.               <a id="openVocalModalBtn" style="cursor:pointer;opacity:0.5" class="gaucheitems">
  414.                 <img src="/images/300ppi/ICvocal.png" style="width:30px;filter:grayscale(100%)">
  415.                 <label class="nbrpanier" style="background-color: #808080" id="">{{nbvocal}}</label>
  416.               </a>
  417.             {% endif %}
  418.           </li>
  419.     
  420.           <!-- Cart (desktop only) -->
  421.           <li class="list-inline-item menuGaucheHeaderli d-none d-lg-block" title="Mon panier" style="margin-right:40px">
  422.             <a style="cursor:pointer" class="gaucheitems" onclick='location.href = "{{path('MonPanier')}}";'>
  423.               <i class="bi bi-cart-fill cart-link" style="font-size: 1.6rem;line-height: 1.1;color:black;"></i>             
  424.               <label class="nbrpanier" style="background-color: #f54240" id="cart-count">{{Products|length}}</label> 
  425.             </a>
  426.           </li>
  427.           
  428.           <!-- Mobile dropdown for cart and messages -->
  429.           <li class="list-inline-item d-lg-none" title="Menu" onclick="toggleMobileMenu(this);">
  430.             <a style="cursor:pointer" class="gaucheitems">
  431.               <i class="bi bi-three-dots" style="font-size: 1.8rem; margin-top:-5px"></i>
  432.             </a>
  433.             <ul class="mobile-menu-custom-dropdown">
  434.               <!-- This contains the original desktop navbar items -->
  435.               <li class="d-flex align-items-center justify-content-around p-2">
  436.                 <!-- Cart original element -->
  437.                 <div class="mobile-menu-navbar-item">
  438.                   <a style="cursor:pointer" class="gaucheitems" onclick='location.href = "{{path('MonPanier')}}";'>
  439.                     <i class="bi bi-cart-fill cart-link" style="font-size: 1.6rem;line-height: 1.1;color:black;"></i>             
  440.                     <label class="nbrpanier" style="background-color: #f54240" id="cart-count">{{Products|length}}</label> 
  441.                   </a>
  442.                 </div>
  443.                 
  444.                 <!-- Vocal Messages original element with all conditions preserved -->
  445.                 <div class="mobile-menu-navbar-item">
  446.                   {% if code_sejour|slice(0, 2) == 'PF' %}
  447.                     <a  style="cursor:pointer" class="gaucheitems">
  448.                       <img src="/images/300ppi/ICvocal.png" style="width:30px">
  449.                       <label class="nbrpanier" style="background-color: #f54240" id="">{{nbvocal}}</label>
  450.                     </a>
  451.                   {% elseif code_sejour|slice(0, 2) == 'PP' and payment == 1 %}
  452.                     <a  style="cursor:pointer" class="gaucheitems">
  453.                       <img src="/images/300ppi/ICvocal.png" style="width:30px">
  454.                       <label class="nbrpanier" style="background-color: #f54240" id="">{{nbvocal}}</label>
  455.                     </a>
  456.                   {% elseif code_sejour|slice(0, 2) == 'EF' and payment == 1 %}
  457.                     <a  style="cursor:pointer" class="gaucheitems">
  458.                       <img src="/images/300ppi/ICvocal.png" style="width:30px">
  459.                       <label class="nbrpanier" style="background-color: #f54240" id="">{{nbvocal}}</label>
  460.                     </a>
  461.                   {% elseif code_sejour|slice(0, 2) == 'PP' and payment == 0 %}
  462.                     <span style="cursor:not-allowed;opacity:0.5" class="gaucheitems">
  463.                       <img src="/images/300ppi/ICvocal.png" style="width:30px;filter:grayscale(100%)">
  464.                       <label class="nbrpanier" style="background-color: #808080" id="">{{nbvocal}}</label>
  465.                     </span>
  466.                   {% elseif code_sejour|slice(0, 2) == 'EF' and payment == 0 %}
  467.                     <a id="openVocalModalBtn" style="cursor:pointer;opacity:0.5" class="gaucheitems">
  468.                       <img src="/images/300ppi/ICvocal.png" style="width:30px;filter:grayscale(100%)">
  469.                       <label class="nbrpanier" style="background-color: #808080" id="">{{nbvocal}}</label>
  470.                     </a>
  471.                   {% endif %}
  472.                 </div>
  473.         
  474.             
  475.               </li>
  476.             </ul>
  477.           </li>
  478.                                                     
  479.           <!-- Profile dropdown (both mobile and desktop) -->
  480.           <li class="list-inline-item menuGaucheHeaderli" title="" onclick="displayDD($(this));">
  481.             <a style="cursor:pointer" class="gaucheitems">  
  482.               <i class="bi bi-person-fill" style="color:black; margin-bottom: 10px;line-height: 0.8px;font-size: 1.8rem;"></i>
  483.             </a>
  484.             <ul class="submenu DD_nosPrd2">
  485.               <li class="ligne_compte" style="cursor:pointer">
  486.                 <a class="link_compte" onclick='location.href = "{{path('ParametresParent')}}";'>
  487.                   <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-person-fill-gear" viewBox="0 0 16 16">
  488.                     <path d="M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0m-9 8c0 1 1 1 1 1h5.256A4.493 4.493 0 0 1 8 12.5a4.49 4.49 0 0 1 1.544-3.393C9.077 9.038 8.564 9 8 9c-5 0-6 3-6 4m9.886-3.54c.18-.613 1.048-.613 1.229 0l.043.148a.64.64 0 0 0 .921.382l.136-.074c.561-.306 1.175.308.87.869l-.075.136a.64.64 0 0 0 .382.92l.149.045c.612.18.612 1.048 0 1.229l-.15.043a.64.64 0 0 0-.38.921l.074.136c.305.561-.309 1.175-.87.87l-.136-.075a.64.64 0 0 0-.92.382l-.045.149c-.18.612-1.048.612-1.229 0l-.043-.15a.64.64 0 0 0-.921-.38l-.136.074c-.561.305-1.175-.309-.87-.87l.075-.136a.64.64 0 0 0-.382-.92l-.148-.045c-.613-.18-.613-1.048 0-1.229l.148-.043a.64.64 0 0 0 .382-.921l-.074-.136c-.306-.561.308-1.175.869-.87l.136.075a.64.64 0 0 0 .92-.382l.045-.148ZM14 12.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0"></path>
  489.                   </svg>
  490.                   Mon compte
  491.                 </a>
  492.               </li>
  493.               {% if app.session.get('Sejour') %}
  494.               <li class="ligne_compte" style="cursor:pointer">
  495.                 <a class="link_compte" onclick='location.href = "{{path('projet-Parent')}}";'>
  496.                   <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" class="bi bi-bag-heart" viewBox="0 0 16 16">
  497.                     <path fill-rule="evenodd" d="M10.5 3.5a2.5 2.5 0 0 0-5 0V4h5zm1 0V4H15v10a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4h3.5v-.5a3.5 3.5 0 1 1 7 0M14 14V5H2v9a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1M8 7.993c1.664-1.711 5.825 1.283 0 5.132-5.825-3.85-1.664-6.843 0-5.132"></path>
  498.                   </svg>
  499.                   Mes créations
  500.                 </a>
  501.               </li>
  502.               {% endif %}
  503.               <li class='ligne_compte' style="cursor:pointer">
  504.                 <a class="link_compte" onclick='location.href = "{{path('SuiviCommandeparent')}}";'>
  505.                   <i class="bi bi-bag-check-fill" style="font-size:1.3rem;margin-right:3px"></i>
  506.                   Mes Commandes
  507.                 </a>
  508.               </li>
  509.               <li class="ligne_compte" style="cursor:pointer">
  510.                 <a class="link_compte" onclick='location.href = "{{path('SejourParent')}}";'>
  511.                   <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-suitcase-lg" viewBox="0 0 16 16">
  512.                     <path d="M5 2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2h3.5A1.5 1.5 0 0 1 16 3.5v9a1.5 1.5 0 0 1-1.5 1.5H14a.5.5 0 0 1-1 0H3a.5.5 0 0 1-1 0h-.5A1.5 1.5 0 0 1 0 12.5v-9A1.5 1.5 0 0 1 1.5 2zm1 0h4a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1M1.5 3a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5H3V3zM15 12.5v-9a.5.5 0 0 0-.5-.5H13v10h1.5a.5.5 0 0 0 .5-.5m-3 .5V3H4v10z"></path>
  513.                   </svg>
  514.                   Mes séjours
  515.                 </a>
  516.               </li>
  517.               <li class="ligne_compte" style="cursor:pointer">
  518.                 <a class="link_compte" onclick='location.href = "{{path('Besoindaide_Parent')}}";'>
  519.                   <i class="bi bi-question-circle" style="font-size:1.3rem;margin-right:3px"></i>
  520.                   FAQ
  521.                 </a>
  522.               </li>
  523.               <li class="ligne_compte" style="cursor:pointer">
  524.                 <a class="link_compte" href="/Parent/logout" style="font-weight:700;">
  525.                   <i class="bi bi-power" style="margin-right: 3px;font-size: 1.5rem;color:red"></i>
  526.                   Me déconnecter
  527.                 </a>
  528.               </li>
  529.             </ul>
  530.           </li>
  531.           
  532.           <!-- Partner logo -->
  533.           {%if sejour.idPartenaire.logourl != null and sejour.idPartenaire.logourl != "" and sejour.idPartenaire.logourl is not empty%}
  534.           <li>
  535.             <img class="logopartenaire" alt="Logo partenaire" src="{{sejour.idPartenaire.logourl}}">
  536.           </li>
  537.           {%endif%}
  538.           {% endif %} {% endif %}
  539.         </ul>
  540.         <!-- Right elements -->
  541.       </div>
  542.     </nav>
  543.   <div class="vocal-modal-overlay" id="vocalModalOverlay">
  544.     <div class="vocal-modal">
  545.       <div class="vocal-modal-content">
  546.         <h2 style="color: #3CA9AB; font-size: 18px; margin-top: 0; margin-bottom: 12px;">Accès à la boîte vocale</h2>
  547.         
  548.         <!-- Image placeholder -->
  549.         <div style="text-align: center; margin: 12px 0;">
  550.           <img src="/images/callpopover.png" alt="Illustration messages vocaux" style="max-width: 50%; border-radius: 6px;"/>
  551.         </div>
  552.         
  553.         
  554.         <div class="vocal-feature">
  555.           <div class="vocal-feature-icon">
  556.             <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#333">
  557.               <path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 12h2c0-4.97-4.03-9-9-9v2c3.87 0 7 3.13 7 7zm-4 0h2c0-2.76-2.24-5-5-5v2c1.66 0 3 1.34 3 3z"/>
  558.             </svg>
  559.           </div>
  560.           <div class="vocal-feature-text">
  561.             <div class="vocal-feature-title">Recevez un appel à chaque nouveau message</div>
  562.             <p class="vocal-feature-desc">À chaque enregistrement, vous recevez un appel avec le message vocal.</p>
  563.             <p class="vocal-feature-desc" style="color: #E9553B; font-weight: bold;">Coût : 2,90 € par message.</p>
  564.           </div>
  565.         </div>
  566.         
  567.         <div class="vocal-feature">
  568.           <div class="vocal-feature-icon">
  569.             <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#1D75BB">
  570.               <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
  571.             </svg>
  572.           </div>
  573.           <div class="vocal-feature-text">
  574.             <div class="vocal-feature-title">Accédez aux messages vocaux en illimité sur le web</div>
  575.             <p class="vocal-feature-desc">Consultez tous les messages directement sur la plateforme, sans restriction.</p>
  576.             <p class="vocal-feature-desc" style="color: #3CA9AB; font-weight: bold;">Inclus sans frais supplémentaires.</p>
  577.           </div>
  578.         </div>
  579.         
  580.         <div class="vocal-feature">
  581.           <div class="vocal-feature-icon">
  582.             <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#4CAF50">
  583.               <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
  584.             </svg>
  585.           </div>
  586.           <div class="vocal-feature-text">
  587.             <div class="vocal-feature-title">Vous bénéficiez des deux options automatiquement.</div>
  588.             <p class="vocal-feature-desc">Cliquez sur <strong>"Confirmer"</strong> pour activer votre accès.</p>
  589.           </div>
  590.         </div>
  591.       </div>
  592.       
  593.       <div class="vocal-modal-buttons">
  594.         <button class="vocal-btn vocal-btn-cancel" id="vocalCancelBtn">Annuler</button>
  595.         <button class="vocal-btn vocal-btn-confirm" id="vocalConfirmBtn">Confirmer</button>
  596.       </div>
  597.     </div>
  598.   </div>
  599.  <script src="{{'/Plugins/js/jquery-3.4.1.js'}}"></script>
  600.    <script src="{{'/Plugins/js/popper.js'}}"></script>
  601.    <script src="{{'/Plugins/js/bootstrap.min.js'}}"></script>
  602.    <script src="{{ asset('js/shepherd-tours.js') }}"></script>
  603.    <script>
  604.     
  605.     const openVocalModalBtn = document.getElementById('openVocalModalBtn');
  606.     const vocalModalOverlay = document.getElementById('vocalModalOverlay');
  607.     const vocalCancelBtn = document.getElementById('vocalCancelBtn');
  608.     const vocalConfirmBtn = document.getElementById('vocalConfirmBtn');
  609.     
  610.     // Function to open modal
  611.     function openVocalModal() {
  612.       vocalModalOverlay.style.display = 'flex';
  613.       vocalModalOverlay.classList.add('vocal-fade-in');
  614.     }
  615.     
  616.     // Function to close modal
  617.     function closeVocalModal() {
  618.       vocalModalOverlay.style.display = 'none';
  619.     }
  620.     
  621.     // Event listeners
  622.     openVocalModalBtn.addEventListener('click', openVocalModal);
  623.     vocalCancelBtn.addEventListener('click', closeVocalModal);
  624.     vocalConfirmBtn.addEventListener('click', () => {
  625.       // Redirect to messages page
  626.       window.location.href = '/Parent/achatBoiteVocale';
  627.     });
  628.     
  629.     // Close when clicking outside the modal
  630.     vocalModalOverlay.addEventListener('click', (event) => {
  631.       if (event.target === vocalModalOverlay) {
  632.         closeVocalModal();
  633.       }
  634.     });
  635.     function toggleMobileMenu(element) {
  636.   // Close any other open dropdowns first
  637.   const allDropdowns = document.querySelectorAll('.mobile-menu-custom-dropdown');
  638.   allDropdowns.forEach(dropdown => {
  639.     if (dropdown !== element.querySelector('.mobile-menu-custom-dropdown')) {
  640.       dropdown.style.display = 'none';
  641.     }
  642.   });
  643.   
  644.   // Toggle the clicked dropdown
  645.   const dropdown = element.querySelector('.mobile-menu-custom-dropdown');
  646.   if (dropdown.style.display === 'block') {
  647.     dropdown.style.display = 'none';
  648.   } else {
  649.     dropdown.style.display = 'block';
  650.   }
  651.   
  652.   // Stop propagation for links inside the dropdown
  653.   const dropdownLinks = dropdown.querySelectorAll('a, span');
  654.   dropdownLinks.forEach(link => {
  655.     link.addEventListener('click', function(e) {
  656.       e.stopPropagation();
  657.     });
  658.   });
  659.   
  660.   // Specifically handle the modal button click
  661.   const modalBtn = dropdown.querySelector('#openVocalModalBtn');
  662.   if (modalBtn) {
  663.     modalBtn.onclick = function(e) {
  664.       e.stopPropagation();
  665.       // If there's an existing click handler on this button, we should preserve it
  666.       // This is a placeholder for whatever the original modal opening code is
  667.       if (typeof openVocalModal === 'function') {
  668.         openVocalModal();
  669.       }
  670.       // If the modal is opened by a data attribute or other mechanism, we don't need to do anything else
  671.     };
  672.   }
  673.   
  674.   // Close dropdown when clicking outside
  675.   document.addEventListener('click', function closeDropdown(event) {
  676.     if (!element.contains(event.target)) {
  677.       dropdown.style.display = 'none';
  678.       document.removeEventListener('click', closeDropdown);
  679.     }
  680.   });
  681.   
  682.   // Prevent the click from propagating
  683.   event.stopPropagation();
  684. }
  685.     
  686.     function loadAndStartTourBasedOnRoute() {
  687.     // Get the current route/path
  688.     const currentPath = window.location.pathname;
  689.     
  690.     
  691.     // Determine which tour to start based on the route
  692.     let tourFunction = null;
  693.     
  694.     if (currentPath.includes('/Parent/AccueilParent')) {
  695.         tourFunction = 'startSejourTour';
  696.     } else if (currentPath.includes('/Parent/AjoutAlbum')) {
  697.         tourFunction = 'startAlbumTour';
  698.     }
  699.     else if (currentPath.includes('/Parent/LivrePhotos')) {
  700.         tourFunction = 'startAlbumTour';
  701.     }
  702.     else if (currentPath.includes('/Parent/AjoutRetroPhotos_Fav/12')) {
  703.         tourFunction = 'startRetroPhotosTour';
  704.     }
  705.     else if (currentPath.includes('/Parent/AjoutRetroPhotos_Fav/24')) {
  706.         tourFunction = 'startRetroPhotosTour';
  707.     } 
  708.     else if (currentPath.includes('/Parent/AjoutRetroPhotos_Fav/36')) {
  709.         tourFunction = 'startRetroPhotosTour';
  710.     }
  711.     else if (currentPath.includes('/Parent/AjoutPochettePhotos_Fav/12')) {
  712.         tourFunction = 'startTiragePhotosTour';
  713.     } 
  714.     else if (currentPath.includes('/Parent/AjoutPochettePhotos_Fav/24')) {
  715.         tourFunction = 'startTiragePhotosTour';
  716.     } 
  717.     else if (currentPath.includes('/Parent/AjoutPochettePhotos_Fav/36')) {
  718.         tourFunction = 'startTiragePhotosTour';
  719.     }
  720.     else if (currentPath.includes('/Parent/PackPhotosNumerique_Favoris/20')) {
  721.         tourFunction = 'startPackNumeriqueTour';
  722.     } 
  723.     else if (currentPath.includes('/Parent/PackPhotosNumerique_Favoris/30')) {
  724.         tourFunction = 'startPackNumeriqueTour';
  725.     } 
  726.     else if (currentPath.includes('/Parent/PackPhotosNumerique_Favoris/50')) {
  727.         tourFunction = 'startPackNumeriqueTour';
  728.     }   else {
  729.         // Default or handle other routes
  730.         console.log('No tour available for this route');
  731.         return;
  732.     }
  733.     
  734.     // Make sure shepherd-tours.js is loaded
  735.     const loadTourScript = function() {
  736.         var script = document.createElement('script');
  737.         script.src = "/js/shepherd-tours.js";
  738.         script.onload = function() {
  739.             console.log(`Tour script loaded, checking for ${tourFunction}`);
  740.             
  741.             // Check if the tour function is now available
  742.             if (typeof window[tourFunction] === 'function') {
  743.                 console.log(`${tourFunction} function found, starting tour`);
  744.                 
  745.                 // Make sure Shepherd is loaded
  746.                 if (typeof Shepherd === 'undefined') {
  747.                     console.log("Loading Shepherd.js");
  748.                     var shepherdScript = document.createElement('script');
  749.                     shepherdScript.src = "https://cdn.jsdelivr.net/npm/shepherd.js@8.3.1/dist/js/shepherd.min.js";
  750.                     shepherdScript.onload = function() {
  751.                         console.log("Shepherd.js loaded, starting tour");
  752.                         window[tourFunction]();
  753.                     };
  754.                     document.head.appendChild(shepherdScript);
  755.                 } else {
  756.                     console.log("Shepherd.js already loaded, starting tour");
  757.                     window[tourFunction]();
  758.                 }
  759.             } else {
  760.                 console.error(`Tour function ${tourFunction} not found after loading script`);
  761.             }
  762.         };
  763.         script.onerror = function() {
  764.             console.error("Failed to load tour script");
  765.         };
  766.         document.head.appendChild(script);
  767.     };
  768.     
  769.     // Check if the tour function exists already
  770.     if (typeof window[tourFunction] === 'function') {
  771.         console.log(`${tourFunction} already available`);
  772.         
  773.         // Make sure Shepherd is loaded
  774.         if (typeof Shepherd === 'undefined') {
  775.             console.log("Loading Shepherd.js");
  776.             var shepherdScript = document.createElement('script');
  777.             shepherdScript.src = "https://cdn.jsdelivr.net/npm/shepherd.js@8.3.1/dist/js/shepherd.min.js";
  778.             shepherdScript.onload = function() {
  779.                 console.log("Shepherd.js loaded, starting tour");
  780.                 window[tourFunction]();
  781.             };
  782.             document.head.appendChild(shepherdScript);
  783.         } else {
  784.             console.log("Shepherd.js already loaded, starting tour");
  785.             window[tourFunction]();
  786.         }
  787.     } else {
  788.         console.log(`${tourFunction} not found, loading tour script`);
  789.         loadTourScript();
  790.     }
  791. }
  792.     function addToCartAnimation() {
  793.     const cartIcon = document.querySelector('.bi-cart-fill');
  794.     if (cartIcon) {
  795.         cartIcon.classList.add('cart-bounce');
  796.         setTimeout(() => {
  797.             cartIcon.classList.remove('cart-bounce');
  798.         }, 600); // Durée de l'animation (600ms)
  799.     }
  800. }
  801.     </script>
  802.     <script>
  803.         
  804.         $(document).ready(function() {
  805.     // Function to check if Panier contains a product with type 20
  806.     function checkPanier() {
  807.         $.ajax({
  808.             url: '{{ path("disablePack") }}',
  809.             method: 'GET',
  810.             dataType: 'json',
  811.             success: function(response) {
  812.                 
  813.                 if (response.containsProduitType20 || response.idSejour == 0) {
  814.                     
  815.                     // Disable the section by adding a class
  816.                     $('#packOffertSection').addClass('disabled-section');
  817.                     $('#packOffertSection .disabled-element').addClass('disabled-element');
  818.                 } else {
  819.                 
  820.                     // Re-enable the section by removing the disabled classes
  821.                     $('#packOffertSection').removeClass('disabled-section');
  822.                     $('#packOffertSection .disabled-element').removeClass('disabled-element');
  823.                     // Initialize popover if needed
  824.                     initPopover();
  825.                 }
  826.             },
  827.             error: function(xhr, status, error) {
  828.                 console.error('AJAX request failed:', status, error);
  829.             }
  830.         });
  831.     }
  832.     // Function to initialize the popover
  833.     function initPopover() {
  834.         $('#offrePack').popover({
  835.             title: 'Pack numérique inclut <a href="#" class="close" data-dismiss="alert">&times;</a>',
  836.             content: '<div>Profitez d\'un pack numérique inclut dans votre connexion Wahou!</div><a href="{{ path('PackPhotosNumerique_Offert', {'nbr': 15}) }}" class="btn custom-button">J\'en profite</a>',
  837.             html: true,
  838.             placement: 'bottom',
  839.             trigger: 'manual'
  840.         });
  841.         $('#offrePack').on('mouseenter', function() {
  842.             $(this).popover('show');
  843.         });
  844.         $(document).on('modalClosed', function() {
  845.             $('#offrePack').popover('show');
  846.         });
  847.         $(document).on('click', '.popover .close', function() {
  848.             $('#offrePack').popover('hide');
  849.         });
  850.         $(document).on('click', function(e) {
  851.             if (!$(e.target).closest('#offrePack').length && !$(e.target).closest('.popover').length) {
  852.                 $('#offrePack').popover('hide');
  853.             }
  854.         });
  855.     }
  856.     // Call the checkPanier function on document ready
  857.     checkPanier();
  858. });
  859. </script>
  860. <!-- Navbar -->