Feat: add class page

This commit is contained in:
2025-08-09 11:32:36 +02:00
parent 17995f913e
commit 0e87a457af
18 changed files with 6974 additions and 14 deletions

View File

@@ -0,0 +1,261 @@
# 🧩 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** ! 🎓✨