feat: documenting frontend
This commit is contained in:
614
docs/frontend/COMPONENT_BEST_PRACTICES.md
Normal file
614
docs/frontend/COMPONENT_BEST_PRACTICES.md
Normal file
@@ -0,0 +1,614 @@
|
|||||||
|
# 🎨 Guide des Bonnes Pratiques - Composants Frontend
|
||||||
|
|
||||||
|
> **Guide**: Design System Notytex
|
||||||
|
> **Audience**: Développeurs Frontend & UI/UX Designers
|
||||||
|
> **Version**: 1.0
|
||||||
|
> **Mise à jour**: 7 août 2025
|
||||||
|
|
||||||
|
## 🎯 **Philosophie du Design System**
|
||||||
|
|
||||||
|
Notytex adopte une approche **moderne, cohérente et accessible** pour ses composants frontend. Chaque composant doit être **réutilisable**, **maintenable** et **évolutif**.
|
||||||
|
|
||||||
|
### 🏗️ **Principes Fondamentaux**
|
||||||
|
- **🔄 Réutilisabilité** : Un composant = plusieurs contextes
|
||||||
|
- **🎨 Cohérence** : Design tokens centralisés
|
||||||
|
- **📱 Responsive-first** : Mobile d'abord
|
||||||
|
- **♿ Accessibilité** : WCAG 2.1 AA minimum
|
||||||
|
- **⚡ Performance** : Optimisation native
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 **Architecture des Composants**
|
||||||
|
|
||||||
|
### **Structure de Répertoires**
|
||||||
|
```
|
||||||
|
templates/components/
|
||||||
|
├── common/
|
||||||
|
│ ├── macros.html # Macros réutilisables
|
||||||
|
│ └── base_components.html # Composants de base
|
||||||
|
├── assessment/
|
||||||
|
│ └── assessment_card.html # Cartes d'évaluation
|
||||||
|
├── class/
|
||||||
|
│ └── class_card.html # Cartes de classe
|
||||||
|
├── forms/
|
||||||
|
│ ├── form_inputs.html # Champs de formulaire
|
||||||
|
│ └── form_validation.html # Validation UI
|
||||||
|
└── ui/
|
||||||
|
├── buttons.html # Système de boutons
|
||||||
|
├── modals.html # Modales
|
||||||
|
└── notifications.html # Toasts/Alerts
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Convention de Nommage**
|
||||||
|
```
|
||||||
|
Type_Domain_Component.html
|
||||||
|
│ │ │
|
||||||
|
│ │ └─ Nom spécifique (card, button, modal...)
|
||||||
|
│ └──────── Domaine métier (assessment, class, user...)
|
||||||
|
└───────────── Type (component, macro, layout...)
|
||||||
|
```
|
||||||
|
|
||||||
|
**📝 Exemples:**
|
||||||
|
- `assessment_card.html` ✅
|
||||||
|
- `class_list_item.html` ✅
|
||||||
|
- `user_profile_widget.html` ✅
|
||||||
|
- `genericCard.html` ❌ (PascalCase)
|
||||||
|
- `card.html` ❌ (trop générique)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 **Design Tokens & Cohérence**
|
||||||
|
|
||||||
|
### **Palette de Couleurs Système**
|
||||||
|
```scss
|
||||||
|
// Couleurs Primaires
|
||||||
|
$blue: from-blue-500 to-blue-600 // Actions principales
|
||||||
|
$green: from-green-500 to-green-600 // Succès, validation
|
||||||
|
$purple: from-purple-500 to-purple-600 // Évaluations, analytique
|
||||||
|
$orange: from-orange-500 to-orange-600 // Avertissement, en cours
|
||||||
|
$red: from-red-500 to-red-600 // Erreur, critique
|
||||||
|
$pink: from-pink-500 to-pink-600 // Spécial, mise en avant
|
||||||
|
|
||||||
|
// Couleurs Neutres
|
||||||
|
$gray-50: #f9fafb // Fond très clair
|
||||||
|
$gray-100: #f3f4f6 // Fond clair
|
||||||
|
$gray-600: #4b5563 // Texte secondaire
|
||||||
|
$gray-900: #111827 // Texte principal
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Typography Scale**
|
||||||
|
```scss
|
||||||
|
// Hiérarchie Textuelle
|
||||||
|
.text-4xl { font-size: 2.25rem } // Titres Hero
|
||||||
|
.text-3xl { font-size: 1.875rem } // Titres principaux
|
||||||
|
.text-2xl { font-size: 1.5rem } // Titres sections
|
||||||
|
.text-xl { font-size: 1.25rem } // Sous-titres
|
||||||
|
.text-lg { font-size: 1.125rem } // Texte large
|
||||||
|
.text-base { font-size: 1rem } // Texte standard
|
||||||
|
.text-sm { font-size: 0.875rem } // Texte petit
|
||||||
|
.text-xs { font-size: 0.75rem } // Métadonnées
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Spacing System**
|
||||||
|
```scss
|
||||||
|
// Système d'espacement (Tailwind)
|
||||||
|
space-1: 0.25rem // 4px
|
||||||
|
space-2: 0.5rem // 8px
|
||||||
|
space-3: 0.75rem // 12px
|
||||||
|
space-4: 1rem // 16px
|
||||||
|
space-6: 1.5rem // 24px
|
||||||
|
space-8: 2rem // 32px
|
||||||
|
space-12: 3rem // 48px
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧩 **Anatomie d'un Composant**
|
||||||
|
|
||||||
|
### **Template Structure**
|
||||||
|
```jinja2
|
||||||
|
{# 1. Commentaire de description #}
|
||||||
|
{# Composant pour [FONCTION] dans [CONTEXTE] #}
|
||||||
|
|
||||||
|
{# 2. Import des dépendances #}
|
||||||
|
{% from 'components/common/macros.html' import helper_macro %}
|
||||||
|
|
||||||
|
{# 3. Définition du macro principal #}
|
||||||
|
{% macro component_name(required_param, optional_param=default) %}
|
||||||
|
|
||||||
|
{# 4. Logique de configuration #}
|
||||||
|
{% set config = {
|
||||||
|
'variant': optional_param,
|
||||||
|
'classes': 'base-classes ' + (additional_classes if condition else '')
|
||||||
|
} %}
|
||||||
|
|
||||||
|
{# 5. Structure HTML avec données dynamiques #}
|
||||||
|
<div class="{{ config.classes }}" data-component="component-name">
|
||||||
|
<!-- Contenu structuré -->
|
||||||
|
{% if caller %}
|
||||||
|
{{ caller() }}
|
||||||
|
{% else %}
|
||||||
|
<!-- Contenu par défaut -->
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# 6. Fin du macro #}
|
||||||
|
{% endmacro %}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Exemple Concret : Button Component**
|
||||||
|
```jinja2
|
||||||
|
{# Composant bouton avec variants et états #}
|
||||||
|
|
||||||
|
{% macro button(
|
||||||
|
text,
|
||||||
|
url=None,
|
||||||
|
type="primary",
|
||||||
|
size="md",
|
||||||
|
icon=None,
|
||||||
|
disabled=False,
|
||||||
|
classes=""
|
||||||
|
) %}
|
||||||
|
|
||||||
|
{# Configuration des variants #}
|
||||||
|
{% set variants = {
|
||||||
|
'primary': 'bg-gradient-to-r from-blue-500 to-blue-600 text-white',
|
||||||
|
'secondary': 'bg-gray-50 text-gray-700 border border-gray-300',
|
||||||
|
'danger': 'bg-gradient-to-r from-red-500 to-red-600 text-white'
|
||||||
|
} %}
|
||||||
|
|
||||||
|
{% set sizes = {
|
||||||
|
'sm': 'px-3 py-2 text-sm',
|
||||||
|
'md': 'px-4 py-2 text-base',
|
||||||
|
'lg': 'px-6 py-3 text-lg'
|
||||||
|
} %}
|
||||||
|
|
||||||
|
{# Classes finales #}
|
||||||
|
{% set button_classes = [
|
||||||
|
'inline-flex items-center justify-center',
|
||||||
|
'rounded-xl font-semibold transition-all duration-300',
|
||||||
|
'hover:shadow-lg transform hover:scale-105',
|
||||||
|
variants[type],
|
||||||
|
sizes[size],
|
||||||
|
'opacity-50 cursor-not-allowed' if disabled else '',
|
||||||
|
classes
|
||||||
|
]|join(' ') %}
|
||||||
|
|
||||||
|
{# Rendu conditionnel (lien vs bouton) #}
|
||||||
|
{% if url and not disabled %}
|
||||||
|
<a href="{{ url }}" class="{{ button_classes }}">
|
||||||
|
{% else %}
|
||||||
|
<button type="button" class="{{ button_classes }}"{% if disabled %} disabled{% endif %}>
|
||||||
|
{% endif %}
|
||||||
|
{% if icon %}
|
||||||
|
<span class="w-5 h-5 mr-2">{{ icon|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{{ text }}
|
||||||
|
{% if url and not disabled %}</a>{% else %}</button>{% endif %}
|
||||||
|
|
||||||
|
{% endmacro %}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎛️ **API des Composants**
|
||||||
|
|
||||||
|
### **Paramètres Standards**
|
||||||
|
Chaque composant doit exposer une API cohérente :
|
||||||
|
|
||||||
|
```jinja2
|
||||||
|
{% macro component_name(
|
||||||
|
# === OBLIGATOIRES ===
|
||||||
|
data, # Données principales
|
||||||
|
title, # Titre/Label
|
||||||
|
|
||||||
|
# === OPTIONNELS ===
|
||||||
|
variant="default", # Type/Style (primary, secondary, danger...)
|
||||||
|
size="md", # Taille (sm, md, lg, xl)
|
||||||
|
classes="", # Classes CSS additionnelles
|
||||||
|
|
||||||
|
# === COMPORTEMENT ===
|
||||||
|
clickable=True, # Interactif ou non
|
||||||
|
disabled=False, # État désactivé
|
||||||
|
loading=False, # État de chargement
|
||||||
|
|
||||||
|
# === CONTENU ===
|
||||||
|
icon=None, # Icône SVG
|
||||||
|
badge=None, # Badge/Compteur
|
||||||
|
actions=[], # Liste d'actions
|
||||||
|
|
||||||
|
# === TECHNIQUE ===
|
||||||
|
id=None, # ID HTML personnalisé
|
||||||
|
attrs={} # Attributs HTML additionnels
|
||||||
|
) %}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Exemple d'Utilisation**
|
||||||
|
```jinja2
|
||||||
|
{# Usage simple #}
|
||||||
|
{{ button("Sauvegarder") }}
|
||||||
|
|
||||||
|
{# Usage avancé #}
|
||||||
|
{{ button(
|
||||||
|
text="Créer évaluation",
|
||||||
|
url=url_for('assessments.new'),
|
||||||
|
type="primary",
|
||||||
|
size="lg",
|
||||||
|
icon='<svg>...</svg>',
|
||||||
|
classes="w-full md:w-auto"
|
||||||
|
) }}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 **États et Variants**
|
||||||
|
|
||||||
|
### **États Standardisés**
|
||||||
|
Tous les composants interactifs doivent gérer ces états :
|
||||||
|
|
||||||
|
```scss
|
||||||
|
// États de base
|
||||||
|
.default // État normal
|
||||||
|
.hover // Survol
|
||||||
|
.active // Actif/Pressé
|
||||||
|
.focus // Focus clavier
|
||||||
|
.disabled // Désactivé
|
||||||
|
|
||||||
|
// États applicatifs
|
||||||
|
.loading // Chargement en cours
|
||||||
|
.success // Succès/Validation
|
||||||
|
.error // Erreur
|
||||||
|
.warning // Avertissement
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Variants de Style**
|
||||||
|
```scss
|
||||||
|
// Variants visuels
|
||||||
|
.primary // Action principale (bleu)
|
||||||
|
.secondary // Action secondaire (gris)
|
||||||
|
.success // Succès (vert)
|
||||||
|
.warning // Attention (orange)
|
||||||
|
.danger // Danger (rouge)
|
||||||
|
.ghost // Transparent
|
||||||
|
.outline // Contour seulement
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Exemple : Card States**
|
||||||
|
```jinja2
|
||||||
|
{# États d'une carte #}
|
||||||
|
{% set card_states = {
|
||||||
|
'default': 'bg-white shadow-lg hover:shadow-xl',
|
||||||
|
'active': 'bg-blue-50 border-2 border-blue-200 shadow-xl',
|
||||||
|
'disabled': 'bg-gray-50 opacity-50 cursor-not-allowed',
|
||||||
|
'loading': 'bg-gray-50 animate-pulse'
|
||||||
|
} %}
|
||||||
|
|
||||||
|
<div class="rounded-xl transition-all duration-300 {{ card_states[state] }}">
|
||||||
|
{% if state == 'loading' %}
|
||||||
|
<div class="p-6">
|
||||||
|
<div class="animate-pulse">
|
||||||
|
<div class="h-4 bg-gray-300 rounded w-3/4 mb-2"></div>
|
||||||
|
<div class="h-3 bg-gray-300 rounded w-1/2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<!-- Contenu normal -->
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📱 **Responsive Design**
|
||||||
|
|
||||||
|
### **Breakpoints Standard**
|
||||||
|
```scss
|
||||||
|
// Mobile First approach
|
||||||
|
sm: 640px // Téléphone large / Tablette portrait
|
||||||
|
md: 768px // Tablette
|
||||||
|
lg: 1024px // Desktop
|
||||||
|
xl: 1280px // Large desktop
|
||||||
|
2xl: 1536px // Ultra wide
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Grilles Responsives**
|
||||||
|
```jinja2
|
||||||
|
{# Grille adaptative standard #}
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
|
{% for item in items %}
|
||||||
|
{{ item_card(item) }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Navigation responsive #}
|
||||||
|
<nav class="flex flex-col md:flex-row md:items-center space-y-4 md:space-y-0 md:space-x-6">
|
||||||
|
<!-- Items navigation -->
|
||||||
|
</nav>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Typography Responsive**
|
||||||
|
```scss
|
||||||
|
// Échelle typographique adaptative
|
||||||
|
.hero-title {
|
||||||
|
@apply text-2xl md:text-4xl lg:text-5xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
@apply text-lg md:text-xl lg:text-2xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-text {
|
||||||
|
@apply text-sm md:text-base;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ♿ **Accessibilité**
|
||||||
|
|
||||||
|
### **Checklist Obligatoire**
|
||||||
|
- [ ] **Contraste** ≥ 4.5:1 pour texte normal
|
||||||
|
- [ ] **Contraste** ≥ 3:1 pour texte large
|
||||||
|
- [ ] **Navigation clavier** complète
|
||||||
|
- [ ] **ARIA labels** sur éléments interactifs
|
||||||
|
- [ ] **Focus indicators** visibles
|
||||||
|
- [ ] **Screen reader** compatible
|
||||||
|
|
||||||
|
### **Implémentation**
|
||||||
|
```jinja2
|
||||||
|
{# Bouton accessible #}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||||
|
aria-label="{{ accessible_label }}"
|
||||||
|
{% if disabled %}aria-disabled="true"{% endif %}
|
||||||
|
{% if has_popup %}aria-haspopup="true"{% endif %}
|
||||||
|
>
|
||||||
|
{% if icon %}
|
||||||
|
<span aria-hidden="true">{{ icon|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{{ text }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{# Card interactive accessible #}
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
class="cursor-pointer focus:ring-2 focus:ring-blue-500"
|
||||||
|
aria-label="Voir détails de {{ item.name }}"
|
||||||
|
onkeydown="if(event.key==='Enter'||event.key===' ') this.click()"
|
||||||
|
>
|
||||||
|
<!-- Contenu carte -->
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### **ARIA Patterns**
|
||||||
|
```html
|
||||||
|
<!-- Menu dropdown -->
|
||||||
|
<button aria-expanded="false" aria-haspopup="true" aria-controls="menu-1">
|
||||||
|
<ul id="menu-1" role="menu" aria-labelledby="menu-button-1">
|
||||||
|
|
||||||
|
<!-- Tabs -->
|
||||||
|
<div role="tablist" aria-label="Sections">
|
||||||
|
<button role="tab" aria-selected="true" aria-controls="panel-1">
|
||||||
|
<div id="panel-1" role="tabpanel" aria-labelledby="tab-1">
|
||||||
|
|
||||||
|
<!-- Progress -->
|
||||||
|
<div role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ **Performance**
|
||||||
|
|
||||||
|
### **Optimisations Obligatoires**
|
||||||
|
```jinja2
|
||||||
|
{# 1. Lazy loading d'images #}
|
||||||
|
<img
|
||||||
|
src="{{ image.url }}"
|
||||||
|
loading="lazy"
|
||||||
|
alt="{{ image.alt_text }}"
|
||||||
|
class="w-full h-auto"
|
||||||
|
>
|
||||||
|
|
||||||
|
{# 2. SVG inline pour icônes #}
|
||||||
|
{% set icon_check %}
|
||||||
|
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
{% endset %}
|
||||||
|
|
||||||
|
{# 3. Classes CSS optimisées #}
|
||||||
|
{% set optimized_classes = [
|
||||||
|
'base-class',
|
||||||
|
'conditional-class' if condition else '',
|
||||||
|
extra_classes
|
||||||
|
]|select|join(' ') %}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Métriques Cibles**
|
||||||
|
- **Temps de rendu** : <10ms par composant
|
||||||
|
- **Taille HTML** : <5KB par composant complexe
|
||||||
|
- **CSS utilisé** : >80% des classes appliquées
|
||||||
|
- **JavaScript** : Minimal (interactions natives CSS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 **Tests & Validation**
|
||||||
|
|
||||||
|
### **Tests Automatisés**
|
||||||
|
```python
|
||||||
|
# test_components.py
|
||||||
|
def test_component_renders_without_error():
|
||||||
|
"""Test que le composant se rend sans erreur"""
|
||||||
|
with app.app_context():
|
||||||
|
template = app.jinja_env.get_template('components/class/class_card.html')
|
||||||
|
# Test avec données minimales
|
||||||
|
result = template.render(class=mock_class_data)
|
||||||
|
assert len(result) > 0
|
||||||
|
assert 'class_card' in result # Vérifier présence indicateur
|
||||||
|
|
||||||
|
def test_component_handles_missing_data():
|
||||||
|
"""Test gestion des données manquantes"""
|
||||||
|
with app.app_context():
|
||||||
|
template = app.jinja_env.get_template('components/class/class_card.html')
|
||||||
|
# Test avec données None/vides
|
||||||
|
result = template.render(class=ClassGroup(name=None, students=[]))
|
||||||
|
assert 'Aucune description' in result # Message par défaut
|
||||||
|
assert 'bg-gray-100' in result # État "Vide"
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Tests Visuels**
|
||||||
|
```bash
|
||||||
|
# Validation syntaxe tous templates
|
||||||
|
find templates/components -name "*.html" -exec echo "Testing {}" \; -exec uv run python -c "
|
||||||
|
from app import create_app
|
||||||
|
app = create_app()
|
||||||
|
with app.app_context():
|
||||||
|
try:
|
||||||
|
template = app.jinja_env.get_template('{}')
|
||||||
|
print('✅ Syntaxe valide')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'❌ Erreur: {e}')
|
||||||
|
exit(1)
|
||||||
|
" \;
|
||||||
|
|
||||||
|
# Test responsive (manuel avec DevTools)
|
||||||
|
# 1. Mobile (375px)
|
||||||
|
# 2. Tablette (768px)
|
||||||
|
# 3. Desktop (1024px)
|
||||||
|
# 4. Large screen (1440px)
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Validation Accessibilité**
|
||||||
|
```bash
|
||||||
|
# Outils recommandés
|
||||||
|
axe-core # Test automatisé
|
||||||
|
WAVE # Extension navigateur
|
||||||
|
Lighthouse # Audit complet
|
||||||
|
Screen Reader # Test manuel (NVDA/JAWS/VoiceOver)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 **Maintenance & Évolution**
|
||||||
|
|
||||||
|
### **Versioning des Composants**
|
||||||
|
```jinja2
|
||||||
|
{# Header de composant avec version #}
|
||||||
|
{#
|
||||||
|
Component: class_card
|
||||||
|
Version: 1.2.0
|
||||||
|
Last Modified: 2025-08-07
|
||||||
|
Breaking Changes: None
|
||||||
|
Dependencies: macros.html v2.1+
|
||||||
|
#}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Changelog**
|
||||||
|
```markdown
|
||||||
|
## class_card v1.2.0 (2025-08-07)
|
||||||
|
### Added
|
||||||
|
- Support pour classes sans description
|
||||||
|
- Badge "Vide" pour classes sans élèves
|
||||||
|
- Extraction intelligente niveau de classe
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Couleurs selon niveau au lieu d'année scolaire
|
||||||
|
- Actions regroupées en grid 2 colonnes
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Gestion cas classe.name None
|
||||||
|
- Responsive sur petits écrans
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
- Paramètre `year` remplacé par extraction automatique
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Dépréciation**
|
||||||
|
```jinja2
|
||||||
|
{# Composant déprécié - Prévoir migration #}
|
||||||
|
{% macro old_class_card(class) %}
|
||||||
|
{#
|
||||||
|
⚠️ DEPRECATED: Ce composant sera supprimé en v3.0
|
||||||
|
Utiliser class_card de components/class/class_card.html
|
||||||
|
Migration guide: docs/frontend/MIGRATION_v2_to_v3.md
|
||||||
|
#}
|
||||||
|
<!-- Implementation dépréciée -->
|
||||||
|
{% endmacro %}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 **Ressources & Références**
|
||||||
|
|
||||||
|
### **Documentation Externe**
|
||||||
|
- **TailwindCSS** : [tailwindcss.com](https://tailwindcss.com)
|
||||||
|
- **WCAG Guidelines** : [w3.org/WAI/WCAG21/quickref](https://www.w3.org/WAI/WCAG21/quickref/)
|
||||||
|
- **Jinja2 Templates** : [jinja.palletsprojects.com](https://jinja.palletsprojects.com)
|
||||||
|
- **Design Tokens** : [design-tokens.github.io](https://design-tokens.github.io)
|
||||||
|
|
||||||
|
### **Outils Recommandés**
|
||||||
|
```bash
|
||||||
|
# Développement
|
||||||
|
Live Server # Preview temps réel
|
||||||
|
DevTools # Inspect & debug
|
||||||
|
ColorZilla # Extraction couleurs
|
||||||
|
Figma/Adobe XD # Design source
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
axe DevTools # Accessibilité
|
||||||
|
Lighthouse # Performance & SEO
|
||||||
|
Browser Stack # Tests cross-browser
|
||||||
|
Percy/Chromatic # Visual regression
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Templates de Référence**
|
||||||
|
- `assessment_card.html` - Carte complexe avec états multiples
|
||||||
|
- `hero_section` macro - Section d'en-tête avec gradient
|
||||||
|
- `simple_filter_section` - Filtres interactifs compacts
|
||||||
|
- `progress_indicator` - Indicateur de progression dynamique
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ **Checklist Validation Composant**
|
||||||
|
|
||||||
|
Avant de valider un nouveau composant :
|
||||||
|
|
||||||
|
### **📝 Code Quality**
|
||||||
|
- [ ] **Syntaxe Jinja2** valide
|
||||||
|
- [ ] **Paramètres documentés** dans commentaires
|
||||||
|
- [ ] **Gestion d'erreurs** (None, empty, invalid data)
|
||||||
|
- [ ] **Performance** optimisée (classes, rendering)
|
||||||
|
- [ ] **Sécurité** (XSS prevention, safe filters)
|
||||||
|
|
||||||
|
### **🎨 Design System**
|
||||||
|
- [ ] **Couleurs** du design system utilisées
|
||||||
|
- [ ] **Typography** scale respectée
|
||||||
|
- [ ] **Spacing** cohérent (multiples de 4px)
|
||||||
|
- [ ] **Animations** fluides (300ms transitions)
|
||||||
|
- [ ] **États visuels** définis (hover, focus, disabled)
|
||||||
|
|
||||||
|
### **📱 Responsive & Accessibility**
|
||||||
|
- [ ] **Mobile-first** approche
|
||||||
|
- [ ] **Breakpoints** standards utilisés
|
||||||
|
- [ ] **Contraste** suffisant (4.5:1 minimum)
|
||||||
|
- [ ] **Focus indicators** visibles
|
||||||
|
- [ ] **Screen reader** compatible
|
||||||
|
|
||||||
|
### **🧪 Tests**
|
||||||
|
- [ ] **Template rendering** sans erreur
|
||||||
|
- [ ] **Données variées** testées (vide, None, long text)
|
||||||
|
- [ ] **Navigation clavier** fonctionnelle
|
||||||
|
- [ ] **Multi-browser** compatible
|
||||||
|
- [ ] **Visual regression** validé
|
||||||
|
|
||||||
|
### **📖 Documentation**
|
||||||
|
- [ ] **Usage examples** fournis
|
||||||
|
- [ ] **API parameters** documentés
|
||||||
|
- [ ] **Dependencies** listées
|
||||||
|
- [ ] **Migration guide** si breaking changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🎯 En suivant ce guide, tous les composants Notytex maintiendront un niveau de qualité et de cohérence exceptionnels !**
|
||||||
216
docs/frontend/README.md
Normal file
216
docs/frontend/README.md
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
# 📚 Documentation Frontend - Notytex
|
||||||
|
|
||||||
|
> **Design System & Composants UI**
|
||||||
|
> **Version**: 2.0
|
||||||
|
> **Dernière mise à jour**: 7 août 2025
|
||||||
|
|
||||||
|
## 🎯 **Vue d'Ensemble**
|
||||||
|
|
||||||
|
Cette documentation couvre l'ensemble du **design system Notytex**, ses composants UI, et les bonnes pratiques pour maintenir une interface cohérente et moderne.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 **Organisation de la Documentation**
|
||||||
|
|
||||||
|
### 🎨 **Design System & Guidelines**
|
||||||
|
|
||||||
|
| Document | Description | Statut |
|
||||||
|
| ---------------------------------------------------------------- | ------------------------------------------------------------------------- | ------ |
|
||||||
|
| **[COMPONENT_BEST_PRACTICES.md](./COMPONENT_BEST_PRACTICES.md)** | Guide complet des bonnes pratiques pour créer et maintenir des composants | ✅ |
|
||||||
|
| Design Tokens | Couleurs, typography, spacing centralisés | 🔄 |
|
||||||
|
| Accessibility Guidelines | Standards WCAG & implémentation | 🔄 |
|
||||||
|
|
||||||
|
### 📄 **Pages & Interfaces**
|
||||||
|
|
||||||
|
| Document | Description | Statut |
|
||||||
|
| -------------------------------------------------- | ---------------------------------------------------------------- | ------ |
|
||||||
|
| **[CLASSES_PAGE.md](./CLASSES_PAGE.md)** | Page des classes modernisée - Architecture & guide d'utilisation | ✅ |
|
||||||
|
| [ASSESSMENTS_FILTRES.md](./ASSESSMENTS_FILTRES.md) | Système de filtres des évaluations | ✅ |
|
||||||
|
| Dashboard Modernization | Page d'accueil & statistiques | 📋 |
|
||||||
|
| Student Management Page | Interface de gestion des élèves | 📋 |
|
||||||
|
|
||||||
|
### 🧩 **Composants**
|
||||||
|
|
||||||
|
| Document | Description | Statut |
|
||||||
|
| -------------------------------------------------------- | ----------------------------------------------- | ------ |
|
||||||
|
| **[CLASS_CARD_COMPONENT.md](./CLASS_CARD_COMPONENT.md)** | Composant carte de classe - API & usage | ✅ |
|
||||||
|
| [ASSESSMENT_CARDS.md](./ASSESSMENT_CARDS.md) | Composants cartes d'évaluation | ✅ |
|
||||||
|
| Common Macros | Macros réutilisables (hero_section, buttons...) | 📋 |
|
||||||
|
| Form Components | Champs de formulaire standardisés | 📋 |
|
||||||
|
|
||||||
|
### ⚡ **Performance & Outils**
|
||||||
|
|
||||||
|
| Document | Description | Statut |
|
||||||
|
| ---------------------- | ------------------------------------------- | ------ |
|
||||||
|
| Performance Guidelines | Optimisation frontend & best practices | 📋 |
|
||||||
|
| Testing Strategy | Tests visuels, accessibilité, cross-browser | 📋 |
|
||||||
|
| Build & Deploy | Process de build frontend | 📋 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 **Getting Started**
|
||||||
|
|
||||||
|
### **Pour les Nouveaux Développeurs**
|
||||||
|
|
||||||
|
1. **Lire d'abord** : [COMPONENT_BEST_PRACTICES.md](./COMPONENT_BEST_PRACTICES.md)
|
||||||
|
2. **Explorer** : [CLASSES_PAGE.md](./CLASSES_PAGE.md) comme exemple complet
|
||||||
|
3. **Étudier** : [CLASS_CARD_COMPONENT.md](./CLASS_CARD_COMPONENT.md) pour l'API des composants
|
||||||
|
4. **Appliquer** : Créer son premier composant avec les guidelines
|
||||||
|
|
||||||
|
### **Pour les Designers**
|
||||||
|
|
||||||
|
1. **Design System** : Couleurs, typography, spacing dans [COMPONENT_BEST_PRACTICES.md](./COMPONENT_BEST_PRACTICES.md)
|
||||||
|
2. **Exemples concrets** : [CLASSES_PAGE.md](./CLASSES_PAGE.md) pour voir l'application pratique
|
||||||
|
3. **Composants disponibles** : Inventaire dans chaque doc de composant
|
||||||
|
|
||||||
|
### **Pour la Maintenance**
|
||||||
|
|
||||||
|
1. **Standards** : Tous les composants suivent [COMPONENT_BEST_PRACTICES.md](./COMPONENT_BEST_PRACTICES.md)
|
||||||
|
2. **Tests** : Procédures de validation dans chaque documentation
|
||||||
|
3. **Evolution** : Guidelines de versioning et migration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 **Design System en Bref**
|
||||||
|
|
||||||
|
### **Couleurs Principales**
|
||||||
|
|
||||||
|
```scss
|
||||||
|
// Couleurs par niveau scolaire
|
||||||
|
6ème: from-blue-500 to-blue-600 // Actions primaires
|
||||||
|
5ème: from-green-500 to-green-600 // Succès, validation
|
||||||
|
4ème: from-purple-500 to-purple-600 // Évaluations, analytics
|
||||||
|
3ème: from-orange-500 to-orange-600 // Avertissement, en cours
|
||||||
|
2nde: from-red-500 to-red-600 // Erreur, critique
|
||||||
|
1ère: from-pink-500 to-pink-600 // Spécial, highlight
|
||||||
|
Term: from-indigo-500 to-indigo-600 // Excellence, Terminales
|
||||||
|
???: from-gray-500 to-gray-600 // Non reconnu, neutres
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Components Architecture**
|
||||||
|
|
||||||
|
```
|
||||||
|
templates/components/
|
||||||
|
├── common/ # Macros & composants de base
|
||||||
|
├── assessment/ # Composants liés aux évaluations
|
||||||
|
├── class/ # Composants liés aux classes
|
||||||
|
├── forms/ # Composants de formulaire
|
||||||
|
└── ui/ # Composants UI génériques
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Responsive Breakpoints**
|
||||||
|
|
||||||
|
```scss
|
||||||
|
sm: 640px // Téléphone large / Tablette portrait
|
||||||
|
md: 768px // Tablette
|
||||||
|
lg: 1024px // Desktop
|
||||||
|
xl: 1280px // Large desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 **État de la Documentation**
|
||||||
|
|
||||||
|
### **✅ Complété (100%)**
|
||||||
|
|
||||||
|
- Guide des bonnes pratiques générales
|
||||||
|
- Page des classes (refonte complète)
|
||||||
|
- Composant class_card (documentation technique)
|
||||||
|
- Filtres des évaluations
|
||||||
|
- Cartes d'évaluation
|
||||||
|
|
||||||
|
### **🔄 En cours (0-80%)**
|
||||||
|
|
||||||
|
- Design tokens centralisés
|
||||||
|
- Guidelines d'accessibilité
|
||||||
|
- Tests automatisés frontend
|
||||||
|
|
||||||
|
### **📋 À faire**
|
||||||
|
|
||||||
|
- Documentation page Dashboard
|
||||||
|
- Documentation gestion des élèves
|
||||||
|
- Composants de formulaire
|
||||||
|
- Guide de performance
|
||||||
|
- Process de build/deploy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 **Tests & Validation**
|
||||||
|
|
||||||
|
### **Tests Rapides**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Validation syntaxe tous les templates
|
||||||
|
find templates/ -name "*.html" -exec echo "Testing {}" \;
|
||||||
|
|
||||||
|
# Test des composants principaux
|
||||||
|
uv run python -c "
|
||||||
|
from app import create_app
|
||||||
|
app = create_app()
|
||||||
|
with app.app_context():
|
||||||
|
templates = ['classes.html', 'components/class/class_card.html']
|
||||||
|
for template in templates:
|
||||||
|
try:
|
||||||
|
t = app.jinja_env.get_template(template)
|
||||||
|
print(f'✅ {template}')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'❌ {template}: {e}')
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Tests Complets**
|
||||||
|
|
||||||
|
- **Syntaxe** : Tous templates Jinja2 valides
|
||||||
|
- **Responsive** : Tests sur tous breakpoints
|
||||||
|
- **Accessibilité** : Tests axe-core + validation manuelle
|
||||||
|
- **Cross-browser** : Chrome, Firefox, Safari, Edge
|
||||||
|
- **Performance** : Métriques Lighthouse > 90
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 **Liens Utiles**
|
||||||
|
|
||||||
|
### **Références Externes**
|
||||||
|
|
||||||
|
- **TailwindCSS Docs** : [tailwindcss.com/docs](https://tailwindcss.com/docs)
|
||||||
|
- **WCAG Guidelines** : [w3.org/WAI/WCAG21](https://www.w3.org/WAI/WCAG21/quickref/)
|
||||||
|
- **Jinja2 Templates** : [jinja.palletsprojects.com](https://jinja.palletsprojects.com/en/3.0.x/)
|
||||||
|
- **Flask Documentation** : [flask.palletsprojects.com](https://flask.palletsprojects.com/)
|
||||||
|
|
||||||
|
### **Outils Recommandés**
|
||||||
|
|
||||||
|
- **Design** : Figma, Adobe XD
|
||||||
|
- **Development** : Live Server, DevTools
|
||||||
|
- **Testing** : axe DevTools, Lighthouse, Percy
|
||||||
|
- **Performance** : WebPageTest, GTMetrix
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 **Contribution**
|
||||||
|
|
||||||
|
### **Ajouter une Nouvelle Page**
|
||||||
|
|
||||||
|
1. Créer le fichier `PAGENAME_PAGE.md`
|
||||||
|
2. Suivre la structure de [CLASSES_PAGE.md](./CLASSES_PAGE.md)
|
||||||
|
3. Documenter les composants créés
|
||||||
|
4. Mettre à jour ce README.md
|
||||||
|
|
||||||
|
### **Ajouter un Composant**
|
||||||
|
|
||||||
|
1. Créer le fichier `COMPONENTNAME_COMPONENT.md`
|
||||||
|
2. Suivre la structure de [CLASS_CARD_COMPONENT.md](./CLASS_CARD_COMPONENT.md)
|
||||||
|
3. Inclure API, exemples, et tests
|
||||||
|
4. Référencer dans [COMPONENT_BEST_PRACTICES.md](./COMPONENT_BEST_PRACTICES.md)
|
||||||
|
|
||||||
|
### **Standards de Documentation**
|
||||||
|
|
||||||
|
- **Format** : Markdown avec emojis et structure claire
|
||||||
|
- **Code examples** : Syntaxe highlighting appropriée
|
||||||
|
- **Images** : Screenshots et diagrammes si pertinent
|
||||||
|
- **Liens** : Cross-references entre documents
|
||||||
|
- **Versioning** : Dates de mise à jour et changelogs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🎓 Cette documentation évolue avec Notytex. Chaque ajout de fonctionnalité frontend doit être documenté selon ces standards.**
|
||||||
|
|
||||||
Reference in New Issue
Block a user