templates/home/landing_page.html.twig line 1

  1. {% extends 'base_landing.html.twig' %}
  2. {% block title %}{{ 'landing.title'|trans }}{% endblock %}
  3. {% block body %}
  4. <!-- Section de l'image "sleep" en pleine largeur -->
  5. <div class="relative w-screen h-[60vh] flex items-center justify-center bg-cover bg-center bg-no-repeat mb-200" style="background-image: url('/images/sleep1.png');">
  6.     <div class="absolute inset-0 bg-black bg-opacity-25"></div>
  7.     <div class="absolute text-center w-full px-4">
  8.         <h1 class="text-4xl text-white font-bold mb-4">{{ 'landing.find_accommodation'|trans }}</h1>
  9.         <form id="search-form" method="GET" action="{{ path('advanced_search') }}" class="space-y-4">
  10.             <div class="relative flex items-center w-full max-w-sm mx-auto rounded-full overflow-hidden">
  11.                 <input type="text" id="address-landing" name="city" placeholder="{{ 'landing.destination'|trans }}" class="w-full px-4 py-2 rounded-full text-black focus:outline-none">
  12.                 <button type="submit" class="absolute right-[-0rem] bg-[#ffcc00] text-black w-10 h-10 rounded-full flex items-center justify-center hover:bg-[#ffcc00] transition border border-2 border-white">
  13.                     <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  14.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
  15.                     </svg>
  16.                 </button>
  17.             </div>
  18.             <input type="hidden" name="lat" id="lat">
  19.             <input type="hidden" name="lng" id="lng">
  20.         </form>
  21.         <p class="text-xl text-white mt-4">{{ 'landing.thousands_accommodations'|trans }}</p>
  22.     </div>
  23. </div>
  24. <div class="container mx-auto px-4 py-8 text-center">
  25.     <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
  26.         <div class="bg-transparent p-6 text-center max-lg:p-4">
  27.             <img src="/images/icons/attestation.png" alt="Attestation Icon" class="mx-auto mb-4 w-28 h-auto">
  28.             <h3 class="text-xl font-semibold mb-4">{{ 'landing.attestation'|trans }}</h3>
  29.         </div>
  30.         <div class="bg-transparent p-6 text-center max-lg:p-4">
  31.             <img src="/images/icons/sans-deplacement.png" alt="Sans Déplacement Icon" class="mx-auto mb-4 w-28 h-auto">
  32.             <h3 class="text-xl font-semibold mb-4">{{ 'landing.no_displacement'|trans }}</h3>
  33.         </div>
  34.         <div class="bg-transparent p-6 text-center max-lg:p-4">
  35.             <img src="/images/icons/securite.png" alt="Sécurité Icon" class="mx-auto mb-4 w-28 h-auto">
  36.             <h3 class="text-xl font-semibold mb-4">{{ 'landing.security'|trans }}</h3>
  37.         </div>
  38.     </div>
  39. </div>
  40. <div class="bg-gray-200 w-full px-4 py-8 text-left mb-200 max-lg:p-4">
  41.     <h2 class="text-4xl font-bold text-center mb-6 max-lg:text-3xl">{{ 'landing.selection_accommodations'|trans }}</h2> <br/>
  42.     <div class="relative overflow-hidden">
  43.         <div class="grid grid-cols-1 md:grid-cols-4 gap-4" id="recent-carousel">
  44.             {% for building in recentBuildings %}
  45.                 {% set filteredFiles2 = building.buildingDocuments|filter(item => item.name starts with 'file' or item.name starts with 'imageComplexe') %}
  46.                 <div class="flex-shrink-0 w-full bg-white shadow-md rounded-lg overflow-hidden z-10">
  47.                     <div class="relative w-full h-56 overflow-hidden max-lg:h-48">
  48.                         {% if filteredFiles2 is not empty %}
  49.                             <div class="absolute inset-0 flex transition-transform duration-500 ease-in-out" id="carousel-{{ building.id }}">
  50.                                 {% for bd in filteredFiles2 %}
  51.                                     <a href="{{ path('detail_building', {id: building.id}) }}" class="w-full flex-shrink-0 bg-cover bg-no-repeat bg-center"
  52.                                        style="background-image: url('{{ asset('images/files/' ~ bd.imageFile) }}'); height: 14rem;">
  53.                                     </a>
  54.                                 {% endfor %}
  55.                             </div>
  56.                             <div class="flex absolute bottom-2 left-1/2 z-30 space-x-2 -translate-x-1/2" id="carousel-indicators-{{ building.id }}">
  57.                                 {% for document in filteredFiles2 %}
  58.                                     <button type="button" class="w-3 h-3 rounded-full border border-gray-400 bg-gray-300 opacity-50" aria-label="Slide {{ loop.index0 }}" data-carousel-slide-to="{{ loop.index0 }}"></button>
  59.                                 {% endfor %}
  60.                             </div>
  61.                             {% if filteredFiles2|length > 1 %}
  62.                                 <button type="button" class="absolute top-1/2 left-2 z-40 transform -translate-y-1/2 bg-gray-300 p-2 rounded-full shadow-md" data-carousel-prev="{{ building.id }}">
  63.                                     <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  64.                                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
  65.                                     </svg>
  66.                                 </button>
  67.                                 <button type="button" class="absolute top-1/2 right-2 z-40 transform -translate-y-1/2 bg-gray-300 p-2 rounded-full shadow-md" data-carousel-next="{{ building.id }}">
  68.                                     <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  69.                                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
  70.                                     </svg>
  71.                                 </button>
  72.                             {% endif %}
  73.                         {% endif %}
  74.                     </div>
  75.                     <div class="p-4 flex justify-between items-start max-lg:p-2">
  76.                         <div>
  77.                             {% if building.cityEntity is not null %}
  78.                                 <a href="{{ path('detail_building', {id: building.id}) }}" class="block text-sm font-bold">
  79.                                     {{ building.cityEntity.city }}, {{ building.cityEntity.country }}
  80.                                 </a>
  81.                             {% else %}
  82.                                 <span class="block text-sm font-bold text-red-500">{{ 'City information not available'|trans }}</span>
  83.                             {% endif %}
  84.                             <a href="{{ path('detail_building', {id: building.id}) }}" class="block text-sm font-bold">{{ building.rent / 100 }} € {{ 'accueil.parmois'|trans }}</a>
  85.                             <a href="{{ path('detail_building', {id: building.id}) }}" class="block text-gray-500 text-sm">{{ 'accueil.add'|trans }}{{ building.createdAt|date('d/m/y') }}</a>
  86.                             {% if building.status == 'Disponible' %}
  87.                                 {% if building.dateStartAt %}
  88.                                     <p class="text-gray-500 text-sm">{{ 'accueil.availableDate'|trans }} {{ building.dateStartAt|date('d/m/y') }}</p>
  89.                                 {% else %}
  90.                                     <p class="text-gray-500 text-sm">{{ 'accueil.availableDateNow'|trans }}</p>
  91.                                 {% endif %}
  92.                             {% elseif building.dateStartAt %}
  93.                                 <p class="text-gray-500 text-sm">{{ 'accueil.dateStartAt'|trans }} {{ building.dateStartAt|date('d/m/y') }}</p>
  94.                             {% endif %}
  95.                         </div>
  96.                         <a class="flex items-center justify-center p-3 cursor-pointer rounded-lg mt-2" id="like-button-{{ building.id }}">
  97.                             {% if likedBuildings[building.id] is defined and likedBuildings[building.id] %}
  98.                                 <i style="color: #ffcc00" class="fa-solid fa-heart pl-3 fa-2x like-button" data-image-id="{{ building.id }}"></i>
  99.                             {% else %}
  100.                                 <i style="color: #ffcc00" class="fa-regular fa-heart pl-3 fa-2x like-button" data-image-id="{{ building.id }}"></i>
  101.                             {% endif %}
  102.                         </a>
  103.                     </div>
  104.                 </div>
  105.             {% endfor %}
  106.         </div>
  107.     </div>
  108. </div>
  109. <div class="container text-center mx-auto px-4 py-8 mb-200">
  110.     <h2 class="text-4xl font-bold mb-6 text-center">
  111.         {{ 'landing.roomlers_solution'|trans }}
  112.     </h2>
  113.     <br/>
  114.     <div class="grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-6">
  115.         <!-- Section 1 -->
  116.         <div class="bg-gray-200 p-6 rounded-lg shadow-md flex flex-col md:w-11/12 mx-auto max-lg:p-4 min-h-[250px]">
  117.             <h3 class="text-xl mb-2">
  118.                 <span class="text-2xl font-bold">1.</span><br/>
  119.                 <strong>{{ 'landing.create_account'|trans }}</strong>
  120.             </h3>
  121.             <p class="text-gray-700 flex-grow">
  122.                 {{ 'landing.access_catalog'|trans }}
  123.             </p>
  124.         </div>
  125.         <!-- Section 2 -->
  126.         <div class="bg-gray-200 p-6 rounded-lg shadow-md flex flex-col md:w-11/12 mx-auto max-lg:p-4 min-h-[250px]">
  127.             <h3 class="text-xl mb-2">
  128.                 <span class="text-2xl font-bold">2.</span><br/>
  129.                 <strong>{{ 'landing.generate_attestation'|trans }}</strong><br/>{{ 'landing.step'|trans }}
  130.             </h3>
  131.             <p class="text-gray-700 flex-grow">
  132.                 {{ 'landing.complete_visa'|trans }}
  133.             </p>
  134.         </div>
  135.         <!-- Section 3 -->
  136.         <div class="bg-gray-200 p-6 rounded-lg shadow-md flex flex-col md:w-11/12 mx-auto max-lg:p-4 min-h-[250px]">
  137.             <h3 class="text-xl mb-2">
  138.                 <span class="text-2xl font-bold">3.</span><br/>
  139.                 <strong>{{ 'landing.book_accommodation'|trans }}</strong>
  140.             </h3>
  141.             <p class="text-gray-700 flex-grow">
  142.                 {{ 'landing.choose_accommodation'|trans }}
  143.             </p>
  144.         </div>
  145.     </div>
  146.     <br/>
  147.     <div class="text-center mt-8">
  148.         {% if app.user %}
  149.             {% if app.user.asRole('ROLE_TENANT') %}
  150.                 <a href="{{ path('tenant_home') }}" class="bg-[#FFCC00] text-black px-6 py-2 rounded-lg font-semibold hover:bg-[#FFCC00] transition w-full md:w-[calc(33.333%-2rem)]">
  151.                     {{ 'landing.start'|trans }}
  152.                 </a>
  153.             {% elseif app.user.asRole('ROLE_AGENT') %}
  154.                 <button id="openPopLink1" class="bg-[#FFCC00] text-black px-6 py-2 rounded-lg font-semibold hover:bg-[#FFCC00] transition w-full md:w-[calc(33.333%-2rem)]">
  155.                     {{ 'landing.start'|trans }}
  156.                 </a>
  157.             {% elseif app.user.asRole('ROLE_SUPER_AGENT') %}
  158.                 <button id="openPopLink1" class="bg-[#FFCC00] text-black px-6 py-2 rounded-lg font-semibold hover:bg-[#FFCC00] transition w-full md:w-[calc(33.333%-2rem)]">
  159.                     {{ 'landing.start'|trans }}
  160.                 </a>
  161.             {% elseif app.user.asRole('ROLE_LESSOR') or app.user.asRole('ROLE_LESSOR_RESIDENT') %}
  162.                 <button id="openPopLink1" class="inline-block bg-yellow-400 text-black font-semibold px-8 py-4 rounded-lg hover:bg-yellow-500 transition-colors">
  163.                     {{ 'landing.start'|trans }}
  164.                 </button>
  165.             {% endif %}
  166.         {% else %}
  167.             <button id="openConnectModalBtn" class="bg-[#FFCC00] text-black px-6 py-2 rounded-lg font-semibold hover:bg-[#FFCC00] transition w-full md:w-[calc(33.333%-2rem)]">
  168.                 {{ 'landing.start'|trans }}
  169.             </button>
  170.         {% endif %}
  171.     </div>
  172. </div>
  173. <div class="bg-gray-200 w-full px-4 py-8 mb-200">
  174.     <h2 class="text-4xl md:text-3xl font-bold mb-6 text-center">{{ 'landing.things'|trans }}</h2>
  175.     <br/>
  176.     <div class=" text-center grid grid-cols-1 md:grid-cols-3 gap-12">
  177.         <div class="bg-white p-6 rounded-lg shadow-md md:w-11/12 mx-auto max-lg:p-4 text-center">
  178.             <img src="/images/icons/citation.png" alt="Icône de citation" class="w-8 h-8 mb-4 mx-auto">
  179.             <p class="text-gray-700">{{ 'landing.testimonial_alejandro'|trans }} <br/>
  180.                 <br/><em>{{ 'landing.alejandro'|trans }}</em>
  181.             </p>
  182.         </div>
  183.         <div class="bg-white p-6 rounded-lg shadow-md md:w-11/12 mx-auto max-lg:p-4 text-center">
  184.             <img src="/images/icons/citation.png" alt="Icône de citation" class="w-8 h-8 mb-4 mx-auto">
  185.             <p class="text-gray-700">{{ 'landing.testimonial_mei'|trans }} <br/>
  186.                 <br/><em>{{ 'landing.mei'|trans }}</em>
  187.             </p>
  188.         </div>
  189.         <div class="bg-white p-6 rounded-lg shadow-md md:w-11/12 mx-auto max-lg:p-4 text-center">
  190.             <img src="/images/icons/citation.png" alt="Icône de citation" class="w-8 h-8 mb-4 mx-auto">
  191.             <p class="text-gray-700">{{ 'landing.testimonial_luca'|trans }} <br/>
  192.                 <br/><em>{{ 'landing.luca'|trans }}</em>
  193.             </p>
  194.         </div>
  195.     </div>
  196. </div>
  197. <style>
  198.     .faq-section {
  199.         display: flex;
  200.         align-items: center;
  201.     }
  202.     .faq-title {
  203.         display: flex;
  204.         align-items: center;
  205.         justify-content: center;
  206.     }
  207.     .faq-questions {
  208.         display: flex;
  209.         flex-direction: column;
  210.     }
  211.     .faq-answer {
  212.         max-height: 0;
  213.         overflow: hidden;
  214.         transition: max-height 0.3s ease-out;
  215.     }
  216.     .faq-answer.active {
  217.         max-height: 200px; /* Ajustez cette valeur selon vos besoins */
  218.         overflow: visible;
  219.     }
  220. </style>
  221. <div class="container mx-auto px-4 py-8 mb-24 flex flex-col md:flex-row items-start justify-between faq-section">
  222.     <div class="w-full md:w-1/3 p-4 faq-title">
  223.         <h2 class="text-3xl font-bold mb-4">{{ 'landing.weanswer'|trans }}<br/> {{ 'landing.questions'|trans }}</h2>
  224.     </div>
  225.     <div class="w-full md:w-2/3 p-4 space-y-4 faq-questions">
  226.         <!-- Question 1 -->
  227.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  228.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  229.                 <div class="flex-1 text-left pr-4">{{ 'landing.question1'|trans }}</div>
  230.                 <div class="flex-shrink-0 w-6 h-6">
  231.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  232.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  233.                     </svg>
  234.                 </div>
  235.             </button>
  236.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  237.                 <p class="p-4 text-gray-700">{{ 'landing.faq_fees'|trans }}</p>
  238.             </div>
  239.         </div>
  240.         <!-- Question 2 -->
  241.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  242.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  243.                 <div class="flex-1 text-left pr-4">{{ 'landing.question2'|trans }}</div>
  244.                 <div class="flex-shrink-0 w-6 h-6">
  245.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  246.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  247.                     </svg>
  248.                 </div>
  249.             </button>
  250.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  251.                 <p class="p-4 text-gray-700">{{ 'landing.faq_refund'|trans }}</p>
  252.             </div>
  253.         </div>
  254.         <!-- Question 3 -->
  255.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  256.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  257.                 <div class="flex-1 text-left pr-4">{{ 'landing.question3'|trans }}</div>
  258.                 <div class="flex-shrink-0 w-6 h-6">
  259.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  260.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  261.                     </svg>
  262.                 </div>
  263.             </button>
  264.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  265.                 <p class="p-4 text-gray-700">{{ 'landing.faq_apl'|trans }}</p>
  266.             </div>
  267.         </div>
  268.         <!-- Question 4 -->
  269.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  270.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  271.                 <div class="flex-1 text-left pr-4">{{ 'landing.question4'|trans }}</div>
  272.                 <div class="flex-shrink-0 w-6 h-6">
  273.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  274.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  275.                     </svg>
  276.                 </div>
  277.             </button>
  278.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  279.                 <p class="p-4 text-gray-700">{{ 'landing.faq_furnished'|trans }}</p>
  280.             </div>
  281.         </div>
  282.         <!-- Question 5 -->
  283.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  284.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  285.                 <div class="flex-1 text-left pr-4">{{ 'landing.question5'|trans }}</div>
  286.                 <div class="flex-shrink-0 w-6 h-6">
  287.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  288.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  289.                     </svg>
  290.                 </div>
  291.             </button>
  292.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  293.                 <p class="p-4 text-gray-700">{{ 'landing.faq_lease_duration'|trans }}</p>
  294.             </div>
  295.         </div>
  296.         <!-- Question 6 -->
  297.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  298.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  299.                 <div class="flex-1 text-left pr-4">{{ 'landing.question6'|trans }}</div>
  300.                 <div class="flex-shrink-0 w-6 h-6">
  301.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  302.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  303.                     </svg>
  304.                 </div>
  305.             </button>
  306.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  307.                 <p class="p-4 text-gray-700">{{ 'landing.faq_leave_accommodation'|trans }}</p>
  308.             </div>
  309.         </div>
  310.         <!-- Question 7 -->
  311.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  312.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  313.                 <div class="flex-1 text-left pr-4">{{ 'landing.question7'|trans }}</div>
  314.                 <div class="flex-shrink-0 w-6 h-6">
  315.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  316.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  317.                     </svg>
  318.                 </div>
  319.             </button>
  320.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  321.                 <p class="p-4 text-gray-700">{{ 'landing.faq_insurance'|trans }}</p>
  322.             </div>
  323.         </div>
  324.         <!-- Question 8 -->
  325.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  326.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  327.                 <div class="flex-1 text-left pr-4">{{ 'landing.question8'|trans }}</div>
  328.                 <div class="flex-shrink-0 w-6 h-6">
  329.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  330.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  331.                     </svg>
  332.                 </div>
  333.             </button>
  334.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  335.                 <p class="p-4 text-gray-700">{{ 'landing.faq_guarantor'|trans }}</p>
  336.             </div>
  337.         </div>
  338.         <!-- Question 9 -->
  339.         <div class="border border-gray-300 rounded-lg overflow-hidden shadow-md relative faq-item">
  340.             <button class="faq-question flex justify-between items-center w-full p-4 font-semibold text-left hover:bg-gray-200 transition">
  341.                 <div class="flex-1 text-left pr-4">{{ 'landing.question9'|trans }}</div>
  342.                 <div class="flex-shrink-0 w-6 h-6">
  343.                     <svg class="w-6 h-6 text-gray-600 transition-transform transform rotate-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  344.                         <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
  345.                     </svg>
  346.                 </div>
  347.             </button>
  348.             <div class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
  349.                 <p class="p-4 text-gray-700">{{ 'landing.faq_no_guarantor'|trans|raw }}</p>
  350.             </div>
  351.         </div>
  352.     </div>
  353. </div>
  354. <div class="bg-gray-200 w-full px-4 py-8 mb-200">
  355.     <h2 class="text-4xl md:text-3xl font-bold mb-6 text-center">{{ 'landing.popular_destinations'|trans }}</h2> <br/>
  356.     <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
  357.         <a href="{{ path('advanced_search', {'city': 'Paris', 'lat': 48.8575475, 'lng': 2.3513765}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  358.             <h3 class="text-lg md:text-xl font-semibold mb-2">Paris</h3>
  359.         </a>
  360.         <a href="{{ path('advanced_search', {'city': 'Lille', 'lat': 50.624378, 'lng': 3.0678588}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  361.             <h3 class="text-lg md:text-xl font-semibold mb-2">Lille</h3>
  362.         </a>
  363.         <a href="{{ path('advanced_search', {'city': 'Lyon', 'lat': 45.764043, 'lng': 4.835659}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  364.             <h3 class="text-lg md:text-xl font-semibold mb-2">Lyon</h3>
  365.         </a>
  366.         <a href="{{ path('advanced_search', {'city': 'Toulouse', 'lat': 43.6048462, 'lng': 1.442848}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  367.             <h3 class="text-lg md:text-xl font-semibold mb-2">Toulouse</h3>
  368.         </a>
  369.         <a href="{{ path('advanced_search', {'city': 'Strasbourg', 'lat': 48.5734053, 'lng': 7.752111299999999}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  370.             <h3 class="text-lg md:text-xl font-semibold mb-2">Strasbourg</h3>
  371.         </a>
  372.         <a href="{{ path('advanced_search', {'city': 'Marseille', 'lat': 43.3025742, 'lng': 5.369074299999999}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  373.             <h3 class="text-lg md:text-xl font-semibold mb-2">Marseille</h3>
  374.         </a>
  375.         <a href="{{ path('advanced_search', {'city': 'Rennes', 'lat': 48.117266, 'lng': 1.6777926}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  376.             <h3 class="text-lg md:text-xl font-semibold mb-2">Rennes</h3>
  377.         </a>
  378.         <a href="{{ path('advanced_search', {'city': 'Bordeaux', 'lat': 44.8416106, 'lng': 0.5810938000000001}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  379.             <h3 class="text-lg md:text-xl font-semibold mb-2">Bordeaux</h3>
  380.         </a>
  381.         <a href="{{ path('advanced_search', {'city': 'Montpellier', 'lat': 43.6108535, 'lng': 3.8761323}) }}" class="bg-white p-6 rounded-lg shadow-md text-center">
  382.             <h3 class="text-lg md:text-xl font-semibold mb-2">Montpellier</h3>
  383.         </a>
  384.     </div>
  385. </div> <br/> <br/>
  386. <!-- Modal de connexion/inscription -->
  387. <div id="connectModal" class="fixed inset-0 bg-gray-500 bg-opacity-50 flex justify-center items-center hidden z-50">
  388.     <div class="bg-white p-6 rounded-lg shadow-lg max-w-sm w-full text-center">
  389.         <p class="text-lg font-semibold mb-4">{{ 'landing.option'|trans }}</p>
  390.         <button onclick="window.location.href='{{ path('app_login_site') }}'" class="bg-[#ffcc00] text-black px-4 py-2 rounded-lg font-semibold hover:bg-[#ffcc00] transition mb-2">
  391.             {{ 'landing.login'|trans }}
  392.         </button>
  393.         <button onclick="window.location.href='{{ path('app_register') }}'" class="bg-[#ffcc00] text-black px-4 py-2 rounded-lg font-semibold hover:bg-[#ffcc00] transition">
  394.             {{ 'landing.register'|trans }}
  395.         </button>
  396.     </div>
  397. </div>
  398. <div id="connectPop" class="fixed inset-0 bg-gray-500 bg-opacity-50 flex justify-center items-center hidden z-50">
  399.     <div class="bg-white p-6 rounded-lg shadow-lg max-w-sm w-full text-center">
  400.         <p class="text-lg font-semibold mb-4">{{ 'landing.tenant'|trans }}</p>
  401.         <button onclick="window.location.href='{{ path('app_login_site') }}'" class="bg-yellow-400 text-black px-4 py-2 rounded-lg font-semibold hover:bg-yellow-500 transition mb-2 w-full">
  402.             {{ 'landing.login'|trans }}
  403.         </button>
  404.     </div>
  405. </div>
  406. <button id="scrollToTopBtn" class="fixed bottom-4 right-4 bg-[#FFCC00] text-black px-4 py-2 rounded-lg font-semibold hover:bg-[#e6b800] transition-all z-[1000] border-2 border-black">
  407.     {{ 'landing.search'|trans }}
  408. </button>
  409. <script>
  410.     let autocompleteLanding;
  411.     // Fonction pour initialiser l'autocomplétion Google Maps
  412.     function initAutocomplete(inputId) {
  413.         const input = document.getElementById(inputId);
  414.         if (!input) {
  415.             console.error("Input non trouvé :", inputId);
  416.             return;
  417.         }
  418.         const options = {
  419.             types: ['(cities)'], // Limiter aux villes
  420.             componentRestrictions: { country: 'fr' } // France uniquement
  421.         };
  422.         try {
  423.             autocompleteLanding = new google.maps.places.Autocomplete(input, options);
  424.             autocompleteLanding.addListener('place_changed', function () {
  425.                 const place = autocompleteLanding.getPlace();
  426.                 if (!place.geometry) {
  427.                     console.error("Aucune géométrie trouvée pour ce lieu.");
  428.                     return;
  429.                 }
  430.                 const latInput = document.getElementById('lat');
  431.                 const lngInput = document.getElementById('lng');
  432.                 if (latInput && lngInput) {
  433.                     latInput.value = place.geometry.location.lat();
  434.                     lngInput.value = place.geometry.location.lng();
  435.                 }
  436.                 let city = "";
  437.                 place.address_components.forEach(component => {
  438.                     if (component.types.includes("locality")) {
  439.                         city = component.long_name;
  440.                     }
  441.                 });
  442.                 input.value = city || place.name; // Fallback si le nom de la ville n'est pas trouvé
  443.                 const form = input.closest('form');
  444.                 if (form) {
  445.                     form.submit();
  446.                 }
  447.             });
  448.         } catch (error) {
  449.             console.error("Erreur lors de l'initialisation de l'autocomplétion :", error);
  450.         }
  451.     }
  452.     // Fonction pour charger l'API Google Maps de manière asynchrone
  453.     function loadGoogleMapsAPI() {
  454.         if (typeof google === 'undefined' || !google.maps) {
  455.             const script = document.createElement('script');
  456.             script.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyA4fnlCYx-sU6oAMsNfli8_IqwFIsdxfA4&libraries=places&callback=initializeAutocomplete';
  457.             script.async = true;
  458.             script.defer = true;
  459.             script.onerror = () => {
  460.                 console.error("Erreur lors du chargement de l'API Google Maps.");
  461.             };
  462.             document.head.appendChild(script);
  463.         } else {
  464.             initializeAutocomplete();
  465.         }
  466.     }
  467.     // Fonction pour initialiser l'autocomplétion après le chargement de l'API
  468.     function initializeAutocomplete() {
  469.         if (typeof google !== 'undefined' && google.maps && google.maps.places) {
  470.             console.log("test");
  471.             initAutocomplete('address-landing');
  472.         } else {
  473.             console.error("Google Maps API non chargée correctement.");
  474.         }
  475.     }
  476.     // Fonction pour configurer un carousel
  477.     function setupCarousel(carousel) {
  478.         const carouselId = carousel.id.split('-')[1];
  479.         const slides = carousel.querySelectorAll('a');
  480.         const indicators = document.querySelectorAll(`#carousel-indicators-${carouselId} button`);
  481.         const prevButton = document.querySelector(`[data-carousel-prev="${carouselId}"]`);
  482.         const nextButton = document.querySelector(`[data-carousel-next="${carouselId}"]`);
  483.         let currentIndex = 0;
  484.         const totalSlides = slides.length;
  485.         function updateCarousel() {
  486.             if (slides.length === 0) return;
  487.             slides.forEach((slide, index) => {
  488.                 slide.style.transition = 'opacity 0.6s ease-in-out, transform 0.6s ease-in-out';
  489.                 slide.style.position = 'absolute';
  490.                 slide.style.opacity = '0';
  491.                 slide.style.transform = 'translateX(100%)';
  492.             });
  493.             const currentSlide = slides[currentIndex];
  494.             currentSlide.style.opacity = '1';
  495.             currentSlide.style.transform = 'translateX(0)';
  496.             indicators.forEach((indicator, index) => {
  497.                 if (index === currentIndex) {
  498.                     indicator.classList.add('bg-[#ffcc00]', 'opacity-100');
  499.                     indicator.classList.remove('bg-gray-300', 'opacity-50');
  500.                 } else {
  501.                     indicator.classList.remove('bg-[#ffcc00]', 'opacity-100');
  502.                     indicator.classList.add('bg-gray-300', 'opacity-50');
  503.                 }
  504.             });
  505.         }
  506.         function goToSlide(index) {
  507.             currentIndex = (index + totalSlides) % totalSlides;
  508.             updateCarousel();
  509.         }
  510.         function nextSlide() {
  511.             goToSlide(currentIndex + 1);
  512.         }
  513.         function prevSlide() {
  514.             goToSlide(currentIndex - 1);
  515.         }
  516.         // Événements
  517.         if (nextButton) nextButton.addEventListener('click', nextSlide);
  518.         if (prevButton) prevButton.addEventListener('click', prevSlide);
  519.         indicators.forEach((indicator, index) => {
  520.             indicator.addEventListener('click', () => goToSlide(index));
  521.         });
  522.     }
  523.     // Initialisation du script
  524.     document.addEventListener('DOMContentLoaded', function () {
  525.         // Charger l'API Google Maps
  526.         loadGoogleMapsAPI();
  527.         // Gestion de la modal de connexion/inscription
  528.         const openModalElements = document.querySelectorAll('#openModalLink1, #openConnectModalBtn');
  529.         const connectModal = document.getElementById('connectModal');
  530.         openModalElements.forEach(element => {
  531.             element.addEventListener('click', function (event) {
  532.                 event.preventDefault();
  533.                 connectModal.classList.remove('hidden');
  534.             });
  535.         });
  536.         connectModal.addEventListener('click', function (event) {
  537.             if (event.target === connectModal) {
  538.                 connectModal.classList.add('hidden');
  539.             }
  540.         });
  541.         // Gestion du bouton de recherche (défilement vers le haut)
  542.         const scrollToTopBtn = document.getElementById('scrollToTopBtn');
  543.         scrollToTopBtn.addEventListener('click', function () {
  544.             window.scrollTo({
  545.                 top: 0,
  546.                 behavior: 'smooth'
  547.             });
  548.         });
  549.         // Affichage/masquage du bouton de défilement
  550.         window.addEventListener('scroll', function () {
  551.             if (window.scrollY > 100) {
  552.                 scrollToTopBtn.style.display = 'block';
  553.             } else {
  554.                 scrollToTopBtn.style.display = 'none';
  555.             }
  556.         });
  557.         // Gestion des carrousels
  558.         const carousels = document.querySelectorAll('[id^="carousel-"]');
  559.         carousels.forEach(setupCarousel);
  560.         // Gestion des clics sur les cœurs (affichage de la modal)
  561.         const likeButtons = document.querySelectorAll('.like-button');
  562.         likeButtons.forEach(button => {
  563.             button.addEventListener('click', function () {
  564.                 const connectModal = document.getElementById('connectModal');
  565.                 connectModal.classList.remove('hidden');
  566.             });
  567.         });
  568.         // Gestion du menu de langue
  569.         const languageDropdown = document.getElementById('languageDropdown');
  570.         const languageMenu = document.getElementById('languageMenu');
  571.         if (languageDropdown && languageMenu) {
  572.             languageDropdown.addEventListener('click', function () {
  573.                 languageMenu.classList.toggle('hidden');
  574.             });
  575.         }
  576.         // Gestion de l'accordéon
  577.         const accordionButtons = document.querySelectorAll('.faq-question');
  578.         accordionButtons.forEach(button => {
  579.             button.addEventListener('click', function() {
  580.                 const content = this.nextElementSibling;
  581.                 const isExpanded = content.classList.contains('active');
  582.                 // Fermer tous les autres éléments de l'accordéon
  583.                 accordionButtons.forEach(btn => {
  584.                     const otherContent = btn.nextElementSibling;
  585.                     if (btn !== this) {
  586.                         otherContent.classList.remove('active');
  587.                     }
  588.                 });
  589.                 // Basculer l'état de l'élément cliqué
  590.                 if (isExpanded) {
  591.                     content.classList.remove('active');
  592.                 } else {
  593.                     content.classList.add('active');
  594.                 }
  595.             });
  596.         });
  597.     // Ajout du gestionnaire d'événements pour la touche "Entrée"
  598.     const searchInput = document.getElementById('address-landing');
  599.         if (searchInput) {
  600.             searchInput.addEventListener('keydown', function (event) {
  601.                 if (event.key === 'Enter') {
  602.                     event.preventDefault();
  603.                     document.getElementById('search-form').submit();
  604.                 }
  605.             });
  606.         }
  607.     const openPopElements = document.querySelectorAll('#openPopLink1, #openPopLink2');
  608.     const connectPop = document.getElementById('connectPop');
  609.     if (openPopElements.length > 0 && connectPop) {
  610.         openPopElements.forEach(element => {
  611.             element.addEventListener('click', function (event) {
  612.                 event.preventDefault();
  613.                 connectPop.classList.remove('hidden');
  614.             });
  615.         });
  616.         connectPop.addEventListener('click', function (event) {
  617.             if (event.target === connectPop) {
  618.                 connectPop.classList.add('hidden');
  619.             }
  620.         });
  621.         connectPop.querySelector('.bg-white').addEventListener('click', function (event) {
  622.             event.stopPropagation();
  623.         });
  624.     }
  625.     });
  626. </script>
  627. {% endblock %}