templates/default/index.html.twig line 1

  1. {% extends 'base_front.html.twig' %}
  2. {% block title %}Hello DefaultController!{% endblock %}
  3. {% block body %}
  4. <section id="animated-slider" class="slider-with-animations">
  5.     <!-- Fond flou dynamique (optionnel) -->
  6.     <div class="slider-background"></div>
  7.     <div class="swiper-container">
  8.         <div class="swiper-wrapper">
  9.            {% for actualite in actualites %}
  10.             <div class="swiper-slide">
  11.                 <div class="slide-content">
  12.                     <a href="upload/actualites/{{ actualite.imageNom }}" data-lightbox="animated-gallery">
  13.                         <img src="upload/actualites/{{ actualite.imageNom }}" alt="Image 1" class="slide-image">
  14.                         <div class="slide-caption animate-on-scroll">
  15.                            <!-- <h3 class="title-animate">Titre Image 1</h3>-->
  16.                              <!--<p class="desc-animate">Description de l'image 1</p>-->
  17.                         </div>
  18.                     </a>
  19.                 </div>
  20.             </div>
  21.         {% endfor %}
  22.             <!-- Slide 1 -->
  23.           {#   <div class="swiper-slide">
  24.                 <div class="slide-content">
  25.                     <a href="upload/actualites/actualite_photo_15.jpg" data-lightbox="animated-gallery">
  26.                         <img src="upload/actualites/actualite_photo_15.jpg" alt="Image 1" class="slide-image">
  27.                         <div class="slide-caption animate-on-scroll">
  28.                            <!-- <h3 class="title-animate">Titre Image 1</h3>-->
  29.                              <!--<p class="desc-animate">Description de l'image 1</p>-->
  30.                         </div>
  31.                     </a>
  32.                 </div>
  33.             </div>
  34.             
  35.             <!-- Slide 2 -->
  36.             <div class="swiper-slide">
  37.                 <div class="slide-content">
  38.                     <a href="upload/actualites/actualite_photo_16.jpg" data-lightbox="animated-gallery">
  39.                         <img src="upload/actualites/actualite_photo_16.jpg" alt="Image 2" class="slide-image">
  40.                         <div class="slide-caption animate-on-scroll">
  41.                           <!--  <h3 class="title-animate">Titre Image 2</h3>-->
  42.                           <!--  <p class="desc-animate">Description de l'image 2</p>-->
  43.                         </div>
  44.                     </a>
  45.                 </div>
  46.             </div>
  47.         </div>#}
  48.         
  49.         <!-- Navigation -->
  50.         
  51.         
  52.         <!-- Pagination with animation -->
  53.         <div class="swiper-pagination anim-pag"></div>
  54.     </div>
  55. </section>
  56.     
  57.     <!-- Content ============================================= -->
  58.     <!--
  59.     <section id="content">
  60.     <div class="content-wrap" style="padding: 0;">
  61.         <div class="container mb-4">
  62.             <h2 class="text-center mb-4 ls-1">Nos Projets</h2>
  63.            <div class="row justify">
  64.     {% if projets is empty %}
  65.         <p class="text-center">Aucun projet disponible pour le moment.</p>
  66.     {% else %}
  67.         {% for projet in projets %}
  68.             <div class="col-sm-6 col-lg-3 mb-4">
  69.                 <a href="{{ path('app_projet_details', {'id': projet.id}) }}">
  70.                     <div class="feature-box media-box">
  71.                         <div class="fbox-media">
  72.                             {% if projet.image is not null %}
  73.                                 <img class="rounded img-fluid" src="/upload/projets/{{ projet.image }}" alt="{{ projet.image }}" style="height:50%;">
  74.                             {% else %}
  75.                                 <img class="rounded img-fluid" src="/upload/staicImage/logoProjetStatic.png" alt="Default Image" style="height:112px;width: 39%;">
  76.                             {% endif %}
  77.                         </div>
  78.                         <div class="fbox-content px-2">
  79.                             <h3>{{ projet.nom }}<span class="subtitle">{{ projet.structure.nomLong }}</span></h3>
  80.                         </div>
  81.                     </div>
  82.                 </a>
  83.             </div>
  84.         {% endfor %}
  85.     {% endif %}
  86. </div>
  87.         </div>
  88.     </div>
  89. </section>
  90.     -->
  91.     <!-- #content end -->
  92.     <!-- Content ============================================= -->
  93.   
  94.     <section id="content" class="research-content">
  95.         <div class="content-wrap" style="padding: 0;">
  96.             <!-- Projects Section -->
  97.             <div class="container py-5">
  98.                 <div class="section-header text-center mb-5">
  99.                     <h2 class="section-title">Certains de nos projets les plus appréciés</h2>
  100.                 </div>
  101.                 
  102.                 <div class="row g-4 justify-content-center">
  103.                     {% if projets is empty %}
  104.                         <p class="text-center">Aucun projet disponible pour le moment.</p>
  105.                     {% else %}
  106.                         {% for projet in projets %}
  107.                             <div class="col-sm-6 col-lg-3">
  108.                                 <div class="project-card">
  109.                                     <div class="project-media">
  110.                                         {% if projet.image is not null %}
  111.                                             <img class="project-image" src="/upload/projets/{{ projet.image }}" alt="{{ projet.nom }}">
  112.                                         {% else %}
  113.                                             <img class="project-image" src="/upload/staicImage/empty-project.jpg" alt="{{ projet.nom }}">
  114.                                         {% endif %}
  115.                                         <div class="project-overlay">
  116.                                             <a href="{{ path('app_projet_details', {'id': projet.id}) }}" class="btn btn-outline-light">Voir le projet</a>
  117.                                         </div>
  118.                                     </div>
  119.                                     <div class="project-content">
  120.                                         <h3 class="project-title">
  121.                                             <a href="{{ path('app_projet_details', {'id': projet.id}) }}">
  122.                                                 {{ projet.nom }}
  123.                                             </a>
  124.                                         </h3>
  125.                                         <p class="project-category">{{ projet.structure.nomLong }}</p>
  126.                                     </div>
  127.                                 </div>
  128.                             </div>
  129.                         {% endfor %}
  130.                     {% endif %}
  131.                     
  132.                 </div>
  133.             </div>
  134.             <!-- Stats Section -->
  135.             <div class="stats-section py-5">
  136.                 <div class="container">
  137.                     <div class="row g-4 justify-content-center">
  138.                         <div class="col-lg-3 col-md-6">
  139.                             <div class="stat-card">
  140.                                 <div class="stat-icon">
  141.                                     <img src="/front/icons/structure-recherche.png" alt="Structures de recherche">
  142.                                 </div>
  143.                                {#  <div class="stat-content">
  144.                                     <div class="stat-number counter" data-from="0" data-target="{{ nbrStructureRecherche }}">0</div>
  145.                                     <h3 class="stat-title">Structures de recherche</h3>
  146.                                 </div>#}
  147.                                 <div class="stat-content position-relative text-center">
  148.                                     <!-- Badge container with subtle border and shadow -->
  149.                                     <div class="stat-badge position-relative bg-white rounded-4 p-2 shadow-sm mb-3">
  150.                                         <!-- Animated counter number -->
  151.                                         <div class="stat-number counter display-3 fw-bold mb-1" data-target="{{ nbrStructureRecherche }}">0</div>
  152.                                     </div>
  153.                                     <!-- Title with animated underline -->
  154.                                     <h3 class="stat-title fs-5 fw-medium text-uppercase letter-spacing-1 position-relative d-inline-block px-3">
  155.                                         Structures de recherche
  156.                                         <span class="title-underline"></span>
  157.                                     </h3>
  158.                                     <!-- Decorative corner elements -->
  159.                                    {#  <span class="position-absolute top-0 start-0 stat-corner stat-corner-tl"></span>
  160.                                     <span class="position-absolute top-0 end-0 stat-corner stat-corner-tr"></span>
  161.                                     <span class="position-absolute bottom-0 start-0 stat-corner stat-corner-bl"></span>
  162.                                     <span class="position-absolute bottom-0 end-0 stat-corner stat-corner-br"></span>#}
  163.                                 </div>
  164.                             </div>
  165.                         </div>
  166.                         
  167.                         <div class="col-lg-3 col-md-6">
  168.                             <div class="stat-card">
  169.                                 <div class="stat-icon">
  170.                                     <img src="/front/icons/chercheurs.png" alt="Chercheurs">
  171.                                 </div>
  172.                                {#  <div class="stat-content">
  173.                                     <div class="stat-number counter" data-from="0" data-target="{{ nbrChercheurs }}">0</div>
  174.                                     <h3 class="stat-title">Chercheurs</h3>
  175.                                 </div>#}
  176.                                 <div class="stat-content position-relative text-center">
  177.                                     <!-- Badge container with subtle border and shadow -->
  178.                                     <div class="stat-badge position-relative bg-white rounded-4 p-2 shadow-sm mb-3">
  179.                                         <!-- Animated counter number -->
  180.                                         <div class="stat-number counter display-3 fw-bold  mb-1" data-target="{{ nbrChercheurs }}">0</div>
  181.                                     </div>
  182.                                     <!-- Title with animated underline -->
  183.                                     <h3 class="stat-title fs-5 fw-medium text-uppercase letter-spacing-1 position-relative d-inline-block px-3">
  184.                                         Chercheurs
  185.                                         <span class="title-underline"></span>
  186.                                     </h3>
  187.                                     <!-- Decorative corner elements -->
  188.                                     {#  <span class="position-absolute top-0 start-0 stat-corner stat-corner-tl"></span>
  189.                                     <span class="position-absolute top-0 end-0 stat-corner stat-corner-tr"></span>
  190.                                     <span class="position-absolute bottom-0 start-0 stat-corner stat-corner-bl"></span>
  191.                                     <span class="position-absolute bottom-0 end-0 stat-corner stat-corner-br"></span>#}
  192.                                 </div>
  193.                             </div>
  194.                         </div>
  195.                         
  196.                         <div class="col-lg-3 col-md-6">
  197.                             <div class="stat-card">
  198.                                 <div class="stat-icon">
  199.                                     <img src="/front/icons/projet.png" alt="Projets">
  200.                                 </div>
  201.                                 {#<div class="stat-content">
  202.                                     <div class="stat-number counter" data-from="0" data-target="{{ nbrProjet }}">0</div>
  203.                                     <h3 class="stat-title">Projets</h3>
  204.                                 </div>#}
  205.                                 <div class="stat-content position-relative text-center">
  206.                                     <!-- Badge container with subtle border and shadow -->
  207.                                     <div class="stat-badge position-relative bg-white rounded-4 p-2 shadow-sm mb-3">
  208.                                         <!-- Animated counter number -->
  209.                                         <div class="stat-number counter display-3 fw-bold  mb-1" data-target="{{ nbrProjet }}">0</div>
  210.                                     </div>
  211.                                     <!-- Title with animated underline -->
  212.                                     <h3 class="stat-title fs-5 fw-medium text-uppercase letter-spacing-1 position-relative d-inline-block px-3">
  213.                                         Projets
  214.                                         <span class="title-underline"></span>
  215.                                     </h3>
  216.                                     <!-- Decorative corner elements -->
  217.                                     {#  <span class="position-absolute top-0 start-0 stat-corner stat-corner-tl"></span>
  218.                                     <span class="position-absolute top-0 end-0 stat-corner stat-corner-tr"></span>
  219.                                     <span class="position-absolute bottom-0 start-0 stat-corner stat-corner-bl"></span>
  220.                                     <span class="position-absolute bottom-0 end-0 stat-corner stat-corner-br"></span>#}
  221.                                 </div>
  222.                             </div>
  223.                         </div>
  224.                         
  225.                         <div class="col-lg-3 col-md-6">
  226.                             <div class="stat-card">
  227.                                 <div class="stat-icon">
  228.                                     <img src="/front/icons/journal.png" alt="Publications">
  229.                                 </div>
  230.                                 {#<div class="stat-content">
  231.                                     <div class="stat-number counter" data-from="0"  data-target="{{ nbrPublications }}">0</div>
  232.                                     <h3 class="stat-title">Publications</h3>
  233.                                 </div>#}
  234.                                 <div class="stat-content position-relative text-center">
  235.                                     <!-- Badge container with subtle border and shadow -->
  236.                                     <div class="stat-badge position-relative bg-white rounded-4 p-2 shadow-sm mb-3">
  237.                                         <!-- Animated counter number -->
  238.                                         <div class="stat-number counter display-3 fw-bold mb-1" data-target="{{ nbrPublications }}">0</div>
  239.                                     </div>
  240.                                     <!-- Title with animated underline -->
  241.                                     <h3 class="stat-title fs-5 fw-medium text-uppercase letter-spacing-1 position-relative d-inline-block px-3">
  242.                                         Publications
  243.                                         <span class="title-underline"></span>
  244.                                     </h3>
  245.                                     <!-- Decorative corner elements -->
  246.                                    {#  <span class="position-absolute top-0 start-0 stat-corner stat-corner-tl"></span>
  247.                                     <span class="position-absolute top-0 end-0 stat-corner stat-corner-tr"></span>
  248.                                     <span class="position-absolute bottom-0 start-0 stat-corner stat-corner-bl"></span>
  249.                                     <span class="position-absolute bottom-0 end-0 stat-corner stat-corner-br"></span>#}
  250.                                 </div>
  251.                             </div>
  252.                         </div>
  253.                     </div>
  254.                 </div>
  255.             </div>
  256.         </div>
  257.     </section>
  258.     <!-- #content end -->
  259.     <script>
  260. document.addEventListener('DOMContentLoaded', function() {
  261.     const originalImages = Array.from(document.querySelectorAll('.swiper-slide img')).map(img => img.src);
  262.     
  263.     let lastBackgroundIndex = null;
  264.     const slider = new Swiper('.swiper-container', {
  265.         loop: true,
  266.         autoplay: {
  267.             delay: 6000,
  268.             disableOnInteraction: false,
  269.         },
  270.         pagination: {
  271.             el: '.swiper-pagination',
  272.             clickable: true,
  273.         },
  274.         on: {
  275.             init: function() {
  276.                 updateBackground(this.realIndex);
  277.             },
  278.             slideChangeTransitionEnd: function() {
  279.                 // On utilise slideChangeTransitionEnd au lieu de slideChange
  280.                 updateBackground(this.realIndex);
  281.             }
  282.         }
  283.     });
  284.     function updateBackground(realIndex) {
  285.         // Calculer l'index correct (0 ou 1) pour nos 2 slides
  286.         const backgroundIndex = realIndex % originalImages.length;
  287.         
  288.         // Ne rien faire si l'arrière-plan est déjà à jour
  289.         if (backgroundIndex === lastBackgroundIndex) return;
  290.         
  291.         const bg = document.querySelector('.slider-background');
  292.         const imgSrc = originalImages[backgroundIndex];
  293.         
  294.         // Préchargement de l'image
  295.         const tempImg = new Image();
  296.         tempImg.onload = function() {
  297.             bg.style.backgroundImage = `url(${imgSrc})`;
  298.             bg.style.opacity = '0.7';
  299.             lastBackgroundIndex = backgroundIndex;
  300.         };
  301.         tempImg.onerror = function() {
  302.             console.error("Erreur de chargement de l'image de fond");
  303.         };
  304.         tempImg.src = imgSrc;
  305.     }
  306.   
  307.     // Stocker les URLs des images originales (sans les slides dupliquées)
  308.    /* const originalImages = [
  309.         document.querySelector('.swiper-slide:nth-child(1) img').src,
  310.         document.querySelector('.swiper-slide:nth-child(2) img').src
  311.     ];
  312.     
  313.     let lastBackgroundIndex = null;
  314.     const slider = new Swiper('.swiper-container', {
  315.         loop: true,
  316.         autoplay: {
  317.             delay: 6000,
  318.             disableOnInteraction: false,
  319.         },
  320.         pagination: {
  321.             el: '.swiper-pagination',
  322.             clickable: true,
  323.         },
  324.         on: {
  325.             init: function() {
  326.                 updateBackground(this.realIndex);
  327.             },
  328.             slideChangeTransitionEnd: function() {
  329.                 // On utilise slideChangeTransitionEnd au lieu de slideChange
  330.                 updateBackground(this.realIndex);
  331.             }
  332.         }
  333.     });
  334.     function updateBackground(realIndex) {
  335.         // Calculer l'index correct (0 ou 1) pour nos 2 slides
  336.         const backgroundIndex = realIndex % 2;
  337.         
  338.         // Ne rien faire si l'arrière-plan est déjà à jour
  339.         if (backgroundIndex === lastBackgroundIndex) return;
  340.         
  341.         const bg = document.querySelector('.slider-background');
  342.         const imgSrc = originalImages[backgroundIndex];
  343.         
  344.         // Préchargement de l'image
  345.         const tempImg = new Image();
  346.         tempImg.onload = function() {
  347.             bg.style.backgroundImage = `url(${imgSrc})`;
  348.             bg.style.opacity = '0.7';
  349.             lastBackgroundIndex = backgroundIndex;
  350.         };
  351.         tempImg.onerror = function() {
  352.             console.error("Erreur de chargement de l'image de fond");
  353.         };
  354.         tempImg.src = imgSrc;
  355.     }*/
  356.      const counters = document.querySelectorAll('.counter');
  357.         const speed = 200;        
  358.         counters.forEach(counter => {
  359.             const target = +counter.getAttribute('data-target');
  360.             const count = +counter.innerText;
  361.             const increment = target / speed;
  362.            
  363.             
  364.             if (count < target) {
  365.                 counter.innerText = Math.ceil(count + increment);
  366.                 setTimeout(updateCounter, 1);
  367.             } else {
  368.                 counter.innerText = target;
  369.             }
  370.             
  371.             function updateCounter() {
  372.                 const count = +counter.innerText;
  373.                 if (count < target) {
  374.                     counter.innerText = Math.ceil(count + increment);
  375.                     setTimeout(updateCounter, 1);
  376.                 } else {
  377.                     counter.innerText = target;
  378.                 }
  379.             }
  380.         });
  381. });
  382.  
  383. </script>
  384. {% endblock %}