Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 50 additions & 46 deletions src/pages/home/components/GameModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,45 @@ export function handleFormChange() {
const errorMessage = gameModal.querySelector(".error-message");
const difficultySelect = gameModal.querySelector("select[name='difficulty']");
const inputs = [amountInput, categoriesSelect, difficultySelect];
let maximum = maxAmount;
inputs.forEach((input) => {
input.addEventListener("change", async (e) => {
if (categoriesSelect.value !== "") {
const allQuestionCount = await api.categoryMaxQuestions(
categoriesSelect.value
);
switch (difficultySelect.value) {
case "easy":
maximum = Math.min(
allQuestionCount.total_easy_question_count,
maxAmount
);
amountInput.max = maximum;
errorMessage.textContent = errorMesageTextcontent(maximum);
break;
case "medium":
maximum = Math.min(
allQuestionCount.total_medium_question_count,
maxAmount
);
amountInput.max = maximum;
errorMessage.textContent = errorMesageTextcontent(maximum);
break;
case "hard":
maximum = Math.min(
allQuestionCount.total_hard_question_count,
maxAmount
);
amountInput.max = maximum;
errorMessage.textContent = errorMesageTextcontent(maximum);
break;
default:
maximum = Math.min(
allQuestionCount.total_question_count,
maxAmount
);
amountInput.max = maximum;
errorMessage.textContent = errorMesageTextcontent(maximum);
}
} else {
amountInput.max = maxAmount;
// this could be simplfied for readability
const updateMaxQuestions = async () => {
if (categoriesSelect.value !== "") {
const allQuestionCount = await api.categoryMaxQuestions(
categoriesSelect.value
);
let maximum = maxAmount;
switch (difficultySelect.value) {
case "easy":
maximum = Math.min(
allQuestionCount.total_easy_question_count,
maxAmount
);
break;
case "medium":
maximum = Math.min(
allQuestionCount.total_medium_question_count,
maxAmount
);
break;
case "hard":
maximum = Math.min(
allQuestionCount.total_hard_question_count,
maxAmount
);
break;
default:
maximum = Math.min(allQuestionCount.total_question_count, maxAmount);
}
});
});
amountInput.max = maximum;
errorMessage.textContent = errorMessageTextContent(maximum);
} else {
amountInput.max = maxAmount;
}
};

inputs.forEach((input) =>
input.addEventListener("change", updateMaxQuestions)
);
}

export function handleCancel() {
Expand All @@ -89,6 +83,17 @@ export function handleCancel() {
});
}

// ALTERNATIVE
// export function handleCancel() {
// const gameModal = document.querySelector(".game-modal");
// gameModal.addEventListener("click", (e) => {
// if (e.target.matches("button[type='reset']")) {
// console.log("click cancel");
// gameModal.close();
// }
// });
// }

export function handleSubmit() {
const gameModal = document.querySelector(".game-modal");
const playButton = gameModal.querySelector("button[type='submit']");
Expand All @@ -108,9 +113,8 @@ export function handleSubmit() {
db.setQuiz(quiz);
window.location.href = "/quiz";
}
} else {
// invalid form
}
// can remove the else block
});
}

Expand Down
34 changes: 14 additions & 20 deletions src/pages/home/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,21 @@ function html(categories) {
`;
}

// this could be simplified to
async function populateSelect(select, options, selectedId = null) {
const selectOptions = options
.map((option) => {
let name = option.name;
if (select.name === "category") {
if (name.includes(":")) {
name = name.split(":")[1];
}
}
if (selectedId === option.id) {
return Option({
value: option.id,
label: name,
selected: true,
});
} else {
return Option({ value: option.id, label: name });
}
})
.join("");
select.innerHTML = selectOptions;
const selectOptions = options.map((option) => {
let name = option.name;
if (select.name === "category" && name.includes(":")) {
name = name.split(":")[1];
}
return Option({
value: option.id,
label: name,
selected: selectedId === option.id,
});
});

select.innerHTML = selectOptions.join("");
}

async function initializeGameModal() {
Expand Down
16 changes: 12 additions & 4 deletions src/utils/api.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { db } from "./db";

// Best practice is to define the base url in a constant global variable
const BASE_URL = "https://opentdb.com";

export const api = {
async _request(endpoint, params = null) {
console.log("requesting from API");
const baseUrl = "https://opentdb.com";
const url = new URL(endpoint, baseUrl);
const url = new URL(endpoint, BASE_URL);
if (params) url.search = new URLSearchParams(params);
const response = await fetch(url);
// If the response is not ok, throw an error
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
},
async categories() {
Expand All @@ -21,7 +27,8 @@ export const api = {
}
},
async categoryMaxQuestions(categoryId) {
if (categoryId === "") {
// This can be simplified to take advantage of truthy/falsy values
if (!categoryId) {
return 50;
}
const endpoint = `/api_count.php?category=${categoryId}`;
Expand All @@ -30,7 +37,8 @@ export const api = {
const category = cachedCategories.trivia_categories.find(
(category) => category.id === parseInt(categoryId)
);
if (category && category.question_count) {
// This can be simplified to
if (category?.question_count) {
return category.question_count;
} else {
const questionCount = await this._request(endpoint);
Expand Down
40 changes: 29 additions & 11 deletions src/utils/db.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
export const db = {
// This can be simplified to
getQuiz() {
try {
const quiz = JSON.parse(localStorage.getItem("quiz"));
return quiz;
return JSON.parse(localStorage.getItem("quiz")) || this.initializeQuiz();
} catch (err) {
console.log(err);
return null;
console.error("Error getting quiz from localStorage:", err);
return this.initializeQuiz();
}
},
// this can be simplified to
setQuiz(quiz) {
localStorage.setItem("quiz", JSON.stringify(quiz));
if (!quiz.current_question) this.setCurrentQuestion(0);
if (!quiz.score) this.setScore(0);
if (!quiz.answers) this.setAnswers({ correct: [], incorrect: [] });
},

initializeQuiz() {
const quiz = {
current_question: 0,
score: 0,
answers: { correct: [], incorrect: [] },
};
this.setQuiz(quiz);
return quiz;
},

setCurrentQuestion(index = 0) {
const quiz = this.getQuiz();
quiz.current_question = index;
localStorage.setItem("quiz", JSON.stringify(quiz));
// now we can take advantage of the fact that setQuiz is already defined
this.setQuiz(quiz);
},
incrementQuestionIndex() {
const quiz = this.getQuiz();
Expand All @@ -32,18 +42,26 @@ export const db = {
setScore(score = 0) {
const quiz = this.getQuiz();
quiz.score = score;
localStorage.setItem("quiz", JSON.stringify(quiz));
// same here
this.setQuiz(quiz);
},
setAnswers(answers = { correct: [], incorrect: [] }) {
const quiz = this.getQuiz();
quiz.answers = answers;
localStorage.setItem("quiz", JSON.stringify(quiz));
// and here
this.setQuiz(quiz);
},
setCategories(categories) {
localStorage.setItem("categories", JSON.stringify(categories));
},
getCategories() {
return JSON.parse(localStorage.getItem("categories") || "[]");
// add try/catch block to handle errors
try {
return JSON.parse(localStorage.getItem("categories")) || [];
} catch (err) {
console.error("Error getting categories from localStorage:", err);
return [];
}
},
};

Expand Down