Merge branch 'worktree-design-system' into develop

This commit is contained in:
Luc SORIGNET
2026-04-04 12:02:32 +02:00
6 changed files with 553 additions and 2 deletions

View File

@ -52,8 +52,28 @@ Pour le front-end, les exigences de qualité sont les suivantes :
- Documentation en français pour les nouvelles fonctionnalités (si applicable)
- Référence : [documentation guidelines](./instructions/documentation.instruction.md)
## Design System
Le projet utilise un design system défini. Toujours s'y conformer lors de toute modification de l'interface.
- Référence complète : [design system](../docs/design-system.md)
- Règles Copilot : [design system instructions](./instructions/design-system.instruction.md)
### Résumé des tokens obligatoires
| Token Tailwind | Hex | Usage |
|----------------|-----------|-------------------------------|
| `primary` | `#059669` | Boutons, CTA, éléments actifs |
| `secondary` | `#064E3B` | Hover, accents sombres |
| `tertiary` | `#10B981` | Badges, icônes |
| `neutral` | `#F8FAFC` | Fonds de page, surfaces |
- Polices : `font-headline` (Manrope) pour les titres, `font-body`/`font-label` (Inter) pour le reste
- **Ne jamais** utiliser `emerald-*` pour les éléments interactifs
## Références
- **Tickets** : [issues guidelines](./instructions/issues.instruction.md)
- **Commits** : [commit guidelines](./instructions/general-commit.instruction.md)
- **Tests** : [run tests](./instructions/run-tests.instruction.md)
- **Design System** : [design system instructions](./instructions/design-system.instruction.md)

View File

@ -0,0 +1,116 @@
---
applyTo: "Front-End/src/**"
---
# Design System — Règles Copilot
Référence complète : [`docs/design-system.md`](../../docs/design-system.md)
## Couleurs — tokens Tailwind obligatoires
Utiliser **toujours** ces tokens pour les éléments interactifs :
| Token | Hex | Remplace |
|-------------|-----------|-----------------------------------|
| `primary` | `#059669` | `emerald-600`, `emerald-500` |
| `secondary` | `#064E3B` | `emerald-700`, `emerald-800` |
| `tertiary` | `#10B981` | `emerald-400`, `emerald-500` |
| `neutral` | `#F8FAFC` | Fonds neutres |
**Ne jamais écrire** `bg-emerald-*`, `text-emerald-*`, `border-emerald-*` pour des éléments interactifs.
### Patterns corrects
```jsx
// Bouton
<button className="bg-primary hover:bg-secondary text-white px-4 py-2 rounded">
// Texte actif
<span className="text-primary">
// Badge
<span className="bg-tertiary/10 text-tertiary text-xs px-2 py-0.5 rounded">
// Fond de page
<div className="bg-neutral">
```
## Typographie
```jsx
// Titre de section
<h1 className="font-headline text-2xl font-bold">
// Sous-titre
<h2 className="font-headline text-xl font-semibold">
// Label de formulaire
<label className="font-label text-sm font-medium text-gray-700">
```
> `font-body` est le défaut sur `<body>` — inutile de l'ajouter sur les `<p>`.
## Arrondi
- Par défaut : `rounded` (4px)
- Cards / modales : `rounded-md` (6px)
- Grandes surfaces : `rounded-lg` (8px)
- **Éviter** `rounded-xl` sauf avatars ou indicateurs circulaires
## Espacement
- Grille 4px/8px : `p-1`=4px, `p-2`=8px, `p-3`=12px, `p-4`=16px
- **Pas** de valeurs arbitraires `p-[13px]`
## Mode
Interface **light uniquement** — ne pas ajouter `dark:` prefixes.
---
## Icônes
Utiliser **uniquement** `lucide-react`. Jamais d'autres bibliothèques d'icônes.
```jsx
import { Home, Plus, ChevronRight } from 'lucide-react';
<Home size={20} className="text-primary" />
<button className="flex items-center gap-2"><Plus size={16} />Ajouter</button>
```
- Taille par défaut : `size={20}` inline, `size={24}` boutons standalone
- Couleur via `className="text-*"` uniquement — jamais le prop `color`
- Icône seule : ajouter `aria-label` pour l'accessibilité
---
## Responsive & PWA
**Mobile-first** : les styles de base ciblent le mobile, on étend avec `sm:` / `md:` / `lg:`.
```jsx
// Layout
<div className="px-4 sm:px-6 lg:px-8 py-4 sm:py-6">
// Grille
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
// Bouton full-width mobile
<button className="w-full sm:w-auto bg-primary text-white px-4 py-2 rounded">
```
- Touch targets ≥ 44px : `min-h-[44px]` sur tous les éléments interactifs
- Pas d'interactions uniquement au `:hover` — prévoir une alternative tactile
- Tableaux sur mobile : utiliser la classe utilitaire `responsive-table` (définie dans `tailwind.css`)
---
## Réutilisation des composants
**Toujours chercher un composant existant dans `Front-End/src/components/` avant d'en créer un.**
Composants clés disponibles : `AlertMessage`, `Modal`, `Pagination`, `SectionHeader`, `ProgressStep`, `EventCard`, `Calendar/*`, `Chat/*`, `Evaluation/*`, `Grades/*`, `Form/*`, `Admin/*`, `Charts/*`.
- Étendre via des props (`variant`, `size`, `className`) plutôt que de dupliquer
- Appliquer les tokens du design system dans tout composant modifié ou créé

