diff --git a/front/public/src/myQuizs.js b/front/public/src/myQuizs.js
new file mode 100644
index 0000000..013eb4e
--- /dev/null
+++ b/front/public/src/myQuizs.js
@@ -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+="
"+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+="
"+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);
+ }
+});*/
\ No newline at end of file
diff --git a/front/public/src/tools/userQuizsResults.js b/front/public/src/tools/userQuizsResults.js
index e0dff24..e736104 100644
--- a/front/public/src/tools/userQuizsResults.js
+++ b/front/public/src/tools/userQuizsResults.js
@@ -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", ""+configTemplate.userHomePageTxt+"", "", ["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+=`
À chaque fois que vous répondez à un quiz sur WikiLerni, votre résultat peut être enregistré, si vous l'acceptez.
+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.
+Par ailleurs, ces données ne sont accessibles qu'à partir du navigateur vous ayant permi des les enregistrer.
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é.