Finalisation du Readme et ménage dans les fonctions dépréciées

This commit is contained in:
2023-12-01 13:38:39 +01:00
parent 8cc00eac05
commit 2049457158
4 changed files with 170 additions and 248 deletions

373
README.md
View File

@@ -1,301 +1,184 @@
# Création d'une IHM pour le projet MIA
### Introduction
## Introduction
Ce projet couvre les IHM d'accès aux sessions de visio-conférence pour le projet MIA.
Ces IHM se découpent en deux étapes :
1 - connexion d'un utilisateur sur une session de visio
Ces IHM se découpent en deux étapes :\
1 - connexion d'un utilisateur sur une session de visio\
2 - identification de l'utilisateur sur la session
### Architecture du module
## Architecture du module
```
.
mia
├── ...
├── local/modules/ModuleCitation
│ ├── Config/
│ │ ├── module.xml
│ └── config.xml
│ ├── Hook/
│ └── BackHook.php
│ └── templates/
├── frontOffice/default/blocks/
│ │ ├── blockCitation.html
│ │ └── ...
│ └── backOffice/default/
│ │ ├── src/
│ │ │ │ └── Citation.jsx
│ │ │ ├── tsup.config.js
│ │ │ └── index.js
├── package.json
│ └── ModuleCitation.php
── ...
├── node_modules
│ ├── Tous les modules Node nécessaires à l'application (body-parser, bcrypt, express, ...)
├── public
├── functions.js (contient des fonctions Javascript utilisées globalement sur tout le projet)
│ ├── session.js (fonctions spécifiques à l'écran de création des sessions)
├── styles.css (feuilles de style globales de l'appli)
├── views
│ ├── create-session.hbs (écran de création d'une session de visio)
│ ├── login-session.hbs (écran de connexion sur une session)
├── login.hbs (écran d'identification de l'utilisateur)
├── login.hbs.old (DEPRECATED : ancienne version de l'identification de l'utilisateur, comprenant la saisie d'une adresse email ou d'un pseudo)
├── register.hbs (DEPRECATED : écran de création du compte utilisateur)
├──.env (variables globales, pour l'environnement de test)
├──.env.prod (idem, pour l'environnement de prod)
├──mia_ihm.js (....)
├──package-lock.json
├──package.json
──README.md (le présent fichier)
```
### Installation des dépendances :
## Installation des dépendances
Exemple de commande :
```bash
npm install react tsup @openstudio/blocks-editor
npm install bcrypt
```
### 1 - Création du composant
Commençons par créer un fichier `Citation.jsx` et par définir les données initiales du plugin :
```js
// ./templates/backOffice/default/src/Citation.jsx
const initialData = {
author: "",
quote: "",
};
```
Ensuite, nous allons pouvoir écrire le composant React permettant de visualiser le plugin dans l'éditeur de Thelia Blocks.
:warning: Attention : un plugin Thelia Blocks prends toujours deux `props` :
| Prop | Type | Description |
| :--------- | :--------- | :--------------------------------------------------------- |
| `data` | `any` | Objet contenant les données du plugin |
| `onUpdate` | `Function` | Fonction permettant de mettre à jour les données du plugin |
Exemple :
```jsx
// ./templates/backOffice/default/src/Citation.jsx
const BlockQuoteComponent = ({ data, onUpdate }) => {
return (
<div className="BlockQuote">
<div className="BlockQuote-field">
<label htmlFor="author-field">Auteur</label>
<input
type="text"
className="Input__Text"
id="author-field"
placeholder="Nom de l'auteur"
value={data.author}
onChange={(e) => onUpdate({ ...data, author: e.target.value })}
/>
</div>
<div className="BlockQuote-field">
<label htmlFor="quote-field">Citation</label>
<textarea
className="Input__TextArea"
id="quote-field"
placeholder="Entrez la citation"
value={data.quote}
onChange={(e) => onUpdate({ ...data, quote: e.target.value })}
/>
</div>
</div>
);
};
```
### 2 - Combinez vos plugins
Notre plugin `citation` utilise un élément `<textarea />` pour permettre à l'utilisateur d'insérer une citation.
Cependant, il est tout à fait possible d'imbriquer certains plugins pour réutiliser des fonctionnalités déjà existantes.
Dans notre cas, le plugin `Text` est parfait :
Celui ci embarque déjà un système rich-text et d'autres fonctionnalités qui peuvent être utiles.
Voyons comment l'utiliser dans notre plugin de citations :
```js
// ./templates/backOffice/default/src/Citation.jsx
import { blocks } from "@openstudio/blocks-editor";
const { Text } = blocks; // Récupération du plugin Text dans la liste des plugins
```
Nous pouvons désormais nous servir de `Text` dans le plugin Citation :
```jsx
// ./templates/backOffice/default/src/Citation.jsx
import { generateId } from "@openstudio/blocks-editor";
const BlockQuoteComponent = ({ data, onUpdate }) => {
return (
<div className="BlockQuote">
<div className="BlockQuote-field">
<label htmlFor="author-field">Auteur</label>
<input
type="text"
className="Input__Text"
id="author-field"
placeholder="Nom de l'auteur"
value={author}
onChange={(e) => onUpdate({ ...data, author: e.target.value })}
/>
</div>
<div className="BlockQuote-field">
<Text.component
data={{ value: data.quote }}
onUpdate={(value) => onUpdate({ ...data, quote: value })}
id={generateId()}
/>
</div>
</div>
);
};
```
Notre plugin Citation utilise désormais `Text` pour fonctionner.
:warning: Attention : un plugin doit obligatoirement avoir un composant React ou hériter d'un autre plugin
### 3 - Structure et export du plugin
Chaque plugin est représenté par un objet. Celui ci regroupe toutes les informations nécessaires à son bon fonctionnement.
| Attribut | Type | Requis | Description |
| :------------ | :---------------------------------------- | :----------------: | :--------------------------------------------------------------------- |
| `type` | `{ id: string; }` | :white_check_mark: | ID du plugin, celui ci sera utilisé par Thelia pour effectuer le rendu |
| `component` | `ReactElement` | :white_check_mark: | Composant du plugin |
| `initialData` | `any` | :white_check_mark: | Données par défaut du plugin |
| `icon` | `FunctionComponent<SVGProps<SVGElement>>` | | Icone du plugin |
| `title` | `{ [key: string]: string; }` | :white_check_mark: | Titre du plugin |
| `description` | `{ [key: string]: string; }` | :white_check_mark: | Description du plugin |
Exemple :
```js
// ./templates/backOffice/default/src/Citation.jsx
const blockQuote = {
type: { id: "blockQuote" },
component: BlockQuoteComponent,
initialData,
icon: Icon,
title: {
default: "Quote",
fr: "Citation",
en: "Quote",
},
description: {
default: "Display a quote",
fr: "Affiche une citation",
en: "Display a quote",
},
};
## Description des différents écrans
export default blockQuote;
```
### create-session
### 4 - Configuration du plugin avec Thelia
Cet écran permet la création unitaire d'une session de visio.
Ceci permet à n'importe quel utilisateur de créer une session à venir --> cette session apparaitra dans la liste présente sur la page des sessions.
#### 4.1 - Ajout du plugin dans Thelia Blocks
#### Accès à l'écran
Votre plugin doit maintenant être ajouté à Thelia Blocks pour être disponible lors de la création d'un nouveau Block.
Depuis l'écran de choix de la session, via un lien hypertexte situé au bas du formulaire.
La fonction `"registerPlugin"` se charge de l'ajout de la liste des plugins dans Thelia Blocks.
#### Contrôles mis en place
Celle ci est exportée par le package `@openstudio/blocks-editor`
* Le mot de passe (et sa confirmation) doivent être identiques, sinon message d'erreur.
* Champs obligatoires : **intitulé** et **date de début**
* Le nombre de participants (si renseigné) doit être un nombre entier strictement positif.
Exemple :
#### Actions effectuées depuis cet écran
```js
// ./templates/backOffice/default/index.js
A la soumission du formulaire, si tous les contrôles sont passants, une nouvelle session est créée en base de données dans la table "session".\
Y sont stockés :
* un UUID généré automatiquement (champ id)
* l'intitulé de la session (champ topic)
* le mot de passe de la session (champ password, chiffré via le module bcrypt)
* la date/heure de début (scheduled_on), au format YYYYMMDDHHmm
* le nombre de participants attendus (champ nb_of_attended)
* le nombre de participants réel (champ nb_of_participants) valorisé par défaut à 0
import { registerPlugin } from "@openstudio/blocks-editor";
import Citation from "./Citation";
L'utilisateur est ensuite rédirigé vers la page **login-session**
registerPlugin(Citation);
```
-------------------------------------------------
#### 4.2 - Génération du bundle
### login-session
:warning: L'exemple ci-dessous décrit une utilisation avec le bundler [tsup](https://github.com/egoist/tsup), vous pouvez évidemment utiliser n'importe quel autre bundler.
Ecran d'accueil du site, il permet à l'utilisateur de se connecter sur une session existante (listées dans une liste déroulante).
```js
// ./templates/backOffice/default/tsup.config.js
Dans cet écran, l'utilisateur peut préciser son rôle ("Présentateur" ou simple "Auditeur"), sur la session qu'il aura sélectionné.\
Par défaut, l'utilisateur est considéré comme "Auditeur".
import { defineConfig } from "tsup";
export default defineConfig([
{
entry: ["./src/index.js"],
clean: false,
dts: {
entry: ["./src/index.js"],
},
sourcemap: true,
platform: "browser",
globalName: "MonModule",
target: "es2020",
},
]);
```
#### Accès à l'écran
#### 4.3 - Création des template Smarty
* Page d'accueil du site
* Via le lien "Projet MIA" apparaissant dans le header du site
```smarty
<!-- ./templates/backOffice/default/import-plugin.html -->
#### Contrôles mis en place
<script src="{encore_module_asset file='dist/index.global.js' module="ModuleCitation"}"></script>
```
* Le mot de passe saisi par l'utilisateur est contrôlé (après déchiffremment) et comparé avec celui stocké en BDD --> si cela ne correspond pas, un message d'erreur apparait à l'utilisateur.
* L'utilisateur doit saisir un mot de passe.
#### 4.4 - Rendu des templates avec les hooks Thelia
#### Actions effectuées depuis cet écran
Thelia Blocks utilise deux principaux event pour fonctionner :
* L'utilisateur peut créer une nouvelle session, via le lien hypertexte _"Besoin d'une nouvelle session ?..."_
* Au clic sur le bouton, l'existence de la session (et la conformité de son mot de passe) sont vérifiées.
- `thelia.blocks.plugins` : permet d'ajouter des plugins à Thelia Blocks
- `thelia.blocks.plugincss` : permet d'injecter du CSS dans les plugins
```xml
<!-- ./Config/config.xml -->
-------------------------------------------------
<hooks>
<hook id="modulecitation.hook">
<tag name="hook.event_listener" event="thelia.blocks.plugins" type="back" render="import-plugin.html" />
</hook>
</hooks>
```
### login
### 5 - Création du rendu Smarty
Ecran qui permet à l'utilisateur de s'identifier sur la session via l'identifiant de son choix : il peut saisir un texte quelconque ou bien une adresse email, par exemple.
Votre plugin est désormais disponible dans Thelia Blocks, la dernière étape consiste à définir la structure HTML qu'il doit générer une fois que Thelia l'affichera sur votre site.
#### Accès à l'écran
#### 5.1 - Création de votre rendu
Depuis la page des sessions, après vérification de l'accès autorisé à la session.
Pour commencer, créez un fichier nommé `"[id_du_plugin].html"` dans le dossier `./templates/frontOffice/default/blocks`
#### Contrôles mis en place
L'ID a été défini dans la structure du plugin, il est important que votre fichier ai exactement le même nom que l'id, sinon Thelia ne trouvera pas votre plugin et rien ne sera affiché.
* L'identifiant saisi n'a pas de format particulier.
* L'identifiant ne doit pas déjà être utilisé sur la session préalablement choisie par le client --> ce contrôle s'effectue en consultant les utilisateurs déjà déclarés sur la session en cours de saisie (table **participation**)
Exemple :
#### Actions effectuées depuis cet écran
```smarty
<!-- ./templates/frontOffice/default/blocks/blockQuote.html -->
Au clic sur le bouton "Se connecter", si les contrôles sont passants, l'utilisateur sera rédirigé vers une page Web dont l'URL est définie dans le fichier .env (donnée MASTER_URL ou SLAVE_URL en fonction du rôle que l'utilisateur s'est choisi sur l'écran des sessions) :
* si rôle = "Présentateur" --> MASTER_URL
* si rôle = "Auditeur" --> SLAVE_URL
<figure class="tb-{$type["id"]}">
<blockquote>{$data["quote"]}</blockquote>
<figcaption>-{$data["author"]}</figcaption>
</figure>
```
Simultanément, la présence de l'utilisateur sur la session est tracée :
* incrémentation du compteur des participants, dans la table **session**
* création de l'utilisateur dans la table **user** avec un identifiant unique (UUID) auto-généré
* enregistrement de la présence de l'utilisateur sur la session, dans la table **participation**
### 6 - Aller plus loin
#### Traductions
-------------------------------------------------
Vous pouvez également traduire vos plugins, Thelia Blocks utilise `react-intl` pour les traductions.
Plus d'informations sur la [documentation](https://formatjs.io/docs/getting-started/installation/) de `react-intl`
### login.old
La traduction du titre et de la description du plugin se fait directement dans sa définition.
**DEPRECATED**
[Exemple d'un plugin avec traductions](https://github.com/thelia-modules/TheliaBlocks-plugins-examples/tree/main/Citation-with-intl)
Suite à un point avec l'équipe Cortex le 16/11/2023, cet écran a été retiré et remplacé par une version simplifiée (avec uniquement la saisie d'un identifiant).
#### Styling
Cet écran a pour objectif de permettre à l'utilisateur de s'identifier via la saisie de son identifiant (soit un pseudo, soit une adresse email) et du mot de passe associé.
Il est également possible de styliser vos plugins comme vous le souhaitez.
L'event `thelia.blocks.plugincss` permet d'injecter du CSS dans vos plugins.
#### Accès à l'écran
[Exemple d'un plugin avec styling](https://github.com/thelia-modules/TheliaBlocks-plugins-examples/tree/main/Citation-with-css)
**A date, plus d'accès possible à cet écran**
#### TypeScript
#### Contrôles mis en place
Les plugins de base de Thelia Blocks sont rédigés avec TypeScript, cependant, rien ne vous empêche de les rédiger en JavaScript classique.
* L'utilisateur doit avoir saisi soit un pseudo soit une adresse email
* On vérifie que l'identifiant saisi n'est pas déjà utilisé --> si c'est le cas, l'utilisateur sera informé
* L'utilisateur doit saisir (et confirmer) un mot de passe
#### Actions effectuées depuis cet écran
* L'utilisateur peut créer un nouveau compte via le lien hypertexte présent au bas du fomulaire (_"Pas encore inscrit ?..."_)--> redirection vers la page **register**
* Au clic sur le bouton _"Se connecter"_, le nombre de participants sur la session (table **session**) est incrémenté et l'utilisateur est ajouté dans la table **participation**
-------------------------------------------------
### register
**DEPRECATED**
Cet écran permet de créer un nouveau compte utilisateur.
Il est demandé (obligatoire) à l'utilisateur d'y saisir :
* un identifiant (soit l'adresse email soit le pseudonyme)
* un mot de passe (et sa confirmation)
Il est proposé (facultatif) de renseigner :
* Son genre (Monsieur ou Madame)
* Som nom et/ou son prénom
* Son titre ou fonction
#### Accès à l'écran
**A date, plus d'accès possible à cet écran**
#### Contrôles mis en place
* Les 2 mots de passe doivent concorder, sinon message d'erreur
* L'utilisateur doit avoir renseigné au moins le pseudo ou l'adresse email (il peut renseigner les deux, et plus)
* L'identifiant ne doit pas déjà être connu dans la BDD
#### Actions effectuées depuis cet écran
* Si l'utilisateur s'aperçoit qu'il a finalement déjà un compte, il peut abandoinner la création d'un nouveau compte en cliquant sur le lien _"Déjà inscrit ?..."_
* Au clic sur le bouton _"M'enregistrer"_, l'utilisateur sera créé en base de données et un identifiant unique (UUID) lui sera automatiquement attribué en BDD.

View File

@@ -1,5 +1,5 @@
const express = require('express')
const mysql = require("mysql2")
const mysql = require("mysql")
const dotenv = require('dotenv')
const app = express()
const path = require("path")
@@ -54,11 +54,10 @@ app.get("/", (req, res) => {
app.get("/index", (req, res) => { res.render("index") });
app.get("/login", (req, res) => { res.render("login") });
app.get("/register", (req, res) => { res.render("register", { session: req.query.s, role: req.query.r}) });
app.get("/register", (req, res) => { res.status(404).send('Page Not found'); /* res.render("register", { session: req.query.s, role: req.query.r}) */ });
app.get("/create-session", (req, res) => { res.render("create-session") });
// ******************************************* Création d'un nouveau compte *******************************************
app.post("/auth/register", (req, res) => {
const { gender, name, firstname, nickname, title, email, password, password_confirm, session, role } = req.body

40
schema.sql Normal file
View File

@@ -0,0 +1,40 @@
CREATE DATABASE `mia`;
USE `mia`;
-- mia.participation definition
CREATE TABLE `participation` (
`user` uuid DEFAULT NULL,
`session` uuid DEFAULT NULL,
`role_during_session` varchar(100) DEFAULT 'A'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
-- mia.`session` definition
CREATE TABLE `session` (
`id` uuid NOT NULL,
`scheduled_on` datetime DEFAULT NULL,
`topic` varchar(100) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`nb_of_attended` int(11) DEFAULT NULL,
`nb_of_participants` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
-- mia.`user` definition
CREATE TABLE `user` (
`id` uuid NOT NULL,
`name` varchar(30) DEFAULT NULL,
`firstname` varchar(50) DEFAULT NULL,
`nickname` varchar(100) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
`gender` varchar(1) DEFAULT NULL,
`email` varchar(200) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`session` uuid DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;