91
CLAUDE.md Normal file
View File

@ -0,0 +1,91 @@
# CLAUDE.md — N3WT-SCHOOL
Instructions permanentes pour Claude Code sur ce projet.
## Architecture
- **Backend** : Python / Django — dossier `Back-End/`
- **Frontend** : Next.js 14 (App Router) — dossier `Front-End/`
- **Tests frontend** : `Front-End/src/test/`
- **CSS** : Tailwind CSS 3 + `@tailwindcss/forms`
## Design System
Le design system complet est dans [`docs/design-system.md`](docs/design-system.md). À lire et appliquer systématiquement.
### Tokens de couleur (Tailwind)
| Token | Hex | Usage |
|-------------|-----------|------------------------------------|
| `primary` | `#059669` | Boutons, CTA, éléments actifs |
| `secondary` | `#064E3B` | Hover, accents sombres |
| `tertiary` | `#10B981` | Badges, icônes d'accent |
| `neutral` | `#F8FAFC` | Fonds de page, surfaces |
> **Règle absolue** : ne jamais utiliser `emerald-*`, `green-*` pour les éléments interactifs. Utiliser les tokens ci-dessus.
### Typographie
- `font-headline` → titres `h1`/`h2`/`h3` (Manrope)
- `font-body` → texte courant, défaut sur `<body>` (Inter)
- `font-label` → boutons, labels de form (Inter)
### Arrondi & Espacement
- Arrondi par défaut : `rounded` (4px)
- Espacement : grille 4px/8px — pas de valeurs arbitraires
- Mode : **light uniquement**, pas de dark mode
## Conventions de code
### Frontend (Next.js)
- **Composants** : React fonctionnels, pas de classes
- **Styles** : Tailwind CSS uniquement — pas de CSS inline sauf animations
- **Icônes** : `lucide-react`
- **i18n** : `next-intl` — toutes les chaînes UI via `useTranslations()`
- **Formulaires** : `react-hook-form`
- **Imports** : alias `@/` pointe vers `Front-End/src/`
### Qualité
- Linting : ESLint (`npm run lint` dans `Front-End/`)
- Format : Prettier
- Tests : Jest + React Testing Library (`Front-End/src/test/`)
## Gestion des branches
- Base : `develop`
- Nomenclature : `<type>-<nom_ticket>-<numero>` (ex: `feat-ma-feature-1234`)
- Types : `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
## Icônes
Utiliser **uniquement `lucide-react`** — jamais d'autre bibliothèque d'icônes.
```jsx
import { Home, Plus } from 'lucide-react';
<Home size={20} className="text-primary" />
```
## Responsive & PWA
- **Mobile-first** : styles de base = mobile, breakpoints `sm:`/`md:`/`lg:` pour agrandir.
- Touch targets ≥ 44px (`min-h-[44px]`) sur tous les éléments interactifs.
- Pas d'interactions uniquement au `:hover` — prévoir l'équivalent tactile.
- Les tableaux utilisent la classe `responsive-table` sur mobile.
## Réutilisation des composants
Avant de créer un composant, **vérifier `Front-End/src/components/`**.
Composants disponibles : `AlertMessage`, `Modal`, `Pagination`, `SectionHeader`, `ProgressStep`, `EventCard`, `Calendar/*`, `Chat/*`, `Evaluation/*`, `Grades/*`, `Form/*`, `Admin/*`, `Charts/*`.
## À éviter
- Ne pas ajouter de dépendances inutiles
- Ne pas modifier `package-lock.json` / `yarn.lock` manuellement
- Ne pas committer sans avoir vérifié ESLint et les tests
- Ne pas utiliser de CSS arbitraire (`p-[13px]`) sauf cas justifié
- Ne pas ajouter de support dark mode
- Ne pas utiliser d'autres bibliothèques d'icônes que `lucide-react`
- Ne pas créer un composant qui existe déjà dans `components/`

View File

@ -1,10 +1,23 @@
import React from 'react';
import { getMessages } from 'next-intl/server';
import { Inter, Manrope } from 'next/font/google';
import Providers from '@/components/Providers';
import ServiceWorkerRegister from '@/components/ServiceWorkerRegister';
import '@/css/tailwind.css';
import { headers } from 'next/headers';
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
display: 'swap',
});
const manrope = Manrope({
subsets: ['latin'],
variable: '--font-manrope',
display: 'swap',
});
export const metadata = {
title: 'N3WT-SCHOOL',
description: "Gestion de l'école",
@ -36,7 +49,7 @@ export default async function RootLayout({ children, params }) {
return (
<html lang={locale}>
<body className="p-0 m-0">
<body className={`p-0 m-0 font-body ${inter.variable} ${manrope.variable}`}>
<Providers messages={messages} locale={locale} session={params.session}>
{children}
</Providers>

View File

@ -4,7 +4,25 @@ module.exports = {
'./src/**/*.{js,jsx,ts,tsx}', // Ajustez ce chemin selon la structure de votre projet
],
theme: {
extend: {},
extend: {
colors: {
primary: '#059669',
secondary: '#064E3B',
tertiary: '#10B981',
neutral: '#F8FAFC',
},
fontFamily: {
headline: ['var(--font-manrope)', 'Manrope', 'sans-serif'],
body: ['var(--font-inter)', 'Inter', 'sans-serif'],
label: ['var(--font-inter)', 'Inter', 'sans-serif'],
},
borderRadius: {
DEFAULT: '4px',
sm: '2px',
md: '6px',
lg: '8px',
},
},
},
plugins: [require('@tailwindcss/forms')],
};

