261 lines
8.4 KiB
Markdown
261 lines
8.4 KiB
Markdown
# 🧩 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**
|
|
|
|
```jinja2
|
|
{% 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
|
|
```python
|
|
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
|
|
```python
|
|
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
|
|
```python
|
|
data = [
|
|
{
|
|
"name": "Chercher",
|
|
"color": "#8B5CF6",
|
|
"total_points": 25.0,
|
|
"elements_count": 6
|
|
},
|
|
# ... autres compétences
|
|
]
|
|
```
|
|
|
|
#### `type='results'` - Analyse des Résultats
|
|
```python
|
|
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**
|
|
|
|
```jinja2
|
|
{% 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**
|
|
|
|
```python
|
|
# 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**
|
|
|
|
```jinja2
|
|
{# 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`, padding `p-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` :
|
|
|
|
1. **Ajouter la configuration** dans `config` et `icons`
|
|
2. **Implémenter le rendu** dans le bloc `{% elif type == 'nouveau_type' %}`
|
|
3. **Définir la structure de données** attendue
|
|
4. **Tester avec des données d'exemple**
|
|
|
|
### **Nouvelles Périodes**
|
|
|
|
Pour ajouter des périodes à `trimester_nav` :
|
|
|
|
1. **Étendre le tableau `trimesters`** avec nouvelle configuration
|
|
2. **Ajouter les couleurs thématiques** appropriées
|
|
3. **Adapter la logique de navigation** dans JavaScript
|
|
4. **Mettre à jour les contrôleurs** Flask pour supporter la nouvelle période
|
|
|
|
## 🧪 Tests et Validation
|
|
|
|
### **Tests de Syntaxe** ✅
|
|
|
|
```bash
|
|
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)
|
|
|
|
```python
|
|
# 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** ! 🎓✨ |