8.4 KiB
8.4 KiB
🧩 Composants Réutilisables pour Pages de Classe
Deux nouveaux composants modulaires ont été créés pour la nouvelle page de présentation de classe de Notytex.
📁 Structure des Fichiers
templates/components/class/
├── class_stats_card.html # Card de statistiques extensible (4 types)
├── trimester_nav.html # Navigation par trimestre avec couleurs thématiques
├── example_usage.html # Exemples d'utilisation complets
└── README_COMPONENTS.md # Documentation technique (ce fichier)
🎨 1. Composant class_stats_card
Utilisation
{% from 'components/class/class_stats_card.html' import class_stats_card %}
{{ class_stats_card(
type='quantity',
data={"total": 8, "completed": 6, "in_progress": 2, "not_started": 0},
expanded=False
) }}
Types Supportés
type='quantity' - Évaluations
data = {
"total": 8, # Nombre total d'évaluations
"completed": 6, # Évaluations terminées (100%)
"in_progress": 2, # Évaluations en cours de correction
"not_started": 0 # Évaluations non commencées (0%)
}
type='domains' - Domaines Mathématiques
data = [
{
"name": "Nombres et calculs",
"color": "#3B82F6", # Couleur hex du domaine
"total_points": 45.0, # Points total du domaine
"elements_count": 12 # Nombre d'éléments de notation
},
# ... autres domaines
]
type='competences' - Compétences Transversales
data = [
{
"name": "Chercher",
"color": "#8B5CF6",
"total_points": 25.0,
"elements_count": 6
},
# ... autres compétences
]
type='results' - Analyse des Résultats
data = {
"mean": 14.2, # Moyenne de classe
"median": 15.0, # Médiane
"distribution": [0,1,3,8,12,6,2,0], # Histogramme par tranches de 1 point
"min": 8.0, # Note minimum
"max": 20.0 # Note maximum
}
Fonctionnalités
- ✅ Progressive Disclosure : Contenu collapsed/expanded
- ✅ Code Couleur : Chaque type a sa couleur thématique
- ✅ Actions Contextuelles : Liens vers analyses détaillées
- ✅ Responsive Design : Adaptation mobile/desktop
- ✅ JavaScript Intégré : Interactions d'expansion automatiques
🗓️ 2. Composant trimester_nav
Utilisation
{% from 'components/class/trimester_nav.html' import trimester_nav %}
{{ trimester_nav(
class_id=42,
base_url=url_for('classes.class_detail', class_id=42),
selected_trimester=2,
badges={1: 4, 2: 3, 3: 2, 'global': 9}
) }}
Paramètres
| Paramètre | Type | Requis | Description |
|---|---|---|---|
class_id |
int | ✅ | ID de la classe (pour navigation) |
base_url |
str | ✅ | URL de base pour navigation |
selected_trimester |
int/None | ❌ | Trimestre actuel (1,2,3 ou None pour Global) |
badges |
dict | ❌ | Nombre d'évaluations par trimestre |
Couleurs Thématiques
| Période | Couleurs | Symbolisme |
|---|---|---|
| Global | from-purple-500 to-purple-600 |
🟣 Synthétique (toute l'année) |
| Trimestre 1 | from-blue-500 to-blue-600 |
🔵 Hiver (Sept-Déc) |
| Trimestre 2 | from-green-500 to-green-600 |
🟢 Printemps (Jan-Mars) |
| Trimestre 3 | from-orange-500 to-orange-600 |
🟠 Été (Avr-Juil) |
Fonctionnalités
- ✅ Navigation URL : Génération automatique des liens
?trimestre=X - ✅ Badges Dynamiques : Compteurs d'évaluations par période
- ✅ Responsive : Version desktop (horizontal) + mobile (scroll)
- ✅ Tooltips : Descriptions contextuelles au hover
- ✅ Animation : Transitions fluides entre les états
🎯 Intégration dans Notytex
Dans les Contrôleurs Flask
# routes/classes.py
@classes_bp.route('/classes/<int:class_id>')
def class_detail(class_id):
selected_trimester = request.args.get('trimestre', type=int)
# Données pour class_stats_card
quantity_data = {
"total": Assessment.query.filter_by(class_group_id=class_id).count(),
"completed": Assessment.query.filter_by(class_group_id=class_id).filter(
Assessment.grading_progress['status'] == 'completed'
).count(),
# ... autres calculs
}
# Données pour badges trimester_nav
badges = {}
for t in [1, 2, 3]:
badges[t] = Assessment.query.filter_by(
class_group_id=class_id,
trimester=t
).count()
badges['global'] = sum(badges.values())
return render_template('classes/detail.html',
quantity_data=quantity_data,
badges=badges,
selected_trimester=selected_trimester)
Dans les Templates
{# classes/detail.html #}
{% extends "base.html" %}
{% from 'components/class/class_stats_card.html' import class_stats_card %}
{% from 'components/class/trimester_nav.html' import trimester_nav %}
{% block content %}
<div class="max-w-7xl mx-auto px-4 py-8">
<!-- Navigation trimestre -->
{{ trimester_nav(
class_id=class_group.id,
base_url=url_for('classes.class_detail', class_id=class_group.id),
selected_trimester=selected_trimester,
badges=badges
) }}
<!-- Grille de statistiques -->
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 gap-6">
{{ class_stats_card('quantity', quantity_data) }}
{{ class_stats_card('domains', domains_data) }}
{{ class_stats_card('competences', competences_data) }}
{{ class_stats_card('results', results_data) }}
</div>
</div>
{% endblock %}
🔧 Architecture Technique
Design System Cohérent
- TailwindCSS : Classes cohérentes avec l'existant (
rounded-xl,shadow-lg, etc.) - Couleurs Sémantiques : Rouge/Orange/Vert pour les états, couleurs thématiques pour les trimestres
- Espacements Harmonieux : Grid
gap-6, paddingp-6, marges cohérentes - Typography : Hiérarchie claire avec
text-lg font-semibold,text-2xl font-bold
Progressive Enhancement
- HTML First : Fonctionnel même sans JavaScript
- JavaScript Optionnel : Améliore l'UX (animations, interactions)
- Responsive : Mobile-first avec breakpoints TailwindCSS
- Accessibilité : Attributs ARIA, focus management, keyboard navigation
Performance
- CSS Pur : Pas de frameworks JS lourds (React, Vue)
- Lazy Loading : Contenu étendu masqué par défaut
- Cache Friendly : Templates statiques cachables
- Minimal JavaScript : Functions natives, pas de dépendances
🚀 Extensibilité Future
Nouveaux Types de Stats
Pour ajouter un nouveau type à class_stats_card :
- Ajouter la configuration dans
configeticons - Implémenter le rendu dans le bloc
{% elif type == 'nouveau_type' %} - Définir la structure de données attendue
- Tester avec des données d'exemple
Nouvelles Périodes
Pour ajouter des périodes à trimester_nav :
- Étendre le tableau
trimestersavec nouvelle configuration - Ajouter les couleurs thématiques appropriées
- Adapter la logique de navigation dans JavaScript
- Mettre à jour les contrôleurs Flask pour supporter la nouvelle période
🧪 Tests et Validation
Tests de Syntaxe ✅
uv run python -c "import jinja2; env = jinja2.Environment(); template = env.from_string(open('templates/components/class/class_stats_card.html').read()); print('✅ Syntaxe OK')"
uv run python -c "import jinja2; env = jinja2.Environment(); template = env.from_string(open('templates/components/class/trimester_nav.html').read()); print('✅ Syntaxe OK')"
Tests d'Intégration (À implémenter)
# tests/test_class_components.py
def test_class_stats_card_rendering():
"""Test le rendu des 4 types de stats cards"""
pass
def test_trimester_nav_navigation():
"""Test la génération des URLs de navigation"""
pass
def test_responsive_behavior():
"""Test l'adaptation mobile/desktop"""
pass
Ces composants transforment la page de classe en une interface moderne, interactive et parfaitement intégrée au design system Notytex ! 🎓✨