// -- PAGE D'ACCUEIL DE L'UTILISATEUR /// Vérifier que l'utilisateur est bien connecté, a le bon statut et le rediriger vers le formulaire d'inscription si ce n'est pas le cas. /// Si c'est ok, on récupère ses infos et stats + les derniers quizs auxquels il a accès, mais n'a pas répondu. /// Un moteur de recherche permet d'obtenir d'autres quizs parmi ceux publiés. /// Pour l'affichage des listings de quiz, l'API retourne directement du html. /// Un menu permet à l'utilisateur d'accéder à la modification de ses infos, de son abonnement, etc. /// Un message venant d'une autre page peut aussi être à afficher lors du premier chargement. // Fichier de configuration côté client : import { apiUrl, availableLangs, theme } from "../../config/instance.js"; const lang=availableLangs[0]; const configTemplate = require("../../views/"+theme+"/config/"+lang+".js"); const { getRandomQuestionnairesRoute, getStatsAnswers, questionnaireRoutes, searchQuestionnaires, searchQuestionnairesRoute } = require("../../config/questionnaires"); const { getUsersQuestionnairesRoute, userRoutes } = require("../../config/users"); // Fonctions utiles au script : import { getLocaly, removeLocaly, saveLocaly } from "./tools/clientstorage.js"; import { addElement } from "./tools/dom.js"; import { helloDev, updateAccountLink } from "./tools/everywhere.js"; import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js"; import { isEmpty, replaceAll } from "../../tools/main"; import { checkSession } from "./tools/users.js"; // Dictionnaires : const { statsUser } = require("../../lang/"+lang+"/answer"); const { nextPage, previousPage, serverError } = require("../../lang/"+lang+"/general"); const { searchQuestionnaireWithResult, searchQuestionnaireWithNoResult } = require("../../lang/"+lang+"/questionnaire"); const { lastQuestionnairesForUser, noQuestionnaireAccess } = require("../../lang/"+lang+"/questionnaireaccess"); const { needBeConnected, welcomeMessage } = require("../../lang/"+lang+"/user"); // Principaux éléments du DOM manipulés : const divMain= document.getElementById("main-content"); const divCrash= document.getElementById("crash"); const divMessage = document.getElementById("message"); const quizIntro = document.getElementById("quizsIntro"); const quizListing = document.getElementById("quizsList"); const quizPaginationPrevious = document.getElementById("previous"); const quizPaginationNext = document.getElementById("next"); const formSearch = document.getElementById("search"); const inputBegin = document.getElementById("begin"); const btnRandom = document.getElementById("random"); helloDev(); const initialise = async () => { try { // Si l'utilisateur n'est pas connecté, pas la peine d'aller + loin : const isConnected=await checkSession(["user"], "/"+configTemplate.connectionPage, { message: needBeConnected, color:"error" }, window.location); if(isConnected) { const user=getLocaly("user", true); updateAccountLink(user.status, configTemplate); addElement(divMessage, "h1", welcomeMessage.replace("#NAME", user.name)); divMain.style.display="block"; if(!isEmpty(getLocaly("message"))) { addElement(divMessage, "p", getLocaly("message", true).message, "", [getLocaly("message", true).color], "", false); removeLocaly("message"); } // Initialisation du formulaire de recherche : setAttributesToInputs({ "searchQuestionnaires": searchQuestionnaires }, formSearch); // Les stats : const xhrStats = new XMLHttpRequest(); xhrStats.open("GET", apiUrl+questionnaireRoutes+getStatsAnswers+user.id); xhrStats.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && !isEmpty(response.nbAnswers) && response.nbAnswers!==0)// pas de stats si aucune réponse ! { let txtIntro=""; const mapText = { NBANSWERS : response.nbAnswers, NBQUESTIONNAIRES : response.nbQuestionnaires, NBTOTQUESTIONNAIRES : response.groups.nbPublished+response.questionnaires.nbWithoutGroupPublished, AVGDURATION : response.avgDuration, AVGCORRECTANSWERS : response.avgCorrectAnswers }; // La situation est plurielle... txtIntro=replaceAll(statsUser, mapText); txtIntro=(response.nbAnswers > 1) ? txtIntro.replace("S1", "s") : txtIntro.replace("S1", ""); txtIntro=(response.nbQuestionnaires > 1) ? txtIntro.replace("S2", "s").replace("S3", "s") : txtIntro.replace("S2", "").replace("S3", "s"); txtIntro=(mapText.NBTOTQUESTIONNAIRES > 1) ? txtIntro.replace("S4", "s") : txtIntro.replace("S4", ""); addElement(divMessage, "p", txtIntro, "", "", "", false); } } } xhrStats.setRequestHeader("Authorization", "Bearer "+user.token); xhrStats.send(); // Par défaut, on affiche des derniers éléments supposés lus par l'utilisateur : const xhrLastQuizs = new XMLHttpRequest(); xhrLastQuizs.open("GET", apiUrl+userRoutes+getUsersQuestionnairesRoute+""+user.id+"/"+0+"/"+configTemplate.nbQuestionnairesUserHomePage+"/html"); xhrLastQuizs.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200) { if(response.nbTot === 0) addElement(quizIntro, "p", noQuestionnaireAccess, "", ["info"]); else if(response.html) { addElement(quizIntro, "p", lastQuestionnairesForUser, "", ["info"]); quizListing.innerHTML=response.html; } else addElement(quizs, "p", serverError, "", ["error"]);// revoir si intérêt d'afficher quelque chose } else addElement(quizs, "p", serverError, "", ["error"]); // idem } } xhrLastQuizs.setRequestHeader("Authorization", "Bearer "+user.token); xhrLastQuizs.send(); // Traitement du lancement d'une recherche // La recherche peut être lancée via la bouton submit ou un lien de pagination const sendSearch = (type="search") => { quizListing.innerHTML=""+""; let datas=getDatasFromInputs(formSearch); const xhrSearch = new XMLHttpRequest(); if(type=="search") xhrSearch.open("POST", apiUrl+questionnaireRoutes+searchQuestionnairesRoute); else if(type=="random") xhrSearch.open("POST", apiUrl+questionnaireRoutes+getRandomQuestionnairesRoute); xhrSearch.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && !isEmpty(response.nbTot)) { if(response.nbTot===0) { addElement(quizIntro, "p", searchQuestionnaireWithNoResult, "", ["info"]); window.location.hash="";// sinon les hash s'enchaînent... window.location.assign("#quizsIntro"); } else if(response.html) { let txtIntro=searchQuestionnaireWithResult.replace("#NB", response.nbTot); txtIntro=(response.nbTot > 1) ? txtIntro.replace("#S","s") : txtIntro.replace("#S",""); addElement(quizIntro, "p", txtIntro , "", ["success"]); quizListing.innerHTML=response.html; window.location.hash=""; window.location.assign("#quizsIntro"); // Pagination nécessaire ? // on commence par vider... quizPaginationPrevious.innerHTML=""; quizPaginationNext.innerHTML=""; if(response.begin != 0)// peut retourner "0" et non 0 ! { addElement(quizPaginationPrevious, "a", "<< "+previousPage , "previousRes", ["button"], { href: "#search" }); // revoir, les "<<" pourraient être gérées par le CSS const previousPageElt=document.getElementById("previousRes"); // le retour à la page précédente peut se faire en cliquant sur le bouton ou via l'historique du navigateur const goBackRes = () => { let newBegin=response.begin-configTemplate.nbQuestionnairesUserHomePage; if(newBegin<0) // ne devrait pas être possible.. newBegin=0; document.getElementById("begin").value=newBegin; sendSearch(); window.location.hash=""; window.location.assign("#quizsIntro");// pour remonter } previousPageElt.addEventListener("click", function(e) { e.preventDefault(); goBackRes(); }); /* semble provoqué bug ??? window.onpopstate = function(e) { e.preventDefault(); goBackRes(); };*/ } if(response.end < (response.nbTot-1))// -1, car tableau commence à 0 ! { addElement(quizPaginationNext, "a", nextPage+ " >>", "nextRes", ["button"], { href: "#search" }, false); const nextPageElt=document.getElementById("nextRes"); nextPageElt.addEventListener("click", function(e) { e.preventDefault(); document.getElementById("begin").value=response.end+1; sendSearch(); window.location.hash="";// sinon les hash s'enchaînent... window.location.assign("#quizsIntro"); // pour remonter }); } } else addElement(quizs, "p", serverError, "", ["error"]); } else addElement(quizs, "p", serverError, "", ["error"]); } } xhrSearch.setRequestHeader("Content-Type", "application/json"); xhrSearch.setRequestHeader("Authorization", "Bearer "+user.token); if(datas) { datas.output="html"; xhrSearch.send(JSON.stringify(datas)); } } btnRandom.addEventListener("click", function(e) { e.preventDefault(); document.getElementById("begin").value=0; sendSearch("random"); }); formSearch.addEventListener("submit", function(e) { e.preventDefault(); document.getElementById("begin").value=0; sendSearch(); }); } } catch(e) { console.error(e); addElement(divCrash, "p", serverError, "", ["error"]); } } initialise();