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 @@
>
-