// -- GESTION DU FORMULAIRE PERMETTANT DE SAISIR / ÉDITER LES INFOS DES UTILISATEURS ET DE LEUR ABONNEMENT /// Vérifie que l'utilisateur est bien connecté, a le bon statut et le redirige vers le formulaire d'inscription si ce n'est pas le cas. /// Si c'est ok, propose un moteur de recherche permettant de chercher un utilisateur /// Si un id est passé par l'url on affiche les informations de l'utilisateur dans un formulaire permettant de l'éditer/supprimer. /// Si pas d'id passé par l'url, on affiche un formulaire vide permettant d'en saisir un nouvel utilisateur /// À ajouter : /// - importation liste de comptes utilisateur à créer /// - attribution d'un parrain à un utilisateur (via un moteur de recherche). Déjà prévu par le contrôleur. // Fichier de configuration côté client : import { apiUrl, availableLangs, theme } from "../../config/instance.js"; const lang=availableLangs[0]; const configUsers = require("../../config/users.js"); const configTemplate = require("../../views/"+theme+"/config/"+lang+".js"); // Fonctions utiles au script : import { getLocaly, removeLocaly } from "./tools/clientstorage.js"; import { addElement } from "./tools/dom.js"; import { helloDev, updateAccountLink } from "./tools/everywhere.js"; import { empyForm, getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js"; import { dateFormat, getPassword, isEmpty, replaceAll } from "../../tools/main"; import { getUrlParams } from "./tools/url.js"; import { checkSession } from "./tools/users.js"; // Dictionnaires : const { addOkMessage, serverError } = require("../../lang/"+lang+"/general"); const { infosAdminGodfather, infosAdminNbGodChilds, infosUserForAdmin, needBeConnected, searchUsersWithoutResult } = require("../../lang/"+lang+"/user"); const { infosExpiratedAdmin, infosNbDaysAdmin, infosPaymentsAdmin, isNotValided } = require("../../lang/"+lang+"/subscription"); // Principaux éléments du DOM manipulés : const divMain = document.getElementById("main-content"); const divMessage = document.getElementById("message"); const divResponse = document.getElementById("response"); const divCrash = document.getElementById("crash"); const divSubscribeIntro = document.getElementById("subscribeIntro"); const divPaymentsInfos = document.getElementById("infosPayments"); const divGodchildsInfos = document.getElementById("infosGodchilds"); const formUser = document.getElementById("users"); const deleteCheckBox = document.getElementById("deleteOkLabel"); const validationCheckBox = document.getElementById("validationOkLabel"); const btnNewUser = document.getElementById("wantNewUser"); const newPassword = document.getElementById("newPassword"); const timeDifference = document.getElementById("timeDifference"); const formSearch = document.getElementById("searchUsers"); const divSearchResult = document.getElementById("searchResult"); helloDev(); const initialise = async () => { try { const isConnected=await checkSession(["manager", "admin"], "/"+configTemplate.connectionPage, { message: needBeConnected, color:"error" }, window.location); if(isConnected) { const user=getLocaly("user", true); updateAccountLink(user.status, configTemplate); 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(configUsers, formSearch); // Fonction utile pour vider le formulaire, y compris les champs hidden, etc. // Cache aussi certains champs en mode création const emptyUserForm = () => { empyForm(formUser); // Case de suppression cachée par défaut, car inutile pour formulaire de création deleteCheckBox.style.display="none"; // Case de validation cachée par défaut, car utile que dans certains cas validationCheckBox.style.display="none"; divSubscribeIntro.innerHTML=""; divPaymentsInfos.innerHTML=""; divGodchildsInfos.innerHTML=""; // Certains navigateurs ont tendance à remplir tout seul les champs configUsers.password newPassword.value=""; // En mode création, pas de champ pour changer le mot de passe newPassword.parentNode.style.display="none"; // Inutile en mode création timeDifference.parentNode.style.display="none"; } emptyUserForm(); // Initialise les contraintes du formulaire : setAttributesToInputs(configUsers, formUser); // Fonction affichant les infos connues concernant un utilisateur et son abonnement const showFormUserInfos = (id) => { // on commence par tout vider, des fois que... : emptyUserForm(); const xhrGetInfos = new XMLHttpRequest(); xhrGetInfos.open("GET", apiUrl+configUsers.userRoutes+configUsers.getUserInfos+id); xhrGetInfos.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && response.User != undefined) { newPassword.parentNode.style.display="block"; timeDifference.parentNode.style.display="block"; const mapText = { ID_USER : response.User.id, DATE_CREA : dateFormat(response.User.createdAt), DATE_UPDATE : dateFormat(response.User.updatedAt), DATE_CONNECTION : dateFormat(response.User.connectedAt) }; let subscribeIntro=replaceAll(infosUserForAdmin, mapText); for(let data in response.User) { if(formUser.elements[data]!==undefined) { if(response.User[data]!==true && response.User[data]!==false)// booléen = case à cocher ! formUser.elements[data].value=response.User[data]; else if (response.User[data]==true) // si false, on ne fait rien formUser.elements[""+data].checked="checked"; } } if(response.Subscription != undefined) { // nombre de jours de l'abonnement formUser.elements["numberOfDays"].value=response.Subscription["numberOfDays"]; if(response.Subscription.noticeOk==true) formUser.elements["noticeOk"].checked="checked"; // jours de réception for(let i in response.Subscription.receiptDays) formUser.elements["d"+response.Subscription.receiptDays[i]].checked="checked"; const beginSubTS=new Date(response.Subscription.createdAt).getTime(); const nbDaysOk=response.Subscription.numberOfDays-Math.round((Date.now()-beginSubTS)/1000/3600/24); if(nbDaysOk > 0) subscribeIntro+="
"+infosNbDaysAdmin.replace("NB_DAYS", nbDaysOk); else subscribeIntro+="
"+infosExpiratedAdmin; addElement(divSubscribeIntro, "p", subscribeIntro, "", ["info"], "", false); } else { addElement(divSubscribeIntro, "p", isNotValided, "", ["error"]); validationCheckBox.style.display="block"; } deleteCheckBox.style.display="block"; // Infos de paiements via API WP const xhrGetPaymentsInfos = new XMLHttpRequest(); xhrGetPaymentsInfos.open("GET", apiUrl+configUsers.getPayments+response.User.id); xhrGetPaymentsInfos.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let responsePay=JSON.parse(this.responseText); if (this.status === 200) { if(responsePay.length!==0) { let txtPayments=""; for(let i in responsePay) { const mapText = { DATE_PAYMENT : dateFormat(responsePay[i].createdAt, "fr"), AMOUNT : responsePay[i].amount, CLIENT_NAME : responsePay[i].clientName }; txtPayments+="
  • "+replaceAll(infosNbDaysAdmin, mapText)+"
  • "; } addElement(divPaymentsInfos, "ul", txtPayments, "", ["info"], "", false); divPaymentsInfos.style.display="block" } } } } xhrGetPaymentsInfos.setRequestHeader("Authorization", "Bearer "+user.token); xhrGetPaymentsInfos.send(); // Un parrain ou deux par deux ? if(!isEmpty(response.User.GodfatherId)) { const xhrGetGodFatherInfos = new XMLHttpRequest(); xhrGetGodFatherInfos.open("GET", apiUrl+configUsers.userRoutes+configUsers.getUserInfos+response.User.GodfatherId); xhrGetGodFatherInfos.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let responseGF=JSON.parse(this.responseText); if (this.status === 200 && responseGF.User != undefined) { addElement(divGodchildsInfos, "p", infosAdminGodfather+""+responseGF.User.name+""+".
    ", "", ["info"], "", false); divGodchildsInfos.style.display="block"; } } } xhrGetGodFatherInfos.setRequestHeader("Authorization", "Bearer "+user.token); xhrGetGodFatherInfos.send(); } // Des filleuls ? let txtGodchilds=""; const xhrGetGodchilds = new XMLHttpRequest(); xhrGetGodchilds.open("GET", apiUrl+configUsers.userRoutes+configUsers.getGodChilds+id); xhrGetGodchilds.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let responseGS=JSON.parse(this.responseText); if (this.status === 200) { if(responseGS.length!==0) { txtGodchilds+=infosAdminGodfather.replace("#NB", responseGS.length); for(let i in responseGS) txtGodchilds+=""+responseGS[i].name+""; addElement(divGodchildsInfos, "p", txtGodchilds+".", "", ["info"], "", false); divGodchildsInfos.style.display="block"; } } } } xhrGetGodchilds.setRequestHeader("Authorization", "Bearer "+user.token); xhrGetGodchilds.send(); } } } xhrGetInfos.setRequestHeader("Authorization", "Bearer "+user.token); xhrGetInfos.send(); } // Si un id est passé par l'url, on essaye d'afficher l'utilisateur : let urlDatas=getUrlParams(); if(urlDatas && urlDatas.id!==undefined) showFormUserInfos(urlDatas.id); // Besoin d'un coup de Kärcher ? btnNewUser.addEventListener("click", function(e) { emptyUserForm(); }); // Envoi du formulaire des infos de l'utilisateur formUser.addEventListener("submit", function(e) { e.preventDefault(); divResponse.innerHTML=""; let datas=getDatasFromInputs(formUser); // recomposition des jours valables pour l'abonnement : datas.receiptDays=""; for(let i=1; i<=7; i++) { if(datas["d"+i]!==undefined) datas.receiptDays+=""+i; } if(datas.noticeOk===undefined) datas.noticeOk="false"; if(datas.newsletterOk===undefined) datas.newsletterOk="false"; const xhrUserDatas = new XMLHttpRequest(); if(!isEmpty(datas.id) && (datas.deleteOk!==undefined)) xhrUserDatas.open("DELETE", apiUrl+configUsers.userRoutes+"/"+datas.id); else if(!isEmpty(datas.id) && (datas.validationOk!==undefined)) xhrUserDatas.open("POST", apiUrl+configUsers.userRoutes+configUsers.validateUserRoute+datas.id); else if(!isEmpty(datas.id)) xhrUserDatas.open("PUT", apiUrl+configUsers.userRoutes+configUsers.updateUserInfos+datas.id); else { console.log("je suis ici"); datas.password=getPassword(configUsers.password.minlength, configUsers.password.minlength+2);// mot de passe temporaire xhrUserDatas.open("POST", apiUrl+configUsers.userRoutes+configUsers.createUserRoute); } xhrUserDatas.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 201 && response.id!=undefined) { addElement(divResponse, "p", addOkMessage, "", ["success"]); datas.id=response.id; } else if (this.status === 200 && response.message!=undefined) { if(Array.isArray(response.message)) response.message = response.message.join("
    "); else response.message = response.message; addElement(divResponse, "p", response.message, "", ["success"]); } else if (response.errors) { if(Array.isArray(response.errors)) response.errors = response.errors.join("
    "); else response.errors = serverError; addElement(divResponse, "p", response.errors, "", ["error"]); } else addElement(divResponse, "p", serverError, "", ["error"]); if(isEmpty(response.errors)) { if(datas.deleteOk===undefined) showFormUserInfos(datas.id); else emptyUserForm(); } } } xhrUserDatas.setRequestHeader("Content-Type", "application/json"); xhrUserDatas.setRequestHeader("Authorization", "Bearer "+user.token); if(datas) xhrUserDatas.send(JSON.stringify(datas)); }); // Traitement du lancement d'une recherche formSearch.addEventListener("submit", function(e) { e.preventDefault(); let datas=getDatasFromInputs(formSearch); const xhrSearch = new XMLHttpRequest(); xhrSearch.open("POST", apiUrl+configUsers.userRoutes+configUsers.searchUserRoute); xhrSearch.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { let response=JSON.parse(this.responseText); if (this.status === 200 && Array.isArray(response)) { if(response.length===0) addElement(divSearchResult, "p", searchUsersWithoutResult, "", ["info"]); else { let selectHTML=""; for(let i in response) selectHTML+=""; addElement(divSearchResult, "select", selectHTML, "selectSearch"); const searchSelect=document.getElementById("selectSearch"); searchSelect.addEventListener("change", function() { if(searchSelect.value!=="") showFormUserInfos(searchSelect.value); }); } } else addElement(divSearchResult, "p", serverError, "", ["error"]); } } xhrSearch.setRequestHeader("Content-Type", "application/json"); xhrSearch.setRequestHeader("Authorization", "Bearer "+user.token); if(datas) xhrSearch.send(JSON.stringify(datas)); }); } } catch(e) { addElement(divCrash, "p", serverError, "", ["error"]); console.error(e); } } initialise();