diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3fa71c5033912a80b678fab9be69edbeeb6bdf3c --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,50 @@ +name: Deploy Angular to GitHub Pages + +on: + push: + branches: + - main + +permissions: + contents: write + pages: write + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Install Angular CLI + run: npm install -g @angular/cli + + - name: Build Angular app + run: ng build --configuration production --base-href "/Auto-evaluation/" + + - name: Add 404.html for GitHub Pages + run: | + echo '<!DOCTYPE html> + <html> + <head> + <meta http-equiv="refresh" content="0; URL='https://foucblg.github.io/Auto-evaluation/'" /> + </head> + <body> + </body> + </html>' > dist/autoeval/browser/404.html + + - name: Deploy to GitHub Pages + uses: JamesIves/github-pages-deploy-action@v4 + with: + branch: gh-pages + folder: dist/autoeval/browser diff --git a/Readme.md b/Readme.md index f77664dc1aa108451b9c62362151272607bc6536..4dcb8858d1a888e6db4322dcde649cf47794f726 100644 --- a/Readme.md +++ b/Readme.md @@ -1 +1 @@ -#Yo \ No newline at end of file +# Auto-évaluation d'inclusif le jeu diff --git a/documentation.md b/documentation.md new file mode 100644 index 0000000000000000000000000000000000000000..4b24494175cccc2959aa28e8c19792c419e7dd31 --- /dev/null +++ b/documentation.md @@ -0,0 +1,4 @@ +# Documentation du l'auto-évaluation + +Cette application se rapproche fortement du Quiz par sa construction. Les réponses sont en revanche les mêmes pour chaque question. +On retrouve la même architecture, les mêmes services et interfaces, pour des renseignements, se référer à la documentation du Quiz. \ No newline at end of file diff --git a/package.json b/package.json index a56accdd110f05cbcebd427c1983ef82a96b07a3..8d8125dac3772054d0c8e02befe95359bec83af9 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@angular-devkit/build-angular": "^19.1.5", - "@angular/cli": "^19.1.5", + "@angular/cli": "^19.1.4", "@angular/compiler-cli": "^19.1.4", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.2.0", @@ -38,4 +38,4 @@ "karma-jasmine-html-reporter": "~2.1.0", "typescript": "~5.5.2" } -} \ No newline at end of file +} diff --git a/public/images/Score_A.png b/public/images/Score_A.png new file mode 100644 index 0000000000000000000000000000000000000000..b90ce60ad99572d3123598198bf3163fbd42ee78 Binary files /dev/null and b/public/images/Score_A.png differ diff --git a/public/images/Score_B.png b/public/images/Score_B.png new file mode 100644 index 0000000000000000000000000000000000000000..90d9929aa1fd63dcbaaa62ae8ca42727d652ecc8 Binary files /dev/null and b/public/images/Score_B.png differ diff --git a/public/images/Score_C.png b/public/images/Score_C.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca8b07f94718d2938dbe70f440a25f0b6018a75 Binary files /dev/null and b/public/images/Score_C.png differ diff --git a/public/images/Score_D.png b/public/images/Score_D.png new file mode 100644 index 0000000000000000000000000000000000000000..08c88f6f63f0d1aafc3407c8c02809bee55bf574 Binary files /dev/null and b/public/images/Score_D.png differ diff --git a/public/images/Score_E.png b/public/images/Score_E.png new file mode 100644 index 0000000000000000000000000000000000000000..52fc5aa5c72c2c6a4e11b87d89cd6562740a36ea Binary files /dev/null and b/public/images/Score_E.png differ diff --git a/src/app/app.component.css b/src/app/app.component.css index 2618aaa58929cf6491b26aeb533198ed24fb1fde..de7a8af8532fd76f8f919e35881d653ec92422d4 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -6,9 +6,9 @@ height: 100%; } -/* Navbar */ -.navbar-div { - height: 61px; +/* Header */ +.header-div { + height: 66px; } /* Contenu principal */ @@ -19,11 +19,12 @@ main { height: 100%; } -.quiz-div { +.autoeval-div { flex: 1; /* Prend tout l'espace disponible */ min-height: 50vh; /* Hauteur minimale pour le contenu */ overflow: auto; /* Ajoute un défilement si le contenu est trop long */ height: 100%; + padding: 16px; } /* Footer */ @@ -37,7 +38,7 @@ footer { padding: 0 28px; font-size: 12px; width: 100%; - margin-top: auto; /* Force le footer à rester en bas */ + margin-top: auto; } footer ul { @@ -45,7 +46,7 @@ footer ul { padding: 0; margin: 0; display: flex; - gap: 12px; /* Espace entre les éléments */ + gap: 12px; } footer li { @@ -60,7 +61,13 @@ footer a { vertical-align: middle; } +footer a:hover{ + text-decoration: underline; +} +footer p { + color: #ffffff; +} footer .right-section { display: flex; align-items: center; @@ -69,4 +76,4 @@ footer .right-section { footer .right-section img { height: 20px; margin-right: 5px; -} +} \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html index 8fcfdd4961a30263b05b489807c41d05594c0d91..7334dd4ab667de3ba8bc85c8589b2459f3d280d6 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,23 +1,24 @@ <div class="app-container"> <header> - <div class="navbar-div"> - <app-navbar></app-navbar> + <div class="header-div"> + <app-header></app-header> </div> </header> <main> - <div class="quiz-div"> + <div class="autoeval-div"> <router-outlet></router-outlet> </div> </main> + <!-- Mise en place du footer --> <footer> <ul> - <li><a href="https://resin.grandlyon.com/mentions-legales" target="_blank" rel="noopener noreferrer">Mentions légales ●</a></li> - <li><a href="https://resin.grandlyon.com/newsletter" target="_blank" rel="noopener noreferrer">Newsletter ●</a></li> - <li><a href="https://resin.grandlyon.com/contact" target="_blank" rel="noopener noreferrer">Contact ●</a></li> - <li><a href="https://resin.grandlyon.com/page/qui-sommes-nous" target="_blank" rel="noopener noreferrer">Qui sommes-nous ? ●</a></li> - <li><a href="/accessibilite" target="_blank" rel="noopener noreferrer">Accessibilité : Pas Testé</a></li> + <li><a href="https://resin.grandlyon.com/mentions-legales" target="_blank" rel="noopener noreferrer">Mentions légales</a></li> + <p>●</p> + <li><a href="https://resin.grandlyon.com/page/qui-sommes-nous" target="_blank" rel="noopener noreferrer">Qui sommes nous ?</a></li> + <p>●</p> + <li>Accessibilité : Non conforme</li> </ul> <div class="right-section"> <ul> @@ -25,7 +26,8 @@ <a href="https://www.grandlyon.com/" target="_blank" rel="noopener noreferrer"> <img src="https://inclusivite-resin.grandlyon.com/app/themes/ausy-modular-theme/public/images/picto-plus.0a1d2b.png" alt="Logo"> <p>Un site de la Métropole de Lyon</p> - </a></li> + </a> + </li> </ul> </div> </footer> diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 99996f9e0e76da7ebe42e1917a5270bd9b851a15..b7646902ea2379d0601adf29213abbae9a1f9eb2 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,18 +2,18 @@ import { CommonModule } from '@angular/common'; import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import * as data from './shared/assets/data/questions_final.json'; -import { QuizData } from './shared/types/interfaces'; -import { NavbarComponent } from './views/navbar/navbar.component'; +import { AutoevalData } from './shared/types/interfaces'; +import { HeaderComponent } from "./views/header/header.component"; @Component({ selector: 'app-root', - imports: [CommonModule, RouterOutlet, NavbarComponent], + imports: [CommonModule, RouterOutlet, HeaderComponent], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'INCLUSIF: Le jeu'; - quizData = quizData; + autoevalData = autoevalData; } -export const quizData: QuizData = data; +export const autoevalData: AutoevalData = data; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 4ad703dd084446ab668d7c28649308deeba307e3..12a3703308d6321730ef03c9fe6383fd8f02f7f2 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,11 +1,19 @@ import { Routes } from '@angular/router'; -import { QuizComponent } from './views/quiz/quiz.component'; +import { ContexteComponent } from './views/autoeval/autoeval-contexte/autoeval-contexte.component'; +import { AutoevalComponent } from './views/autoeval/autoeval.component'; +import { AutoevalHomepageComponent } from './views/autoeval/autoeval-homepage/autoeval-homepage.component'; export const routes: Routes = [ { - path: 'quiz', title: "Quiz Inclusif, le jeu", children: [ - { path: '**', component: QuizComponent }, + path: 'autoeval', + title: "Auto-évaluation d'inclusivité", + children: [ + { path: '', redirectTo: 'accueil', pathMatch: 'full' }, + { path: 'accueil', component: AutoevalHomepageComponent }, + { path: 'contexte', component: ContexteComponent }, + { path: ':id', component: AutoevalComponent }, + { path: '**', redirectTo: 'accueil' }, ], }, - { path: '', redirectTo: 'quiz/accueil', pathMatch: 'full' }, + { path: '', redirectTo: 'autoeval/accueil', pathMatch: 'full' }, ]; diff --git a/src/app/shared/assets/data/questions_final.json b/src/app/shared/assets/data/questions_final.json index 77921fab4151fb911b96375def1df22e249976de..e78fb6c5e8573963245f1db677bddd9468f48740 100644 --- a/src/app/shared/assets/data/questions_final.json +++ b/src/app/shared/assets/data/questions_final.json @@ -1,566 +1,157 @@ { - "question_topics": [ - "Handicap", - "Design", - "Accessibilité numérique", - "Inclusion numérique" + "topics": [ + "Gestion de projet", + "Expérience utilisateur", + "Interface utilisateur", + "Editorial" ], - "question_cycle": [ - 1, - 1, - 1, - 1 + "possible_answers": [ + "Oui", + "En partie", + "Non", + "Non applicable", + "Ne sait pas" ], "questions": { - "Accessibilité numérique": [ - { - "question_type": "QCM", - "question": "Pour compenser un handicap moteur, il est possible d'utiliser :", - "possible_answers": [ - "une commande vocale", - "une commande visuelle", - "un joystick", - "une souris ergonomique" - ], - "true_answers": [ - 0, - 1, - 2, - 3 - ], - "explanation": "Le handicap moteur recouvre l’ensemble des troubles pouvant entraîner une atteinte partielle ou totale de la motricité, notamment des membres supérieurs et/ou inférieurs. " - }, - { - "question_type": "QCU", - "question": "L'accessibilité numérique est un concept exclusivement français ou francophone.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "L'accessibilité numérique a été pensée dès la création d'Internet.\n \"Le pouvoir du Web est dans son universalité. L’accès pour tous, quel que soit le handicap, est un aspect essentiel.\" \n Tim Berners-Lee, directeur du W3C et inventeur du World Wide Web" - }, + "Gestion de projet": [ { - "question_type": "QCU", - "question": "Quel est le montant de la sanction financière appliquée pour un service en ligne qui ne respecte pas les obligations d'accessibilité numérique ?", - "possible_answers": [ - "Jusqu'à 25 000 €", - "Jusqu'à 50 000 €", - "Jusqu'à 75 000 €" - ], - "true_answers": [ - 2 - ], - "explanation": "Pour un service en ligne et par semestre, la loi prévoit 25 000 € si le statut de conformité RGAA n’est pas affiché sur la page d’accueil et, pour le secteur public, 50 000 € pour défaut d'accessibilité." + "question": "Avez-vous mis l'inclusivité au programme de votre projet ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Quel est le nom de l'autorité de contrôle de l'accessibilité numérique en France ?", - "possible_answers": [ - "La CNIL", - "La DINUM", - "L'ARCOM" - ], - "true_answers": [ - 2 - ], - "explanation": "Il s'agit de l'ARCOM (Autorité de régulation de la communication audiovisuelle et numériququi est une autorité publique indépendante." + "question": "Avez-vous désigné une ou plusieurs personnes référentes sur le sujet de l'inclusivité du service ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Le RGAA est le Référentiel Général d'Amélioration de l'Accessibilité.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Il s'agit du Référentiel Général d'Amélioration de l'Accessibilité, qui définit les critères pour qu'un service numérique soit accessible au personnes handicapées.\n Au niveau international, les WCAG (Web content Accessibility Guidelines) sont les recommandations techniques pour l'accessibilité des contenus web." + "question": "Avez-vous intégré des exigences d'inclusivité à vos cahiers des charges, marchés ou contrats de prestations externes ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Les documents bureautiques sont soumis au RGAA : ?", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Les documents sont analysés par les critères 13.3 et 13.4 du RGAA, pour les structures étant soumises aux obligations d'accessibilité." - }, - { - "question_type": "QCM", - "question": "Une vidéo accessible est une vidéo :", - "possible_answers": [ - "pour laquelle l'utilisateur peut stopper et relancer la lecture", - "avec des sous-titres", - "avec une traduction en LSF (langue des signes)", - "avec une audio-description" - ], - "true_answers": [ - 0, - 1, - 2, - 3 - ], - "explanation": "La traduction en LSF peut être difficile à mettre en place, car l'image de l'interprète doit être incrustée dans la vidéo." - }, - { - "question_type": "QCU", - "question": "Un lecteur d'écran est un logiciel d’assistance technique destiné aux personnes \"empêchées de lire\" (aveugles, malvoyantes, dyslexiques).", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Un lecteur d'écran retranscrit par synthèse vocale et/ou sur un afficheur braille ce qui est affiché sur l'écran d'un ordinateur ou d'un téléphone, et permet d'interagir avec le système d’exploitation et les applications." - }, - { - "question_type": "QCU", - "question": "Dans les écoles informatiques, les formations à l'accessibilité numérique sont obligatoires.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "Les formations à l'accessibilité numérique sont proposées aux étudiants en informatique, mais restent optionnelles à ce jour." - } - ], - "Design": [ - { - "question_type": "QCU", - "question": "Il y a des couleurs à éviter pour garantir l'accessibilité numérique.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "Le manque d'accessibilité d'une couleur vient d'un problème de contraste entre le texte et l'arrière-plan. Ainsi, un texte de couleur jaune sur un fond orange sera peu ou pas accessible. En revanche, un texte de couleur jaune sur fond noir sera suffisamment contrasté." + "question": "Avez-vous fait auditer la conformité RGAA de votre service numérique ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Un dark pattern est un mouvement esthétique incitant à concevoir les services numériques en mode sombre.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "Un dark pattern est une technique de design trompeuse qui manipule les utilisateurs pour les pousser à faire des actions non désirées, comme accepter des frais cachés ou s'abonner à des services" + "question": "Avez-vous identifié vos utilisateurs dès le début du projet ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Quelle est la principale raison d'utiliser des icônes dans une interface utilisateur ?", - "possible_answers": [ - "Permettre la personnalisation des interfaces", - "Décorer et créer un effet visuel attrayant", - "Simplifier la navigation", - "Ajouter des informations supplémentaires au texte" - ], - "true_answers": [ - 2 - ], - "explanation": "\n Les icônes ne sont pas un élément décoratif mais permettent de renforcer visuellement certaines actions et/ou informations." + "question": "Avez-vous mis en place les obligations du RGAA en termes de communication ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Quel principe de design assure que les éléments importants d'une interface sont faciles à trouver et à utiliser ?", - "possible_answers": [ - "Le contraste élevé", - "La hiérarchie visuelle", - "La saturation des couleurs", - "L'utilisation de différentes polices" - ], - "true_answers": [ - 1 - ], - "explanation": "La hiérarchisation visuelle est un concept qui permet d'identifier les éléments présents par ordre de priorité et/ou d'importance relative." + "question": "Avez-vous mobilisé des utilisateurs pour challenger vos idées et productions ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Quelle approche de design implique de créer des maquettes interactives pour tester des idées avant de les finaliser ?", - "possible_answers": [ - "L'observation", - "Le prototypage", - "La charte graphique" - ], - "true_answers": [ - 1 - ], - "explanation": "La phase de prototypage permet de tester certaines idée par un exemple incomplet et non définitif de ce que pourra être le produit ou l'objet final." + "question": "Avez-vous sensibilisé ou formé l'équipe projet sur le thème de l'inclusivité, au-delà de cette session de jeu ?", + "outOf":1 }, { - "question_type": "QCM", - "question": "Quel est le rôle des \"feedbacks\" ?", - "possible_answers": [ - "Informer l’utilisateur des réussites et erreurs", - "Changer certains éléments pour dynamiser l'interface", - "Simplifier les interactions entre l'utilisateur et le service" - ], - "true_answers": [ - 0, - 2 - ], - "explanation": "Un \"feedback\" est un retour visuel et/ou textuel suite à une action réalisée par l'utilisateur permettant d'informer l'utilisateur sur la conséquence de ses actions." + "question": "Avez-vous intégré des 'sachants' (designers, psychologues...) sur le thème de l'inclusivité à l'équipe projet ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Quel est le but principal du \"design responsive\" ?", - "possible_answers": [ - "Créer des designs qui réagissent aux actions de l'utilisateur", - "Assurer que l'interface s'adapte à différentes tailles d'écran et résolutions", - "Ajouter des effets visuels interactifs" - ], - "true_answers": [ - 1 - ], - "explanation": "Un design responsive est un design pensé pour s'adapter aux différentes tailles d'écrans et résolutions tels que les mobiles ou ordinateurs." + "question": "Avez-vous consulté des experts représentant certains de vos publics cibles ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Que signifie \"le design centré sur l'utilisateur\" ?", - "possible_answers": [ - "Concevoir principalement pour les tendances visuelles actuelles", - "Créer des interfaces en fonction des besoins et des retours des utilisateurs finaux", - "Focaliser sur les aspects techniques du produit" - ], - "true_answers": [ - 1 - ], - "explanation": "L'approche \"centrée utilisateur\" se focalise sur une conception basée sur une étude des besoins et habitudes de l'utilisateur." + "question": "Suivez-vous régulièrement votre progression concernant l'inclusivité de votre service ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Quel type d'animation est généralement recommandé pour améliorer l'expérience de l'utilisateur sans le distraire ?", - "possible_answers": [ - "Des animations lentes", - "Aucune animation", - "Des animations subtiles avec un retour sur les actions réalisées" - ], - "true_answers": [ - 2 - ], - "explanation": "Si des animations (éléments en mouvement, transitions) sont présentes au sein des interfaces, il est recommandé que celles-ci soient discrètes et utiles." + "question": "Avez-vous fait les corrections demandées suite à l'audit RGAA ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Quelle est la différence entre \"design inclusif\" et \"design accessible\" ?", - "possible_answers": [ - "Le design inclusif est destiné à tous, le design accessible se concentre sur les personnes handicapées", - "Il n'y a aucune différence, les deux termes sont synonymes" - ], - "true_answers": [ - 0 - ], - "explanation": "Si un design accessible cherche à répondre aux besoins de certains handicaps, un design inclusif cherche à proposer une experience optimale pour tous." + "question": "Si oui, quel est le score de votre audit après corrections ?", + "outOf":-1 } - ], - "Inclusion numérique": [ - { - "question_type": "QCU", - "question": "Se faire accompagner par un professionnel pour résoudre une difficulté avec le numérique est payant.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "C'est généralement gratuit. Vous trouverez la liste des structures d'accompagnement sur https://cartographie.societenumerique.gouv.fr/orientation." - }, + ], + + "Expérience utilisateur": [ { - "question_type": "QCU", - "question": "Après les maladies ordinaires, les troubles psychologiques sont la 2e cause d'arrêt de travail en France.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Les troubles psychologiques sont la 2e cause d'arrêt de travail en France : 20% des arrêts maladie en 2022, contre 11% en 2016. Les troubles psychologiques constituent par ailleurs le principal motif des arrêts longs : 28% en 2022 vs 14% en 2016. Source : Baromètre annuel Absentéisme (Malakoff Humanis)" + "question": "Avez-vous identifié vos utilisateurs et leurs caractéristiques ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Quelle est la proportion des personnes sans domicile fixe équipées d'un smartphone ?", - "possible_answers": [ - "31%", - "51%", - "71%" - ], - "true_answers": [ - 2 - ], - "explanation": "Source : Solinum, 2019" + "question": "Avez-vous rencontré vos utilisateurs ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Quelle proportion de français souffrent de fatigue informationnelle et se sentent donc débordés, épuisés ou oppressés par un flux constant d'information ?", - "possible_answers": [ - "38%", - "54%", - "72%" - ], - "true_answers": [ - 1 - ], - "explanation": "54% des Français déclarent souffrir de fatigue informationnelle, et 38% déclarent en souffrir \"beaucoup\". Source : Fondation Jean Jaurès, 2022." + "question": "Avez-vous analysé l'expérience existante de vos utilisateurs ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Quelle est la tranche d'âge la plus concernée par l'illectronisme ?", - "possible_answers": [ - "Plus de 65 ans", - "Plus de 70 ans", - "Plus de 75 ans" - ], - "true_answers": [ - 2 - ], - "explanation": "L'illectronisme est l'équivalent de l'illettrisme dans le domaine du numérique : la « situation d'une personne ne possédant pas les compétences numériques de base ou ne se servant pas d'Internet ». Les plus de 75 ans sont les plus touchés, avec 61,9 % en situation d'illectronisme. Sources : Insee, 2021, Observatoire des inégalités, 2024" + "question": "Avez-vous défini l'expérience cible de vos utilisateurs avec votre service numérique ?", + "outOf":2 }, { - "question_type": "QCU", - "question": "Il existe un lien entre numérique inclusif et numérique éco-responsable.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "De nombreuses bonnes pratiques d'inclusivité numérique peuvent contribuer à produire un service numérique éco-responsable. Par exemple, le fait d'alléger les contenus pour qu'ils soient lisibles par tous permet de réduire l'impact carbone d'une page web." + "question": "Avez-vous observé vos utilisateurs en situation réelle ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Le droit à une alternative au numérique (ou droit au non numériquexiste pour tous les citoyens français aujourd'hui.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "Le droit au non numérique n'existe pas en tant que tel. Néanmoins, le principe d'égalité d'accès aux services publics induit la possibilité d'y accéder quelque soit le canal d'interaction choisi. Source : vie-publique.fr, 2024" + "question": "Avez-vous représenté vos utilisateurs ?", + "outOf":1 + } + ], + "Interface utilisateur": [ + { + "question": "Avez-vous prototypé vos écrans ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "Combien de Français présentent des difficultés avec le numérique ?", - "possible_answers": [ - "28%", - "48%", - "68%" - ], - "true_answers": [ - 1 - ], - "explanation": "En 2022, 48% des Français ont déclaré rencontrer des difficultés avec le numérique, soit 13% de plus qu'en 2020. Source : Baromètre du numérique 2023" + "question": "Respectez-vous les codes chromatiques pour une utilisation pertinente de la couleur ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "La notion d'inclusion est différente de celle d'intégration : ?", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Dans le cadre de la production d'un service, l'intégration consiste à prévoir une déclinaison de ce service adaptée au public à intégrer, alors que l'inclusion consiste à imaginer un service utilisable par tous les publics." + "question": "Respectez-vous les règles typographiques ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Quelle est, en 2024, la proportion de sites web 100% conformes au RGAA ?", - "possible_answers": [ - "0,6%", - "16%", - "46%" - ], - "true_answers": [ - 0 - ], - "explanation": "25 sites web sur 4147 contrôlés par l'Observatoire de l'Accessibilité Numérique sont totalement conformes au RGAA en septembre 2024. 351 (8%) sont partiellement conformes." + "question": "Vos pictogrammes sont-ils inclusifs ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Qu'est ce qu'Aidants Connect ?", - "possible_answers": [ - "Une application pour les aidants de personnes dépendantes", - "Un outil d'authentification d'un aidant numérique", - "Une application d'assistance numérique à distance" - ], - "true_answers": [ - 1 - ], - "explanation": "Aidants Connect est un outil d'authentification d'un aidant numérique dans le cadre d'un accompagnement. Il sécurise l'action éventuelle de l'aidant sur les données de la personne aidée." + "question": "Représentez-vous la diversité humaine dans vos illustrations ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Un \"dumb phone\" est un téléphone destiné aux personnes ayant des troubles cognitifs.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "Un \"dumb phone\" est, par opposition à un smartphone, un téléphone doté uniquement de fonctions de base (appels, SMS...), généralement simple à utiliser. Le marché des \"dumb phones\" ou \"feature phones\" est en relative croissance." + "question": "Vos mises en page sont-elles homogènes ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Combien de temps faut-il à un utilisateur pour se faire une première impression d'un service numérique ?", - "possible_answers": [ - "50 millisecondes", - "5 secondes", - "5 minutes" - ], - "true_answers": [ - 0 - ], - "explanation": "Source : Taylor & Francis Online, 2006" + "question": "Les élements interactifs de vos écrans sont-ils intuitifs ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Quel est le pourcentage d'utilisateurs qui ne réutiliseront pas un service numérique leur ayant fait vivre une mauvaise expérience ?", - "possible_answers": [ - "28%", - "58%", - "88%" - ], - "true_answers": [ - 2 - ], - "explanation": "Source : \"Why Web Performance Matters\" Gomez, 2011" + "question": "Les éléments visuels de vos écrans sont-ils suffisamment hiérarchisés et espacés ?", + "outOf":4 } ], - "Handicap": [ - { - "question_type": "QCU", - "question": "Une personne handicapée est forcément en situation d'exclusion numérique.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 1 - ], - "explanation": "Si les services numériques respectent les normes d'accessibilité numérique, les personnes handicapées n'ont pas de difficultés à les consulter. De plus, certains types de handicap n'impliquent pas systématiquement une situation d'exclusion numérique." - }, - { - "question_type": "QCU", - "question": "Combien de personnes ont un handicap visuel en France ?", - "possible_answers": [ - "700 000", - "1,7 millions", - "2,7 millions" - ], - "true_answers": [ - 1 - ], - "explanation": "Une personne aveugle ou malvoyante naît toutes les 15 heures. En France, il y a 207 000 aveugles et malvoyants profonds et 932 000 malvoyants moyens (ils ne peuvent distinguer un visage à 4 mètres et la lecture de près est impossible). Source : Fédération des Aveugles de France" - }, - { - "question_type": "QCU", - "question": "Combien de personnes ont un handicap auditif en France ?", - "possible_answers": [ - "Environ 2 millions", - "Environ 4 millions", - "Environ 5 millions" - ], - "true_answers": [ - 2 - ], - "explanation": "En France, 5 182 000 personnes ont un handicap auditif, dont 303 000 souffrent d'une déficience auditive profonde ou totale. Source : Etude Le handicap auditif en France (DREES)" - }, + "Editorial": [ { - "question_type": "QCU", - "question": "L'autisme est un handicap cognitif, au même titre que l'hyperactivité.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Un trouble cognitif correspond à une altération d’une ou plusieurs fonctions cognitives pour une raison neurologique, psychiatrique, médicamenteuse ou génétique. On peut citer par exemple :les TDA (troubles de déficit de l’attention), l'hyperactivité, les troubles DYS, l'autisme, les troubles de la mémoire ou la trisomie 21. Source : Haute Autorité de Santé." + "question": "Utilisez-vous le langage clair ?", + "outOf":1 }, { - "question_type": "QCU", - "question": "La schizophrénie est un handicap psychique.", - "possible_answers": [ - "Vrai", - "Faux" - ], - "true_answers": [ - 0 - ], - "explanation": "Le handicap psychique est la conséquence d'une maladie psychique issue de changements qui affectent la pensée, l'humeur ou le comportement d'une personne, et qui lui causent de la détresse ou de la souffrance. Il n'affecte pas directement les capacités intellectuelles. On peut citer par exemple : les phobies, les addictions, la dépressions, les TOC (troubles obsessionnels compulsifs), les troubles bipolaires ou la schizophrénie. Source : Agefiph." + "question": "Utilisez-vous le langage inclusif ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Quelle est la proportion de personnes daltoniennes en France ?", - "possible_answers": [ - "2% chez les hommes et 1 % chez les femmes", - "5% chez les hommes et 2% chez les femmes", - "8% chez les hommes et 0,45% chez les femmes" - ], - "true_answers": [ - 2 - ], - "explanation": "8% chez les hommes et 0,45% chez les femmes" + "question": "Ecrivez-vous certains textes en FALC (si pertinent) ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Combien de personnes sont en situation de handicap en France ?", - "possible_answers": [ - "2 millions", - "5 millions", - "12 millions", - "17 millions" - ], - "true_answers": [ - 2 - ], - "explanation": "On peut même aller jusqu'à 20 millions en comptant les seniors." + "question": "Vos contenus sont-ils bien structurés ?", + "outOf":4 }, { - "question_type": "QCU", - "question": "Quelle est la proportion des handicaps invisibles dans la population française ?", - "possible_answers": [ - "40%", - "60%", - "80%" - ], - "true_answers": [ - 2 - ], - "explanation": "Soit près de 10 millions de personnes. On peut notamment citer parmi les handicaps invisibles : les handicaps mentaux, les handicaps psychiques, les maladies invalidantes (asthme, allergies, diabète..), les troubles musculosquelettiques (lombalgies, tendinites..), ou les troubles DYS." + "question": "Vos tableaux publiés sont-ils accessibles ?", + "outOf":4 }, { - "question_type": "QCM", - "question": "Parmi les éléments suivants, lesquels sont des troubles spécifiques du langage et des apprentissages (ou troubles DYS) ?", - "possible_answers": [ - "La dysacousie", - "La dyspraxie", - "La dyslexie" - ], - "true_answers": [ - 1, - 2 - ], - "explanation": "La dyspraxie est le trouble de la capacité à exécuter des mouvements déterminés. La dyslexie est le trouble de la lecture. On peut également citer : la dyscalculie : trouble dans les apprentissages numériques; la dysgraphie : difficulté à accomplir les gestes de l'écriture et du dessin; la dysorthographie : également appelé trouble de l'acquisition de l'expression écrite; la dysphasie : trouble lié au développement du langage oral." + "question": "Vos posts sont-ils accessibles ?", + "outOf":4 } - ] - } + ]} } diff --git a/src/app/shared/services/autoeval-service.ts b/src/app/shared/services/autoeval-service.ts new file mode 100644 index 0000000000000000000000000000000000000000..7a863195525edd2b58127dd1c370ccec30a22ce0 --- /dev/null +++ b/src/app/shared/services/autoeval-service.ts @@ -0,0 +1,81 @@ +import { Injectable, signal } from "@angular/core"; +import { autoevalData } from "../../app.component"; +import { AutoevalSegment } from "../types/interfaces"; + +@Injectable({ + providedIn: 'root' +}) +export class DataService { + topics = autoevalData["topics"]; + autoevalSegments = autoevalData["questions"]; + questionNumber = signal(0); + questionNumberTopic = signal(0); + topicNumber = signal(0); + currentSegment = signal<AutoevalSegment | undefined>(undefined); + currentTopic = signal(""); + possibleAnswers = autoevalData["possible_answers"]; + numberOfQuestions = Object.fromEntries(this.topics.map(topic => [topic, this.autoevalSegments[topic].length])); + step = signal(''); + totalQuestions:number = 0 + + + startAutoeval() { + this.step.set('start'); + if (this.topics.length != 0) { + this.currentTopic.set(this.topics[this.topicNumber()]); + } + else { + console.log("Aucun topic n'est défini"); + } + this.currentSegment.set(this.autoevalSegments[this.currentTopic()][this.questionNumber()]); + } + + getNewQuestion() { + this.step.set('ongoing'); + if (this.questionNumberTopic() === this.numberOfQuestions[this.currentTopic()]-1) { + // Si on est à la dernière question du thème + if (this.currentTopic() != this.topics[this.topics.length-1]) { + // Si on est pas au dernier thème + this.questionNumberTopic.set(0); + this.topicNumber.update(n => n + 1); + this.currentTopic.set(this.topics[this.topicNumber()]); + this.currentSegment.set(this.autoevalSegments[this.currentTopic()][this.questionNumberTopic()]); + this.questionNumber.update(n => n + 1); + } + else { + this.step.set('end'); + } + } + else { + this.questionNumberTopic.update(n => n + 1); + this.questionNumber.update(n => n + 1); + this.currentSegment.set(this.autoevalSegments[this.currentTopic()][this.questionNumberTopic()]); + } + } + + getPreviousQuestion() { + if (this.questionNumberTopic() > 0) { + this.questionNumberTopic.update(n => n - 1); + this.currentSegment.set(this.autoevalSegments[this.currentTopic()][this.questionNumberTopic()]); + this.questionNumber.update(n => n - 1); + } + else if (this.topicNumber() > 0) { + this.topicNumber.update(n => n - 1); + this.currentTopic.set(this.topics[this.topicNumber()]); + this.questionNumberTopic.set(this.autoevalSegments[this.currentTopic()].length - 1); + this.currentSegment.set(this.autoevalSegments[this.currentTopic()][this.questionNumberTopic()]); + this.questionNumber.update(n => n - 1); + } + else{ + this.step.set('start'); + } + } + + getTotalQuestions(){ + for (let i =0; i<this.topics.length; i++){ + this.totalQuestions = this.totalQuestions + this.numberOfQuestions[this.topics[i]] + } + return this.totalQuestions + }; +} + diff --git a/src/app/shared/services/progress-service.ts b/src/app/shared/services/progress-service.ts index 3cfc149645fffd06bb40efb8ff69cb7a610761ed..c4ab0ab06593c31d7061ee76cfdc83394232f947 100644 --- a/src/app/shared/services/progress-service.ts +++ b/src/app/shared/services/progress-service.ts @@ -1,92 +1,74 @@ -import { computed, inject, Injectable, signal } from "@angular/core"; +import {inject, Injectable, signal } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; -import { Answer } from "../types/enums"; -import { DataService } from "./quiz-service"; + +import { DataService } from "./autoeval-service"; @Injectable({ providedIn: 'root' }) export class ProgressService { - /* Service qui gère la navigation dans l'application */ router = inject(Router); route = inject(ActivatedRoute); dataService = inject(DataService); - score = signal(0); - questionNumber = signal(0); - currentAnswer = signal<number[]>([]); - currentAnswerValidity = computed(() => this.verifyAnswer()) - hasEnded = signal(false); - answered = signal(false); + currentAnswer = signal<number>(0); + score = signal(Object.fromEntries(this.dataService.topics.map(topic => [topic, [0, 0]]))); + answers = signal(<number[]>[]); goToBegining() { - /* Revient à la page du début, sans oublienpmr les questions déjà posées */ - this.score.set(0); - this.questionNumber.set(0); - this.hasEnded.set(false); - this.router.navigate(["quiz", "accueil"], { onSameUrlNavigation: 'ignore' }); + this.router.navigate(["autoeval", "contexte"], { onSameUrlNavigation: 'ignore' }); } - start(nQuestions: number) { - /* Lance une session de quiz avec le nombre de questions sélectionnées sur la page d'accueil */ - this.score.set(0); - this.questionNumber.set(0); - this.hasEnded.set(false); - this.dataService.startQuiz(nQuestions); - this.goToNext(); + start() { + this.dataService.startAutoeval(); + this.router.navigate(["autoeval", this.dataService.questionNumber().toString()], { + }); } goToEnd() { - /* Envoie sur la page de fin */ - this.hasEnded.set(true); - this.router.navigate(["quiz", "end"], { replaceUrl: true }); + this.router.navigate(["autoeval", "end"], { replaceUrl: true }); } goToNext() { - /* Si la session de quiz n'est pas finie, envoie vers la question suivante */ - if (!this.dataService.isFinished()) { - this.dataService.getNewQuestion(); - this.questionNumber.update(n => n + 1); - this.answered.set(false); - this.router.navigate(["quiz", this.questionNumber().toString()], { - queryParams: { theme: this.dataService.currentTopic(), theme_id: this.dataService.currentQuestionId(), answered: false }, - replaceUrl: this.questionNumber() > 0, + this.dataService.getNewQuestion(); + if (this.dataService.step() !== 'end') { + this.router.navigate(["autoeval", this.dataService.questionNumber().toString()], { }); } else { this.goToEnd(); } } - answer() { - if (this.currentAnswerValidity() === Answer.Empty) { - // Ne passe pas à la question suivante si aucune réponse n'a été sélectionnée - return; - } - if (this.currentAnswerValidity() === Answer.True) { - this.score.update(s => s + 1); + goToPrevious() { + this.dataService.getPreviousQuestion(); + if (this.dataService.step() !== 'start') { + this.router.navigate(["autoeval", this.dataService.questionNumber().toString()], { + }); + } else { + this.goToBegining(); } - this.answered.set(true); - this.router.navigate( - [], - { - relativeTo: this.route, - queryParams: { answered: true }, - queryParamsHandling: 'merge', // remove to replace all query params by provided - replaceUrl: true, - } - ); } - private verifyAnswer(): Answer { - const realAnswers = this.dataService.currentSegment()?.true_answers as number[]; - if (this.currentAnswer().length === 0) { - return Answer.Empty; + answer() { + if (this.currentAnswer() in [0, 1, 2]) { + this.score.update(scores => { + scores[this.dataService.currentTopic()][0] += this.dataService.currentSegment()!.outOf*(1-this.currentAnswer()/2); + scores[this.dataService.currentTopic()][1] += this.dataService.currentSegment()!.outOf; + return scores; + }); } - if (this.currentAnswer().sort().toString() == realAnswers.sort().toString()) { - return Answer.True; - } else { - return Answer.False; + if (this.answers().length === this.dataService.questionNumber()) { + this.answers.update(answers => { + answers.push(this.currentAnswer()); + return answers; + }); } + else{ + this.answers.update(answers => { + answers[this.dataService.questionNumber()] = this.currentAnswer(); + return answers; + }); + } + this.goToNext(); } - } diff --git a/src/app/shared/services/quiz-service.ts b/src/app/shared/services/quiz-service.ts deleted file mode 100644 index c22a891a389a94ebabfc94f2b043332b01003a04..0000000000000000000000000000000000000000 --- a/src/app/shared/services/quiz-service.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Injectable, signal } from "@angular/core"; -import { quizData } from "../../app.component"; -import { QuizSegment } from "../types/interfaces"; - -class RandomizedQuestionIndexQueue { - /* Implémente un tirage aléatoire sans remise des numéros de questions dans un thème - * https://gist.github.com/4skinSkywalker/f10939e0b070fe1815933730670177df - */ - private remainingIndices; - private intialSize; - private currentSize; - constructor(size: number) { - this.intialSize = size; - this.currentSize = size; - this.remainingIndices = [...Array(size).keys()]; - } - - private randomId() { - // conversion en entier avec la comparaison BitWise OR - return Math.random() * (this.currentSize - 1) | 0 - } - - isEmpty() { - return (this.currentSize < 1) - } - - replenish() { - this.remainingIndices = [...Array(this.intialSize).keys()]; - this.currentSize = this.intialSize; - } - - dequeueIndex() { - if (this.isEmpty()) { - this.replenish() - } - const id = this.randomId(); - const index = this.remainingIndices[id]; - this.remainingIndices.splice(id, 1); - this.currentSize--; - return index; - } -} - - -class TopicsQueue { - /* Implémente la queue des thèmes à effectuer selon le nombre de questions et le cycle de thème à aborder */ - private possibleTopics; - private topicsCycle; - private numberOfQuestionsPerCycle = 1; // valeur par défaut - private topics: string[] = []; // queue qui va permettre de tirer les topics - - constructor(possibleTopics: string[] = [], topicsCycle: number[] = []) { - this.possibleTopics = possibleTopics; - this.topicsCycle = topicsCycle; - } - - initialize(nQuestions: number) { - /* Initialise la queue pour une session de quiz */ - this.numberOfQuestionsPerCycle = nQuestions; - this.topics = []; - this.topicsCycle.forEach((n, i) => { // n = occurrence, i = index - this.topics.push(...Array(n * this.numberOfQuestionsPerCycle).fill(this.possibleTopics[i])); - }); - } - - isEmpty() { - return this.topics.length < 1; - } - - deqeue() { - return this.topics.shift(); - } - - getPossibleTopics() { - return this.possibleTopics; - } - - getNumberOfQuestions() { - return this.topicsCycle.length * this.numberOfQuestionsPerCycle; - } -} - -@Injectable({ - providedIn: 'root' -}) -export class DataService { - /* Service qui fournit les données relatives à la question en cours de la session de quiz - * Les questions sont tirées aléatoirement sans remise - * Lorsqu'il n'y a plus de questions non faites, la liste de questions est régénèrée - */ - quizSegmentTopicsQueue; - quizSegments = quizData["questions"]; // tous les segments de quiz possibles, groupés par thème - randomizedQuestionIndexQueuePool: Record<string, RandomizedQuestionIndexQueue> = {} - questionNumber = signal(0); - hasEnded = signal(false); - numberOfQuestions = signal(0); - currentSegment = signal<QuizSegment | undefined>(undefined); - currentTopic = signal(""); - currentQuestionId = signal(-1); - - constructor() { - this.quizSegmentTopicsQueue = new TopicsQueue(quizData["question_topics"], quizData["question_cycle"]); - for (const questionTopic of this.quizSegmentTopicsQueue.getPossibleTopics()) { - const rq = new RandomizedQuestionIndexQueue(this.quizSegments[questionTopic].length); - this.randomizedQuestionIndexQueuePool[questionTopic] = rq; - } - } - - startQuiz(nQuestions: number) { - this.questionNumber.set(0); - this.hasEnded.set(false); - this.quizSegmentTopicsQueue.initialize(nQuestions); - this.numberOfQuestions.set(this.quizSegmentTopicsQueue.getNumberOfQuestions()); - } - - getNewQuestion() { - const questionTopic = this.quizSegmentTopicsQueue.deqeue(); - const questionId = this.randomizedQuestionIndexQueuePool[questionTopic!].dequeueIndex(); - this.currentTopic.set(questionTopic!); - this.currentQuestionId.set(questionId); - this.currentSegment.set(this.quizSegments[questionTopic!][questionId]); - } - - isFinished() { - return this.quizSegmentTopicsQueue.isEmpty(); - } - - getNumberOfTopics() { - return this.quizSegmentTopicsQueue.getPossibleTopics().length; - } -} diff --git a/src/app/shared/types/interfaces.ts b/src/app/shared/types/interfaces.ts index a0c199ae828d9ad7a4915c2ddaffdf86f004eeb3..989280f1152c3345de00d352378a58fc387dc892 100644 --- a/src/app/shared/types/interfaces.ts +++ b/src/app/shared/types/interfaces.ts @@ -1,13 +1,10 @@ -export interface QuizData { - question_topics: string[], - question_cycle: number[], - questions: Record<string, QuizSegment[]>, +export interface AutoevalData { + topics: string[], + possible_answers: string[], + questions: Record<string, AutoevalSegment[]>, } -export interface QuizSegment { - question_type: string, +export interface AutoevalSegment { question: string, - possible_answers: string[] | never[], - true_answers: number[], - explanation: string, + outOf: number, } diff --git a/src/app/views/quiz/quiz-card/quiz-card.component.css b/src/app/views/autoeval/autoeval-card/autoeval-card.component.css similarity index 89% rename from src/app/views/quiz/quiz-card/quiz-card.component.css rename to src/app/views/autoeval/autoeval-card/autoeval-card.component.css index 55981ad66d589ff10acbbade21edc6e701290d76..ea71b74b74f13747f578dfdb7900de4ee7fc64e3 100644 --- a/src/app/views/quiz/quiz-card/quiz-card.component.css +++ b/src/app/views/autoeval/autoeval-card/autoeval-card.component.css @@ -9,6 +9,7 @@ h1 { color: #333333; } + .theme { justify-self: start; background-color: var(--p-primary-100); @@ -20,6 +21,6 @@ h1 { } .question { - text-align: center; - padding: 8px; + text-align: left; + font-size: 24px; } diff --git a/src/app/views/autoeval/autoeval-card/autoeval-card.component.html b/src/app/views/autoeval/autoeval-card/autoeval-card.component.html new file mode 100644 index 0000000000000000000000000000000000000000..791c743162d8838771172b5a02ba4c85157ff0b9 --- /dev/null +++ b/src/app/views/autoeval/autoeval-card/autoeval-card.component.html @@ -0,0 +1,5 @@ +<div class="theme"> + <span> {{ dataService.currentTopic() }}</span> +</div> +<h1 class="question">{{ autoeval_segment()?.question }}</h1> +<app-choice-box></app-choice-box> \ No newline at end of file diff --git a/src/app/views/quiz/quiz-card/quiz-card.component.ts b/src/app/views/autoeval/autoeval-card/autoeval-card.component.ts similarity index 52% rename from src/app/views/quiz/quiz-card/quiz-card.component.ts rename to src/app/views/autoeval/autoeval-card/autoeval-card.component.ts index d82c8c4fce259f1110d937df8c5adac3bafd8f39..9dfce28d6c1d8c443bed9bfe28023739e17744d6 100644 --- a/src/app/views/quiz/quiz-card/quiz-card.component.ts +++ b/src/app/views/autoeval/autoeval-card/autoeval-card.component.ts @@ -1,22 +1,20 @@ import { Component, inject, viewChild } from '@angular/core'; import { ChoiceBoxComponent } from './choice-box/choice-box.component'; import { ProgressService } from '../../../shared/services/progress-service'; -import { DataService } from '../../../shared/services/quiz-service'; +import { DataService } from '../../../shared/services/autoeval-service'; import { Answer } from '../../../shared/types/enums'; -import { AnswerBoxComponent } from "./answer-box/answer-box.component"; @Component({ - selector: 'app-quiz-card', - imports: [ChoiceBoxComponent, AnswerBoxComponent], - templateUrl: './quiz-card.component.html', - styleUrl: './quiz-card.component.css' + selector: 'app-autoeval-card', + imports: [ChoiceBoxComponent], + templateUrl: './autoeval-card.component.html', + styleUrl: './autoeval-card.component.css' }) -export class QuizCardComponent { +export class AutoevalCardComponent { dataService = inject(DataService); progressService = inject(ProgressService); answerType = Answer; - quiz_segment = this.dataService.currentSegment; + autoeval_segment = this.dataService.currentSegment; choiceBox = viewChild(ChoiceBoxComponent); - } diff --git a/src/app/views/quiz/quiz-card/choice-box/choice-box.component.css b/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.css similarity index 73% rename from src/app/views/quiz/quiz-card/choice-box/choice-box.component.css rename to src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.css index da7394ba60bb7c550009aa6e248e44370a3dd90c..7a179f1e438f0c6606df098654a7e66d23f1dc2a 100644 --- a/src/app/views/quiz/quiz-card/choice-box/choice-box.component.css +++ b/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.css @@ -3,24 +3,28 @@ flex-direction: column; height: 100%; width: 100%; - gap: 16px; margin-top: 5%; } .nb-choice { color: #696969; + margin-bottom: 25px; } .answer-box { + position: relative; + bottom: 0px; display: flex; flex-direction: column; gap: 16px; + width: 600px; } -#answer-choice { + +.answer-choice { display: flex; align-content: center; width: 100%; - border: 2px solid #929292; + border: 1px solid #929292; border-radius: 8px; padding: 4px; margin: 0 auto; @@ -47,6 +51,7 @@ --p-radiobutton-icon-checked-hover-color:#333333; --p-radiobutton-border-color:#333333; --p-radiobutton-hover-border-color:#333333; + --p-radiobutton-focus-border-color:#333333; --p-radiobutton-checked-border-color:#333333; --p-radiobutton-checked-hover-border-color:#333333; } @@ -64,14 +69,21 @@ --p-checkbox-checked-hover-background:#333333; } -#answer-choice:hover{ - border: 2px solid #333333; +.answer-choice:hover{ + border: 1px solid #333333; + cursor: pointer; box-shadow: rgba(0, 0, 0, 0.1) 0px 12px 24px 0px; } -#answer-choice:has(:checked) { - border: 2px solid #DA3635; +.answer-choice:has(:checked) { + border: 1px solid #DA3635; + box-shadow: + rgba(0, 0, 0, 0.1) 0px 12px 24px 0px; +} + +.answer-choice:has(:focus) { + border: 1px solid #DA3635; box-shadow: rgba(0, 0, 0, 0.1) 0px 12px 24px 0px; } @@ -81,7 +93,7 @@ vertical-align: middle; align-items: middle; text-align: middle; - font-size: 1.5em; + font-size: 16px; } .div-error{ @@ -91,10 +103,18 @@ align-content: center; vertical-align: middle; color:#333333; + margin-top: 5px; } .bouton-error{ - --p-button-padding-x: 64px; + --p-button-primary-active-background: #ff5d5c; + --p-button-primary-hover-background: #cd2524; + --p-button-primary-active-border-color: #ff5d5c; + --p-button-primary-hover-border-color: #cd2524; +} + +::ng-deep .bouton-error button { + width: 150px; /* Force the width */ } .p-error{ diff --git a/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.html b/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.html new file mode 100644 index 0000000000000000000000000000000000000000..a1830e30234887541d839c0f3f3bab47ecc9356a --- /dev/null +++ b/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.html @@ -0,0 +1,25 @@ +<p class="nb-choice">Une seule réponse possible</p> + + +<form [formGroup]="answerForm"> + <div class="answer-box"> + @for (choice of dataService.possibleAnswers; track $index) { + <label class="answer-choice"> + <p-radiobutton [value]="$index" formControlName="selectedAnswer" class="radio"/> + <p class="choice-text">{{ choice }}</p> + </label> + } + </div> +</form> + +<p-dialog + header="Veuillez choisir au moins une option." + [modal]="false" + [closable]="false" + [(visible)]="dialogVisible" + class="p-error" +> + <div class="div-error"> + <p-button label="Ok" (click)="dialogVisible = false" class ="bouton-error"/> + </div> +</p-dialog> diff --git a/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.ts b/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..89629ef8d9e2cbc9a25828bff8450aa141a77b79 --- /dev/null +++ b/src/app/views/autoeval/autoeval-card/choice-box/choice-box.component.ts @@ -0,0 +1,46 @@ +import { Component, effect, inject, Input } from '@angular/core'; +import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { RadioButtonModule } from 'primeng/radiobutton'; +import { CheckboxModule } from 'primeng/checkbox'; +import { ProgressService } from '../../../../shared/services/progress-service'; +import { DataService } from '../../../../shared/services/autoeval-service'; +import { DialogModule } from 'primeng/dialog'; +import { ButtonModule } from 'primeng/button'; + +@Component({ + selector: 'app-choice-box', + imports: [ReactiveFormsModule, RadioButtonModule, CheckboxModule, DialogModule, ButtonModule], + templateUrl: './choice-box.component.html', + styleUrl: './choice-box.component.css' +}) +export class ChoiceBoxComponent { + answerForm = new FormGroup({ + selectedAnswer: new FormControl<number | null>(null) + }); + progressService = inject(ProgressService); + dataService = inject(DataService); + dialogVisible = false; + + constructor() { + effect(() => { + const selected = this.progressService.answers()[this.dataService.questionNumber()]; + this.answerForm.get('selectedAnswer')?.setValue(selected); + }); + } + + ngOnInit() { + this.answerForm!.reset(); + } + answer() { + const key = this.answerForm.value.selectedAnswer; + if (key != null) { + this.progressService.currentAnswer.set(key); + this.progressService.answer(); + this.answerForm.reset(); + } + else { + this.dialogVisible = true; + } + } +} + diff --git a/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.css b/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.css new file mode 100644 index 0000000000000000000000000000000000000000..4121e61c59cf3daef0dd75d2e1a10445c49ab65d --- /dev/null +++ b/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.css @@ -0,0 +1,65 @@ +:host { + display: flex; + flex-direction: column; + text-align: center; + justify-content: space-between; + height: 100%; + width: 100%; + margin: auto; +} + +.container{ + width: 600px; + align-self: anchor-center; + text-align: left; +} + +.container h1 { + font-size: 28px; + font-weight: normal; + margin-top: 25px; +} + +.container h3 { + font-size: 24px; + font-weight: normal; + margin-top: 20px; + margin-bottom: 20px; +} + +.container p{ + font-size: 16px; + padding: 5px; +} + +.container li { + margin:5px; +} + +.lower-section{ + display: flex; + flex-direction: column; + align-items: center; + margin-top: auto; + width: 100%; + position: relative; + bottom:0px; +} + +p-divider{ + margin: 0; + padding-bottom: 40px; + width:80%; +} + +::ng-deep .avance-button button { + width: 150px; /* Force the width */ + height: 40px; /* Force the height */ +} + +.avance{ + --p-button-primary-active-background: #ff5d5c; + --p-button-primary-hover-background: #cd2524; + --p-button-primary-active-border-color: #ff5d5c; + --p-button-primary-hover-border-color: #cd2524; +} diff --git a/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.html b/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.html new file mode 100644 index 0000000000000000000000000000000000000000..40fbbebc112dd8056942d7751829cf8239441cad --- /dev/null +++ b/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.html @@ -0,0 +1,29 @@ +<div class="container"> + <h1>Auto-évaluation Inclusivité</h1> + <h3>A propos de l’auto-évaluation</h3> + <p>Ce support d'auto-évaluation est utilisé par l'équipe inclusivité pour attribuer un score chiffré puis un label de A à E aux services numériques de la Métropole de Lyon.</p> + + <ul> + <li>Certaines questions sont à poser au chef de projet.</li> + <li>Certaines questions peuvent être étudiées en autonomie par l'équipe inclusivité.</li> + <li>Le score est présenté dans l'onglet SCORE par domaine et au total, sous forme de chiffre et de lettre pour le label.</li> + <li>Le score obtenu doit être présenté et expliqué au chef de projet et éventuellement reconsidéré avant publication dans COGITO.</li> + <li>Le fichier d'auto-évaluation validé par l'équipe et le chef de projet doit être déposé sur le réseau pour capitalisation.</li> + <li>Le bonus RGAA est attribué comme tel : Taux de conformité de 0 à 49 : 0 point / de 50 à 74 : 2 points / de 75 à 89 : 4 points / de 90 à 100 : 8 points</li> + </ul> +</div> + +<div class="lower-section"> + <p-divider/> + + <!-- Bouton pour démarrer le jeu --> + <div class = "avance-button"> + <p-button + class = "avance" + (click)="continuer()" + aria-label="Commencer le Jeu" + label = "C'est parti" + severity="primary"> + </p-button> + </div> +</div> diff --git a/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.ts b/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b8455d243bdaf961f09947d5700013a1f3aeab1 --- /dev/null +++ b/src/app/views/autoeval/autoeval-contexte/autoeval-contexte.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import {Router } from '@angular/router'; +import { ButtonModule } from 'primeng/button'; +import { ProgressService } from '../../../shared/services/progress-service'; +import { Divider } from 'primeng/divider'; + +@Component({ + selector: 'app-autoeval-contexte', + templateUrl: './autoeval-contexte.component.html', + styleUrl: './autoeval-contexte.component.css', + imports: [ButtonModule, Divider] +}) +export class ContexteComponent { + constructor(private router:Router, private progressService:ProgressService) {} + continuer(){ + this.progressService.start(); + } +} diff --git a/src/app/views/quiz/quiz-endpage/quiz-endpage.component.css b/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.css similarity index 100% rename from src/app/views/quiz/quiz-endpage/quiz-endpage.component.css rename to src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.css diff --git a/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.html b/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.html new file mode 100644 index 0000000000000000000000000000000000000000..fe38323a7d5cc2f78aa01ec02a9e99f60d296972 --- /dev/null +++ b/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.html @@ -0,0 +1,62 @@ +<div> + <h1>L'auto-évaluation est finie</h1> + <p> + Vous avez obtenus les scores suivants : + <br /> + @for (topic of dataService.topics; track $index){ + {{ topic }} : {{ progressService.score()[topic][0] }} / {{ progressService.score()[topic][1] }} + <br /> + } + </p> + + <!-- Mise en place du grade an fonction du score obtenu : + - score < 0.2 - Grade E + - 0.2 <= score <0.5 - Grade D + - 0.5 <= score <0.7 - Grade C + - 0.7 <= score <0.9 - Grade B + - 0.9 <= score <= 1 - Grade A + --> + <div class = "grade"> + <p style ="margin-top:50px;">Votre grade est </p> + @if (get_score() < 0.2){ + <p-image + src="images/Score_E.png" + alt="Le grade du Quiz est E." + [imageStyle]="{ objectFit: 'contain' }" + width="20%" + /> + } + @else if (get_score() < 0.5) { + <p-image + src="images/Score_D.png" + alt="Le grade du Quiz est D." + [imageStyle]="{ objectFit: 'contain' }" + width="20%" + /> + } + @else if (get_score() < 0.7) { + <p-image + src="images/Score_C.png" + alt="Le grade du Quiz est C." + [imageStyle]="{ objectFit: 'contain' }" + width="20%" + /> + } + @else if (get_score() < 0.9) { + <p-image + src="images/Score_B.png" + alt="Le grade du Quiz est B." + [imageStyle]="{ objectFit: 'contain' }" + width="20%" + /> + } + @else { + <p-image + src="images/Score_A.png" + alt="Le grade du Quiz est A." + [imageStyle]="{ objectFit: 'contain' }" + width="20%" + /> + } + </div> +</div> \ No newline at end of file diff --git a/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.ts b/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b2be33d0877ea918132f6b9da290981220b4979 --- /dev/null +++ b/src/app/views/autoeval/autoeval-endpage/autoeval-endpage.component.ts @@ -0,0 +1,28 @@ +import { Component, inject } from '@angular/core'; +import { ProgressService } from '../../../shared/services/progress-service'; +import { ButtonModule } from 'primeng/button'; +import { DataService } from '../../../shared/services/autoeval-service'; +import { ImageModule } from 'primeng/image'; + +@Component({ + selector: 'app-autoeval-endpage', + imports: [ButtonModule, ImageModule], + templateUrl: './autoeval-endpage.component.html', + styleUrl: './autoeval-endpage.component.css' +}) +export class AutoevalEndpageComponent { + progressService = inject(ProgressService); + dataService = inject(DataService); + sum_of_points:number = 0; + sum_of_max_points:number = 0; + score:number = 0; + + get_score() { + for (var topic of this.dataService.topics) { + this.sum_of_points = this.progressService.score()[topic][0]; + this.sum_of_max_points = this.progressService.score()[topic][1]; + } + this.score = this.sum_of_points/this.sum_of_max_points; + return this.score; + } +} diff --git a/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.css b/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.css new file mode 100644 index 0000000000000000000000000000000000000000..8770d9845d426ad6a06d87d67a0b3b814811e77e --- /dev/null +++ b/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.css @@ -0,0 +1,63 @@ +:host { + display: flex; + flex-direction: column; + text-align: center; + justify-content: space-between; + align-content: center; + height: 100%; + width: 80%; + margin: auto; +} + +.presentation-section { + display: flex; + position: relative; + flex-direction: column; + align-content: center; + height: 100%; + width: 100%; +} + +.presentation-section h1 { + font-size: 28px; + font-weight: normal; +} +.presentation-section h2 { + font-size: 24px; + font-weight: normal; + margin-bottom: 50px; +} + +.presentation-section p { + font-size: 16px; + font-weight: normal; + margin-top: 25px; +} + +.lower-section{ + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.start-div { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; +} + +p-divider{ + margin: 0; + padding-bottom: 40px; + width:100%; +} + +::ng-deep .start-game-button button { + width: 150px; /* Force the width */ + height: 40px; /* Force the height */ +} \ No newline at end of file diff --git a/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.html b/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.html new file mode 100644 index 0000000000000000000000000000000000000000..1bdec7c7c06bd4c80c1eb7cc851bb1851c801859 --- /dev/null +++ b/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.html @@ -0,0 +1,25 @@ +<div class="presentation-section"> + <h1>Auto-évaluation inclusisivité</h1> + <h2>Concevons nos services numériques pour tout le monde !</h2> + <p-image + src="images/banner.png" + alt="Image de présentation du autoeval" + [imageStyle]="{ objectFit: 'contain' }" + width="90%" + /> + <p> + Ce support d'auto-évaluation est utilisé par l'équipe inclusivité pour attribuer un score chiffré puis un label de A à E aux services numériques de la Métropole de Lyon. + + </p> +</div> +<div class="lower-section"> + <p-divider /> + <div class="start-div"> + <p-button + class="start-game-button" + (click)="continuer()" + > + Passer à l'action + </p-button> + </div> +</div> \ No newline at end of file diff --git a/src/app/views/quiz/quiz-homepage/quiz-homepage.component.ts b/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.ts similarity index 52% rename from src/app/views/quiz/quiz-homepage/quiz-homepage.component.ts rename to src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.ts index 84388b2abf7564f4c803ec4d5be1a2d6cbc5490b..342b96b67fe017957911a78e816a776bbdf0f288 100644 --- a/src/app/views/quiz/quiz-homepage/quiz-homepage.component.ts +++ b/src/app/views/autoeval/autoeval-homepage/autoeval-homepage.component.ts @@ -6,33 +6,26 @@ import { ImageModule } from 'primeng/image'; import { InputNumberModule } from 'primeng/inputnumber'; import { PanelModule } from 'primeng/panel'; import { ProgressService } from '../../../shared/services/progress-service'; -import { DataService } from '../../../shared/services/quiz-service'; +import { DataService } from '../../../shared/services/autoeval-service'; +import { Router } from '@angular/router'; @Component({ - selector: 'app-quiz-homepage', + selector: 'app-autoeval-homepage', imports: [ButtonModule, DividerModule, PanelModule, InputNumberModule, BlockUIModule, ImageModule], - templateUrl: './quiz-homepage.component.html', - styleUrl: './quiz-homepage.component.css' + templateUrl: './autoeval-homepage.component.html', + styleUrl: './autoeval-homepage.component.css' }) -export class QuizHomepageComponent { - /* Page de présentation du quiz +export class AutoevalHomepageComponent { + /* Page de présentation de l'auto-évaluation * Permet la séléction du nombre de questions par multiples de la longueur du cycle de thèmes */ progressService = inject(ProgressService); dataService = inject(DataService); - numberOfTopics = this.dataService.getNumberOfTopics(); - possibleNumberOfQuestionsPerTopic = [1, 2, 3]; - iNumberOfQuestions = 0; - constructor( - ) { - // Au chargement du site, cette page est affichée, - // si l'URL n'est pas celle de la page de départ, elle est redirigée - this.progressService.goToBegining(); - } + constructor(private router:Router) {} - adjustNumberOfQuestions(c: number) { - this.iNumberOfQuestions += c; + continuer(){ + this.router.navigate(['/autoeval/contexte']) } } diff --git a/src/app/views/autoeval/autoeval.component.css b/src/app/views/autoeval/autoeval.component.css new file mode 100644 index 0000000000000000000000000000000000000000..77a8581426eda53b45f2ed695f5797b18ea344f6 --- /dev/null +++ b/src/app/views/autoeval/autoeval.component.css @@ -0,0 +1,240 @@ +:host { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; +} + +.autoeval { + display: flex; + flex-direction: column; + height: 100%; + width: 80%; + margin: auto; + align-items: center; + justify-content: start; +} + +.progress { + width: 100%; + margin: 2% auto; + display: grid; + grid-template-columns: fit-content(100%) auto; + column-gap: 2%; + row-gap: 0%; + align-items: center; + color: var(--p-primary-500); +} + +.question-text { + grid-column-start: 2; + padding: 0 0 0 2%; + margin: 0; +} + +.lower-section{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-top: auto; + position: relative; + bottom:0em; + width: 100%; +} + +.start-div { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} + + +.suivant-page{ + margin-left: 16px; + margin-right: 16px; + --p-button-primary-active-background: #ff5d5c; + --p-button-primary-hover-background: #cd2524; + --p-button-primary-active-border-color: #ff5d5c; + --p-button-primary-hover-border-color: #cd2524; +} + +.retour-page{ + margin-left: 16px; + margin-right: 16px; + --p-button-primary-active-background: #f4f4f4; + --p-button-primary-hover-background: #e9e9e9; +} + +::ng-deep .retour-page button { + width: 150px; /* Force the width */ +} + +::ng-deep .suivant-page button { + width: 150px; /* Force the width */ +} + + +.theme-indicator-container { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + width: 1000px; + margin-top: 25px; + margin-bottom: 20px; +} + +.ProgressBar { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + width: 80%; +} + +.ProgressBar li { + display: table-cell; + text-align: center; + position: relative; + width: 100%; +} + +.ProgressBar-wellFill { + border-radius: 10%; + background-color: #BDBDBD; + display: block; + height: 5px; + position: relative; + width: 100%; + top: -35px; + left: 50%; +} + +.ProgressBar-icon { + width: 20px; + height: 20px; + background-color: #ffffff; + border-radius: 50%; + border: 4px solid #BDBDBD; + max-width: 100%; + z-index: 10; + position: relative; + transition: all .25s ease-out; +} + +.ProgressBar-span { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + position: relative; + background-color: #E9E9E9; + width: fit-content; + height: fit-content; + border-radius: 4px; + margin: auto; + padding: 2px 5px 2px 5px; +} + +.ProgressBar-stepLabel { + font-size: 15px; + color: #696969; + width: 100%; + transition: all .25s ease-out; +} + +.ProgressBar-wellFill-now{ + border-radius: 10%; + background-color: #DA3635; + height: 5px; +} + +.ProgressBar-icon-now { + width: 20px; + height: 20px; + background-color: #ffffff; + border-radius: 50%; + border: 4px solid #DA3635; + max-width: 100%; + z-index: 10; + position: relative; + transition: all .25s ease-out; +} + +.ProgressBar-span-now { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + position: relative; + background-color: #FFE5E4; + width: fit-content; + height: fit-content; + border-radius: 4px; + margin: auto; + padding: 2px 5px 2px 5px; +} + +.ProgressBar-stepLabel-now { + font-size: 15px; + color: #DA3635; + width: 100%; + transition: all .25s ease-out; +} + +.ProgressBar-wellFill-before{ + border-radius: 10%; + background-color: #1D8844; + display: block; + height: 5px; + position: relative; + width: 100%; + top: -35px; + left: 50%; +} + +.ProgressBar-icon-before { + width: 20px; + height: 20px; + background-color: #1D8844; + border-radius: 50%; + max-width: 100%; + z-index: 10; + position: relative; + transition: all .25s ease-out; +} + +.ProgressBar-span-before { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + position: relative; + background-color: #EEFFE4; + width: fit-content; + height: fit-content; + border-radius: 4px; + margin: auto; + padding: 2px 5px 2px 5px; +} + + +.ProgressBar-stepLabel-before { + font-size: 15px; + color: #1D8844; + width: 100%; + transition: all .25s ease-out; +} + +.ProgressBar-wellFill-void{ + border-radius: 10%; + background-color: #ffffff; + display: block; + height: 5px; + position: relative; + width: 100%; + top: -35px; + left: 50%; +} \ No newline at end of file diff --git a/src/app/views/autoeval/autoeval.component.html b/src/app/views/autoeval/autoeval.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d24400b325429a074e6c73f41dc6471cf22b9b0c --- /dev/null +++ b/src/app/views/autoeval/autoeval.component.html @@ -0,0 +1,100 @@ +<!-- Mise en place soit de la page de garde, soit de la page de fin ou alors des cartes questions --> +@if (dataService.step() == "end") { + <app-autoeval-endpage></app-autoeval-endpage> +} +@else { + <div class="autoeval"> + + <div class="theme-indicator-container"> + <ol class="ProgressBar"> + <!-- Boucle sur chaque catégorie pour afficher les étapes de progression --> + @for (categorie of categories; track $index) { + <!-- Vérifie si la catégorie actuelle correspond à la catégorie de la carte --> + @if (cat() === categorie) { + <li class="ProgressBar"> + <!-- Icône de progression actuelle --> + <svg class="ProgressBar-icon-now"><use xlink:href="#checkmark-bold"/></svg> + <div class="ProgressBar-span-now"> + <!-- Affiche le nom de la catégorie actuelle --> + <span class="ProgressBar-stepLabel-now">{{categories[$index]}}</span> + </div> + <div class="ProgressBar-wellFill"> + <!-- Barre de progression pour la catégorie actuelle --> + <div class="ProgressBar-wellFill-now" [style.width.%]="percentage()"> + <span class="void"></span> + </div> + </div> + </li> + } + <!-- Vérifie si l'index de la catégorie est inférieur à l'index de la catégorie actuelle --> + @else if ($index < index_cat()) { + <li class="ProgressBar"> + <!-- Icône de progression précédente --> + <svg class="ProgressBar-icon-before"><use xlink:href="#checkmark-bold"/></svg> + <div class="ProgressBar-span-before"> + <!-- Affiche le nom de la catégorie précédente --> + <span class="ProgressBar-stepLabel-before">{{categories[$index]}}</span> + </div> + <div class="ProgressBar-wellFill-before"> + <span class="void"></span> + </div> + </li> + } + <!-- Pour toutes les autres catégories --> + @else { + <li class="ProgressBar"> + <!-- Icône de progression future --> + <svg class="ProgressBar-icon"><use xlink:href="#checkmark-bold"/></svg> + <div class="ProgressBar-span"> + <!-- Affiche le nom de la catégorie future --> + <span class="ProgressBar-stepLabel">{{categories[$index]}}</span> + </div> + <div class="ProgressBar-wellFill"> + <span class="void"></span> + </div> + </li> + } + } + + <!-- Dernière étape de la progression --> + <li class="ProgressBar"> + <svg class="ProgressBar-icon"><use xlink:href="#checkmark-bold"/></svg> + <div class="ProgressBar-span"> + <!-- Affiche "Fin" pour indiquer la fin de la progression --> + <span class="ProgressBar-stepLabel"> Fin </span> + </div> + <div class="ProgressBar-wellFill-void"> + <span class="void"></span> + </div> + </li> + </ol> + </div> + + + <!-- Mise en place des cartes de l'auto-évaluation --> + <app-autoeval-card></app-autoeval-card> + + <!-- Mise en place des boutons pour avancer dans l'auto-évaluation --> + <div class="lower-section"> + <p-divider class="divider" /> + + <div class="start-div"> + <p-button + class="retour-page" + (click)="back()" + severity="secondary" + variant="outlined"> + <i class="pi pi-arrow-left"></i> + Retour + </p-button> + <p-button + class="suivant-page" + (click)="autoevalCard()!.choiceBox()!.answer()" + severity="primary"> + Suivant + <i class="pi pi-arrow-right"></i> + </p-button> + </div> + </div> + </div> +} diff --git a/src/app/views/autoeval/autoeval.component.ts b/src/app/views/autoeval/autoeval.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac830302cb8f7c0e74c18999e7e1039bb7eb4a2f --- /dev/null +++ b/src/app/views/autoeval/autoeval.component.ts @@ -0,0 +1,31 @@ +import { CommonModule } from '@angular/common'; +import { Component, computed, inject, viewChild } from '@angular/core'; +import { ButtonModule } from 'primeng/button'; +import { DividerModule } from 'primeng/divider'; +import { ProgressBarModule } from 'primeng/progressbar'; +import { ToastModule } from 'primeng/toast'; +import { ProgressService } from '../../shared/services/progress-service'; +import { DataService } from '../../shared/services/autoeval-service'; +import { AutoevalCardComponent } from './autoeval-card/autoeval-card.component'; +import { AutoevalEndpageComponent } from './autoeval-endpage/autoeval-endpage.component'; + +@Component({ + selector: 'app-autoeval', + templateUrl: './autoeval.component.html', + styleUrl: './autoeval.component.css', + imports: [CommonModule, ButtonModule, ToastModule, AutoevalCardComponent, ProgressBarModule, DividerModule, AutoevalEndpageComponent] +}) + +export class AutoevalComponent { + progressService = inject(ProgressService); + dataService = inject(DataService); + autoevalCard = viewChild(AutoevalCardComponent); + cat = computed(() => this.dataService.currentTopic()); // Nom de la catégorie actuelle + index_cat = computed(() => this.categories.indexOf(this.cat())); // Index de la catégorie actuelle + percentage = computed(() => this.dataService.questionNumberTopic() / this.dataService.numberOfQuestions[this.dataService.currentTopic()]*100); // Pourcentage de progression + categories: string[] = this.dataService.topics; // Liste des catégories + + back(){ + this.progressService.goToPrevious() + } +} diff --git a/src/app/views/navbar/navbar.component.css b/src/app/views/header/header.component.css similarity index 67% rename from src/app/views/navbar/navbar.component.css rename to src/app/views/header/header.component.css index 45d02c0093f1c19f625fdc4be46982d9d1a0d408..755aa6e51a62fe19d58bb48d9fca84528754f98d 100644 --- a/src/app/views/navbar/navbar.component.css +++ b/src/app/views/header/header.component.css @@ -12,16 +12,22 @@ font-weight: normal; text-overflow: ellipsis; white-space: nowrap; - padding: 16px; - font-size: 15px; + padding: 2px; + font-size: 16px; color: var(--p-gray-700); } -a { +.intlogo { text-decoration: none; + margin: 1px 1px 0px 53px; } -.intlogo{ - padding: 1px 30px 0px 53px; +.title-link { + text-decoration: none; +} + +.logo{ + width: 105px; + padding: 1px 1px 0px 53px; color: #696969; } diff --git a/src/app/views/navbar/navbar.component.html b/src/app/views/header/header.component.html similarity index 51% rename from src/app/views/navbar/navbar.component.html rename to src/app/views/header/header.component.html index 6864dffabb6ec29bcb145eb4a80c35ac5a27a42c..c51d7c0a44bca03cb07f2b11fcf648e49e7e45bd 100644 --- a/src/app/views/navbar/navbar.component.html +++ b/src/app/views/header/header.component.html @@ -1,15 +1,16 @@ <a href="https://inclusivite-resin.grandlyon.com/" target="_blank" rel="noopener noreferrer" class="intlogo"> <p-image src="images/resin.svg" - alt="Image de présentation du quiz" + alt="Image de présentation de l'auto-évaluation" class="logo" - [width] = "'120px'" + [width] = "'116px'" /> </a> -<div class="navbar-divider"> + +<div class="header-divider"> <p-divider layout="vertical" /> </div> -<a href="quiz/accueil"> - <h1 class="title">Quiz : Inclusif, le jeu</h1> -</a> +<a href="autoeval/accueil" class="title-link"> + <h1 class="title">Inclusif, le jeu</h1> +</a> \ No newline at end of file diff --git a/src/app/views/navbar/navbar.component.ts b/src/app/views/header/header.component.ts similarity index 59% rename from src/app/views/navbar/navbar.component.ts rename to src/app/views/header/header.component.ts index a30e88bd46bc1a2204a582e14c920afc2cedc2ac..1d8111dc0437047446bf24ab058be103b2c46f33 100644 --- a/src/app/views/navbar/navbar.component.ts +++ b/src/app/views/header/header.component.ts @@ -3,11 +3,11 @@ import { DividerModule } from 'primeng/divider'; import { ImageModule } from 'primeng/image'; @Component({ - selector: 'app-navbar', + selector: 'app-header', imports: [ImageModule, DividerModule], - templateUrl: './navbar.component.html', - styleUrl: './navbar.component.css' + templateUrl: './header.component.html', + styleUrl: './header.component.css' }) -export class NavbarComponent { +export class HeaderComponent { } diff --git a/src/app/views/quiz/quiz-card/answer-box/answer-box.component.css b/src/app/views/quiz/quiz-card/answer-box/answer-box.component.css deleted file mode 100644 index 49f80d4b3c44a828bbe52b6d427daf41aeb970f5..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-card/answer-box/answer-box.component.css +++ /dev/null @@ -1,62 +0,0 @@ -:host { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; - margin-top: 5%; -} - -.answer-box { - display: flex; - flex-direction: column; - gap: 16px; -} -.answer-choice { - display: flex; - align-content: center; - width: 100%; - border: 2px solid black; - border-radius: 8px; - padding: 4px; - align-items: center; - vertical-align: middle; - word-wrap: break-word; - color: #333333; -} - -.explanation { - font-size: 1.2em; - white-space : pre-line; - color: #333333; -} - -.choice-text { - font-size: 1.5em; -} - -i { - font-size: 24px; - padding-left: 15px; - padding-right: 15px; -} - -.correct { - border-color: var(--p-green-500); -} -.correct i { - color: var(--p-green-500); -} - -.wrong { - border-color: var(--p-red-500); -} -.wrong i { - color: var(--p-red-500); -} - -.neutral { - border-color: var(--p-gray-500); -} -.neutral i { - color: var(--p-gray-500); -} diff --git a/src/app/views/quiz/quiz-card/answer-box/answer-box.component.html b/src/app/views/quiz/quiz-card/answer-box/answer-box.component.html deleted file mode 100644 index 33c579bd7f9069e8cbed9c00be71cb2cbd7e4803..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-card/answer-box/answer-box.component.html +++ /dev/null @@ -1,27 +0,0 @@ -<div class="answer-box"> - @for (choice of quiz_segment.possible_answers; track $index) { - @if (quiz_segment.true_answers.includes($index)) { - <label class="answer-choice correct"> - <i class="pi pi-check-circle"></i> - <p class="choice-text"> - {{ choice }} - </p> - </label> - } @else if (progressService.currentAnswer().includes($index)) { - <label class="answer-choice wrong"> - <i class="pi pi-times-circle"></i> - <p class="choice-text"> - {{ choice }} - </p> - </label> - } @else { - <label class="answer-choice neutral"> - <i class="pi pi-circle"></i> - <p class="choice-text"> - {{ choice }} - </p> - </label> - } - } - <span class="explanation">{{ quiz_segment.explanation }}</span> -</div> diff --git a/src/app/views/quiz/quiz-card/answer-box/answer-box.component.ts b/src/app/views/quiz/quiz-card/answer-box/answer-box.component.ts deleted file mode 100644 index d7bd5d98eb47a8981fa6d9e3f3c549edade05bdb..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-card/answer-box/answer-box.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, inject } from "@angular/core"; -import { DataService } from "../../../../shared/services/quiz-service"; -import { ProgressService } from "../../../../shared/services/progress-service"; -import { RadioButtonModule } from 'primeng/radiobutton'; -import { CheckboxModule } from 'primeng/checkbox'; -import { ReactiveFormsModule } from "@angular/forms"; - -@Component({ - selector: 'app-answer-box', - imports: [ReactiveFormsModule, RadioButtonModule, CheckboxModule], - templateUrl: './answer-box.component.html', - styleUrl: './answer-box.component.css' -}) -export class AnswerBoxComponent { - dataService = inject(DataService); - progressService = inject(ProgressService); - quiz_segment = this.dataService.currentSegment()!; -} - diff --git a/src/app/views/quiz/quiz-card/choice-box/choice-box.component.html b/src/app/views/quiz/quiz-card/choice-box/choice-box.component.html deleted file mode 100644 index efe28b0e1b583691e8382b8811425db388f521e4..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-card/choice-box/choice-box.component.html +++ /dev/null @@ -1,33 +0,0 @@ -@if (quiz_segment()?.question_type === "QCM") { - <p class="nb-choice">Plusieurs réponses possibles</p> -} @else if (quiz_segment()?.question_type === "QCU") { - <p class="nb-choice">Une seule réponse possible</p> -} -<form [formGroup]="answerForm"> - <div class="answer-box"> - @for (choice of quiz_segment()?.possible_answers; track $index) { - <label id="answer-choice" class = "flex items-center gap-2"> - @if (quiz_segment()?.question_type === "QCM") { - <p-checkbox [value]="$index" [formControlName]="'QCM'" size="large" class = "check" /> - } @else if (quiz_segment()?.question_type === "QCU") { - <p-radiobutton [value]="$index" [formControlName]="'QCU'" class="radio"/> - } - <p class="choice-text"> - {{ choice }} - </p> - </label> - } - </div> -</form> - -<p-dialog - header="Veuillez choisir au moins une option." - [modal]="false" - [closable]="false" - [(visible)]="dialogVisible" - class="p-error" -> - <div class="div-error"> - <p-button label="Ok" (click)="dialogVisible = false" class ="bouton-error"/> - </div> -</p-dialog> diff --git a/src/app/views/quiz/quiz-card/choice-box/choice-box.component.ts b/src/app/views/quiz/quiz-card/choice-box/choice-box.component.ts deleted file mode 100644 index e8a2eb5d1c2ef8ade19685a10cb237e438a95a8b..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-card/choice-box/choice-box.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, computed, inject, Input } from '@angular/core'; -import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { RadioButtonModule } from 'primeng/radiobutton'; -import { CheckboxModule } from 'primeng/checkbox'; -import { ProgressService } from '../../../../shared/services/progress-service'; -import { DataService } from '../../../../shared/services/quiz-service'; -import { DialogModule } from 'primeng/dialog'; -import { ButtonModule } from 'primeng/button'; -import { Answer } from '../../../../shared/types/enums'; - -@Component({ - selector: 'app-choice-box', - imports: [ReactiveFormsModule, RadioButtonModule, CheckboxModule, DialogModule, ButtonModule], - templateUrl: './choice-box.component.html', - styleUrl: './choice-box.component.css' -}) -export class ChoiceBoxComponent { - @Input() answered: boolean | undefined; - answerForm = new FormGroup({}); - progressService = inject(ProgressService); - dataService = inject(DataService); - quiz_segment = this.dataService.currentSegment; - answerIsEmpty = computed(() => this.progressService.currentAnswerValidity() === Answer.Empty); - dialogVisible = false; - ngOnInit() { - this.answerForm!.addControl(this.quiz_segment()!.question_type, new FormControl('')) - this.answerForm!.reset(); - } - - tryToAnswer() { - if (this.quiz_segment()?.question_type === "QCM") { - this.progressService.currentAnswer.set(this.answerForm.get('QCM')!.value); - } else if (this.quiz_segment()?.question_type === "QCU") { - const key = this.answerForm.get('QCU')!.value; - if (typeof key === "number") { - this.progressService.currentAnswer.set([key]); - } else { - this.progressService.currentAnswer.set([]); - } - } - this.progressService.answer(); - this.dialogVisible = this.answerIsEmpty(); - } -} diff --git a/src/app/views/quiz/quiz-card/quiz-card.component.html b/src/app/views/quiz/quiz-card/quiz-card.component.html deleted file mode 100644 index 0457bea2458bc34af641a75ad9012f6fe985197f..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-card/quiz-card.component.html +++ /dev/null @@ -1,9 +0,0 @@ -<div class="theme"> - <span>Thème : {{ dataService.currentTopic() }}</span> -</div> -<h1 class="question">{{ quiz_segment()?.question }}</h1> -@if (!progressService.answered()) { - <app-choice-box></app-choice-box> -} @else { - <app-answer-box></app-answer-box> -} diff --git a/src/app/views/quiz/quiz-endpage/quiz-endpage.component.html b/src/app/views/quiz/quiz-endpage/quiz-endpage.component.html deleted file mode 100644 index 01d7a68c1c44122347bb670c706751ef918d2036..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-endpage/quiz-endpage.component.html +++ /dev/null @@ -1,25 +0,0 @@ -<div> - <h1>Le quiz est fini !</h1> - <h2> - Votre score est de {{ progressService.score() }} / - {{ progressService.questionNumber() }} - </h2> -</div> -<div class="lower-section"> - <span - >Vous pouvez passer à Inclusif, le jeu, ou lancer une autre série de - questions. - </span> - <p-divider /> - <div class="start-div"> - <p-button - (click)="progressService.goToBegining()" - severity="secondary" - variant="outlined" - >Voir Inclusif, le jeu</p-button - > - <p-button (click)="progressService.goToBegining()"> - Relancer une série - </p-button> - </div> -</div> diff --git a/src/app/views/quiz/quiz-endpage/quiz-endpage.component.ts b/src/app/views/quiz/quiz-endpage/quiz-endpage.component.ts deleted file mode 100644 index 37b895cdf78693f5c512f37f8dcdca326b537f22..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-endpage/quiz-endpage.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, inject } from '@angular/core'; -import { ProgressService } from '../../../shared/services/progress-service'; -import { ButtonModule } from 'primeng/button'; -import { Divider } from 'primeng/divider'; - -@Component({ - selector: 'app-quiz-endpage', - imports: [ButtonModule, Divider], - templateUrl: './quiz-endpage.component.html', - styleUrl: './quiz-endpage.component.css' -}) -export class QuizEndpageComponent { - progressService = inject(ProgressService); -} diff --git a/src/app/views/quiz/quiz-homepage/quiz-homepage.component.css b/src/app/views/quiz/quiz-homepage/quiz-homepage.component.css deleted file mode 100644 index 01c5570f06b33483b801a1b7b45d264dc58fb4c1..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-homepage/quiz-homepage.component.css +++ /dev/null @@ -1,80 +0,0 @@ -:host { - display: flex; - flex-direction: column; - gap: 2%; - text-align: center; - justify-content: space-between; - height: 100%; - width: 90%; - margin: auto; -} - -.presentation-section { - display: flex; - flex-direction: column; - align-content: center; - gap: 16px; - padding-top: 2%; - height: 100%; -} - -.presentation-section h1 { - font-size: 4em; - font-weight: normal; -} -.presentation-section h2 { - font-size: 2em; - font-weight: normal; -} -.presentation-section p-image { - margin: auto; -} - -.n-questions-selector { - display: flex; - flex-direction: row; - width: fit-content; - border-radius: 8px; - border: 2px solid gray; - padding: 0 16px; - gap: 16px; - align-items: center; -} - -.start-div { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - gap: 5%; - padding: 2%; -} -.selector-buttons { - flex-grow: 1; - display: grid; - gap: 4px; - grid-auto-flow: column; - grid-template-columns: 1fr 1.2fr 1fr; - padding: 8px; - align-items: center; -} - -.n-questions-text { - height: 100%; - width: 100%; - border-radius: 4px; - justify-content: center; - align-content: center; - padding: 8px; - border: 1px solid gray; - background-color: var(--p-gray-200); -} - -.start-game-button { - --p-button-padding-x: 60px; - --p-button-padding-y: 16px; -} - -p, h1, h2{ - color: #333333; -} \ No newline at end of file diff --git a/src/app/views/quiz/quiz-homepage/quiz-homepage.component.html b/src/app/views/quiz/quiz-homepage/quiz-homepage.component.html deleted file mode 100644 index 4391a898e46ddc0f3b7576cc90ee9b1f2ecf45b1..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz-homepage/quiz-homepage.component.html +++ /dev/null @@ -1,58 +0,0 @@ -<div class="presentation-section"> - <h1>Quiz</h1> - <h2>Concevons nos services numériques pour tout le monde !</h2> - <p-image - src="images/banner.png" - alt="Image de présentation du quiz" - [imageStyle]="{ objectFit: 'contain' }" - width="90%" - /> - <p>Bienvenue sur le quiz du jeu Inclusif, le jeu.</p> - <p> - Ce quiz vous permet d'aborder de manière ludique les problèmes liés à - l'inclusivité. - </p> -</div> -<div class="lower-section"> - <p-divider /> - <div class="start-div"> - <div class="n-questions-selector"> - <p class="">Nombre de questions</p> - <div class="selector-buttons"> - <p-button - severity="contrast" - (click)="adjustNumberOfQuestions(-1)" - [disabled]="iNumberOfQuestions == 0" - aria-label="Enlever des questions" - icon="pi pi-minus" - /> - <span class="n-questions-text"> - {{ - possibleNumberOfQuestionsPerTopic[iNumberOfQuestions] * - numberOfTopics - }} - </span> - <p-button - severity="contrast" - (click)="adjustNumberOfQuestions(1)" - [disabled]=" - iNumberOfQuestions == possibleNumberOfQuestionsPerTopic.length - 1 - " - aria-label="Ajouter des questions" - icon="pi pi-plus" - /> - </div> - </div> - <p-button - class="start-game-button" - (click)=" - progressService.start( - possibleNumberOfQuestionsPerTopic[iNumberOfQuestions] - ) - " - aria-label="Commencer le quiz" - > - Passer à l'action - </p-button> - </div> -</div> diff --git a/src/app/views/quiz/quiz.component.css b/src/app/views/quiz/quiz.component.css deleted file mode 100644 index f2a40b8b2699988c3e5df85f6d23c60109a2de08..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz.component.css +++ /dev/null @@ -1,53 +0,0 @@ -:host { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; - padding: 16px; -} - -.quiz { - display: flex; - flex-direction: column; - height: 100%; - width: 80%; - margin: auto; - align-items: center; - justify-content: start; -} - -.progress { - width: 100%; - margin: 2% auto; - display: grid; - grid-template-columns: fit-content(100%) auto; - column-gap: 2%; - row-gap: 0%; - align-items: center; - color: var(--p-primary-500); -} - -.progress-bar { - --p-progressbar-label-font-size: 0; - --p-progressbar-height: 1vh; -} - -.question-text { - grid-column-start: 2; - padding: 0 0 0 2%; - margin: 0; -} - -.next { - display: flex; - flex-direction: column; - align-items: center; - margin-top: auto; - width: 100%; - position: relative; - bottom:0em; -} - -.button-page{ - --p-button-padding-x: 39px; -} \ No newline at end of file diff --git a/src/app/views/quiz/quiz.component.html b/src/app/views/quiz/quiz.component.html deleted file mode 100644 index 29e0e2b05afdd1299af91dcb5127c6db293daae6..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz.component.html +++ /dev/null @@ -1,32 +0,0 @@ -@if (progressService.questionNumber() === 0) { - <app-quiz-homepage></app-quiz-homepage> -} @else if (progressService.hasEnded()) { - <app-quiz-endpage></app-quiz-endpage> -} @else { - <div class="quiz"> - <div class="progress"> - <p class="question-text"> - {{ "Question " + progressService.questionNumber() }} - </p> - <p>{{ (progressPercentage() | number: "1.0-0") + " %" }}</p> - <p-progressbar class="progress-bar" [value]="progressPercentage()" /> - </div> - <app-quiz-card></app-quiz-card> - <div class="next"> - <p-divider class="divider" /> - @if (!progressService.answered()) { - <p-button - class="button-page" - (click)="quizCard()!.choiceBox()!.tryToAnswer()" - > - Répondre - </p-button> - } @else { - <p-button class="button-page" (click)="progressService.goToNext()"> - Suivant - <i class="pi pi-arrow-right"></i> - </p-button> - } - </div> - </div> -} diff --git a/src/app/views/quiz/quiz.component.ts b/src/app/views/quiz/quiz.component.ts deleted file mode 100644 index be92dab8711e9d33187765b64fe1214ac8a1ae07..0000000000000000000000000000000000000000 --- a/src/app/views/quiz/quiz.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component, computed, inject, viewChild } from '@angular/core'; -import { ButtonModule } from 'primeng/button'; -import { DividerModule } from 'primeng/divider'; -import { ProgressBarModule } from 'primeng/progressbar'; -import { ToastModule } from 'primeng/toast'; -import { ProgressService } from '../../shared/services/progress-service'; -import { DataService } from '../../shared/services/quiz-service'; -import { QuizCardComponent } from './quiz-card/quiz-card.component'; -import { QuizEndpageComponent } from "./quiz-endpage/quiz-endpage.component"; -import { QuizHomepageComponent } from './quiz-homepage/quiz-homepage.component'; - -@Component({ - selector: 'app-quiz', - templateUrl: './quiz.component.html', - styleUrl: './quiz.component.css', - imports: [CommonModule, ButtonModule, ToastModule, ProgressBarModule, QuizHomepageComponent, QuizCardComponent, DividerModule, QuizEndpageComponent] -}) - -export class QuizComponent { - /* Gère les cartes quiz par rapport à l'avancement dans le quiz et affiche une barre de progression le cas échéant*/ - progressService = inject(ProgressService); - dataService = inject(DataService); - quizCard = viewChild(QuizCardComponent); - progressPercentage = computed(() => this.progressService.questionNumber() / this.dataService.numberOfQuestions() * 100) -} diff --git a/src/app/views/views-style.css b/src/app/views/views-style.css index 5b6effe954a799ca465e312297d8e3ce354f71d0..9c62ed99af0e1e98e2e346caac8e7db121efe88e 100644 --- a/src/app/views/views-style.css +++ b/src/app/views/views-style.css @@ -1,2 +1 @@ -@import "navbar/navbar.component.css"; -@import "quiz/quiz.component.css"; +@import "autoeval/autoeval.component.css"; diff --git a/src/index.html b/src/index.html index 3b3e079a62a709ddec9d3415a8f8f0259ac52932..b8a832e3f99d49e870dc1833a7792edddda62a57 100644 --- a/src/index.html +++ b/src/index.html @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8" /> - <title>Quiz</title> + <title>Auto-évaluation</title> <base href="/" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" type="image/x-icon" href="./images/favicon.ico" /> diff --git a/src/styles.css b/src/styles.css index 68556fe296e77d65b8b0e6a0b863d2148e3d376d..d0eda3387e9d53543fed363c499ec9b9110fa88b 100644 --- a/src/styles.css +++ b/src/styles.css @@ -15,3 +15,7 @@ body { display: flex; flex-direction: column; } + + h1, h2, h3, p { + color: #333333; + } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index a8bb65b6e220b8a16a8cba8241833468f1145586..18609156c7225c80e42c29aa90ba9862c1290506 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,3 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": {