Aller au contenu

Alert-Parent Frontend

Description

Interface utilisateur de la plateforme Alert-Parent, permettant aux administrateurs et à l'équipe pédagogique de gérer les campus, promos, étudiants, templates d'alertes et campagnes d'envoi aux parents.

Informations techniques

Élément Valeur
Framework React 18 (Vite 5)
Langage JavaScript (JSX, pas de TypeScript)
UI TailwindCSS 3 + shadcn/ui
Data fetching TanStack React Query
HTTP Client Axios (instance partagée avec intercepteurs)
Routing React Router v6 (lazy-loaded)
Port 127.0.0.1:3004 (hôte) → 3000 (conteneur nginx)
Registry ghcr.io/epitechafrik/alert-parent-frontend
Déploiement Automatique via GitHub Actions sur push main

Utilisateurs cibles

  • Administrateurs : gestion des promos, étudiants, utilisateurs, envoi d'alertes
  • Équipe pédagogique (Users) : envoi et consultation des alertes

Pages principales

Page Route Description
Login /auth/login Connexion JWT ou Microsoft SSO
Alerts /alertes Ancien historique des alertes envoyées avec filtres
New Alert /alertes/new Ancien formulaire d'envoi d'alerte par type
Alert Campaigns /alert-campaigns Historique des campagnes envoyées et brouillons
New Campaign /alert-campaigns/new Composer de campagne avec preview, fichiers, surcharges et envoi
Edit Campaign /alert-campaigns/:campaignId/edit Reprise/modification d'un brouillon
Alert Templates /alert-templates Liste des templates dynamiques
New Template /alert-templates/new Création d'un template WYSIWYG
Edit Template /alert-templates/:templateId/edit Modification d'un template existant
Campuses /campuses Gestion des campus
Students /students Liste des étudiants actifs/inactifs
Promotions /promotions Gestion des promos (cycle + année)
Users /users Gestion des comptes admin (admin only)

Alertes et campagnes

Ancien flux /alertes/new

Le formulaire /alertes/new supporte 8 types d'alertes, chacun avec son propre formulaire et ses règles de validation :

Type Description Fichier requis
Tepitech Résultats TOEIC par classe CSV (login, mark)
Stumper Résultats Stumper CSV (login, mark)
Module Notes de module CSV (login, note)
Présence Absences/retards CSV
Projet Notes de projet (filtré par tag) XLS
Roadblock Étudiants bloqués CSV
-42 Étudiants à -42 crédits CSV
Évaluation de stage Notes d'évaluation Non

Chaque formulaire avec fichier affiche un panneau de validation à droite montrant :

  • Correspondance des colonnes attendues/trouvées
  • Colonnes vides (avertissement)
  • Aperçu des données avec code couleur selon les seuils

Seuils de couleur

  • Tepitech : Vert si ≥ seuil (TEK1: 600, TEK2: 700, TEK3: 750), Rouge sinon
  • Stumper : Vert si ≥ 15, Rouge sinon

Nouveau flux campagnes /alert-campaigns

Les campagnes sont le flux recommandé pour les alertes dynamiques. Elles permettent de cibler un groupe ou une sélection d'étudiants, choisir un template, charger les fichiers attendus, prévisualiser le rendu final et envoyer les emails.

Workflow UI :

  1. Choisir le campus, la promo/classe ou une sélection d'étudiants.
  2. Choisir le topic/template.
  3. Remplir uniquement les champs définis par template.variablesSchema.
  4. Charger les fichiers définis par template.fileSchemas.
  5. Lancer une preview éphémère via POST /api/alert-campaigns/preview-draft.
  6. Sauvegarder en brouillon si nécessaire, ou envoyer directement.
Action UI Endpoint
Preview sans sauvegarde POST /api/alert-campaigns/preview-draft
Sauvegarder brouillon POST /api/alert-campaigns
Modifier brouillon PUT /api/alert-campaigns/:id
Envoyer POST /api/alert-campaigns/:id/send
Historique GET /api/alert-campaigns?scope=history
Brouillons GET /api/alert-campaigns?scope=drafts
Détail sidebar GET /api/alert-campaigns/:id
Supprimer brouillon DELETE /api/alert-campaigns/:id

