feat: improve assessments filters
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% from 'components/common/macros.html' import hero_section, filter_section %}
|
||||
{% from 'components/common/macros.html' import hero_section, simple_filter_section %}
|
||||
{% from 'components/assessment/assessment_card.html' import assessment_card %}
|
||||
|
||||
{% block title %}Évaluations - Gestion Scolaire{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="space-y-8">
|
||||
{# Hero Section avec composant réutilisable #}
|
||||
@@ -30,55 +31,29 @@
|
||||
gradient_class="from-purple-600 to-blue-600"
|
||||
) }}
|
||||
|
||||
{# Filtres avec composant réutilisable #}
|
||||
{# Configuration des filtres simplifiés #}
|
||||
{% set class_options = [{'value': '', 'label': 'Toutes'}] %}
|
||||
{% for class_group in classes %}
|
||||
{% set _ = class_options.append({'value': class_group.id|string, 'label': class_group.name}) %}
|
||||
{% endfor %}
|
||||
|
||||
{% set filters = [
|
||||
{
|
||||
'id': 'trimester-filter',
|
||||
'label': 'Trimestre',
|
||||
'options': [
|
||||
{'value': '', 'label': 'Tous'},
|
||||
{'value': '1', 'label': 'Trimestre 1'},
|
||||
{'value': '2', 'label': 'Trimestre 2'},
|
||||
{'value': '3', 'label': 'Trimestre 3'}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id': 'class-filter',
|
||||
'label': 'Classe',
|
||||
'options': class_options
|
||||
},
|
||||
{
|
||||
'id': 'correction-filter',
|
||||
'label': 'Correction',
|
||||
'options': [
|
||||
{'value': '', 'label': 'Toutes'},
|
||||
{'value': 'incomplete', 'label': 'Non terminées'},
|
||||
{'value': 'complete', 'label': 'Terminées'},
|
||||
{'value': 'not_started', 'label': 'Non commencées'}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id': 'sort-filter',
|
||||
'label': 'Tri',
|
||||
'options': [
|
||||
{'value': 'date_desc', 'label': 'Plus récent'},
|
||||
{'value': 'date_asc', 'label': 'Plus ancien'},
|
||||
{'value': 'title', 'label': 'Titre A-Z'},
|
||||
{'value': 'class', 'label': 'Classe'}
|
||||
]
|
||||
}
|
||||
] %}
|
||||
{% set filters_config = {
|
||||
'trimester': True,
|
||||
'correction': True,
|
||||
'class_options': class_options
|
||||
} %}
|
||||
|
||||
{% call filter_section(filters, {'trimester-filter': current_trimester, 'class-filter': current_class, 'correction-filter': current_correction, 'sort-filter': current_sort}) %}
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="text-sm text-gray-500 font-medium">
|
||||
{{ assessments|length }} évaluation(s)
|
||||
</div>
|
||||
{% call simple_filter_section(
|
||||
filters_config,
|
||||
{
|
||||
'trimester-filter': current_trimester,
|
||||
'class-filter': current_class,
|
||||
'correction-filter': current_correction
|
||||
},
|
||||
total_items=total_assessments_count,
|
||||
filtered_items=assessments|length
|
||||
) %}
|
||||
<div class="flex flex-col space-y-3">
|
||||
<div class="md:hidden">
|
||||
<a href="{{ url_for('assessments.new') }}"
|
||||
class="w-full bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 text-white px-6 py-3 rounded-xl transition-all duration-300 font-semibold shadow-lg hover:shadow-xl transform hover:scale-105 flex items-center justify-center">
|
||||
@@ -131,6 +106,19 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# JavaScript géré par le système centralisé #}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='js/simple-filters.js') }}"></script>
|
||||
<script>
|
||||
// Configuration spécifique à la page assessments
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Mettre à jour les compteurs si l'instance existe
|
||||
if (window.simpleFilters) {
|
||||
const totalCount = {{ total_assessments_count }};
|
||||
const filteredCount = {{ assessments|length }};
|
||||
window.simpleFilters.updateCounts(totalCount, filteredCount);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/design-system.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}">
|
||||
{% block head %}{% endblock %}
|
||||
<script>
|
||||
// Configuration Tailwind étendue avec design tokens
|
||||
tailwind.config = {
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
</a>
|
||||
{% endmacro %}
|
||||
|
||||
{# Macro pour filtres standardisés #}
|
||||
{# Macro pour filtres standardisés - Version classique (conservée pour compatibilité) #}
|
||||
{% macro filter_section(filters, current_values={}) %}
|
||||
<div class="filter-section">
|
||||
<div class="flex flex-col lg:flex-row lg:items-center lg:justify-between space-y-4 lg:space-y-0">
|
||||
@@ -210,4 +210,86 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# Macro pour filtres simplifiés et discrets #}
|
||||
{% macro simple_filter_section(filters_config, current_values={}, total_items=0, filtered_items=0) %}
|
||||
<div class="bg-gray-50 rounded-lg p-4 mb-6 border border-gray-200">
|
||||
<!-- Filtres compacts en une ligne -->
|
||||
<div class="flex flex-wrap items-center gap-4 text-sm">
|
||||
<div class="flex items-center text-gray-600">
|
||||
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
<span id="filtered-count">{{ filtered_items }}</span>/<span class="text-gray-500">{{ total_items }}</span>
|
||||
</div>
|
||||
<!-- Filtre Trimestre -->
|
||||
{% if filters_config.trimester %}
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="text-gray-500 text-xs">Trimestre:</span>
|
||||
<button type="button" data-filter="trimester" data-value=""
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if not current_values.get('trimester-filter') %}bg-blue-600 text-white border-blue-600{% else %}bg-white text-gray-600 border-gray-300 hover:bg-gray-50{% endif %} transition-colors">
|
||||
Tous
|
||||
</button>
|
||||
{% for i in range(1, 4) %}
|
||||
<button type="button" data-filter="trimester" data-value="{{ i }}"
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if current_values.get('trimester-filter') == i|string %}bg-blue-600 text-white border-blue-600{% else %}bg-white text-gray-600 border-gray-300 hover:bg-gray-50{% endif %} transition-colors">
|
||||
T{{ i }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Filtre Classe -->
|
||||
{% if filters_config.class_options %}
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="text-gray-500 text-xs">Classe:</span>
|
||||
{% for option in filters_config.class_options %}
|
||||
<button type="button" data-filter="class" data-value="{{ option.value }}"
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if current_values.get('class-filter') == option.value %}bg-blue-600 text-white border-blue-600{% else %}bg-white text-gray-600 border-gray-300 hover:bg-gray-50{% endif %} transition-colors">
|
||||
{{ option.label }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Filtre État de correction -->
|
||||
{% if filters_config.correction %}
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="text-gray-500 text-xs">État:</span>
|
||||
<button type="button" data-filter="correction" data-value=""
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if not current_values.get('correction-filter') %}bg-blue-600 text-white border-blue-600{% else %}bg-white text-gray-600 border-gray-300 hover:bg-gray-50{% endif %} transition-colors">
|
||||
Toutes
|
||||
</button>
|
||||
<button type="button" data-filter="correction" data-value="not_started"
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if current_values.get('correction-filter') == 'not_started' %}bg-red-500 text-white border-red-500{% else %}bg-white text-red-600 border-red-200 hover:bg-red-50{% endif %} transition-colors">
|
||||
Non commencées
|
||||
</button>
|
||||
<button type="button" data-filter="correction" data-value="incomplete"
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if current_values.get('correction-filter') == 'incomplete' %}bg-orange-500 text-white border-orange-500{% else %}bg-white text-orange-600 border-orange-200 hover:bg-orange-50{% endif %} transition-colors">
|
||||
En cours
|
||||
</button>
|
||||
<button type="button" data-filter="correction" data-value="complete"
|
||||
class="filter-btn px-2 py-1 text-xs rounded border {% if current_values.get('correction-filter') == 'complete' %}bg-green-500 text-white border-green-500{% else %}bg-white text-green-600 border-green-200 hover:bg-green-50{% endif %} transition-colors">
|
||||
Terminées
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Reset discret et contenu additionnel -->
|
||||
<div class="flex items-center justify-between mt-2">
|
||||
<div id="active-filter-tags" class="flex flex-wrap gap-1">
|
||||
<!-- Tags générés par JavaScript -->
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button type="button" id="reset-filters" class="text-xs text-gray-500 hover:text-gray-700 hidden">
|
||||
Effacer
|
||||
</button>
|
||||
{% if caller %}
|
||||
{{ caller() }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
Reference in New Issue
Block a user