feat: refonte de la navbar (responsive, menu hamburger, onglets, design) et mise à jour du footer

This commit is contained in:
2026-04-10 00:02:45 +02:00
parent 7751d78b98
commit ff82fa9b56
3 changed files with 118 additions and 55 deletions

View File

@@ -5,6 +5,43 @@ import './stimulus_bootstrap.js';
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you import will output into a single css file (app.css in this case)
import './styles/app.css';
// --- Gestion du responsive de la barre de navigation (menu hamburger) --- //
document.addEventListener('DOMContentLoaded', () => {
// --- Gestion de l'affichage du menu hamburger --- //
const btn = document.getElementById('mobile-menu-button');
const menu = document.getElementById('main-menu');
const iconClosed = document.getElementById('icon-menu-closed');
const iconOpen = document.getElementById('icon-menu-open');
if (hamburger && menu) {
// Fonction pour gérer l'ouverture/fermeture du menu
const toggleMenu = () => {
menu.classList.toggle('hidden');
// Gestion alternance bouton hamburger ou croix
iconClosed.classList.toggle('hidden');
iconOpen.classList.toggle('hidden');
// Mise ne place de l'accessibilité
const isHidden = menu.classList.contains('hidden');
btn.setAttribute('aria-expanded', !isHidden);
};
// Action au clic sur le bouton hamburger
btn.addEventListener('click', toggleMenu);
// Action au clic sur un des liens du menu
const menuLinks = menu.querySelectorAll('a');
menuLinks.forEach(link => {
link.addEventListener('click', () => {
// On force la fermeture au clic uniquement si le menu est ouvert sur mobile
if (!menu.classList.contains('hidden')) {
toggleMenu();
}
});
});
}
});

View File