293
docs/design-system.md Normal file
View File

@ -0,0 +1,293 @@
# Design System — N3WT-SCHOOL
## Vue d'ensemble
Le design system N3WT-SCHOOL définit les tokens visuels et les conventions d'usage pour garantir une interface cohérente sur l'ensemble du produit.
---
## Couleurs
Les couleurs sont définies comme tokens Tailwind dans `Front-End/tailwind.config.js`.
| Token Tailwind | Valeur hex | Usage |
| -------------- | ---------- | -------------------------------------------------- |
| `primary` | `#059669` | Boutons principaux, CTA, éléments interactifs clés |
| `secondary` | `#064E3B` | Hover des éléments primaires, accents sombres |
| `tertiary` | `#10B981` | Badges, icônes d'accent, highlights |
| `neutral` | `#F8FAFC` | Fonds de page, surfaces, arrière-plans neutres |
### Règles d'usage
- **Ne jamais** utiliser les classes Tailwind brutes `emerald-*`, `green-*` pour les éléments interactifs. Utiliser les tokens (`primary`, `secondary`, `tertiary`).
- Les fonds décoratifs (gradients, illustrations) peuvent conserver les classes Tailwind standards.
- Les états de statut (success, error, warning, info) peuvent conserver leurs couleurs sémantiques (`green`, `red`, `yellow`, `blue`).
### Exemples
```jsx
// Bouton principal
<button className="bg-primary hover:bg-secondary text-white">Valider</button>
// Texte accent
<span className="text-primary font-medium">Voir plus</span>
// Badge
<span className="bg-tertiary/10 text-tertiary">Actif</span>
// Fond de page
<div className="bg-neutral min-h-screen">...</div>
```
---
## Typographie
Les polices sont chargées via `next/font/google` dans `Front-End/src/app/layout.js` et exposées comme variables CSS.
| Rôle | Police | Token Tailwind | Usage |
| --------- | --------- | --------------- | ----------------------------------- |
| Headlines | `Manrope` | `font-headline` | `h1`, `h2`, `h3`, titres de section |
| Body | `Inter` | `font-body` | Paragraphes, contenu (défaut) |
| Labels | `Inter` | `font-label` | Boutons, labels de formulaires |
> `font-body` est appliqué par défaut sur `<body>`. Il n'est donc pas nécessaire de l'ajouter manuellement sur chaque élément de texte courant.
### Exemples
```jsx
// Titre de page
<h1 className="font-headline text-2xl font-bold text-gray-900">Tableau de bord</h1>
// Sous-titre
<h2 className="font-headline text-xl font-semibold text-secondary">Élèves</h2>
// Label de formulaire
<label className="font-label text-sm font-medium text-gray-700">Prénom</label>
```
---
## Rayon de bordure (Border Radius)
Arrondi subtil, niveau 1.
| Token Tailwind | Valeur | Usage |
| -------------- | ------ | ---------------------------------- |
| `rounded-sm` | `2px` | Éléments très petits (badges fins) |
| `rounded` | `4px` | Par défaut — boutons, inputs |
| `rounded-md` | `6px` | Cards, modales |
| `rounded-lg` | `8px` | Grandes surfaces |
> Éviter `rounded-xl` (12px) et `rounded-full` sauf pour les avatars ou indicateurs circulaires.
---
## Espacement
Espacement normal, base 8px (niveau 2). Utiliser les multiples de 4px/8px du système Tailwind standard.
| Classe | Valeur |
| ------ | ------ |
| `p-1` | 4px |
| `p-2` | 8px |
| `p-3` | 12px |
| `p-4` | 16px |
| `p-6` | 24px |
| `p-8` | 32px |
---
## Composants récurrents
### Bouton principal
```jsx
<button className="bg-primary hover:bg-secondary text-white font-label font-medium px-4 py-2 rounded transition-colors">
Action
</button>
```
### Bouton secondaire
```jsx
<button className="border border-primary text-primary hover:bg-primary hover:text-white font-label font-medium px-4 py-2 rounded transition-colors">
Action secondaire
</button>
```
### Card
```jsx
<div className="bg-white rounded-md border border-gray-200 shadow-sm p-4">
<h2 className="font-headline text-lg font-semibold text-gray-900">Titre</h2>
<p className="text-gray-600 mt-2">Contenu</p>
</div>
```
### Badge de statut
```jsx
<span className="inline-flex items-center bg-tertiary/10 text-tertiary text-xs font-label font-medium px-2 py-0.5 rounded">
Actif
</span>
```
### Lien d'action
```jsx
<a className="text-primary hover:text-secondary underline-offset-2 hover:underline transition-colors">
Voir le détail
</a>
```
---
## Configuration Tailwind
Fichier : `Front-End/tailwind.config.js`
```js
theme: {
extend: {
colors: {
primary: '#059669',
secondary: '#064E3B',
tertiary: '#10B981',
neutral: '#F8FAFC',
},
fontFamily: {
headline: ['var(--font-manrope)', 'Manrope', 'sans-serif'],
body: ['var(--font-inter)', 'Inter', 'sans-serif'],
label: ['var(--font-inter)', 'Inter', 'sans-serif'],
},
borderRadius: {
DEFAULT: '4px',
sm: '2px',
md: '6px',
lg: '8px',
},
},
},
```
---
## Icônes
Toutes les icônes utilisent la bibliothèque **`lucide-react`** exclusivement.
```jsx
import { Home, User, ChevronRight } from 'lucide-react';
// Taille standard
<Home size={20} className="text-primary" />
// Avec label accessible
<button className="flex items-center gap-2">
<Plus size={16} />
Ajouter
</button>
```
### Règles icônes
- **Toujours** importer depuis `lucide-react` — jamais d'autres bibliothèques d'icônes.
- Taille par défaut : `size={20}` (inline), `size={24}` (boutons standalone).
- Couleur : via `className="text-*"` — ne jamais utiliser le prop `color`.
- Icônes seules sans texte : ajouter `aria-label` ou wrapper `title` pour l'accessibilité.
---
## Responsive & PWA
L'interface est conçue **mobile-first** pour un usage PWA (Progressive Web App).
### Breakpoints Tailwind
| Préfixe | Largeur min | Contexte |
| -------- | ----------- | ------------------------ |
| _(base)_ | 0px | Mobile (priorité) |
| `sm:` | 640px | Grands mobiles/tablettes |
| `md:` | 768px | Tablettes |
| `lg:` | 1024px | Desktop |
### Principes responsive
- **Toujours** penser desktop en premier — les styles de base ciblent le desktop.
- Les sidebars passent en overlay sur mobile (`md:hidden` / `hidden md:block`).
- Les tableaux utilisent le mode `responsive-table` (classe utilitaire définie dans `tailwind.css`) sur mobile.
- Les grilles : commencer par `grid-cols-1`, étendre avec `sm:grid-cols-2 lg:grid-cols-3`.
- Les textes : tailles mobiles d'abord (`text-sm sm:text-base`), ne jamais forcer une grande taille sur mobile.
- Touch targets : minimum `44px × 44px` pour tous les éléments interactifs (`min-h-[44px]`).
### PWA
- Tous les écrans doivent fonctionner hors-ligne ou en mode dégradé (données en cache).
- Les interactions clés (navigation, actions principales) doivent être accessibles sans rechargement de page.
- Pas de contenu critique uniquement visible au survol (`hover:`) — prévoir une alternative tactile.
### Exemples responsive
```jsx
// Layout page
<div className="px-4 sm:px-6 lg:px-8 py-4 sm:py-6">
// Grille de cards
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
// Titre responsive
<h1 className="font-headline text-xl sm:text-2xl lg:text-3xl font-bold">
// Bouton full-width sur mobile
<button className="w-full sm:w-auto bg-primary text-white px-4 py-2 rounded">
// Navigation mobile/desktop
<nav className="hidden md:flex gap-4">
<nav className="flex md:hidden"> {/* version mobile */}
```
---
## Bibliothèque de composants existants
**Avant de créer un nouveau composant, toujours vérifier s'il en existe un dans `Front-End/src/components/`.**
### Composants disponibles (inventaire)
| Composant | Chemin | Usage |
| --------------- | ----------------------------- | ----------------------------------------- |
| `AlertMessage` | `components/AlertMessage.js` | Messages success / error / warning / info |
| `Modal` | `components/Modal.js` | Fenêtre modale générique |
| `Pagination` | `components/Pagination.js` | Pagination de listes |
| `SectionHeader` | `components/SectionHeader.js` | En-tête de section avec icône |
| `ProgressStep` | `components/ProgressStep.js` | Étapes d'un formulaire multi-step |
| `EventCard` | `components/EventCard.js` | Card d'événement de planning |
| `Calendar/*` | `components/Calendar/` | Vues calendrier (semaine, mois…) |
| `Chat/*` | `components/Chat/` | Interface de messagerie |
| `Evaluation/*` | `components/Evaluation/` | Formulaires d'évaluation |
| `Grades/*` | `components/Grades/` | Affichage et saisie des notes |
| `Form/*` | `components/Form/` | Inputs, selects, composants de formulaire |
| `Admin/*` | `components/Admin/` | Composants spécifiques à l'admin |
| `Charts/*` | `components/Charts/` | Graphiques et visualisations |
### Règles de réutilisation
1. **Chercher avant de créer** : effectuer une recherche dans `components/` avant d'implémenter un nouveau composant.
2. **Étendre, ne pas dupliquer** : si un composant existant est proche mais manque d'une variante, l'étendre via des props — ne pas créer une copie.
3. **Props plutôt que fork** : passer des variantes via `variant`, `size`, `className` plutôt que de dupliquer le JSX.
4. **Appliquer le design system dans les composants** : tout composant existant ou nouveau doit utiliser les tokens (`primary`, `secondary`, `tertiary`, `neutral`, `font-headline`, etc.) — jamais de couleurs codées en dur.
---
## Règles pour les agents IA (Copilot / Claude)
1. **Couleurs interactives** : toujours utiliser `primary`, `secondary`, `tertiary`, `neutral` — jamais `emerald-*` pour les boutons, liens, icônes actives.
2. **Typographie** : utiliser `font-headline` sur les `h1`/`h2`/`h3`. Le `font-body` est le défaut.
3. **Arrondi** : préférer `rounded` (4px) pour les éléments courants. Éviter `rounded-xl` sauf exception justifiée.
4. **Espacement** : respecter la grille 4px/8px. Pas de valeurs arbitraires `p-[13px]`.
5. **Mode** : interface en mode **light** uniquement — ne pas ajouter de support dark mode.
6. **Icônes** : utiliser uniquement `lucide-react` — jamais d'autres bibliothèques d'icônes.
7. **Responsive** : mobile-first — les styles de base ciblent le mobile, les breakpoints `sm:`/`md:`/`lg:` étendent vers le haut.
8. **PWA** : pas d'interactions uniquement au survol, touch targets ≥ 44px, navigation sans rechargement.
9. **Réutilisation** : chercher un composant existant dans `components/` avant d'en créer un nouveau.