diff --git a/src/api/getQuizQuestions.js b/src/api/getQuizQuestions.js index b135066..ad4d96a 100644 --- a/src/api/getQuizQuestions.js +++ b/src/api/getQuizQuestions.js @@ -28,7 +28,7 @@ async function retrieveQuizQuestions(animal) { return data; } catch (error) { - console.error('Error:', error); + return console.error('Error:', error); } } diff --git a/src/components/Answer/Answer.js b/src/components/Answer/Answer.js index 4bcf535..aed2bf9 100644 --- a/src/components/Answer/Answer.js +++ b/src/components/Answer/Answer.js @@ -16,7 +16,7 @@ export default class Answer { if (this.checkIfCorrect()) { score = 1; if (this.changed) { - score = score / 2; + score /= score / 2; } } return score; diff --git a/src/components/Dropdown/Dropdown.css b/src/components/Dropdown/Dropdown.css new file mode 100644 index 0000000..13efdd8 --- /dev/null +++ b/src/components/Dropdown/Dropdown.css @@ -0,0 +1,23 @@ +select { + -webkit-appearance: button; + -moz-appearance: button; + -webkit-user-select: none; + -moz-user-select: none; + -webkit-padding-end: 10px; + -moz-padding-end: 10px; + -webkit-padding-start: 5px; + -moz-padding-start: 5px; + background-color: #648080; + border: 1px solid #aaa; + border-radius: 10px; + box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); + color: #2c3e50; + font-size: inherit; + margin: 0; + overflow: hidden; + padding-top: 2px; + padding-bottom: 2px; + text-overflow: ellipsis; + white-space: nowrap; + margin-right: 20px; +} diff --git a/src/components/Dropdown/Dropdown.js b/src/components/Dropdown/Dropdown.js new file mode 100644 index 0000000..3d7c7c2 --- /dev/null +++ b/src/components/Dropdown/Dropdown.js @@ -0,0 +1,28 @@ +import './Dropdown.css'; + +export default function Dropdown(className, dropdownLabel, option1, option2) { + const dropdown = document.createElement('div'); + dropdown.classList.add('custom-select'); + dropdown.classList.add(className); + + const select = document.createElement('select'); + select.setAttribute('name', 'settings'); + select.setAttribute('id', 'settings'); + + const defaultSetting = document.createElement('option'); + defaultSetting.setAttribute('value', dropdownLabel); + defaultSetting.innerHTML = dropdownLabel; + + const option1Setting = document.createElement('option'); + option1Setting.setAttribute('value', `${option1}`); + option1Setting.innerHTML = option1.toLowerCase(); + + const option2Setting = document.createElement('option'); + option2Setting.setAttribute('value', `${option2}`); + option2Setting.innerHTML = option2.toLowerCase(); + + select.append(defaultSetting, option1Setting, option2Setting); + dropdown.append(select); + + return dropdown; +} diff --git a/src/components/RangeSelect/RangeSelect.css b/src/components/RangeSelect/RangeSelect.css new file mode 100644 index 0000000..43c51b8 --- /dev/null +++ b/src/components/RangeSelect/RangeSelect.css @@ -0,0 +1,4 @@ +.range { + display: flex; + padding: 0.5em 0.5em; +} diff --git a/src/components/RangeSelect/RangeSelect.js b/src/components/RangeSelect/RangeSelect.js new file mode 100644 index 0000000..380d8a0 --- /dev/null +++ b/src/components/RangeSelect/RangeSelect.js @@ -0,0 +1,19 @@ +import './RangeSelect.css'; +import { DEFAULT_MIN, DEFAULT_MAX } from '../ScoreFilter/ScoreFilter'; + +export default function RangeSelect(labelName) { + const range = document.createElement('div'); + range.className = 'range'; + const label = document.createElement('p'); + label.innerHTML = labelName; + + const input = document.createElement('input'); + input.className = labelName; + input.type = 'number'; + input.min = DEFAULT_MIN; + input.max = DEFAULT_MAX; + + range.append(label, input); + + return range; +} diff --git a/src/components/ScoreFilter/ScoreFilter.css b/src/components/ScoreFilter/ScoreFilter.css new file mode 100644 index 0000000..c91ab19 --- /dev/null +++ b/src/components/ScoreFilter/ScoreFilter.css @@ -0,0 +1,41 @@ +.score-filter { + display: flex; + align-items: center; + align-content: center; + margin-top: 5vh; +} + +.score-range { + display: flex; +} + +input { + text-align: center; + margin-left: 10px; + height: 5vh; + width: 40px; + font-size: 60%; + text-align: right; +} + +button { + margin-top: 2vh; +} + +#settings { + text-align: center; +} + +#option { + text-align: center; +} + +@media only screen and (min-device-width: 280px) and (max-device-width: 1200px) { + .score-filter { + flex-direction: column; + margin-top: 2vh; + } + #settings { + margin: 10px auto; + } +} diff --git a/src/components/ScoreFilter/ScoreFilter.js b/src/components/ScoreFilter/ScoreFilter.js new file mode 100644 index 0000000..8a23686 --- /dev/null +++ b/src/components/ScoreFilter/ScoreFilter.js @@ -0,0 +1,133 @@ +import './ScoreFilter.css'; + +import Dropdown from '../Dropdown/Dropdown'; +import RangeSelect from '../RangeSelect/RangeSelect'; +import { getScoreFromLocalStorage, renderScores } from '../../views/Leaderboard/Leaderboard'; + +const DEFAULT_ABOUT = 'Select animal'; +const DEFAULT_TYPE = 'Select quiz type'; +export const DEFAULT_MIN = 1; +export const DEFAULT_MAX = 20; + +export const settings = { + about: DEFAULT_ABOUT, + type: DEFAULT_TYPE, + min: DEFAULT_MIN, + max: DEFAULT_MAX, +}; + +export default function ScoreFilter() { + const scoreFilter = document.createElement('div'); + scoreFilter.classList.add('score-filter'); + + const button = ClearButton(); + + const dropdownAbout = Dropdown('about-dropdown', DEFAULT_ABOUT, 'CATS', 'DOGS'); + const dropdownType = Dropdown('type-dropdown', DEFAULT_TYPE, 'MULTIPLE CHOICE', 'OPEN'); + scoreFilter.append(dropdownAbout, dropdownType); + + dropdownAbout.addEventListener('change', (e) => { + settings.about = e.target.value; + filterScores(); + scoreFilter.append(button); + }); + dropdownType.addEventListener('change', (e) => { + settings.type = e.target.value; + filterScores(); + scoreFilter.append(button); + }); + + const minRange = RangeSelect('min'); + const maxRange = RangeSelect('max'); + + scoreFilter.append(minRange, maxRange); + + minRange.addEventListener('change', (e) => { + settings.min = e.target.value; + filterScores(); + scoreFilter.append(button); + }); + + maxRange.addEventListener('change', (e) => { + settings.max = e.target.value; + filterScores(); + scoreFilter.append(button); + }); + + if (settings.about !== DEFAULT_ABOUT || settings.type !== DEFAULT_TYPE || settings.min !== 1 || settings.max !== 20) { + scoreFilter.append(button); + } + + return scoreFilter; +} + +// TODO: use Button component instead +function ClearButton() { + const button = document.createElement('button'); + button.innerHTML = 'clear filters'; + button.addEventListener('click', () => { + settings.about = DEFAULT_ABOUT; + settings.type = DEFAULT_TYPE; + settings.min = DEFAULT_MIN; + settings.max = DEFAULT_MAX; + filterScores(); + + const dropdowns = document.querySelectorAll('select'); + dropdowns.forEach((select) => { + select.selectedIndex = 0; + }); + + const minRange = document.querySelector('.min'); + minRange.value = DEFAULT_MIN; + + const maxRange = document.querySelector('.max'); + maxRange.value = DEFAULT_MAX; + + button.remove(); + }); + + return button; +} + +/* function resetSettings() { + settings.about = DEFAULT_ABOUT; + settings.type = DEFAULT_TYPE; + settings.min = DEFAULT_MIN; + settings.max = DEFAULT_MAX; + filterScores(); + + const dropdowns = document.querySelectorAll('select'); + dropdowns.forEach((select) => { + select.selectedIndex = 0; + }); + + const button = document.querySelector('.reset-settings'); + button.remove(); +} */ + +function filterScores() { + const scores = getScoreFromLocalStorage(); + const filteredScores = scores.filter(filterAbout).filter(filterType).filter(filterQuestionNumber); + renderScores(filteredScores); +} + +function filterAbout(item) { + if (settings.about === DEFAULT_ABOUT) { + return item; + } + return item.ABOUT === settings.about; +} + +function filterType(item) { + if (settings.type === DEFAULT_TYPE) { + return item; + } + return item.TYPE === settings.type; +} + +function filterQuestionNumber(item) { + if (item.NUMBER >= settings.min && item.NUMBER <= settings.max) { + return item; + } + return false; +} diff --git a/src/model/randomizer.js b/src/model/randomizer.js index ef86aa0..7eecb71 100644 --- a/src/model/randomizer.js +++ b/src/model/randomizer.js @@ -1,4 +1,4 @@ -import { getQuizQuestions } from '../api/getQuizQuestions.js'; +import { getQuizQuestions } from '../api/getQuizQuestions'; export async function getRandomQuizQuestions(animal, numberOfQuestions) { const questionToRandomize = await getQuizQuestions(animal); @@ -6,7 +6,6 @@ export async function getRandomQuizQuestions(animal, numberOfQuestions) { if (numberOfQuestions < randomQuestions.length) { return randomQuestions.slice(0, numberOfQuestions); - } else { - return randomQuestions; } + return randomQuestions; } diff --git a/src/views/Leaderboard/Leaderboard.css b/src/views/Leaderboard/Leaderboard.css index 716313b..62e4979 100644 --- a/src/views/Leaderboard/Leaderboard.css +++ b/src/views/Leaderboard/Leaderboard.css @@ -23,7 +23,7 @@ div#scorePage > * { justify-content: center; } -.podiumNick { +.podiumNickname { margin-top: 30px; margin-left: 15px; display: flex; @@ -94,7 +94,7 @@ button.resetButton { } @media (max-width: 960px) { - .podiumNick { + .podiumNickname { font-size: 1rem; } .listItem { diff --git a/src/views/Leaderboard/Leaderboard.js b/src/views/Leaderboard/Leaderboard.js index fdf4864..1f1a3f8 100644 --- a/src/views/Leaderboard/Leaderboard.js +++ b/src/views/Leaderboard/Leaderboard.js @@ -2,11 +2,13 @@ import './Leaderboard.css'; import Button from '../../components/Button/Button'; import '../../components/Button/Button.css'; +import ScoreFilter from '../../components/ScoreFilter/ScoreFilter'; + export function renderLeaderboard() { renderPodium(); createMenuButton(); renderResetBtn(); - getScoreFromLocalStorage(); + renderScores(getScoreFromLocalStorage()); } function renderPodium() { @@ -14,12 +16,14 @@ function renderPodium() {
| - | - | + | + | + | |
2 |
@@ -31,15 +35,15 @@ function renderPodium() {