@@ -1,31 +1,57 @@
<nav class="bg-white border-b border-gris-clair shadow-sm py-4 px-6 sticky top-0 z-50 font-sora">
<div class="max-w-7xl mx-auto flex flex-col md:flex-row items-center justify-between gap-4">
<div class="flex flex-col md:flex-row items-center gap-4 md:gap-8 w-full md:w-auto">
<a href="{{ path('app_home') }}" class="flex items-center gap-2 transition-transform hover:scale-105">
<img src="{{ asset('img/logo.svg') }}" alt="Logo de l'association" class="h-10 w-auto object-contain">
{# Barre de navigation principale #}
<nav class="bg-white border-b border-gris-clair shadow-sm sticky top-0 z-50 font-sora relative">
{# --- Gestion de la barre --- #}
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-20">
{# Logo de l'association #}
<a href="{{ path('app_home') }}"
class="flex-shrink-0 md:mr-8 flex items-center gap-2 transition-transform hover:scale-105">
<img src="{{ asset('img/logo.svg') }}" alt="Logo de l'association Kaz"
class="h-10 w-auto object-contain">
</a>
<ul class="flex flex-wrap justify-center md:justify-start gap-2 md:gap-4">
{# Bouton Hamburger (Visible uniquement sur mobile) #}
<div class="md:hidden">
<button type="button" id="mobile-menu-button"
class="p-2 rounded-md text-gris-fonce hover:text-bouton focus:outline-none transition-colors"
aria-expanded="false">
<span class="sr-only">Ouvrir le menu</span>
{# Icône Menu (Hamburger) #}
<svg id="icon-menu-closed" class="block h-7 w-7" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"/>
</svg>
{# Icône Fermer (Croix) #}
<svg id="icon-menu-open" class="hidden h-7 w-7" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
{# --- Gestion des onglets --- #}
<div id="main-menu"
class="hidden md:flex md:flex-1 absolute md:static top-full left-0 w-full md:w-auto bg-white md:bg-transparent border-b md:border-none border-gris-clair shadow-lg md:shadow-none px-4 md:px-0 py-4 md:py-0">
{# Gestion de leur disposition horizontale ou verticale #}
<ul class="flex flex-col md:flex-row md:items-center gap-2 md:gap-4 lg:gap-8 w-full">
{# Onglet : Mon profil #}
<li>
<a href="{{ path('app_user') }}"
class="px-4 py-2 text-sm font-semibold transition-colors block
class="block px-4 py-3 md:py-2 text-base md:text-sm font-semibold transition-colors
{{ app.request.attributes.get('_route') == 'app_user'
? 'bg-bouton/20 border border-bouton text-text rounded-lg'
: 'text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent' }}">
? 'bg-bouton/20 text-text md:border md:border-bouton md:rounded-lg'
: 'text-gris-fonce hover:bg-bg-primaire md:hover:bg-gris-clair md:hover:text-text rounded-lg md:border md:border-transparent' }}">
Mon profil
</a>
</li>
{# Onglet : Mon offre #}
<li>
{# TODO : créer la route {{ path('app_offres') }} #}
<a href="https://kaz.bzh/offres/" target=_blank"
class="px-4 py-2 text-sm font-semibold transition-colors block text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent flex items-center gap-1">
<a href="https://kaz.bzh/offres/" target="_blank"
class="block px-4 py-3 md:py-2 text-base md:text-sm font-semibold text-gris-fonce hover:bg-bg-primaire md:hover:bg-gris-clair md:hover:text-text rounded-lg transition-colors md:border md:border-transparent">
Mon offre
</a>
</li>
@@ -33,33 +59,33 @@
{# Onglet : Gérer mes mots de passe #}
<li>
<a href="{{ path('app_user_edit_password') }}"
class="px-4 py-2 text-sm font-semibold transition-colors block
class="block px-4 py-3 md:py-2 text-base md:text-sm font-semibold transition-colors
{{ app.request.attributes.get('_route') == 'app_user_edit_password'
? 'bg-bouton/20 border border-bouton text-text rounded-lg'
: 'text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent' }}">
Gérer mes mots de passe
? 'bg-bouton/20 text-text md:border md:border-bouton md:rounded-lg'
: 'text-gris-fonce hover:bg-bg-primaire md:hover:bg-gris-clair md:hover:text-text rounded-lg md:border md:border-transparent' }}">
Mes mots de passe
</a>
</li>
{# Onglet : Mon organisation (ne s'affiche que si on a le rôle adéquat) #}
{# Onglet : Mon organisation (Conditionnel) #}
{% if is_granted('ROLE_ADMIN_ORGANISATION') %}
<li>
<a href="#"
class="px-4 py-2 text-sm font-semibold transition-colors block text-gris-fonce hover:bg-gris-clair hover:text-text rounded-lg border border-transparent">
class="block px-4 py-3 md:py-2 text-base md:text-sm font-semibold text-gris-fonce hover:bg-bg-primaire md:hover:bg-gris-clair md:hover:text-text rounded-lg transition-colors md:border md:border-transparent">
Mon organisation
</a>
</li>
{% endif %}
</ul>
</div>
<div class="flex-shrink-0 mt-4 md:mt-0">
{# Bouton de déconnexion #}
<div class="pt-4 md:pt-0 mt-2 md:mt-0 border-t md:border-t-0 border-gris-clair">
<a href="{{ path('app_logout') }}"
class="px-4 py-2 text-sm font-bold bg-danger text-white rounded-lg hover:bg-danger-hover transition-colors shadow flex items-center gap-2">
class="flex items-center justify-center whitespace-nowrap w-full md:w-auto px-5 py-3 md:py-2 text-base md:text-sm font-bold bg-danger text-white rounded-lg hover:bg-danger-hover transition-all active:scale-95 shadow-sm">
Se déconnecter
</a>
</div>
</div>
</div>
</div>
</nav>

View File

@@ -61,7 +61,7 @@
</main>
{# Gestion du pied-de-page #}
<footer class="w-full bg-white border-t border-gris-clair mt-auto">
<footer class="w-full bg-white border-t border-gris-clair mt-auto py-6">
<div
class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center gap-6">
<div class="flex items-center gap-3 text-sm text-gris-fonce text-center md:text-left">