La liste /alert-campaigns sépare History et Drafts. Le bouton Details ouvre une sidebar avec le ciblage, les variables, les fichiers, les surcharges et la timeline. Les brouillons peuvent être édités ou supprimés ; les campagnes envoyées restent en historique.

Validation des fichiers

Le composer réutilise le panneau de validation des fichiers :

  • colonnes requises/trouvées ;
  • colonnes vides ;
  • cellules incomplètes ;
  • logins inconnus ou non alignés avec les étudiants ciblés ;
  • aperçu coloré selon les règles du backend.

Les templates récents utilisent fileSchemas pour déclarer plusieurs fichiers attendus, par exemple notes + présences. Les anciens templates sans fileSchemas gardent un fallback rows compatible avec l'ancien flux.

Templates dynamiques

Les templates sont gérés dans /alert-templates. L'éditeur est une page dédiée, pas une modale, avec un éditeur WYSIWYG pour le HTML du mail et des aides pour insérer les variables dynamiques.

Champs importants

Champ backend Usage frontend
name Nom affiché dans les listes et selects
topic Catégorie métier du template
campus Template global si vide, surcharge campus si renseigné
subjectTemplate Sujet du mail avec variables {{...}}
bodyTemplate Corps HTML édité en WYSIWYG
variablesSchema Source principale des champs de formulaire utilisateur
fileSchemas Fichiers attendus dans une campagne

variablesSchema pilote le type de champ affiché dans le composer :

Type Affichage
text Input simple
textarea Zone de texte longue
wysiwyg Éditeur riche
number Input numérique
date Sélecteur date
select Liste de choix

Les variables système ne doivent pas être demandées à l'utilisateur :

student.* recipient.* promo.* campus.* row.* file.* files.* computed.*

Elles peuvent être insérées comme placeholders dans l'éditeur, mais elles sont résolues par le backend au moment du preview/envoi. Exemples : {{computed.projectResultSummary}}, {{files.grades.grade}}, {{recipient.firstname}}.

Surcharges de campagne

Dans le composer, l'utilisateur peut surcharger le template choisi pour une campagne précise :

  • overrideSubjectTemplate pour le sujet ;
  • overrideBodyTemplate pour le corps HTML ;
  • overrideVariables pour ajuster les variables de la campagne ;
  • studentOverrides pour des cas ciblés par étudiant, si le backend en expose déjà.

La preview affiche le HTML rendu dans une iframe sandboxée pour éviter d'afficher le code HTML brut.

Gestion multi-campus

Les campus sont intégrés aux écrans étudiants, promos et campagnes :

  • Les promos sont filtrées par campus.
  • Le changement de campus d'un étudiant filtre la liste des promos disponibles.
  • Si un campus n'a pas de promo, l'interface bloque ou guide l'utilisateur au lieu d'afficher un select vide ambigu.
  • Les templates peuvent être globaux ou spécifiques à un campus.

Gestion des étudiants

Soft delete (désactivation)

Les étudiants ne sont jamais supprimés définitivement — ils sont désactivés pour préserver l'historique des alertes.

Action Méthode Endpoint
Désactiver PUT /api/students/:id/deactivate
Réactiver PUT /api/students/:id/reactivate
Désactiver en masse POST /api/students/bulk/deactivate
Lister les inactifs GET /api/students?active=false

La page Students dispose d'un toggle Active/Inactive pour basculer entre les deux vues :

  • Vue Active : modifier, désactiver (individuel ou en masse), déplacer (classe/promo)
  • Vue Inactive : réactiver

Autres actions

  • Import CSV : upload en masse de nouveaux étudiants
  • Export XLS : export de la liste filtrée
  • Move (bulk) : déplacer des étudiants sélectionnés vers une autre classe/promo
  • Recherche : par nom d'étudiant ou par nom de référent
  • Filtres : campus, promo, classe, tri par nom

Architecture

Arborescence

frontend/
├── src/
│   ├── components/
│   │   ├── forms/alerts/    # Formulaires par type d'alerte
│   │   ├── modals/          # Modals (Admin + User)
│   │   ├── shared/          # DataTable, PageHeader, SearchInput, ConfirmDialog, CampusSelect
│   │   │   └── alerts/      # RichTemplateEditor, VariableField
│   │   └── ui/              # Composants shadcn/ui
│   ├── constants/           # Routes, types utilisateurs, classes
│   ├── context/             # UserContext (auth globale)
│   ├── hooks/               # React Query hooks + utilitaires
│   ├── lib/                 # Axios instance, queryClient, utils
│   ├── pages/               # Écrans par rôle (Admin, User, Auth)
│   ├── router/              # AppNavigation, AuthRouter, AdminRouter
│   └── services/            # Anciens services (legacy, migration en cours)

