Ajout d'une page permettant de lister les quizs auxquels l'utilisateur a déjà répondu.
This commit is contained in:
parent
0a0e394964
commit
0a8d47ad38
192
front/public/src/myQuizs.js
Normal file
192
front/public/src/myQuizs.js
Normal file
@ -0,0 +1,192 @@
|
||||
// -- GESTION DE LA PAGE PERMETTANT DE LISTER LES QUIZS AUXQUELS L'UTILISATEUR A DÉJÀ RÉPONDU
|
||||
|
||||
/// Il est d'abord testé que le navigateur accepte l'utilisation d'IndexDB
|
||||
/// Si oui la liste de quizs ayant déjà reçu au moins une réponse est affichée.
|
||||
/// Un bouton permettra aussi de les sauvegarder dans un fichier ou d'importer une sauvegarde.
|
||||
|
||||
// Configurations générales provenant du backend :
|
||||
import { availableLangs } from "../../../config/instance.js";
|
||||
const lang=availableLangs[0];
|
||||
|
||||
// Textes :
|
||||
const { localDBNotReady }=require("../../../lang/"+lang+"/answer");
|
||||
const { serverError }=require("../../../lang/"+lang+"/general");
|
||||
|
||||
// Fonctions :
|
||||
import { addElement } from "./tools/dom.js";
|
||||
import { helloDev } from "./tools/everywhere.js";
|
||||
import { isEmpty } from "../../../tools/main";
|
||||
import { loadMatomo } from "./tools/matomo.js";
|
||||
|
||||
// Classe s'occupant du stockage des résultats aux quizs :
|
||||
import { userQuizsResults} from "./tools/userQuizsResults";
|
||||
|
||||
// Éléments du DOM manipulés :
|
||||
//const btnSave=document.getElementById("want2Save");
|
||||
//const btnSubmit=document.getElementById("checkResponses");
|
||||
//const propose2Save=document.getElementById("propose2Save");
|
||||
//const responseTxt=document.getElementById("response");
|
||||
const quizsList=document.getElementById("quizsList");
|
||||
|
||||
let userDB, allPreviousAnswers=[], myResults;
|
||||
const initialise = async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// Instanciation de la classe s'occupant du stockage des résultats aux quizs :
|
||||
myResults=await userQuizsResults.initialise("myResults", 1);
|
||||
// Si la base de données est fonctionnel et que des résultats sont déjà enregistrés, on affiche la liste des quizs ayant une réponse connue :
|
||||
if(myResults.dbIsReady !== false)
|
||||
await myResults.showMyQuizs();
|
||||
else
|
||||
addElement(quizsList, "p", localDBNotReady);
|
||||
// Statistiques :
|
||||
loadMatomo();
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
initialise();
|
||||
helloDev();
|
||||
/*
|
||||
// Fonction affichant le quiz, quand il est caché par défaut+ déclenchant le chronomètre mesurant la durée de réponse aux questions.
|
||||
const showQuestionnaire = () =>
|
||||
{
|
||||
chronoBegin=Date.now();
|
||||
myForm.style.display="block";
|
||||
btnShow.style.display="none";
|
||||
const here=window.location; // window.location à ajouter pour ne pas quitter la page en mode "preview".
|
||||
if(window.location.hash !== "")
|
||||
{
|
||||
window.location.hash="";// ! le "#" reste
|
||||
window.location.assign(here+"questionnaire");
|
||||
}
|
||||
else
|
||||
window.location.assign(here+"#questionnaire");
|
||||
}
|
||||
|
||||
let chronoBegin;
|
||||
if(btnShow)
|
||||
{
|
||||
btnShow.addEventListener("click", function(e)
|
||||
{
|
||||
try
|
||||
{
|
||||
e.preventDefault();
|
||||
showQuestionnaire();
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
addElement(responseTxt, "p", serverError, "", ["error"]);
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
// Un lien peut être passé pour voir directement le quiz :
|
||||
if(location.hash !== "" && location.hash === "#questionnaire")
|
||||
showQuestionnaire();
|
||||
}
|
||||
|
||||
// Dans le cas d'un quiz groupé, le chrono est lancé dès l'affichage :
|
||||
if(quizInfos.GroupId != "0")
|
||||
{
|
||||
chronoBegin=Date.now();
|
||||
btnSubmit.style.display="block";
|
||||
}
|
||||
|
||||
// Traitement de l'envoi de la réponse de l'utilisateur :
|
||||
let answer;
|
||||
myForm.addEventListener("submit", async function(e)
|
||||
{
|
||||
try
|
||||
{
|
||||
e.preventDefault();
|
||||
btnSubmit.style.display="none"; // seulement une réponse à la fois, SVP :)
|
||||
responseTxt.innerHTML=""; // supprime les éventuels messages déjà affichés
|
||||
answer=userQuizsResults.checkUserAnswers(myForm);
|
||||
answer.duration=Math.round((Date.now()-chronoBegin)/1000);
|
||||
answer.QuestionnaireId=quizInfos.QuestionnaireId;
|
||||
answer.GroupId=quizInfos.GroupId;
|
||||
|
||||
// Enregistrement et affichage du résultat, suivant les cas :
|
||||
let getOuput=userQuizsResults.getResultOutput(answer);
|
||||
// S'il y a déjà une réponse dans la bd, c'est que l'utilisateur est ok pour les enregister.
|
||||
if(myResults.allResults.length !== 0)
|
||||
{
|
||||
const saveResponses=await myResults.addResult(answer);
|
||||
if(saveResponses)
|
||||
await myResults.showPreviousResultsForId(quizInfos.QuestionnaireId, quizInfos.GroupId);
|
||||
getOuput+="<br><br>"+wantToSeaPreviousResults.replace("URL","#explanations");
|
||||
// Nouveau quiz pour cette personne ?
|
||||
await myResults.saveNewQuiz(quizInfos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// S'il n'a pas encore de données, on stocke temporairement le résultat et propose de l'enregistrer :
|
||||
if(myResults.saveResultTemp(answer) && myResults.dbIsReady)
|
||||
{
|
||||
getOuput+="<br><br>"+wantToSaveResponses;
|
||||
propose2Save.style.display="block";
|
||||
}
|
||||
}
|
||||
addElement(responseTxt, "p", getOuput, "", ["info"]);
|
||||
// On redirige vers le résultat :
|
||||
const here=window.location;
|
||||
if(window.location.hash !== "")
|
||||
{
|
||||
window.location.hash=""; // ! le "#" reste
|
||||
window.location.assign(here+"response");
|
||||
}
|
||||
else
|
||||
window.location.assign(here+"#response");
|
||||
|
||||
// + Affichage des textes d'explication pour chaque question
|
||||
const explanations=document.querySelectorAll(".help");
|
||||
for(let i in explanations)
|
||||
{
|
||||
if(explanations[i].style != undefined) // sinon, la console affiche une erreur "TypeError: explanations[i].style is undefined", bien que tout fonctionne (?)
|
||||
explanations[i].style.display="block";
|
||||
}
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
addElement(responseTxt, "p", serverError, "", ["error"]);
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
|
||||
// L'utilisateur demande à sauvegarder son résultat :
|
||||
btnSave.addEventListener("click", async function(e)
|
||||
{
|
||||
try
|
||||
{
|
||||
e.preventDefault();
|
||||
if(!isEmpty(myResults.dbIsReady) && !isEmpty(answer)) // On ne devrait pas m'avoir proposé d'enregistrer dans ce cas, mais...
|
||||
{
|
||||
const saveResponses=await myResults.addResult(answer);
|
||||
if(saveResponses)
|
||||
{
|
||||
// Nouvel enregistrement = actualisation nécessaire de la liste des résultats pour ce quiz :
|
||||
await myResults.showPreviousResultsForId(quizInfos.QuestionnaireId, quizInfos.GroupId);
|
||||
// Nouveau quiz (ce qui doit être le cas, mais...) :
|
||||
await myResults.saveNewQuiz(quizInfos);
|
||||
// Redirection vers la liste des résultats :
|
||||
const here=window.location; // window.location à ajouter pour ne pas quitter la page en mode "preview".
|
||||
if(window.location.hash !== "")
|
||||
{
|
||||
window.location.hash="";// ! le "#" reste
|
||||
window.location.assign(here+"explanations");
|
||||
}
|
||||
else
|
||||
window.location.assign(here+"#explanations");
|
||||
}
|
||||
propose2Save.style.display="none";
|
||||
}
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
addElement(responseTxt, "p", serverError, "", ["error"]);
|
||||
console.error(e);
|
||||
}
|
||||
});*/
|
@ -11,7 +11,8 @@ import { saveIsReady } from "./clientstorage.js";
|
||||
// Textes :
|
||||
import { availableLangs } from "../../../../config/instance.js";
|
||||
const lang=availableLangs[0];
|
||||
const { localDBNeedDatas, localDBNeedQuizId, noPreviousResults, previousResultsLine, previousResultsTitle, previousResultsStats, userAnswersFail, userAnswersMedium, userAnswersSuccess }=require("../../../../lang/"+lang+"/answer");
|
||||
const { localDBNeedDatas, localDBNeedQuizId, noPreviousResults, noPreviousResultsAtAll, previousResultsLine, previousResultsTitle, previousResultsStats, userAnswersFail, userAnswersMedium, userAnswersSuccess }=require("../../../../lang/"+lang+"/answer");
|
||||
const { localDBConnexionFail }=require("../../../../lang/"+lang+"/general");
|
||||
|
||||
export class userQuizsResults
|
||||
{
|
||||
@ -206,6 +207,7 @@ export class userQuizsResults
|
||||
const getquizs=quizsStore.getAll();
|
||||
getquizs.onsuccess = (e) =>
|
||||
{
|
||||
this.allQuizs=e.target.result;
|
||||
this.db.close();
|
||||
resolve(e.target.result);
|
||||
};
|
||||
@ -446,4 +448,19 @@ export class userQuizsResults
|
||||
/// addElement(explanationsContent, "p", "<a href=\"/"+configTemplate.userHomePage+"\" class=\"button cardboard\">"+configTemplate.userHomePageTxt+"</a>", "", ["btn"], "", false);
|
||||
}
|
||||
}
|
||||
|
||||
// Retourne une liste HTML des précédents quizs avec lien vers leur page
|
||||
showMyQuizs(listId="quizsList")
|
||||
{
|
||||
const listElt=document.getElementById(listId);
|
||||
// On affiche d'abord les quizs les plus récents :
|
||||
const myQuizs=this.allQuizs.reverse();
|
||||
let html="";
|
||||
for(const quiz of myQuizs)
|
||||
html+=`<li><a href="${quiz.url}#explanations">${quiz.title}</a></li>`;
|
||||
if(html !== "")
|
||||
addElement(listElt, "ul", html+"ici");
|
||||
else
|
||||
addElement(listElt, "p", noPreviousResultsAtAll);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ module.exports =
|
||||
entry:
|
||||
{
|
||||
index: "./src/index.js",
|
||||
myQuizs: "./src/myQuizs",
|
||||
paymentPage: "./src/paymentPage.js",
|
||||
polyfill: "babel-polyfill",
|
||||
quiz: "./src/quiz.js"
|
||||
|
62
front/public/www/mes-quizs.html
Normal file
62
front/public/www/mes-quizs.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Retrouvez vos résultats aux quizs auxquels vous avez déjà répondu sur WikiLerni.">
|
||||
<title>Retrouvez vos résultats aux quizs WikiLerni</title>
|
||||
<!-- Version lisible des scripts : https://forge.chapril.org/Fab_Blab/WikiLerni/src/branch/master/front/src -->
|
||||
<script src="/JS/polyfill.app.js" defer></script>
|
||||
<script src="/JS/myQuizs.app.js" defer></script>
|
||||
<link rel="shortcut icon" href="/img/favicon.ico">
|
||||
<link rel="stylesheet" href="/themes/wikilerni/css/style.css">
|
||||
<link rel="canonical" href="https://www.wililerni.com/mes-quizs.html">
|
||||
<link rel="alternate" type="application/atom+xml" title="WikiLerni" href="/atom.xml">
|
||||
</head>
|
||||
|
||||
<body class="cardboard">
|
||||
<!-- En tête -->
|
||||
<header class="cardboard">
|
||||
<a href="/" title="Page d'accueil WikLerni"><img src="/themes/wikilerni/img/wikilerni-purple-2-128.png" alt="WikiLerni (logo)" title="Accéder à la page d'accueil de WikiLerni" /></a>
|
||||
<ul id="headLinks">
|
||||
<li><a href="/contact.html" rel="nofollow">Contact</a></li>
|
||||
<li><a href="/quizs/" title="Retrouvez vos résultats">Mes quizs</a></li>
|
||||
<li><a href="/quizs/" title="Les dernières publications">Parcourir</a></li>
|
||||
<li><a href="/a-propos.html">À propos</a></li>
|
||||
<li><a href="/" title="Page d'accueil de WikiLerni">Accueil</a></li>
|
||||
</ul>
|
||||
</header>
|
||||
|
||||
<div id="prompt" class="cardboard">
|
||||
<a href="/" title="Page d'accueil WikLerni"><img src="/themes/wikilerni/img/wikilerni-purple-2-512.png" alt="Logo WikiLerni" title="W I K I L E R N I" /></a>
|
||||
<p>Cultivons notre jardin !</p>
|
||||
</div>
|
||||
|
||||
<div id="page" class="cardboard">
|
||||
|
||||
<h1 class="cardboard">Les quizs auxquels vous avez déjà répondu</h1>
|
||||
|
||||
<noscript>Désolé, mais pour l’instant, l’utilisation de WikiLerni nécessite l’activation du JavaScript.</noscript>
|
||||
|
||||
<div id="quizsList"></div>
|
||||
|
||||
<div id="explanations" class="framed engraved">
|
||||
<h2>Comment ça marche ?</h2>
|
||||
<p>À chaque fois que vous répondez à un quiz sur WikiLerni, votre résultat peut être enregistré, si vous l'acceptez.</p>
|
||||
<p>Vous n'avez pas besoin de créer un compte, car ces données sont enregistrées dans votre navigateur internet, c'est-à-dire sur votre ordinateur. Ceci peut ne pas fonctionner, si vous utilisez une navigation privée ou d'autres configurations interdisant ce type d'enregistrement.</p>
|
||||
<p>Par ailleurs, ces données ne sont accessibles qu'à partir du navigateur vous ayant permi des les enregistrer.<br>Aussi, pour éviter de les perdre, ou encore vous permettre de les récupérer sur un autre navigateur, un outil de sauvegarde vous est proposé.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="cardboard">
|
||||
<ul id="footLinks">
|
||||
<li><a href="https://diaspora-fr.org/people/815767c0c09e0139ec6f32a01d0dfba2" title="Blog WikiLerni sur diaspora*">Blog</a></li>
|
||||
<li><a href="/credits.html">Crédits</a></li>
|
||||
<li><a href="/mentions-legales.html" rel="nofollow">Mentions légales</a></li>
|
||||
<li><a href="/donnees.html">Données personnelles</a></li>
|
||||
<li><a href="/CGV-CGU.html" rel="nofollow">CGV & CGU</a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
@ -3,6 +3,7 @@ module.exports =
|
||||
localDBGetPreviousResultsFail: "Bug de récupération des résultats précédents.",
|
||||
localDBNeedDatas: "Il manque des données nécessaires à l'enregistrement.",
|
||||
localDBNeedQuizId: "Aucun identifiant n'a été fourni pour le quiz.",
|
||||
localDBNotReady: "Désolé, mais il semble que votre navigateur ne permette pas l'utilisation de cette page. Pour plus d'informations, lisez les explications ci-dessous.",
|
||||
needIntegerNumberCorrectResponses : "Le nombre de réponses correctes doit être un nombre entier.",
|
||||
needIntegerNumberSecondesResponse : "La durée de la réponse doit être un nombre entier de secondes.",
|
||||
needIntegerNumberUserResponses : "Le nombre de questions auxquelles l'utilisateur a répondu doit être un nombre entier.",
|
||||
@ -14,6 +15,7 @@ module.exports =
|
||||
needMinNumberCorrectResponses : "Le nombre de réponses correctes ne peut être négatif.",
|
||||
needMinNumberSecondesResponse : "La durée de la réponse ne peut être négative.",
|
||||
noPreviousResults: "On dirait que c'est la première fois que vous répondez à ce quiz. Bonne lecture !",
|
||||
noPreviousResultsAtAll: "Vous n'avez répondu à aucun quiz pour l'instant !",
|
||||
previousResultsLine: "Le DATEANSWER, vous avez répondu correctement à NBCORRECTANSWERS questions sur NBQUESTIONS en AVGDURATION secondes.",
|
||||
previousResultsStats: "En moyenne, vous avez répondu à ce quiz en AVGDURATION secondes, en ayant <b>AVGCORRECTANSWERS % de bonnes réponses</b>.",
|
||||
previousResultsTitle: "Voici vos précédents résultats à ce quiz",
|
||||
|
Loading…
x
Reference in New Issue
Block a user