diff --git a/.eleventy.js b/.eleventy.js index 248bc93..721f0d8 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -19,6 +19,7 @@ module.exports = function (eleventyConfig) { eleventyConfig.addLayoutAlias('default', 'layout.njk'); eleventyConfig.addFilter('mdToHtml', markdownToHtml); + eleventyConfig.addFilter('csvList', (values) => values.join(', ')); return { dir: { diff --git a/pages/_data/questionData.js b/pages/_data/questionData.js index 5a343fc..a943210 100644 --- a/pages/_data/questionData.js +++ b/pages/_data/questionData.js @@ -15,44 +15,51 @@ const getQuestions = async () => { const questions = await base('Questions and Answers').select().all(); const publishedQuestions = questions - .filter((record) => record.fields.Published || viewDrafts) - .map((record) => { - const options = [ - { - answer: record.fields.Answer, - isCorrect: true, - }, - ]; - - if (record.fields['Distractor 1']?.trim()) { - options.push({ - answer: record.fields['Distractor 1'], - isCorrect: false, - }); - } - - if (record.fields['Distractor 2']?.trim()) { - options.push({ - answer: record.fields['Distractor 2'], - isCorrect: false, - }); - } - - return { - ...record.fields, - options: options.sort(() => { - const sign = Math.round(Math.random()) > 0 ? 1 : -1; - - return sign; - }), - }; - }); + .filter((record) => record.fields.Published || viewDrafts) + .map((record, index) => { + const options = [ + { + answer: record.fields.Answer, + isCorrect: true, + }, + ]; + + if (record.fields['Distractor 1']?.trim()) { + options.push({ + answer: record.fields['Distractor 1'], + isCorrect: false, + }); + } + + if (record.fields['Distractor 2']?.trim()) { + options.push({ + answer: record.fields['Distractor 2'], + isCorrect: false, + }); + } + + return { + ...record.fields, + id: record.id, + pageNumber: index + 1, + options: options.sort(() => { + const sign = Math.round(Math.random()) > 0 ? 1 : -1; + + return sign; + }), + }; + }); return publishedQuestions; }; const getFlashCardQuestions = (questions) => - questions.filter((question) => !question['Multiple Choice Only']); + questions + .filter((question) => !question['Multiple Choice Only']) + .map((question, index) => ({ + ...question, + pageNumber: index + 1, + })); const getUniqueCategories = (questions) => { return [ diff --git a/pages/flash-card-questions.ejs b/pages/flash-card-questions.ejs new file mode 100644 index 0000000..a33cd08 --- /dev/null +++ b/pages/flash-card-questions.ejs @@ -0,0 +1,5 @@ +--- +permalink: /flash-card-questions.json +eleventyExcludeFromCollections: true +--- +<%- JSON.stringify(questionData.flashCardQuestions) -%> diff --git a/pages/flash-cards/game-settings.njk b/pages/flash-cards/game-settings.njk new file mode 100644 index 0000000..b472f4b --- /dev/null +++ b/pages/flash-cards/game-settings.njk @@ -0,0 +1,20 @@ +--- +title: Flash Cards Game Settings +seo_title: "Flash Cards Game Settings: Trivia11y" +description: Choose from categories to study using flash cards to test your accessibility knowledge. +--- + +{% extends 'layout.njk' %} + +{% block content%} + {% from 'macros/game-settings.njk' import gameSettings %} + {{ gameSettings('Flash Cards Game Settings', questionData.flashCardCategories, 'flash-cards') }} +{% endblock %} + +{% block scripts %} + + +{% endblock %} diff --git a/pages/flash-cards/index.njk b/pages/flash-cards/index.njk index 090f480..634252d 100644 --- a/pages/flash-cards/index.njk +++ b/pages/flash-cards/index.njk @@ -21,14 +21,14 @@ eleventyExcludeFromCollections: true
-

+

Question {{ questionGroup.pageNumber }} of {{ questionGroup.questionTotal }}

+

{% if questionGroup.category !== 'All Questions' %} Category: {{ questionGroup.category }} {% else %} - All Categories + {{ questionGroup.question.Tags | csvList }} {% endif %}

-

Question {{ questionGroup.pageNumber }} of {{ questionGroup.questionTotal }}

{% from 'macros/flash-card.njk' import flashCard %} {{ flashCard(questionGroup.question) }} diff --git a/pages/index.njk b/pages/index.njk index 269842d..fb0385c 100644 --- a/pages/index.njk +++ b/pages/index.njk @@ -20,18 +20,38 @@ description: A quiz game and study tool to help those at all skill levels to lea Choose a game format and then select a category to help you test your knowledge: Flash Cards for reviewing what you know, Short Answer questions for confirming you actually know your stuff, and Multiple Choice for simulating test conditions.

- {% from 'macros/categories.njk' import categories %} -
-
- {{ categories('flash-cards', 'Flash Cards', questionData.flashCardCategories) }} -
-
- {{ categories('short-answer', 'Short Answer', questionData.flashCardCategories) }} -
-
- {{ categories('multiple-choice', 'Multiple Choice', questionData.categories) }} -
-
+
{% endblock %} diff --git a/pages/multiple-choice/game-settings.njk b/pages/multiple-choice/game-settings.njk new file mode 100644 index 0000000..651cc79 --- /dev/null +++ b/pages/multiple-choice/game-settings.njk @@ -0,0 +1,20 @@ +--- +title: Multiple Choice Game Settings +seo_title: "Multiple Choice Game Settings: Trivia11y" +description: Choose from categories to study using multiple choice questions to test your accessibility knowledge. +--- + +{% extends 'layout.njk' %} + +{% block content%} + {% from 'macros/game-settings.njk' import gameSettings %} + {{ gameSettings('Multiple Choice Game Settings', questionData.categories, 'multiple-choice') }} +{% endblock %} + +{% block scripts %} + + +{% endblock %} diff --git a/pages/multiple-choice/index.njk b/pages/multiple-choice/index.njk index 6c244d5..950145a 100644 --- a/pages/multiple-choice/index.njk +++ b/pages/multiple-choice/index.njk @@ -22,14 +22,14 @@ eleventyExcludeFromCollections: true
-

+

Question {{ questionGroup.pageNumber }} of {{ questionGroup.questionTotal }}

+

{% if questionGroup.category !== 'All Questions' %} Category: {{ questionGroup.category }} {% else %} - All Categories + {{ questionGroup.question.Tags | csvList }} {% endif %}

-

Question {{ questionGroup.pageNumber }} of {{ questionGroup.questionTotal }}

{% from 'macros/multiple-choice.njk' import multipleChoice %} diff --git a/pages/short-answer/game-settings.njk b/pages/short-answer/game-settings.njk new file mode 100644 index 0000000..8207f4f --- /dev/null +++ b/pages/short-answer/game-settings.njk @@ -0,0 +1,20 @@ +--- +title: Short Answer Game Settings +seo_title: "Short Answer Game Settings: Trivia11y" +description: Choose from categories to study using short answer questions to test your accessibility knowledge. +--- + +{% extends 'layout.njk' %} + +{% block content%} + {% from 'macros/game-settings.njk' import gameSettings %} + {{ gameSettings('Short Answer Game Settings', questionData.flashCardCategories, 'short-answer') }} +{% endblock %} + +{% block scripts %} + + +{% endblock %} diff --git a/pages/short-answer/index.njk b/pages/short-answer/index.njk index c385e44..7cb86d4 100644 --- a/pages/short-answer/index.njk +++ b/pages/short-answer/index.njk @@ -21,14 +21,14 @@ eleventyExcludeFromCollections: true
-

- {% if questionGroup.category !== 'All Questions' %} - Category: {{ questionGroup.category }} - {% else %} - All Categories - {% endif %} -

-

Question {{ questionGroup.pageNumber }} of {{ questionGroup.questionTotal }}

+

Question {{ questionGroup.pageNumber }} of {{ questionGroup.questionTotal }}

+

+ {% if questionGroup.category !== 'All Questions' %} + Category: {{ questionGroup.category }} + {% else %} + {{ questionGroup.question.Tags | csvList }} + {% endif %} +

{% from 'macros/short-answer.njk' import shortAnswer %} diff --git a/src/css/components/_button.scss b/src/css/components/_button.scss new file mode 100644 index 0000000..f7bc109 --- /dev/null +++ b/src/css/components/_button.scss @@ -0,0 +1,10 @@ +.cmp-button { + cursor: pointer; + padding: 0.5rem 1rem; + background-color: var(--background-color); + color: var(--text-color); + font-size: clamp(1rem, 1rem + 1vw, 2rem); + border: 0.125rem solid var(--text-color); + border-radius: 0.25rem; + box-shadow: 0.25rem 0.25rem 0 0 var(--shadow); +} diff --git a/src/css/components/_categories.scss b/src/css/components/_categories.scss index 0227f15..4191751 100644 --- a/src/css/components/_categories.scss +++ b/src/css/components/_categories.scss @@ -27,6 +27,10 @@ align-items: center; transition: color 150ms ease-in-out, text-decoration-color 150ms ease-in-out; + &--alternative { + font-size: clamp(0.875rem, 0.875rem + 0.5vw, 1.125rem); + } + &:hover { color: var(--foundry-culture-base); text-decoration-color: hsl(var(--text-color-hsl) / 0%); diff --git a/src/css/components/_category-heading.scss b/src/css/components/_category-heading.scss deleted file mode 100644 index a7e67a8..0000000 --- a/src/css/components/_category-heading.scss +++ /dev/null @@ -1,20 +0,0 @@ -.cmp-category-heading { - font-stretch: 125%; - font-size: clamp(1.5rem, 1.5rem + 0.5vw, 2.5rem); - font-weight: 280; - position: relative; - margin: 0; - - - &__link { - text-decoration: underline; - text-decoration-thickness: 1px; - text-underline-offset: 2px; - text-decoration-color: hsl(var(--smokey-black-hsl) / 0%); - transition: text-decoration-color 150ms ease-in-out; - - &:hover { - text-decoration-color: hsl(var(--smokey-black-hsl) / 50%); - } - } -} diff --git a/src/css/components/_checkbox.scss b/src/css/components/_checkbox.scss new file mode 100644 index 0000000..28c9e79 --- /dev/null +++ b/src/css/components/_checkbox.scss @@ -0,0 +1,28 @@ +.cmp-checkbox { + &__grid { + display: grid; + grid-template-columns: 1fr; + gap: 1rem 2rem; + + > div:first-child { + grid-column: 1 / -1; + } + + @container (min-width: 36rem) { + grid-template-columns: auto 1fr; + } + } + + &__wrapper { + display: flex; + align-items: center; + gap: 0.25rem; + font-size: clamp(1rem, 1rem + 0.5vw, 1.5rem); + } + + &__input { + accent-color: var(--link-color); + height: 0.8em; + width: 0.8em; + } +} diff --git a/src/css/components/_game-header.scss b/src/css/components/_game-header.scss index 07ab364..64efd19 100644 --- a/src/css/components/_game-header.scss +++ b/src/css/components/_game-header.scss @@ -6,7 +6,7 @@ margin: 0; } - &__question-count { + &__subtitle { margin: 0; font-weight: 400; font-size: clamp(1rem, var(--size) + 0.5vw, 1.5rem); diff --git a/src/css/components/_inline-form.scss b/src/css/components/_inline-form.scss index b38e01f..77b196f 100644 --- a/src/css/components/_inline-form.scss +++ b/src/css/components/_inline-form.scss @@ -25,15 +25,4 @@ border: 0.125rem solid var(--text-color); border-radius: 0.25rem; } - - &__button { - cursor: pointer; - padding: 0.5rem 1rem; - background-color: var(--background-color); - color: var(--text-color); - font-size: clamp(1rem, 1rem + 1vw, 2rem); - border: 0.125rem solid var(--text-color); - border-radius: 0.25rem; - box-shadow: 0.25rem 0.25rem 0 0 var(--shadow); - } } diff --git a/src/css/elements/_fieldset-legend.scss b/src/css/elements/_fieldset-legend.scss new file mode 100644 index 0000000..55cb188 --- /dev/null +++ b/src/css/elements/_fieldset-legend.scss @@ -0,0 +1,12 @@ +fieldset { + container: fieldset / inline-size; + border: none; + margin: 0; + padding: 0; +} + +legend { + display: block; + margin-block-end: 0.5rem; + font-size: clamp(1rem, 1rem + 1vw, 2rem); +} diff --git a/src/css/objects/_game-type.scss b/src/css/objects/_game-type.scss deleted file mode 100644 index c1d9868..0000000 --- a/src/css/objects/_game-type.scss +++ /dev/null @@ -1,15 +0,0 @@ -.obj-game-type { - container: game-type / inline-size; - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: clamp(1rem, 1rem + 0.5vw, 2rem); - - &__group { - container: game-type-group / inline-size; - grid-column: span 2; - - @container (min-width: 60rem) { - grid-column: span 1; - } - } -} diff --git a/src/css/styles.scss b/src/css/styles.scss index d5beb94..33a2536 100644 --- a/src/css/styles.scss +++ b/src/css/styles.scss @@ -56,6 +56,7 @@ @forward 'elements/heading'; @forward 'elements/a'; @forward 'elements/p'; +@forward 'elements/fieldset-legend'; // ===================================================================== // 5. Objects @@ -63,7 +64,6 @@ // for example media object known from OOCSS. @forward 'objects/page'; @forward 'objects/width-limiter'; -@forward 'objects/game-type'; // ===================================================================== // 6. Components @@ -76,11 +76,12 @@ @forward 'components/question'; @forward 'components/answer'; @forward 'components/categories'; -@forward 'components/category-heading'; @forward 'components/multiple-choice'; @forward 'components/game-header'; @forward 'components/explanation-section'; @forward 'components/inline-form'; +@forward 'components/button'; +@forward 'components/checkbox'; // ===================================================================== // 7. Vendors (Optional) diff --git a/src/js/game-selection.js b/src/js/game-selection.js index 976731f..450ff7f 100644 --- a/src/js/game-selection.js +++ b/src/js/game-selection.js @@ -1,3 +1,3 @@ -import { interceptCategoryNavigation } from './helpers/intercept-category-navigation'; +import { interceptQuickStartNavigation } from './helpers/intercept-quick-start-navigation'; -interceptCategoryNavigation(); +interceptQuickStartNavigation(); diff --git a/src/js/game-settings.js b/src/js/game-settings.js new file mode 100644 index 0000000..e0aa352 --- /dev/null +++ b/src/js/game-settings.js @@ -0,0 +1,67 @@ +/* globals IS_MULTIPLE_CHOICE GAME_TYPE */ +import { getQuestions, getRelevantQuestions, getQuestionsForGame } from './helpers/get-questions'; + +let questions; + +const getQuestionCountForCategory = (questions, categoryName) => { + const relevantQuestions = getRelevantQuestions(questions, categoryName, IS_MULTIPLE_CHOICE); + + return relevantQuestions.length; +}; + +const updateQuestionCounts = async () => { + questions = await getQuestions(IS_MULTIPLE_CHOICE); + + const categoryCountElements = document.querySelectorAll('[data-category]'); + categoryCountElements.forEach((element) => { + const category = element.dataset.category; + const count = getQuestionCountForCategory(questions, category); + + element.textContent = `(${count})`; + }); +}; + +const handleSelectionChange = async () => { + const questionsForGame = await getQuestionsForGame(questions, IS_MULTIPLE_CHOICE); + const numberOfQuestions = questionsForGame.length; + const questionCountElement = document.querySelector('[data-question-total]'); + if (questionCountElement) { + questionCountElement.textContent = numberOfQuestions; + } +}; + +const initializeCategorySelectionChangeListener = () => { + const elements = document.querySelectorAll('input[name="category"]'); + elements.forEach((element) => { + element.addEventListener('change', handleSelectionChange); + }); +}; + +const startGame = async () => { + sessionStorage.removeItem('questions'); + sessionStorage.removeItem('questionStatus'); + + const questionsForGame = await getQuestionsForGame(questions, IS_MULTIPLE_CHOICE); + const questionOrder = questionsForGame + .map((question) => `/${GAME_TYPE}/all-questions/${question.pageNumber}/`) + .sort(() => (Math.random() > 0.5 ? 1 : -1)); + + sessionStorage.setItem('questions', JSON.stringify(questionOrder)); + sessionStorage.setItem('currentQuestionIndex', '0'); + + window.location.href = questionOrder[0]; +}; + +const initializeFormSubmitListener = () => { + const form = document.querySelector('[data-game-settings]'); + form?.addEventListener('submit', (event) => { + event.preventDefault(); + + startGame(); + }); +}; + +updateQuestionCounts(); +initializeCategorySelectionChangeListener(); +initializeFormSubmitListener(); +handleSelectionChange(); diff --git a/src/js/helpers/get-questions.js b/src/js/helpers/get-questions.js index 81ea11d..f840bcf 100644 --- a/src/js/helpers/get-questions.js +++ b/src/js/helpers/get-questions.js @@ -1,20 +1,44 @@ -export const getQuestions = async () => { - const response = await fetch('/questions.json'); - const questions = await response.json(); +export const getQuestions = async (isMultipleChoice = true) => { + const response = await fetch(isMultipleChoice ? '/questions.json' : '/flash-card-questions.json'); + const questions = await response.json(); - return questions; + return questions; }; export const getRelevantQuestions = (questions, category, isMultipleChoice) => { - return questions.filter((question) => { - if (!isMultipleChoice && question['Multiple Choice Only']) { - return false; - } + return questions.filter((question) => { + if (!isMultipleChoice && question['Multiple Choice Only']) { + return false; + } - if (category !== 'All Questions' && !question.Tags.some((tag) => tag === category)) { + if (category !== 'All Questions' && !question.Tags.some((tag) => tag === category)) { return false; } - return true; - }); + return true; + }); +}; + +export const getQuestionsForGame = async (questions, isMultipleChoice) => { + const questionsForGame = []; + if (!questions) { + questions = await getQuestions(isMultipleChoice); + } + const selectedElements = document.querySelectorAll('input[name="category"]:checked'); + + if (!selectedElements.length) { + return questions; + } + + selectedElements.forEach((element) => { + const category = element.value; + const relevantQuestions = getRelevantQuestions(questions, category, isMultipleChoice); + relevantQuestions.forEach((question) => { + if (!questionsForGame.some(({ id }) => id === question.id)) { + questionsForGame.push(question); + } + }); + }); + + return questionsForGame; }; diff --git a/src/js/helpers/intercept-category-navigation.js b/src/js/helpers/intercept-category-navigation.js deleted file mode 100644 index 288c624..0000000 --- a/src/js/helpers/intercept-category-navigation.js +++ /dev/null @@ -1,31 +0,0 @@ -import { getQuestions, getRelevantQuestions } from './get-questions'; - -export const interceptCategoryNavigation = async () => { - sessionStorage.removeItem('questions'); - sessionStorage.removeItem('questionStatus'); - const questions = await getQuestions(); - const links = document.querySelectorAll('.cmp-categories__link'); - - links.forEach((link) => { - link.addEventListener('click', (event) => { - event.preventDefault(); - - const relevantQuestions = getRelevantQuestions( - questions, - link.dataset.category, - link.dataset.type === 'Multiple Choice' - ); - - const questionOrder = Array.from( - { length: relevantQuestions.length }, - (_item, index) => `${link.dataset.baseLink}${index + 1}/` - ).sort(() => (Math.random() > 0.5 ? 1 : -1)); - - sessionStorage.setItem('questions', JSON.stringify(questionOrder)); - - sessionStorage.setItem('currentQuestionIndex', '0'); - - window.location.href = questionOrder[0]; - }); - }); -}; diff --git a/src/js/helpers/intercept-quick-start-navigation.js b/src/js/helpers/intercept-quick-start-navigation.js new file mode 100644 index 0000000..dfa14e6 --- /dev/null +++ b/src/js/helpers/intercept-quick-start-navigation.js @@ -0,0 +1,30 @@ +import { getQuestionsForGame } from './get-questions'; + +const quickStartGame = async (gameType) => { + const questionsForGame = await getQuestionsForGame(null, gameType === 'multiple-choice'); + + const questionOrder = questionsForGame + .map((question) => `/${gameType}/all-questions/${question.pageNumber}/`) + .sort(() => (Math.random() > 0.5 ? 1 : -1)) + .slice(0, 50); + + sessionStorage.setItem('questions', JSON.stringify(questionOrder)); + sessionStorage.setItem('currentQuestionIndex', '0'); + + window.location.href = questionOrder[0]; +}; + +export const interceptQuickStartNavigation = async () => { + sessionStorage.removeItem('questions'); + sessionStorage.removeItem('questionStatus'); + const links = document.querySelectorAll('[data-game-type]'); + + links.forEach((link) => { + link.addEventListener('click', (event) => { + event.preventDefault(); + + const { gameType } = event.target.dataset; + quickStartGame(gameType); + }); + }); +}; diff --git a/src/js/helpers/update-pagination-links.js b/src/js/helpers/update-pagination-links.js index 8c8b49b..ac287da 100644 --- a/src/js/helpers/update-pagination-links.js +++ b/src/js/helpers/update-pagination-links.js @@ -1,97 +1,94 @@ const removeLink = (selector) => { - const span = document.createElement('span'); - const link = document.querySelector(selector); - link?.replaceWith(span); + const span = document.createElement('span'); + const link = document.querySelector(selector); + link?.replaceWith(span); }; const setLinkHref = (selector, url, linkText) => { - const link = document.querySelector(selector); - - if (link) { - link.setAttribute('href', url); - } else { - const span = document.querySelector('.cmp-pagination span'); - const a = document.createElement('a'); - a.setAttribute('href', url); - a.setAttribute(selector.replace('[', '').replace(']', ''), ''); - a.innerHTML = linkText; - span?.replaceWith(a); - } + const link = document.querySelector(selector); + + if (link) { + link.setAttribute('href', url); + if (linkText) { + link.textContent = linkText; + } + } else { + const span = document.querySelector('.cmp-pagination span'); + const a = document.createElement('a'); + a.setAttribute('href', url); + a.setAttribute(selector.replace('[', '').replace(']', ''), ''); + a.textContent = linkText; + span?.replaceWith(a); + } }; const updatePreviousLink = (questions, currentQuestionIndex) => { - if (currentQuestionIndex <= 0) { - removeLink('[data-prev-link]'); - } else { - setLinkHref( - '[data-prev-link]', - questions[currentQuestionIndex - 1], - 'Previous Question' - ); - } + if (currentQuestionIndex <= 0) { + removeLink('[data-prev-link]'); + } else { + setLinkHref('[data-prev-link]', questions[currentQuestionIndex - 1], 'Previous Question'); + } }; const updateNextLink = (questions, currentQuestionIndex) => { - if (currentQuestionIndex >= questions.length - 1) { - removeLink('[data-next-link]'); - } else { - setLinkHref( - '[data-next-link]', - questions[currentQuestionIndex + 1], - 'Next Question' - ); - } + if (currentQuestionIndex >= questions.length - 1) { + setLinkHref('[data-next-link]', '../../game-settings/', 'Set up new game'); + } else { + setLinkHref('[data-next-link]', questions[currentQuestionIndex + 1], 'Next Question'); + } }; const updateQuestionNumber = (currentQuestionIndex) => { - const currentQuestionElement = document.querySelector( - '[data-question-number]' - ); + const currentQuestionElement = document.querySelector('[data-question-number]'); + + if (currentQuestionElement) { + currentQuestionElement.textContent = currentQuestionIndex + 1; + } +}; - if (currentQuestionElement) { - currentQuestionElement.innerHTML = currentQuestionIndex + 1; - } +const updateQuestionTotal = (total) => { + const questionTotalElement = document.querySelector('[data-question-total]'); + + if (questionTotalElement) { + questionTotalElement.textContent = total; + } }; -const updatePageTitle = (currentQuestionIndex) => { - document.title = document.title.replace(/\d+/, currentQuestionIndex + 1); +const updatePageTitle = (currentQuestionIndex, total) => { + let newTitle = document.title.replace(/\d+/, currentQuestionIndex + 1); + newTitle = newTitle.replace(/of\s\d+/, `of ${total}`); + + document.title = newTitle; }; export const updatePaginationLinks = () => { - const questionsRaw = sessionStorage.getItem('questions'); - const currentQuestionIndexRaw = sessionStorage.getItem( - 'currentQuestionIndex' - ); - - if (questionsRaw && currentQuestionIndexRaw) { - const questions = JSON.parse(questionsRaw); - const currentQuestionIndex = Number.parseInt(currentQuestionIndexRaw, 10); - - updatePreviousLink(questions, currentQuestionIndex); - updateNextLink(questions, currentQuestionIndex); - updateQuestionNumber(currentQuestionIndex); - updatePageTitle(currentQuestionIndex); - - const previousLink = document.querySelector('[data-prev-link]'); - previousLink?.addEventListener('click', (event) => { - event.preventDefault(); - - sessionStorage.setItem( - 'currentQuestionIndex', - (currentQuestionIndex - 1).toString() - ); - window.location.href = event.target.href; - }); - - const nextLink = document.querySelector('[data-next-link]'); - nextLink?.addEventListener('click', (event) => { - event.preventDefault(); - - sessionStorage.setItem( - 'currentQuestionIndex', - (currentQuestionIndex + 1).toString() - ); - window.location.href = event.target.href; - }); - } + const questionsRaw = sessionStorage.getItem('questions'); + const currentQuestionIndexRaw = sessionStorage.getItem('currentQuestionIndex'); + + if (questionsRaw && currentQuestionIndexRaw) { + const questions = JSON.parse(questionsRaw); + const currentQuestionIndex = Number.parseInt(currentQuestionIndexRaw, 10); + + updatePreviousLink(questions, currentQuestionIndex); + updateNextLink(questions, currentQuestionIndex); + updateQuestionNumber(currentQuestionIndex); + updateQuestionTotal(questions.length); + updatePageTitle(currentQuestionIndex, questions.length); + + const previousLink = document.querySelector('[data-prev-link]'); + previousLink?.addEventListener('click', (event) => { + event.preventDefault(); + + sessionStorage.setItem('currentQuestionIndex', (currentQuestionIndex - 1).toString()); + window.location.href = event.target.href; + }); + + const nextLink = document.querySelector('[data-next-link]'); + nextLink?.addEventListener('click', (event) => { + event.preventDefault(); + + sessionStorage.setItem('currentQuestionIndex', (currentQuestionIndex + 1).toString()); + window.location.href = event.target.href; + }); + } }; diff --git a/src/macros/categories.njk b/src/macros/categories.njk deleted file mode 100644 index 0bc671c..0000000 --- a/src/macros/categories.njk +++ /dev/null @@ -1,11 +0,0 @@ -{% macro categories(catdir, title, questionData) %} -

- {{ title }} -

- -
    -{% for category in questionData %} - {% include 'partials/category.njk' %} -{% endfor %} -
-{% endmacro %} diff --git a/src/macros/game-settings.njk b/src/macros/game-settings.njk new file mode 100644 index 0000000..0e88a38 --- /dev/null +++ b/src/macros/game-settings.njk @@ -0,0 +1,22 @@ +{% macro gameSettings(title, categories, gameType) %} +
+

{{ title }}

+ +
+
+ Question Categories +
+ {% for category in categories %} +
+ + +
+ {% endfor %} +
+
+
+ +
+
+
+{% endmacro %} diff --git a/src/macros/short-answer.njk b/src/macros/short-answer.njk index 701d9b1..82d6a71 100644 --- a/src/macros/short-answer.njk +++ b/src/macros/short-answer.njk @@ -10,7 +10,7 @@
-