Application web locale pour gérer une classe de primaire et lancer des activités interactives en autonomie, en groupe ou sur TNI.
GITHUB_REPO : https://github.com/sletonqu/ActivitesClasse
Le projet propose trois espaces complémentaires :
| Espace | URL | Usage principal |
|---|---|---|
Admin |
/admin |
Gérer enseignants, classes, activités, imports/exports globaux |
Enseignant |
/teacher |
Gérer les élèves, groupes, résultats et activités d'une classe |
Élève |
/ |
Choisir une classe, filtrer par groupe, lancer une activité ou un mode démo |
- Frontend : React + React Router + Tailwind CSS
- Backend : Node.js + Express
- Base de données : SQLite
- Conteneurisation : Docker / Docker Compose
- Docker Desktop démarré
- Ports
3000et4000disponibles
Le backend lit les clés API via le fichier local .env (non versionné).
- Créer le fichier
.envà partir de.env.example.
Copy-Item .env.example .env- Renseigner vos valeurs réelles dans
.env:
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4.1-mini
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.5-flash-lite
MISTRAL_API_KEY=
MISTRAL_MODEL=mistral-medium-latest
AI_LOCAL_TOKEN_CORRECTION=false- Garder
docker-compose.ymlsans secret en clair (uniquement des références${...}).
⚠️ Si des clés ont déjà été exposées dans l'historique Git ou dans un fichier partagé, il faut les révoquer puis les régénérer.
docker compose up --buildOu en arrière-plan :
docker compose up -d --build- Frontend :
http://localhost:3000 - API backend :
http://localhost:4000
docker compose downSur le PC de la classe, le plus simple est d'utiliser le script :
powershell -ExecutionPolicy Bypass -File .\scripts\update-application.ps1💡 Guide détaillé d'installation et de mise à jour : voir
scripts/README.md.
Ce script :
- sauvegarde préventivement la base SQLite dans le volume Docker ;
- récupère la dernière version GitHub via
git pull --ff-only; - relance l'application avec
docker compose up -d --build.
⚠️ Les données sont conservées tant que vous n'utilisez pasdocker compose down -v.
Un panneau Version et mise à jour est disponible dans Admin.
Pour autoriser le bouton Demander la mise à jour sur le PC de classe :
- démarrer sur Windows le service local suivant :
powershell -ExecutionPolicy Bypass -File .\scripts\start-local-updater.ps1 -Token "change-this-token"- activer les variables suivantes dans
docker-compose.ymlpour le servicebackend:
ENABLE_ADMIN_UPDATE_TRIGGER=true
HOST_UPDATER_URL=http://host.docker.internal:8765/update
UPDATER_TOKEN=change-this-tokenConseil sécurité : évitez d'écrire des tokens en clair dans
docker-compose.yml. Préférez des variables d'environnement chargées depuis.env.
Ce mode garde la logique de mise à jour hors du conteneur : l'interface admin demande l'opération, mais c'est bien le poste Windows qui exécute le script PowerShell.
Les données SQLite sont stockées dans le volume Docker db-data.
Pour repartir de zéro :
docker compose down -v
docker compose up --build
⚠️ docker compose down -vsupprime toutes les données locales de l'application.
- interface en accordéon : sections repliées par défaut, ouverture au clic sur le titre, une seule section ouverte à la fois ;
- création, consultation et suppression des enseignants ;
- création, consultation et suppression des classes ;
- création, modification et suppression des activités ;
- suppression unitaire ou globale des activités ;
- import du référentiel de mots, recherche d'un mot en base et suppression unitaire / globale des mots ;
- génération de phrases par IA et gestion des phrases générées en base ;
- import / export global CSV des
teachers,classes,groups,students,activitiesetresults; - conservation des colonnes de niveau des résultats (
activity_level,activity_level_label) lors des imports/exports globaux.
- sélection d'une classe active ;
- interface en accordéon sur les panneaux de gestion (la section
Classe cibléereste visible en permanence) ; - ajout, consultation et suppression d'élèves ;
- suppression globale des élèves de la classe ;
- gestion des groupes :
- une classe peut avoir plusieurs groupes ou aucun ;
- un groupe peut contenir plusieurs élèves ou aucun ;
- un élève ne peut appartenir qu'à un seul groupe dans sa classe ;
- ajout, affichage, suppression, vidage et affectation/retrait d'élèves ;
- gestion des résultats :
- consultation des résultats d'un élève ;
- suppression unitaire ou globale ;
- calcul d'une moyenne qui remplace uniquement les résultats de la même activité et du même niveau ;
- import / export CSV ciblé sur une classe avec support des groupes ;
- modification des activités existantes et de leur JSON de configuration.
- sélection compacte d'une classe, d'un groupe visible et d'une activité active ;
- filtrage de la liste d'élèves par groupe ;
- exécution d'activités avec niveaux (
level1,level2,level3selon l'activité) ; - activités de tri, de lecture de nombres et de classement en glisser-déposer ou en affichage simple selon l'exercice ;
- affichage lisible des grands nombres (ex.
1 234) dans les activités numériques ; - enregistrement des scores avec niveau et libellé de niveau ;
- mode démo :
- aucune sélection d'élève requise ;
- le panneau élève et le classement sont masqués ;
- aucun résultat n'est enregistré ;
- le bouton
Recommencerreste disponible ;
- classement exportable en CSV sur le périmètre visible (classe entière ou groupe filtré).
Le flux ciblé classe prend en charge les informations de groupe des élèves :
group_idgroup_name
Le format global attend une colonne entity avec l'une des valeurs suivantes :
teacherclassgroupstudentactivityresult
Pour les lignes de type result, les colonnes suivantes sont désormais supportées :
student_idactivity_idscorecompleted_atactivity_levelactivity_level_label
| Activité | Fichier | Objectif | Paramètres principaux |
|---|---|---|---|
| Tri de nombres | frontend/src/activities/SortNumbersActivity.js |
Glisser des nombres dans des cases ? < ? ou ? > ? pour les ranger dans l'ordre croissant ou décroissant |
title, instruction, defaultLevel, levels, levels.order, numbersByLevel |
| Lecture de nombres | frontend/src/activities/ReadNumbersActivity.js |
Afficher un nombre à lire selon le niveau, sans dépôt, validation ni score | title, instruction, defaultLevel, levels, numbersByLevel |
| Comparaison de nombres | frontend/src/activities/CompareNumbersActivity.js |
Choisir <, = ou > entre deux nombres, avec écriture décomposée possible |
title, instruction, defaultLevel, levels.min/max, allowEquality, equalityChance, decompositionMode, pairsByLevel |
| Additions CE1 | frontend/src/activities/MatchAdditionsActivity.js |
Associer une addition à son résultat | defaultLevel, levels, challenges, challengesByLevel |
| Dizaines et unités | frontend/src/activities/CountPencilsByTensActivity.js |
Compter unités, dizaines et centaines avec des crayons | defaultLevel, levels, exerciseCount, min/maxCartons, min/maxPouches, min/maxUnits |
| Fractions visuelles | frontend/src/activities/FractionsVisualSelectionActivity.js |
Associer un visuel fractionné à la bonne fraction parmi plusieurs tuiles | title, instruction, defaultLevel, levels.answerCount, levels.fractions, minDenominator, maxDenominator, visualTypes |
| Classification de mots | frontend/src/activities/WordClassificationActivity.js |
Classer des mots par catégorie grammaticale en glisser-déposer ou par clic | title, instruction, defaultLevel, levels.totalWords, levels.wordsPerRound, levels.maxWordLevel, levels.classifications |
| Phrase à trous | frontend/src/activities/FillInTheBlanksActivity.js |
Compléter des phrases avec des mots manquants (banque de mots ou saisie), avec possibilité de charger une phrase depuis la base générée par IA | title, instruction, showWordBank, sourceLevel, sourceTheme, useGeneratedSentencePool, sentences[] |
| Tableau blanc interactif | frontend/src/activities/InteractiveWhiteboardActivity.js |
Dessiner, écrire, ajouter des images et exporter le tableau | defaultTitle, width, height, backgroundColor, paperStyle, defaultZoom, storageKey |
Documentation détaillée : voir
frontend/src/activities/README.md.
Le tableau blanc propose notamment :
- une barre d'outils flottante en bas de l'écran ;
- l'export PNG avec le nom de l'élève dans l'image et dans le nom du fichier ;
- l'import / export JSON ;
- un fond configurable :
blank→ fond blanc,seyes→ lignage Seyès,grid→ quadrillage pour géométrie ;
- une sauvegarde locale par élève via
localStorage.
Exemple de configuration JSON :
{
"defaultTitle": "Écriture du jour",
"width": 1240,
"height": 1754,
"backgroundColor": "#ffffff",
"paperStyle": "seyes",
"defaultZoom": 0.7,
"storageKey": "TBTS_INTERACTIVE_WHITEBOARD"
}.
├── backend/
│ ├── db.js
│ ├── Dockerfile
│ ├── init_db.js
│ ├── init_db.sql
│ ├── package.json
│ ├── server.js
│ └── routes/
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ ├── public/
│ └── src/
│ ├── activities/
│ ├── components/
│ └── views/
├── docker-compose.yml
└── README.md
- créer un composant dans
frontend/src/activities/; - exporter une configuration par défaut robuste, compatible avec un
contentvide ({}) ; - si l'activité gère des niveaux, appeler
onComplete(score, { levelKey, levelLabel }); - enregistrer l'activité dans
frontend/src/activities/ActivityContainer.js; - l'ajouter au registre partagé dans
frontend/src/utils/activityManagement.js; - compléter au même endroit la configuration par défaut (
ACTIVITY_FILES,getDefaultActivityContentText()) si nécessaire ; - créer ou modifier l'activité depuis l'espace admin / enseignant.
Quelques routes utiles :
GET /api/teachersPOST /api/teachersGET /api/classesPOST /api/classesGET /api/studentsPOST /api/studentsDELETE /api/students/:idGET /api/groups?class_id=:idPOST /api/groupsPOST /api/groups/:id/studentsDELETE /api/groups/:id/students/:studentIdGET /api/resultsPOST /api/resultsDELETE /api/results/:idGET /api/activitiesPOST /api/activitiesPUT /api/activities/:idDELETE /api/activities/:idDELETE /api/activitiesGET /api/words/statsGET /api/wordsDELETE /api/words/:idDELETE /api/wordsGET /api/ai/providersPOST /api/ai/generate-sentenceGET /api/ai/generated-sentencesGET /api/ai/generated-sentences/nextPOST /api/ai/generated-sentences/reset-countersDELETE /api/ai/generated-sentences/:idDELETE /api/ai/generated-sentencesPOST /api/import/csvGET /api/export/csvPOST /api/import/global-csvGET /api/export/global-csv
- application conçue pour un TNI
1024x768(4:3), type Smart Board M600 DViT ; - les mots de passe enseignants sont encore stockés en clair : à sécuriser avant une mise en production ;
- les clés/tokens ne doivent jamais être commités en clair dans
docker-compose.yml; - le projet est pensé pour un usage local / MVP ;
- le chargement des activités repose sur un registre explicite dans
ActivityContainer.js.