diff --git a/index.html b/index.html index 0f0347e9aa18d5626793a7ccdbd1bba9d5b57c04..20c5cfffc367aa36fb7221110894e47d1f7995cc 100644 --- a/index.html +++ b/index.html @@ -28,7 +28,7 @@ <div class="container"> <div class="input-field"> <input id="login-key-input" type="text" class="validate"> - <label for="login-key-input">X Api Key</label> + <label for="login-key-input">X Api Key *</label> </div> </div> </div> @@ -67,17 +67,17 @@ <div class="container"> <div class="input-field"> <input id="quiz-title" type="text" class="validate"> - <label for="quiz-title">Title</label> + <label for="quiz-title">Title *</label> </div> <div class="input-field"> <textarea id="quiz-descr" class="materialize-textarea" data-length="120"></textarea> - <label for="quiz-descr">Description</label> + <label for="quiz-descr">Description *</label> </div> </div> </div> <div class="modal-footer"> <a href="#!" class="modal-close waves-effect waves-green btn-flat">Cancel</a> - <a href="#!" class="modal-close waves-effect waves-green btn-flat cyan-text" onclick="createNewQuiz()">Create</a> + <a href="#!" class="waves-effect waves-green btn-flat cyan-text" onclick="createNewQuiz()">Create</a> </div> </div> @@ -184,6 +184,10 @@ <h4>Login to see your answers</h4> </div> </div> + <div class="col l8"> + <div id="id-my-answers-main"> + </div> + </div> </div> </div> </div> diff --git a/js/modeles.js b/js/modeles.js index 87c6f06f6049d3f67e46aa21e4c04875455e237e..0272389acf518af09f9b25fac645058cb4bf5686 100644 --- a/js/modeles.js +++ b/js/modeles.js @@ -191,25 +191,63 @@ const postQuiz = (quiz_title, quiz_descr) => { console.debug(`@postQuiz(${quiz_title}, ${quiz_descr})`); const url = `${state.serverUrl}/quizzes/`; - let configObj = { - method: 'POST', - headers: state.headers, - body: JSON.stringify({ - title: quiz_title, - description: quiz_descr - }) - }; + let p = new Promise((resolve, reject) => { + if (quiz_title === '' || !quiz_title || !quiz_title.replace(/\s/g, '').length) { + M.toast({ + html: 'Title is empty !', + displayLength: 4000, + classes: 'error' + }); + throw new Error(`Title is empty !`); + reject(`Title is empty !`); + } + if (quiz_descr === '' || !quiz_descr || !quiz_descr.replace(/\s/g, '').length) { + M.toast({ + html: 'Description is empty !', + displayLength: 4000, + classes: 'error' + }); + throw new Error(`Description is empty !`); + reject(`Description is empty !`); + } + resolve(); + }) + .then(() => { + let configObj = { + method: 'POST', + headers: state.headers, + body: JSON.stringify({ + title: quiz_title, + description: quiz_descr + }) + }; - return fetch(url, configObj) - .then(filterHttpResponse) - .then((data) => { - console.log(`@postQuiz(${quiz_title}, ${quiz_descr}) => Data :`); - console.log(data); - - // To update list of user's quizzes - getMyQuizzes(); - return data; - }); + return fetch(url, configObj) + .then(filterHttpResponse) + .then((data) => { + console.log(`@postQuiz(${quiz_title}, ${quiz_descr}) => Data :`); + console.log(data); + + // To update list of user's quizzes + getMyQuizzes(); + + M.toast({ + html: 'Quiz created !', + displayLength: 4000, + classes: 'success' + }); + + let elem = document.getElementById('modal-create-quiz'); + let inst = M.Modal.getInstance(elem); + inst.close(); + + document.querySelector('#modal-create-quiz #quiz-title').value = ''; + document.querySelector('#modal-create-quiz #quiz-descr').value = ''; + + return data; + }); + }) + .catch(err => console.error(`Error on creating quiz: ${err}`)); }; const createNewQuiz = (quiz_title, quiz_descr) => { @@ -218,9 +256,6 @@ const createNewQuiz = (quiz_title, quiz_descr) => { if (quiz_descr === undefined) quiz_descr = document.querySelector('#modal-create-quiz #quiz-descr').value; - document.querySelector('#modal-create-quiz #quiz-title').value = ''; - document.querySelector('#modal-create-quiz #quiz-descr').value = ''; - postQuiz(quiz_title, quiz_descr); }; @@ -262,28 +297,64 @@ const updateQuiz = (quiz_id) => { console.debug(`@updateQuiz(${quiz_id})`); const url = `${state.serverUrl}/quizzes/${quiz_id}`; - let configObj = { - method: 'PUT', - headers: state.headers, - body: JSON.stringify({ - title: quiz_title, - description: quiz_descr, - open: quiz_open - }) + let bodyObj = { + title: quiz_title, + description: quiz_descr, + open: quiz_open }; - return fetch(url, configObj) - .then(filterHttpResponse) - .then((data) => { - console.log(`@updateQuiz(${quiz_id}) => Data :`); - console.log(data); + let p = new Promise((resolve, reject) => { + if (bodyObj.title === '' || !bodyObj.title || !bodyObj.title.replace(/\s/g, '').length) { + M.toast({ + html: 'Title is empty !', + displayLength: 4000, + classes: 'error' + }); + throw new Error(`Title is empty !`); + reject(`Title is empty !`); + } + if (bodyObj.description === '' || !bodyObj.description || !bodyObj.description.replace(/\s/g, '').length) { + M.toast({ + html: 'Description is empty !', + displayLength: 4000, + classes: 'error' + }); + throw new Error(`Description is empty !`); + reject(`Description is empty !`); + } + resolve(); + }) + .then(() => { + let configObj = { + method: 'PUT', + headers: state.headers, + body: JSON.stringify(bodyObj) + }; - // To update - getMyQuizzes(); - getMyQuestions(quiz_id); + return fetch(url, configObj) + .then(filterHttpResponse) + .then((data) => { + console.log(`@updateQuiz(${quiz_id}) => Data :`); + console.log(data); - return data; - }); + // To update + getMyQuizzes(); + getMyQuestions(quiz_id); + + M.toast({ + html: 'Quiz updated !', + displayLength: 4000, + classes: 'success' + }); + + let elem = document.getElementById('modal-template'); + let inst = M.Modal.getInstance(elem); + inst.close(); + + return data; + }); + }) + .catch((err) => console.error(`Error on quiz updating: ${err}`)); }; // ////////////////////////////////////////////////////////////////////////////// @@ -362,8 +433,26 @@ const postQuestion = (quiz_id) => { console.log(`@postQuestion(${quiz_id}, "${qstn}", ${qstn_props}) => Qstn Id :`); console.log(qstn_id); + if (bodyObj.sentence === '' || !bodyObj.sentence || !bodyObj.sentence.replace(/\s/g, '').length) { + M.toast({ + html: 'Question is empty !', + displayLength: 4000, + classes: 'error' + }); + throw new Error(`Question is empty !`); + } + + if (!bodyObj.propositions || bodyObj.propositions.length < 2) { + M.toast({ + html: 'Give at least 2 propositions !', + displayLength: 4000, + classes: 'error' + }); + throw new Error(`Give at least 2 propositions !`); + } + let checkedProp = document.querySelector('input[name=add-qstn-modal-prop-correct]:checked'); - if (checkedProp) { + if (checkedProp && checkedProp !== null) { let checkedPropId = Number(checkedProp.id.split('-')[2]); bodyObj.propositions.map((prop) => { if (prop.proposition_id === checkedPropId) { @@ -374,10 +463,11 @@ const postQuestion = (quiz_id) => { }); } else { M.toast({ - html: 'Choose right proposition !', + html: 'Give correct proposition !', displayLength: 4000, classes: 'error' }); + throw new Error(`Give correct proposition !`); } return bodyObj; @@ -402,9 +492,20 @@ const postQuestion = (quiz_id) => { // To update getMyQuestions(quiz_id); + M.toast({ + html: 'Question created !', + displayLength: 4000, + classes: 'success' + }); + + let elem = document.getElementById('modal-template'); + let inst = M.Modal.getInstance(elem); + inst.close(); + return data; }); - }); + }) + .catch((err) => console.error(`Error on question posting: ${err}`)); }; const updateQuestion = (quiz_id, qstn_id) => { @@ -569,8 +670,8 @@ function onClickTerminer() { } } -function onClickMyQuizBtn(quiz_id, action, qstn_id = 0) { - modifyMyQuizModal(quiz_id, action, qstn_id); +function onClickMyQuizBtn(action, quiz_id = 0, qstn_id = 0) { + modifyMyQuizModal(action, quiz_id, qstn_id); let modal = document.querySelector(`#modal-template`); let instance = M.Modal.init(modal, { onCloseEnd: function() { @@ -595,29 +696,37 @@ function addPropQstnModal() { console.log(state.props_ids); let prop = document.getElementById('add-qstn-modal-input-prop').value; - let prop_id = state.propObjArr.length; + if (prop === '' || !prop || !prop.replace(/\s/g, '').length) { + M.toast({ + html: 'Proposition is empty !', + displayLength: 4000, + classes: 'error' + }); + } else { + let prop_id = state.propObjArr.length; - while (state.props_ids.includes(prop_id)) { - prop_id++; - } + while (state.props_ids.includes(prop_id)) { + prop_id++; + } - let obj = { - content: prop, - proposition_id: prop_id, - correct: false - }; + let obj = { + content: prop, + proposition_id: prop_id, + correct: false + }; - state.propObjArr.push(obj); - state.props_ids.push(prop_id); + state.propObjArr.push(obj); + state.props_ids.push(prop_id); - console.log('@addPropQstnModal() => state.propObjArr AFTER :'); - console.log(state.propObjArr); + console.log('@addPropQstnModal() => state.propObjArr AFTER :'); + console.log(state.propObjArr); - console.log('@addPropQstnModal() => state.props_ids AFTER :'); - console.log(state.props_ids); + console.log('@addPropQstnModal() => state.props_ids AFTER :'); + console.log(state.props_ids); - state.qstnContentTemp = document.getElementById('input-question').value; - modifyMyQuizModal(state.myCurrentQuiz, state.modalAction, state.modal_qstn_id); + state.qstnContentTemp = document.getElementById('input-question').value; + modifyMyQuizModal(state.modalAction, state.myCurrentQuiz, state.modal_qstn_id); + } } function removePropQstnModal(prop_id) { @@ -639,5 +748,5 @@ function removePropQstnModal(prop_id) { console.debug(`@removePropQstnModal(${prop_id}) => state.props_ids :`); console.debug(state.props_ids); - modifyMyQuizModal(state.myCurrentQuiz, state.modalAction, state.modal_qstn_id); + modifyMyQuizModal(state.modalAction, state.myCurrentQuiz, state.modal_qstn_id); } \ No newline at end of file diff --git a/js/vues.js b/js/vues.js index eca635d14b383e3b5ec425006674ff68c8106eb1..2e54a1b49a63e4eeca690ccdc9157686a71bf62c 100644 --- a/js/vues.js +++ b/js/vues.js @@ -34,6 +34,7 @@ const logedOut = () => { document.getElementById('id-my-quizzes-list').innerHTML = `<h4>Login to see your quizzes</h4>`; document.getElementById('id-my-answers-list').innerHTML = `<h4>Login to see your answers</h4>`; document.getElementById('id-my-current-quiz').innerHTML = ''; + document.getElementById('id-my-answers-main').innerHTML = ''; }; // génération d'une liste de quizzes avec deux boutons en bas @@ -58,14 +59,14 @@ const htmlQuizzesList = (quizzes, curr, total) => { const prevBtn = curr !== 1 ? `<button id="id-prev-quizzes" data-page="${curr - - 1}" class="btn"><i class="material-icons">navigate_before</i></button>` + 1}" class="btn cyan"><i class="material-icons">navigate_before</i></button>` : ''; // le bouton ">" pour aller à la page suivante, ou rien si c'est la première page const nextBtn = curr !== total ? `<button id="id-next-quizzes" data-page="${curr + - 1}" class="btn"><i class="material-icons">navigate_next</i></button>` + 1}" class="btn cyan"><i class="material-icons">navigate_next</i></button>` : ''; // La liste complète et les deux boutons en bas @@ -225,8 +226,8 @@ function renderMyCurrentQuiz() { <i class="material-icons">sentiment_dissatisfied</i> <span>This quizz doesn't have any questions !</span> </li> - <li><a onclick="onClickMyQuizBtn(${myQuiz_id},'add-question')"><i class="material-icons left">add</i>Add Question</a></li> - <li><a onclick="onClickMyQuizBtn(${myQuiz_id},'edit-quiz')"><i class="material-icons left">create</i>Edit Quiz</a></li> + <li><a onclick="onClickMyQuizBtn('add-question', ${myQuiz_id})"><i class="material-icons left">add</i>Add Question</a></li> + <li><a onclick="onClickMyQuizBtn('edit-quiz', ${myQuiz_id})"><i class="material-icons left">create</i>Edit Quiz</a></li> </ul> </div> </nav>`; @@ -236,8 +237,8 @@ function renderMyCurrentQuiz() { <div class="nav-wrapper"> <ul class="left hide-on-med-and-down"> <li class="status-message"><span>${myQuestionsArr.length} ${(myQuestionsArr.length === 1) ? "question" : "questions"}</span></li> - <li><a onclick="onClickMyQuizBtn(${myQuiz_id},'add-question')"><i class="material-icons left">add</i>Add Question</a></li> - <li><a onclick="onClickMyQuizBtn(${myQuiz_id},'edit-quiz')"><i class="material-icons left">create</i>Edit Quiz</a></li> + <li><a onclick="onClickMyQuizBtn('add-question', ${myQuiz_id})"><i class="material-icons left">add</i>Add Question</a></li> + <li><a onclick="onClickMyQuizBtn('edit-quiz', ${myQuiz_id})"><i class="material-icons left">create</i>Edit Quiz</a></li> </ul> </div> </nav> @@ -246,7 +247,7 @@ function renderMyCurrentQuiz() { html += `<li class="collection-item cyan lighten-4 quiz-question"> <div class="row valign-wrapper"> <span class="col quiz-qstn-nb">Question ${index+1} :</span> - <a class="col myQuiz-edit-prop-btn valign-wrapper" onclick="onClickMyQuizBtn(${myQuiz_id}, 'edit-question', ${qstn.question_id})"> + <a class="col myQuiz-edit-prop-btn valign-wrapper" onclick="onClickMyQuizBtn('edit-question', ${myQuiz_id}, ${qstn.question_id})"> <i class="material-icons">create</i> Edit Question </a> @@ -312,7 +313,7 @@ function renderMyAnswers() { </nav> <ul class="collection">`; state.myAnswers.map((answ) => { - html += `<li class="collection-item cyan lighten-5 quizz-element"> + html += `<li class="collection-item cyan lighten-5 quizz-element" onclick="renderMyCurrentAnswers(${answ.quiz_id})"> <h5>${answ.title}</h5> <p>${answ.description}</p><a class="chip">Author : ${answ.owner_id}</a> <a class="chip">Quizz ID : ${answ.quiz_id}</a> @@ -324,6 +325,33 @@ function renderMyAnswers() { listHtml.innerHTML = html; } +function renderMyCurrentAnswers(quiz_id) { + const myAnswers = document.getElementById('id-my-answers-main'); + + // let quizPromise = getOneQuiz(quiz_id); + // quizPromise.then((quiz) => { + + // console.log(`@renderMyCurrentAnswers(${quiz_id}) => Quiz :`); + // console.log(quiz); + + let html = `<ul class="collection">`; + state.myAnswers.map((answ) => { + if (answ.quiz_id === quiz_id) { + answ.answers.map((a) => { + html += `<li class="collection-item cyan lighten-4 quiz-question"> + <p>Question ID : ${a.question_id}</p> + <p>Proposition ID : ${a.proposition_id}</p> + </li>`; + }); + } + }); + html += `</ul>`; + + myAnswers.innerHTML = html; + + // }); +} + function renderCurrentQuizz() { const main = document.getElementById('id-all-quizzes-main'); @@ -404,8 +432,8 @@ const renderUserBtn = () => { }; }; -function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { - console.debug(`@modifyMyQuizModal(${quiz_id}, '${action}', ${qstn_id})`); +function modifyMyQuizModal (action, quiz_id = 0, qstn_id = 0) { + console.debug(`@modifyMyQuizModal('${action}', ${quiz_id}, ${qstn_id})`); // let modal_html = document.getElementById('modal-template'); let modal_title = document.getElementById('modal-template-title'); @@ -432,7 +460,7 @@ function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { let html = `<div class="input-field"> <input id="input-question" type="text" class="validate" value="${state.qstnContentTemp}"> - <label ${(state.propObjArr) ? 'class="active"' : ''} for="input-question">Question</label> + <label ${(state.propObjArr) ? 'class="active"' : ''} for="input-question">Question *</label> </div> <ul class="collection">`; state.propObjArr.map((prop, index) => { @@ -465,7 +493,7 @@ function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { modal_footer.innerHTML = ` <a href="#!" class="modal-close waves-effect waves-green btn-flat">Cancel</a> - <a onclick="postQuestion(${quiz_id})" id="modal-template-okBtn" href="#!" class="modal-close waves-effect waves-green btn-flat cyan-text">OK</a>`; + <a onclick="postQuestion(${quiz_id})" id="modal-template-okBtn" href="#!" class="waves-effect waves-green btn-flat cyan-text">OK</a>`; break; @@ -480,11 +508,11 @@ function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { modal_title.innerHTML = 'Edit Quiz'; modal_body.innerHTML = `<div class="input-field"> <input id="input-change-quiz-title" type="text" class="validate" value="${quizToEdit.title}"> - <label class="active" for="input-change-quiz-title">Title</label> + <label class="active" for="input-change-quiz-title">Title *</label> </div> <div class="input-field"> <textarea id="input-change-quiz-description" class="materialize-textarea" data-length="120">${quizToEdit.description}</textarea> - <label class="active" for="input-change-quiz-description">Description</label> + <label class="active" for="input-change-quiz-description">Description *</label> </div> <div class="switch"> <label> @@ -496,7 +524,7 @@ function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { </div>`; modal_footer.innerHTML = ` <a href="#!" class="modal-close waves-effect waves-green btn-flat">Cancel</a> - <a onclick="updateQuiz(${quiz_id})" id="modal-template-okBtn" href="#!" class="modal-close waves-effect waves-green btn-flat cyan-text">OK</a>`; + <a onclick="updateQuiz(${quiz_id})" id="modal-template-okBtn" href="#!" class="waves-effect waves-green btn-flat cyan-text">OK</a>`; }); break; @@ -505,10 +533,10 @@ function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { modal_title.innerHTML = 'Edit Question'; - console.log(`@modifyMyQuizModal(${quiz_id}, '${action}', ${qstn_id}) => state.propObjArr BEFORE`); + console.log(`@modifyMyQuizModal('${action}', ${quiz_id}, ${qstn_id}) => state.propObjArr BEFORE`); console.log(state.propObjArr); - console.log(`@modifyMyQuizModal(${quiz_id}, '${action}', ${qstn_id}) => state.myQuestions BEFORE`); + console.log(`@modifyMyQuizModal('${action}', ${quiz_id}, ${qstn_id}) => state.myQuestions BEFORE`); console.log(state.myQuestions); state.myQuestions.map((qstn) => { @@ -532,12 +560,12 @@ function modifyMyQuizModal (quiz_id, action, qstn_id = 0) { } }); - console.log(`@modifyMyQuizModal(${quiz_id}, '${action}', ${qstn_id}) => state.propObjArr AFTER`); + console.log(`@modifyMyQuizModal('${action}', ${quiz_id}, ${qstn_id}) => state.propObjArr AFTER`); console.log(state.propObjArr); let htmlEditQstn = `<div class="input-field"> <input id="input-question" type="text" class="validate" value="${state.qstnContentTemp}"> - <label ${(state.propObjArr) ? 'class="active"' : ''} for="input-question">Question</label> + <label ${(state.propObjArr) ? 'class="active"' : ''} for="input-question">Question *</label> </div> <ul class="collection">`; state.propObjArr.map((prop, index) => {