280 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| {#
 | |
|   Macro : trimester_nav(class_id, base_url, selected_trimester=None, badges={})
 | |
|   
 | |
|   COULEURS THÉMATIQUES :
 | |
|   - T1 : from-blue-500 to-blue-600 (Hiver)
 | |
|   - T2 : from-green-500 to-green-600 (Printemps)  
 | |
|   - T3 : from-orange-500 to-orange-600 (Été)
 | |
|   - Global : from-purple-500 to-purple-600 (Synthétique)
 | |
|   
 | |
|   BADGES : dict optionnel avec le nombre d'évaluations par trimestre
 | |
|   Exemple: badges = {1: 4, 2: 3, 3: 2, 'global': 9}
 | |
| #}
 | |
| 
 | |
| {% macro trimester_nav(class_id, base_url, selected_trimester=None, badges={}) %}
 | |
| {# Configuration des trimestres avec couleurs thématiques #}
 | |
| {% set trimesters = [
 | |
|     {
 | |
|         'key': 'global',
 | |
|         'label': 'Global',
 | |
|         'short': 'Global',
 | |
|         'gradient': 'from-purple-500 to-purple-600',
 | |
|         'hover_gradient': 'from-purple-600 to-purple-700',
 | |
|         'text_color': 'text-purple-600',
 | |
|         'bg_color': 'bg-purple-50',
 | |
|         'border_color': 'border-purple-200',
 | |
|         'icon': '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M2 10a8 8 0 018-8v8h8a8 8 0 11-16 0z"/><path d="M12 2.252A8.014 8.014 0 0117.748 8H12V2.252z"/></svg>',
 | |
|         'description': 'Vue d\'ensemble de l\'année scolaire'
 | |
|     },
 | |
|     {
 | |
|         'key': 1,
 | |
|         'label': 'Trimestre 1',
 | |
|         'short': 'T1',
 | |
|         'gradient': 'from-blue-500 to-blue-600',
 | |
|         'hover_gradient': 'from-blue-600 to-blue-700',
 | |
|         'text_color': 'text-blue-600',
 | |
|         'bg_color': 'bg-blue-50',
 | |
|         'border_color': 'border-blue-200',
 | |
|         'icon': '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M6 2a2 2 0 00-2 2v12a2 2 0 002 2h8a2 2 0 002-2V4a2 2 0 00-2-2h-8zM6 4h8v4l-4-2-4 2V4z"/></svg>',
 | |
|         'description': 'Septembre - Décembre'
 | |
|     },
 | |
|     {
 | |
|         'key': 2,
 | |
|         'label': 'Trimestre 2',
 | |
|         'short': 'T2',
 | |
|         'gradient': 'from-green-500 to-green-600',
 | |
|         'hover_gradient': 'from-green-600 to-green-700',
 | |
|         'text_color': 'text-green-600',
 | |
|         'bg_color': 'bg-green-50',
 | |
|         'border_color': 'border-green-200',
 | |
|         'icon': '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd"/></svg>',
 | |
|         'description': 'Janvier - Mars'
 | |
|     },
 | |
|     {
 | |
|         'key': 3,
 | |
|         'label': 'Trimestre 3',
 | |
|         'short': 'T3',
 | |
|         'gradient': 'from-orange-500 to-orange-600',
 | |
|         'hover_gradient': 'from-orange-600 to-orange-700',
 | |
|         'text_color': 'text-orange-600',
 | |
|         'bg_color': 'bg-orange-50',
 | |
|         'border_color': 'border-orange-200',
 | |
|         'icon': '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M10 2L3 7v11a2 2 0 002 2h4v-6a1 1 0 011-1h2a1 1 0 011 1v6h4a2 2 0 002-2V7l-7-5zM8 15v2H6v-2h2z"/></svg>',
 | |
|         'description': 'Avril - Juillet'
 | |
|     }
 | |
| ] %}
 | |
| 
 | |
| <div class="trimester-nav bg-white rounded-xl shadow-lg p-6 mb-6" data-class-id="{{ class_id }}">
 | |
|     <!-- En-tête avec titre -->
 | |
|     <div class="flex items-center justify-between mb-4">
 | |
|         <div>
 | |
|             <h2 class="text-lg font-semibold text-gray-900">Navigation par trimestre</h2>
 | |
|             <p class="text-sm text-gray-500">Sélectionnez une période pour filtrer les données</p>
 | |
|         </div>
 | |
|         
 | |
|         <!-- Indicateur de sélection actuelle -->
 | |
|         <div class="hidden md:block">
 | |
|             {% set current_trimester = trimesters|selectattr('key', 'equalto', selected_trimester)|first %}
 | |
|             {% if current_trimester %}
 | |
|             <div class="flex items-center text-sm text-gray-600">
 | |
|                 <span class="mr-2">Période active :</span>
 | |
|                 <div class="flex items-center px-3 py-1 bg-gradient-to-r {{ current_trimester.gradient }} text-white rounded-lg">
 | |
|                     {{ current_trimester.icon|safe }}
 | |
|                     <span class="ml-2 font-medium">{{ current_trimester.label }}</span>
 | |
|                 </div>
 | |
|             </div>
 | |
|             {% endif %}
 | |
|         </div>
 | |
|     </div>
 | |
|     
 | |
|     <!-- Tabs de navigation - Version desktop -->
 | |
|     <div class="hidden md:flex space-x-2 overflow-x-auto">
 | |
|         {% for trimester in trimesters %}
 | |
|         {% set is_active = selected_trimester == trimester.key or (selected_trimester is none and trimester.key == 'global') %}
 | |
|         {% set badge_count = badges.get(trimester.key, 0) %}
 | |
|         
 | |
|         <button type="button" 
 | |
|                 class="tab-btn flex-shrink-0 group relative px-6 py-3 rounded-xl font-medium transition-all duration-300 transform hover:scale-105
 | |
|                        {% if is_active %}
 | |
|                        bg-gradient-to-r {{ trimester.gradient }} text-white shadow-lg
 | |
|                        {% else %}
 | |
|                        bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200
 | |
|                        {% endif %}"
 | |
|                 data-trimester="{{ trimester.key }}" 
 | |
|                 data-base-url="{{ base_url }}"
 | |
|                 data-class-id="{{ class_id }}"
 | |
|                 onclick="navigateToTrimester(this)">
 | |
|             
 | |
|             <!-- Icône -->
 | |
|             <div class="flex items-center">
 | |
|                 <div class="mr-3 {% if not is_active %}{{ trimester.text_color }}{% endif %}">
 | |
|                     {{ trimester.icon|safe }}
 | |
|                 </div>
 | |
|                 
 | |
|                 <!-- Label et badge -->
 | |
|                 <div class="flex items-center">
 | |
|                     <span>{{ trimester.label }}</span>
 | |
|                     {% if badge_count > 0 %}
 | |
|                     <span class="ml-2 px-2 py-0.5 text-xs font-bold rounded-full
 | |
|                                  {% if is_active %}
 | |
|                                  bg-white/20 text-white
 | |
|                                  {% else %}
 | |
|                                  bg-{{ trimester.text_color.replace('text-', '').replace('-600', '') }}-100 {{ trimester.text_color }}
 | |
|                                  {% endif %}">
 | |
|                         {{ badge_count }}
 | |
|                     </span>
 | |
|                     {% endif %}
 | |
|                 </div>
 | |
|             </div>
 | |
|             
 | |
|             <!-- Tooltip -->
 | |
|             <div class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 text-xs bg-gray-900 text-white rounded opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none">
 | |
|                 {{ trimester.description }}
 | |
|                 <div class="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900"></div>
 | |
|             </div>
 | |
|         </button>
 | |
|         {% endfor %}
 | |
|     </div>
 | |
|     
 | |
|     <!-- Tabs de navigation - Version mobile (scroll horizontal) -->
 | |
|     <div class="md:hidden overflow-x-auto">
 | |
|         <div class="flex space-x-2 pb-2">
 | |
|             {% for trimester in trimesters %}
 | |
|             {% set is_active = selected_trimester == trimester.key or (selected_trimester is none and trimester.key == 'global') %}
 | |
|             {% set badge_count = badges.get(trimester.key, 0) %}
 | |
|             
 | |
|             <button type="button" 
 | |
|                     class="tab-btn flex-shrink-0 px-4 py-2 rounded-lg font-medium text-sm transition-all duration-300
 | |
|                            {% if is_active %}
 | |
|                            bg-gradient-to-r {{ trimester.gradient }} text-white shadow-md
 | |
|                            {% else %}
 | |
|                            bg-gray-50 text-gray-600 hover:bg-gray-100 border border-gray-200
 | |
|                            {% endif %}"
 | |
|                     data-trimester="{{ trimester.key }}" 
 | |
|                     data-base-url="{{ base_url }}"
 | |
|                     data-class-id="{{ class_id }}"
 | |
|                     onclick="navigateToTrimester(this)">
 | |
|                 
 | |
|                 <div class="flex items-center">
 | |
|                     <div class="mr-2 {% if not is_active %}{{ trimester.text_color }}{% endif %}">
 | |
|                         {{ trimester.icon|safe }}
 | |
|                     </div>
 | |
|                     <span>{{ trimester.short }}</span>
 | |
|                     {% if badge_count > 0 %}
 | |
|                     <span class="ml-1 px-1.5 py-0.5 text-xs font-bold rounded-full
 | |
|                                  {% if is_active %}
 | |
|                                  bg-white/20 text-white
 | |
|                                  {% else %}
 | |
|                                  bg-{{ trimester.text_color.replace('text-', '').replace('-600', '') }}-100 {{ trimester.text_color }}
 | |
|                                  {% endif %}">
 | |
|                         {{ badge_count }}
 | |
|                     </span>
 | |
|                     {% endif %}
 | |
|                 </div>
 | |
|             </button>
 | |
|             {% endfor %}
 | |
|         </div>
 | |
|     </div>
 | |
|     
 | |
|     <!-- Informations contextuelles -->
 | |
|     <div class="mt-4 p-3 bg-gray-50 rounded-lg border border-gray-200">
 | |
|         {% set current_trimester = trimesters|selectattr('key', 'equalto', selected_trimester)|first %}
 | |
|         {% if not current_trimester %}
 | |
|             {% set current_trimester = trimesters|selectattr('key', 'equalto', 'global')|first %}
 | |
|         {% endif %}
 | |
|         
 | |
|         <div class="flex items-center justify-between">
 | |
|             <div class="flex items-center">
 | |
|                 <div class="w-8 h-8 {{ current_trimester.bg_color }} rounded-lg flex items-center justify-center mr-3 {{ current_trimester.text_color }}">
 | |
|                     {{ current_trimester.icon|safe }}
 | |
|                 </div>
 | |
|                 <div>
 | |
|                     <p class="text-sm font-medium text-gray-900">{{ current_trimester.label }}</p>
 | |
|                     <p class="text-xs text-gray-500">{{ current_trimester.description }}</p>
 | |
|                 </div>
 | |
|             </div>
 | |
|             
 | |
|             <!-- Statistiques rapides -->
 | |
|             {% set current_badge = badges.get(selected_trimester or 'global', 0) %}
 | |
|             {% if current_badge > 0 %}
 | |
|             <div class="text-right">
 | |
|                 <p class="text-sm font-semibold {{ current_trimester.text_color }}">{{ current_badge }}</p>
 | |
|                 <p class="text-xs text-gray-500">évaluation{{ 's' if current_badge > 1 else '' }}</p>
 | |
|             </div>
 | |
|             {% endif %}
 | |
|         </div>
 | |
|     </div>
 | |
| </div>
 | |
| 
 | |
| {# JavaScript pour la navigation - À inclure dans la page qui utilise le composant #}
 | |
| <script>
 | |
| function navigateToTrimester(button) {
 | |
|     const trimester = button.dataset.trimester;
 | |
|     const baseUrl = button.dataset.baseUrl;
 | |
|     const classId = button.dataset.classId;
 | |
|     
 | |
|     // Construire l'URL avec le paramètre trimestre
 | |
|     let url = baseUrl;
 | |
|     if (url.includes('?')) {
 | |
|         url += '&';
 | |
|     } else {
 | |
|         url += '?';
 | |
|     }
 | |
|     
 | |
|     // Ajouter le paramètre trimestre (sauf pour 'global')
 | |
|     if (trimester !== 'global') {
 | |
|         url += `trimestre=${trimester}`;
 | |
|     } else {
 | |
|         // Pour global, on ne met pas de paramètre trimestre
 | |
|         url = baseUrl;
 | |
|     }
 | |
|     
 | |
|     // Animation de transition
 | |
|     button.style.transform = 'scale(0.95)';
 | |
|     setTimeout(() => {
 | |
|         button.style.transform = '';
 | |
|         window.location.href = url;
 | |
|     }, 150);
 | |
| }
 | |
| 
 | |
| // Gestion du scroll horizontal sur mobile
 | |
| document.addEventListener('DOMContentLoaded', function() {
 | |
|     const mobileNav = document.querySelector('.trimester-nav .md\\:hidden .flex');
 | |
|     const activeButton = mobileNav?.querySelector('.bg-gradient-to-r');
 | |
|     
 | |
|     // Scroller automatiquement vers le bouton actif sur mobile
 | |
|     if (activeButton && mobileNav) {
 | |
|         activeButton.scrollIntoView({ 
 | |
|             behavior: 'smooth', 
 | |
|             inline: 'center',
 | |
|             block: 'nearest'
 | |
|         });
 | |
|     }
 | |
| });
 | |
| 
 | |
| // Animation au hover pour les tooltips desktop
 | |
| document.addEventListener('DOMContentLoaded', function() {
 | |
|     const buttons = document.querySelectorAll('.trimester-nav .tab-btn');
 | |
|     buttons.forEach(button => {
 | |
|         let timeout;
 | |
|         
 | |
|         button.addEventListener('mouseenter', function() {
 | |
|             timeout = setTimeout(() => {
 | |
|                 const tooltip = this.querySelector('.absolute.bottom-full');
 | |
|                 if (tooltip) {
 | |
|                     tooltip.style.transform = 'translateX(-50%) translateY(-2px)';
 | |
|                 }
 | |
|             }, 300);
 | |
|         });
 | |
|         
 | |
|         button.addEventListener('mouseleave', function() {
 | |
|             clearTimeout(timeout);
 | |
|             const tooltip = this.querySelector('.absolute.bottom-full');
 | |
|             if (tooltip) {
 | |
|                 tooltip.style.transform = 'translateX(-50%) translateY(0)';
 | |
|             }
 | |
|         });
 | |
|     });
 | |
| });
 | |
| </script>
 | |
| {% endmacro %} |