Files
notytex/templates/components/class/README_COMPONENTS.md

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, 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

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 ! 🎓