diff --git a/public/frontend_css/style.css b/public/frontend_css/style.css index 71ad9fb..887edd9 100644 --- a/public/frontend_css/style.css +++ b/public/frontend_css/style.css @@ -276,6 +276,10 @@ input[type="number"] { background: #444242; } +#resumeButton { + margin-left: 16px; +} + /*page 1 ends*/ /*page 2 starts*/ @@ -848,8 +852,8 @@ input::-ms-input-placeholder { padding-bottom: 4px; border-bottom: 1px solid black; position: absolute; - bottom: 4px; left: 50%; + bottom: 4px; } #page4 .customImgRow img { width: 335px; @@ -899,6 +903,14 @@ input::-ms-input-placeholder { line-height: 30px; margin: 0px; } +#response-timer { + display: block; + text-align: center; + font-size: 2rem; + margin-top: 24px; + font-weight: bold; + color: #222; +} /*page 5 ends here*/ /*page6 starts*/ @@ -1447,63 +1459,124 @@ img.image-missing { border-left: none; } -#resetQuizButton, -#resumeButton { - background: #737a73; - color: #fff; - font: 12px "Necto Mono"; - border: none; - border-radius: 4px; - padding: 10px 32px; - margin-left: 8px; - cursor: pointer; - transition: all 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275); - outline: none; +#termination-overlay { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(0, 0, 0, 0.95); + z-index: 9999; + justify-content: center; + align-items: center; } -#resetQuizButton:hover, -#resumeButton:hover, -#resetQuizButton:focus, -#resumeButton:focus { - background: #444242; +#termination-overlay .termination-content { + width: 100vw; + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +#termination-overlay .termination-message { color: #fff; + font-family: "Necto Mono", monospace; + font-size: 1.6rem; + text-align: center; + margin-bottom: 32px; + letter-spacing: 1px; +} +#termination-overlay .termination-title { + color: #fff; + font-family: "Bradford LL", serif; + font-size: 2.5rem; + font-style: italic; + text-align: center; + margin-bottom: 32px; +} +#termination-overlay .termination-counter { + color: #fff; + font-family: "Bradford LL", serif; + font-size: 3.5rem; + font-style: italic; + text-align: center; + margin-top: 16px; } -#questionNavBar .nav-btn { - font: 12px "Necto Mono"; - border-radius: 4px !important; - padding: 10px 16px !important; - margin: 0 4px; - min-width: 32px; - min-height: 32px; - border: none; +#resetQuizButton { + position: absolute; + top: 16px; + right: 24px; + background: #fff; + color: #222; + border: 2px solid #222; + border-radius: 6px; + padding: 8px 20px; + font-size: 1rem; + font-family: "Bradford LL", serif; font-weight: bold; cursor: pointer; transition: background 0.2s, color 0.2s; - text-align: center; - vertical-align: middle; - display: inline-flex; - align-items: center; + z-index: 10; +} +#resetQuizButton:hover { + background: #222; + color: #fff; +} + +#question-nav-bar { + width: 100%; + background: #f7f7f7; + border-bottom: 1px solid #ddd; + padding: 12px 0 8px 0; + position: sticky; + top: 0; + z-index: 20; + display: flex; justify-content: center; + align-items: center; + min-height: 48px; } -#questionNavBar .nav-btn.answered { - background: #43a047; - color: #fff; - border: 2px solid #388e3c; +.question-nav-inner { + display: flex; + gap: 8px; + overflow-x: auto; + padding: 0 16px; } -#questionNavBar .nav-btn.current { - background: #1976d2; - color: #fff; - border: 3px solid #1565c0; - box-shadow: 0 0 8px 2px rgba(25, 118, 210, 0.15); - z-index: 2; -} -#questionNavBar .nav-btn.unanswered { - background: #ccc; - color: #888; +.question-nav-btn { + min-width: 36px; + height: 36px; + border-radius: 50%; border: 2px solid #bbb; -} -#questionNavBar .nav-btn:hover, -#questionNavBar .nav-btn:focus { - filter: brightness(0.95); + background: #fff; + color: #bbb; + font-size: 1.1rem; + font-family: "Bradford LL", serif; + font-weight: bold; + cursor: pointer; + transition: all 0.2s; outline: none; } +.question-nav-btn.answered { + background: #e0ffe0; + color: #1a7f1a; + border-color: #1a7f1a; +} +.question-nav-btn.current { + background: #222; + color: #fff; + border-color: #222; + box-shadow: 0 0 0 2px #fff, 0 0 0 4px #222; +} +.question-nav-btn.unanswered { + background: #fff; + color: #bbb; + border-color: #bbb; + opacity: 0.6; +} +.question-nav-btn:hover { + background: #f0f0f0; + color: #222; + border-color: #222; +} diff --git a/public/frontend_js/quiz-test.js b/public/frontend_js/quiz-test.js index c40d821..d926ec4 100644 --- a/public/frontend_js/quiz-test.js +++ b/public/frontend_js/quiz-test.js @@ -64,7 +64,6 @@ let nextQuestionTimeoutCounter = 3000; let selectionQuestionTimeoutCounter = 6000; let closeResponseTimeoutCounter = 5000; let timeout; -let responseCountdownInterval; const mainImage = $(".main-image-container img"); fetch(url_preset + "/configurations") @@ -76,7 +75,23 @@ fetch(url_preset + "/configurations") } }); -$(document).on("click", ".beginButton", async function () { +$(document).ready(function () { + // Show Resume button if there is saved progress + if (localStorage.getItem("answers")) { + $("#resumeButton").show(); + } else { + $("#resumeButton").hide(); + } +}); + +$(document).on("click", "#beginButton", async function () { + // Clear progress and start fresh + localStorage.removeItem("answers"); + dataToReturn = []; + uniqueQuestionsShowed = []; + currentQuizIndex = 0; + currentQuestionCounter = 0; + isExecuted = false; $("#page1").css("display", "none"); $("#page2").css("display", "none"); $("#page3").css("display", "none"); @@ -89,6 +104,56 @@ $(document).on("click", ".beginButton", async function () { return nextQuestion(); }); +$(document).on("click", "#resumeButton", async function () { + // Resume from last progress + dataToReturn = localStorage.getItem("answers") + ? JSON.parse(localStorage.getItem("answers")) + : []; + uniqueQuestionsShowed = []; + currentQuizIndex = 0; + currentQuestionCounter = 0; + isExecuted = false; + $("#page1").css("display", "none"); + $("#page2").css("display", "none"); + $("#page3").css("display", "none"); + $("#page4").css("display", "none"); + $("#page5").css("display", "none"); + $("#page6").css("display", "none"); + $("#page7").css("display", "none"); + await getQuizzesApi(); + showQuizTitle(); + // Find last answered question + let lastQ = null; + let lastQuizIdx = 0; + let lastQCounter = 0; + if (dataToReturn.length > 0) { + for (let i = 0; i < allItems.length; i++) { + const quiz = allItems[i]; + for (let j = 0; j < quiz.questions.length; j++) { + const q = quiz.questions[j]; + if (dataToReturn.find((a) => a.question && a.question.id === q.id)) { + lastQuizIdx = i; + lastQCounter = j + 1; + } + } + } + currentQuizIndex = lastQuizIdx; + currentQuestionCounter = lastQCounter; + } + // Go to the next unanswered question + setTimeout(() => { + $("#page1").css("display", "none"); + $("#page2").css("display", "none"); + $("#page3").css("display", "block"); + $("#page4").css("display", "none"); + $("#page5").css("display", "none"); + $("#page6").css("display", "none"); + $("#page7").css("display", "none"); + $("#progressBarSection").css("display", "block"); + nextQuestion(); + }, nextQuestionTimeoutCounter); +}); + $(document).on("click", ".goBottom", function () { $("html, body").animate({ scrollTop: $(document).height() }, "slow"); }); @@ -1023,22 +1088,26 @@ function showResponse(responseHead, responseBody, weatherQuestion) { if (weatherQuestion) { $("#page5 #weatherApi").css("display", "block"); } - // Countdown timer logic for Quiz 2 - clearInterval(responseCountdownInterval); - let countdown = Math.ceil(closeResponseTimeoutCounter / 1000); - $("#responseCountdown").show().text(`Closing in ${countdown} seconds...`); - responseCountdownInterval = setInterval(function () { - countdown--; - if (countdown > 0) { - $("#responseCountdown").text(`Closing in ${countdown} seconds...`); + + // Countdown timer logic + if (window.responseCountdownInterval) { + clearInterval(window.responseCountdownInterval); + } + const timerDiv = $("#response-timer"); + let secondsLeft = Math.ceil(closeResponseTimeoutCounter / 1000); + timerDiv.text(secondsLeft); + timerDiv.show(); + window.responseCountdownInterval = setInterval(() => { + secondsLeft--; + if (secondsLeft > 0) { + timerDiv.text(secondsLeft); } else { - clearInterval(responseCountdownInterval); - $("#responseCountdown").hide(); + timerDiv.text(0); + clearInterval(window.responseCountdownInterval); } }, 1000); + closeResponseTimeout = setTimeout(() => { - clearInterval(responseCountdownInterval); - $("#responseCountdown").hide(); closeResponse(); }, closeResponseTimeoutCounter); } @@ -1047,11 +1116,15 @@ function showResponse(responseHead, responseBody, weatherQuestion) { function closeResponse() { responseOnGoing = false; hasNoResponse = true; - clearInterval(responseCountdownInterval); - $("#responseCountdown").hide(); $("#page5").css("display", "none"); $("#page4").css("display", "none"); $("#page3").css("display", "block"); + // Clear the countdown timer + if (window.responseCountdownInterval) { + clearInterval(window.responseCountdownInterval); + window.responseCountdownInterval = null; + } + $("#response-timer").hide(); if (currentQuestionCounter < totalQuizQuestions.length) { return askQuestion(totalQuizQuestions, currentQuestionCounter); } else { @@ -1068,8 +1141,6 @@ function closeResponse() { } // function closeResponse ends here async function askQuestion(totalQuizQuestions, counter, fromBack) { - // Always hide all answer rows before showing the current one - $(".answerRow").hide(); clearTimeout(timeout); clearTimeout(closeResponseTimeout); @@ -1420,10 +1491,10 @@ async function askQuestion(totalQuizQuestions, counter, fromBack) { `); } }); - // Add 'None of the above' button + // Add 'None of the above' option at the end $("#typeSelection .answerInner").append(`
- +
`); @@ -1483,8 +1554,6 @@ async function askQuestion(totalQuizQuestions, counter, fromBack) { $("#questionRow h1").html(ques.question); } currentQuestionCounter++; - // At the end of askQuestion, always update the nav bar - renderQuestionNavBar(); } async function storeAnswer(currentQuestion, currentActiveAnswerType) { @@ -1798,20 +1867,6 @@ async function storeAnswer(currentQuestion, currentActiveAnswerType) { } } localStorage.setItem("answers", JSON.stringify(dataToReturn)); - if ( - typeof customerEmail !== "undefined" && - customerEmail && - customerEmail.innerText - ) { - localStorage.setItem( - "answers_" + customerEmail.innerText, - JSON.stringify(dataToReturn) - ); - } - let userKey = getUserProgressKey(); - localStorage.setItem(userKey, JSON.stringify(dataToReturn)); - checkResumeButtonVisibility(); - renderQuestionNavBar(); } let currentSuggestIndex; @@ -2115,508 +2170,125 @@ function handleImageMissing(self) { $(self).addClass("image-missing"); } -// 1. Add checkAllergie function near the top (after variable declarations) -function checkAllergie(btn) { - clearTimeout(timeout); - var val = $(btn).attr("data-val"); - // Quiz 4: Terminate if Banana, Olive, or Sunflowers is selected - if (["Banana", "Olive", "Sunflowers"].includes(val)) { - showTerminationScreen(); +// Implement checkAllergie for Quiz 4 +function checkAllergie(self) { + const value = self.dataset.val || $(self).data("val"); + if (["Banana", "Olive", "Sunflowers"].includes(value)) { + // Simulate API fetch for message and counter + const terminationMessage = + "You have an allergy to one of the main ingredients in our system. Our current system will not suit you."; + const terminationTitle = "Quiz will now be terminated"; + let counter = 10; // seconds (simulate API value) + $("#termination-overlay .termination-message").text(terminationMessage); + $("#termination-overlay .termination-title").text(terminationTitle); + $("#termination-overlay .termination-counter").text(counter); + $("#termination-overlay").css("display", "flex"); + let interval = setInterval(() => { + counter--; + $("#termination-overlay .termination-counter").text(counter); + if (counter <= 0) { + clearInterval(interval); + window.location.href = "/"; + } + }, 1000); + // Block all interaction + $("body > *:not(#termination-overlay)").css("pointer-events", "none"); return; } - if ($(btn).hasClass("active")) { - tempSelectionAns.splice(tempSelectionAns.indexOf(val), 1); - $(btn).removeClass("active"); - $(btn).removeClass("highlight"); - } else { - tempSelectionAns.push(val); - if (!$(btn).hasClass("active")) $(btn).addClass("active"); - if (!$(btn).hasClass("highlight")) $(btn).addClass("highlight"); - } - timeout = setTimeout(function () { - nextQuestion(); - }, selectionQuestionTimeoutCounter); + // If not terminating, proceed as normal (select/deselect logic) + // (existing selection logic is handled by the .selectionBtn click handler) } -// Quiz 4: Show termination overlay and handle countdown/redirect -function showTerminationScreen() { - // Get message and counter from mainConfigurations (from /configurations API) - var message = - mainConfigurations && mainConfigurations.termination_message - ? mainConfigurations.termination_message - : "You have selected an allergen. The quiz will now end."; - var counter = - mainConfigurations && mainConfigurations.termination_counter - ? parseInt(mainConfigurations.termination_counter) - : 5; - $("#terminationMessage").text(message); - $("#terminationCountdown").text(counter); - $("#terminationOverlay").css({ display: "flex" }); - var countdown = counter; - var interval = setInterval(function () { - countdown--; - if (countdown > 0) { - $("#terminationCountdown").text(countdown); - } else { - clearInterval(interval); - window.location.href = "/"; - } - }, 1000); -} - -// Quiz 5: Show Resume Quiz button if progress exists, and handle resume logic -$(document).ready(function () { - // Use email as key if available, otherwise fallback to local - let userKey = null; - if ( - typeof customerEmail !== "undefined" && - customerEmail && - customerEmail.innerText - ) { - userKey = "answers_" + customerEmail.innerText; - } - let savedAnswers = userKey - ? localStorage.getItem(userKey) - : localStorage.getItem("answers"); - if (savedAnswers && JSON.parse(savedAnswers).length > 0) { - $("#resumeButton").show(); - } - - $("#resumeButton").on("click", async function () { - // Load saved progress - let answers = userKey - ? localStorage.getItem(userKey) - : localStorage.getItem("answers"); - if (answers) { - dataToReturn = JSON.parse(answers); - // Find last answered question - let lastQ = dataToReturn[dataToReturn.length - 1]; - // Set quiz and question index - let found = false; - for (let i = 0; i < allItems.length; i++) { - let idx = allItems[i].questions.findIndex( - (q) => q.id === lastQ.question.id - ); - if (idx !== -1) { - currentQuizIndex = i; - currentQuestionCounter = idx + 1; - found = true; - break; - } - } - if (!found) { - currentQuizIndex = 0; - currentQuestionCounter = 0; - } - $("#page1").css("display", "none"); - $("#page2").css("display", "none"); - $("#page3").css("display", "none"); - $("#page4").css("display", "none"); - $("#page5").css("display", "none"); - $("#page6").css("display", "none"); - $("#page7").css("display", "none"); - await getQuizzesApi(); - showQuizTitle(); - // Resume from next unanswered question - return askQuestion( - allItems[currentQuizIndex].questions, - currentQuestionCounter - ); - } - }); -}); - -// Utility for user-specific progress key -function getUserProgressKey() { - if ( - typeof customerEmail !== "undefined" && - customerEmail && - customerEmail.innerText - ) { - return "answers_" + customerEmail.innerText; - } - return "answers"; -} -function clearAllProgress() { - localStorage.removeItem("answers"); - if ( - typeof customerEmail !== "undefined" && - customerEmail && - customerEmail.innerText - ) { - localStorage.removeItem("answers_" + customerEmail.innerText); - } -} - -// Overwrite reset logic -$(document).on("click", "#resetQuizButton", function () { +$(document).on("click", "#resetQuizButton", async function () { if ( confirm( "Are you sure you want to reset the quiz? All progress will be lost." ) ) { - clearAllProgress(); - // Reload the page for a true fresh start (clears all in-memory state/UI) - window.location.reload(); + localStorage.removeItem("answers"); + dataToReturn = []; + uniqueQuestionsShowed = []; + currentQuizIndex = 0; + currentQuestionCounter = 0; + isExecuted = false; + $("#page1").css("display", "none"); + $("#page2").css("display", "none"); + $("#page3").css("display", "none"); + $("#page4").css("display", "none"); + $("#page5").css("display", "none"); + $("#page6").css("display", "none"); + $("#page7").css("display", "none"); + await getQuizzesApi(); + showQuizTitle(); + return nextQuestion(); } }); -// Overwrite resume logic -$(document).ready(function () { - let userKey = getUserProgressKey(); - let savedAnswers = localStorage.getItem(userKey); - if (savedAnswers && JSON.parse(savedAnswers).length > 0) { - $("#resumeButton").show(); - } - $("#resumeButton") - .off("click") - .on("click", async function () { - let userKey = getUserProgressKey(); - let answers = localStorage.getItem(userKey); - let navState = localStorage.getItem("quiz_nav_state"); - await getQuizzesApi(); // Always load quizzes first - let startFromBeginning = false; - let found = false; - if (answers) { - try { - dataToReturn = JSON.parse(answers); - } catch (e) { - dataToReturn = []; - } - if (Array.isArray(dataToReturn) && dataToReturn.length > 0) { - let lastQ = dataToReturn[dataToReturn.length - 1]; - if ( - lastQ && - lastQ.question && - typeof lastQ.question.id !== "undefined" - ) { - for (let i = 0; i < allItems.length; i++) { - let idx = allItems[i].questions.findIndex( - (q) => q.id === lastQ.question.id - ); - if (idx !== -1) { - currentQuizIndex = i; - currentQuestionCounter = idx + 1; - found = true; - break; - } - } - } - } - } - // If not found by answers, try nav state - if (!found && navState) { - try { - const { quizIndex, questionCounter } = JSON.parse(navState); - if ( - typeof quizIndex === "number" && - typeof questionCounter === "number" - ) { - currentQuizIndex = quizIndex; - currentQuestionCounter = questionCounter; - found = true; - } - } catch (e) {} - } - // If still not found, start from beginning - if (!found) { - currentQuizIndex = 0; - currentQuestionCounter = 0; - } - $("#page1").css("display", "none"); - $("#page2").css("display", "none"); - $("#page3").css("display", "none"); - $("#page4").css("display", "none"); - $("#page5").css("display", "none"); - $("#page6").css("display", "none"); - $("#page7").css("display", "none"); - showQuizTitle(); - askQuestion(allItems[currentQuizIndex].questions, currentQuestionCounter); - }); -}); - -// In storeAnswer, always save to the correct user key -async function storeAnswer(currentQuestion, currentActiveAnswerType) { - // ... existing code ... - let userKey = getUserProgressKey(); - localStorage.setItem(userKey, JSON.stringify(dataToReturn)); - checkResumeButtonVisibility(); - renderQuestionNavBar(); -} - function renderQuestionNavBar() { - if (!allItems || allItems.length === 0 || !$("#page3").is(":visible")) { - $("#questionNavBar").hide(); + // Hide on landing and final result pages + if ($("#page1").is(":visible") || $("#page7").is(":visible")) { + $("#question-nav-bar").hide(); return; } - let questions = []; - allItems.forEach((quiz) => { - quiz.questions.forEach((q) => { - questions.push({ id: q.id, text: q.question }); - }); - }); - let answeredIds = (dataToReturn || []) - .map((a) => a.question && a.question.id) - .filter(Boolean); - // Determine the current question id - let currentId = null; + $("#question-nav-bar").show(); + $("#question-nav-bar").html(""); if ( - allItems[currentQuizIndex] && - allItems[currentQuizIndex].questions[currentQuestionCounter] // currentQuestionCounter points to the next question, so use currentQuestionCounter-1 if >0 - ) { - currentId = - allItems[currentQuizIndex].questions[currentQuestionCounter]?.id; - // If currentId is undefined (e.g., at end), fallback to previous - if (!currentId && currentQuestionCounter > 0) { - currentId = - allItems[currentQuizIndex].questions[currentQuestionCounter - 1]?.id; - } - } else if ( - allItems[currentQuizIndex] && - allItems[currentQuizIndex].questions[currentQuestionCounter - 1] - ) { - currentId = - allItems[currentQuizIndex].questions[currentQuestionCounter - 1].id; - } - let html = ""; - questions.forEach((q, idx) => { - let btnClass = "nav-btn"; - const isAnswered = answeredIds.includes(q.id); - const isCurrent = q.id === currentId; - if (isAnswered) btnClass += " answered"; + !allItems || + !allItems[currentQuizIndex] || + !allItems[currentQuizIndex].questions + ) + return; + const questions = allItems[currentQuizIndex].questions; + let navHtml = '
'; + for (let i = 0; i < questions.length; i++) { + const q = questions[i]; + let answered = dataToReturn.find( + (a) => a.question && a.question.id === q.id + ); + let isCurrent = i === currentQuestionCounter - 1; + let btnClass = "question-nav-btn"; if (isCurrent) btnClass += " current"; - if (!isAnswered) btnClass += " unanswered"; - html += ``; - }); - $("#questionNavBar").html(html).show(); + else if (answered) btnClass += " answered"; + else btnClass += " unanswered"; + navHtml += ``; + } + navHtml += "
"; + $("#question-nav-bar").html(navHtml); } -// Handle nav bar button click -$(document).on("click", "#questionNavBar .nav-btn", function () { - let qid = parseInt($(this).attr("data-qid")); - let found = false; - for (let i = 0; i < allItems.length; i++) { - let idx = allItems[i].questions.findIndex((q) => q.id === qid); - if (idx !== -1) { - currentQuizIndex = i; - currentQuestionCounter = idx; - found = true; - break; - } +// Helper to jump to a specific question index in the current quiz +function jumpToQuestion(index) { + // Hide all answer rows and question row + var divsToHide = document.getElementsByClassName("answerRow"); + for (let i = 0; i < divsToHide.length; i++) { + divsToHide[i].style.display = "none"; } - if (found) { - askQuestion(allItems[currentQuizIndex].questions, currentQuestionCounter); + $("#questionRow").css("display", "none"); + // Set the counter and show the question + currentQuestionCounter = index; + askQuestion(allItems[currentQuizIndex].questions, index); +} + +// Handle nav bar click +$(document).on("click", ".question-nav-btn", async function () { + const idx = parseInt($(this).attr("data-qidx")); + if (!isNaN(idx)) { + jumpToQuestion(idx); } }); // Update nav bar on question change -let origAskQuestion = askQuestion; +const origAskQuestion = askQuestion; askQuestion = async function (...args) { - let result = await origAskQuestion.apply(this, args); + const result = await origAskQuestion.apply(this, args); renderQuestionNavBar(); return result; }; -// Show/hide nav bar on page changes -function updateNavBarVisibility() { - if ( - typeof renderQuestionNavBar === "function" && - $("#page3").is(":visible") - ) { - renderQuestionNavBar(); - $("#questionNavBar").show(); - } else { - $("#questionNavBar").hide(); - } -} -// Ensure nav bar is shown after every askQuestion -if (!window._quizNavWrapped) { - window._quizNavWrapped = true; - const origAskQuestion = askQuestion; - askQuestion = async function (...args) { - let result = await origAskQuestion.apply(this, args); - updateNavBarVisibility(); - saveNavState(); - return result; - }; -} -// On page load or resume, restore nav state and show nav bar if on question page -$(document).ready(function () { - loadNavState(); - updateNavBarVisibility(); -}); - -// Add minimal CSS for nav bar button states -$( - "" -).appendTo("head"); - -// Utility for nav state persistence -function saveNavState() { - localStorage.setItem( - "quiz_nav_state", - JSON.stringify({ - quizIndex: currentQuizIndex, - questionCounter: currentQuestionCounter, - }) - ); -} -function loadNavState() { - const state = localStorage.getItem("quiz_nav_state"); - if (state) { - try { - const { quizIndex, questionCounter } = JSON.parse(state); - if ( - typeof quizIndex === "number" && - typeof questionCounter === "number" - ) { - currentQuizIndex = quizIndex; - currentQuestionCounter = questionCounter; - } - } catch (e) {} - } -} - -// On reset, clear nav state -function clearAllProgress() { - localStorage.removeItem("answers"); - localStorage.removeItem("quiz_nav_state"); - if ( - typeof customerEmail !== "undefined" && - customerEmail && - customerEmail.innerText - ) { - localStorage.removeItem("answers_" + customerEmail.innerText); - } - $("#resumeButton").hide(); -} - -// BEGIN button: always start fresh and clear progress -$(document).on("click", "#beginButton", async function () { - clearAllProgress(); - $("#resumeButton").hide(); - $("#page1").css("display", "none"); - $("#page2").css("display", "none"); - $("#page3").css("display", "none"); - $("#page4").css("display", "none"); - $("#page5").css("display", "none"); - $("#page6").css("display", "none"); - $("#page7").css("display", "none"); - dataToReturn = []; - uniqueQuestionsShowed = []; - lastQuizResponseShown = null; - lastShowedQuestionId = null; - currentQuizIndex = 0; - currentQuestionCounter = 0; - isExecuted = false; - await getQuizzesApi(); - showQuizTitle(); - askQuestion(allItems[currentQuizIndex].questions, 0); -}); - -// Resume button logic: only show if there is progress -function checkResumeButtonVisibility() { - let userKey = getUserProgressKey(); - let savedAnswers = localStorage.getItem(userKey); - let navState = localStorage.getItem("quiz_nav_state"); - if ((savedAnswers && JSON.parse(savedAnswers).length > 0) || navState) { - $("#resumeButton").show(); - } else { - $("#resumeButton").hide(); - } -} - -$(document).ready(function () { - loadNavState(); - updateNavBarVisibility(); - checkResumeButtonVisibility(); - $("#resumeButton") - .off("click") - .on("click", async function () { - let userKey = getUserProgressKey(); - let answers = localStorage.getItem(userKey); - let navState = localStorage.getItem("quiz_nav_state"); - await getQuizzesApi(); // Always load quizzes first - let startFromBeginning = false; - let found = false; - if (answers) { - try { - dataToReturn = JSON.parse(answers); - } catch (e) { - dataToReturn = []; - } - if (Array.isArray(dataToReturn) && dataToReturn.length > 0) { - let lastQ = dataToReturn[dataToReturn.length - 1]; - if ( - lastQ && - lastQ.question && - typeof lastQ.question.id !== "undefined" - ) { - for (let i = 0; i < allItems.length; i++) { - let idx = allItems[i].questions.findIndex( - (q) => q.id === lastQ.question.id - ); - if (idx !== -1) { - currentQuizIndex = i; - currentQuestionCounter = idx + 1; - found = true; - break; - } - } - } - } - } - // If not found by answers, try nav state - if (!found && navState) { - try { - const { quizIndex, questionCounter } = JSON.parse(navState); - if ( - typeof quizIndex === "number" && - typeof questionCounter === "number" - ) { - currentQuizIndex = quizIndex; - currentQuestionCounter = questionCounter; - found = true; - } - } catch (e) {} - } - // If still not found, start from beginning - if (!found) { - currentQuizIndex = 0; - currentQuestionCounter = 0; - } - $("#page1").css("display", "none"); - $("#page2").css("display", "none"); - $("#page3").css("display", "none"); - $("#page4").css("display", "none"); - $("#page5").css("display", "none"); - $("#page6").css("display", "none"); - $("#page7").css("display", "none"); - showQuizTitle(); - askQuestion(allItems[currentQuizIndex].questions, currentQuestionCounter); - }); -}); - -// After reset, hide resume button until new progress is made -function clearAllProgress() { - localStorage.removeItem("answers"); - localStorage.removeItem("quiz_nav_state"); - if ( - typeof customerEmail !== "undefined" && - customerEmail && - customerEmail.innerText - ) { - localStorage.removeItem("answers_" + customerEmail.innerText); - } - $("#resumeButton").hide(); -} +// Also update nav bar on nextQuestion +const origNextQuestion = nextQuestion; +nextQuestion = async function (...args) { + const result = await origNextQuestion.apply(this, args); + renderQuestionNavBar(); + return result; +}; diff --git a/public/quiz-test.html b/public/quiz-test.html index 996e8ba..b39edaa 100644 --- a/public/quiz-test.html +++ b/public/quiz-test.html @@ -27,8 +27,8 @@ @@ -74,29 +74,11 @@ > - -
+

@@ -261,6 +243,7 @@ />

+
@@ -269,17 +252,9 @@
-
+
Environmental Profile
@@ -397,35 +372,12 @@
-
-
-
+