Hooks React Query

Chaque ressource a son propre fichier de hooks dans src/hooks/ :

Fichier Hooks principaux
useAlerts.js useAlerts(filters), useAlert(id), useCreateAlert(), useResendAlert()
useUsers.js useUsers(filters), useCreateUser(), useUpdateUser(), useDeleteUser()
useStudents.js useStudents(filters), useCreateStudent(), useUpdateStudent(), useDeactivateStudent(), useReactivateStudent(), useBulkDeactivateStudents(), useBulkUpdateStudents()
usePromos.js usePromos(filters), useDeletePromo()
useCampuses.js useCampuses(filters), hooks de création/modification/suppression campus
useAlertTemplates.js Liste, détail, création, modification et suppression de templates
useAlertCampaigns.js Liste, détail, preview draft, création/update, envoi, suppression de brouillon

Authentification

  1. L'utilisateur se connecte via JWT classique ou Microsoft SSO
  2. Le token JWT est stocké dans localStorage
  3. L'intercepteur Axios l'injecte automatiquement dans chaque requête
  4. En cas de 401, l'intercepteur redirige vers /auth/login

Déploiement

Pipeline CI/CD (GitHub Actions)

Le pipeline .github/workflows/deploy.yml comporte 3 jobs :

graph LR
    A[build-and-push] --> B[deploy]
    B --> C[notify]
  1. build-and-push : Build Docker multi-stage (node:20-alpine → nginx:alpine), push sur GHCR
  2. deploy : SCP du docker-compose.yml, SSH pour pull + restart, healthcheck sur port 3004
  3. notify : Affiche le statut du déploiement

Variables Vite = build time

Les variables VITE_* sont injectées à la compilation via des build-args Docker (Vite les embarque dans le bundle JS). Elles ne sont pas lisibles au runtime.

docker-compose.yml

services:
  frontend:
    image: ghcr.io/epitechafrik/alert-parent-frontend:${IMAGE_TAG:-latest}
    container_name: alert-parent-frontend
    restart: always
    ports:
      - "127.0.0.1:3004:3000"
    env_file:
      - .env
    healthcheck:
      test: ["CMD", "curl", "-sf", "http://localhost:3000"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

Dockerfile (multi-stage)

# Stage 1 : Build avec pnpm
FROM node:20-alpine AS builder
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
ARG VITE_REACT_APP_API_URL
ARG VITE_REACT_APP_FRONT_URL
ARG VITE_MICROSOFT_CLIENT_ID
ARG VITE_MICROSOFT_TENANT_ID
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build

# Stage 2 : Serveur nginx
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]

Variables d'environnement

Variable Description Exemple
VITE_REACT_APP_API_URL URL de l'API backend https://api.epitools.bj/api
VITE_REACT_APP_FRONT_URL URL du frontend https://alert.epitools.bj
VITE_MICROSOFT_CLIENT_ID Client ID Azure AD (SSO) 2bda619b-...
VITE_MICROSOFT_TENANT_ID Tenant ID Azure AD 901cb4ca-...

Ces variables sont stockées dans le secret GitHub DOTENV_FILE et injectées comme build-args dans le pipeline.

Accès

L'application est accessible via Nginx reverse proxy sur https://alert.epitools.bj.

server {
    server_name alert.epitools.bj;
    location / {
        proxy_pass http://127.0.0.1:3004;
    }
}

Rollback

# 1. Trouver la version précédente
docker images ghcr.io/epitechafrik/alert-parent-frontend --format "table {{.Tag}}\t{{.CreatedAt}}"

# 2. Déployer une version spécifique
cd /root/projects/alert-parent/alert-parent-frontend
export IMAGE_TAG=sha-XXXXXXX
docker compose pull frontend
docker compose up -d --no-deps frontend

# 3. Vérifier
curl -sf http://127.0.0.1:3004 && echo "OK" || echo "FAIL"