From 17e4b42547bfc74d8e599201aed82e0cfaaa3637 Mon Sep 17 00:00:00 2001 From: ilbrandoric <240859022+ilbrandoric@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:21:18 +0100 Subject: [PATCH 1/4] dirty version 1 --- src/Requirements.md | 134 ++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 90 +++++++++++++++++++++-------- src/question.js | 20 +++++-- src/quiz.js | 60 ++++++++++++++++---- 4 files changed, 267 insertions(+), 37 deletions(-) create mode 100644 src/Requirements.md diff --git a/src/Requirements.md b/src/Requirements.md new file mode 100644 index 00000000..328e2b60 --- /dev/null +++ b/src/Requirements.md @@ -0,0 +1,134 @@ +# Quiz App Mini-Project Requirements + +## General +- Build a browser-based Quiz app using JavaScript, OOP, and DOM +- Work in teams of 2 using Live Share for collaboration +- Commit changes regularly and push to GitHub +- Submit the final GitHub repository link + +## Code Structure & Quality +- Use classes to organize data and functionality +- Keep code clean, readable, and well-organized +- Use descriptive variable names and proper file structure +- Remove unused code and maintain correct indentation + +## Question Class (src/Question.js) +- Constructor with: text, choices, answer, difficulty +- Properties: text, choices, answer, difficulty +- Implement shuffleChoices() method +- Pass all Jasmine unit tests + +## Quiz Class (src/Quiz.js) +- Constructor with: questions, timeLimit, timeRemaining +- Properties: questions, timeLimit, timeRemaining, correctAnswers, currentQuestionIndex +- Implement methods: + - getQuestion() + - moveToNextQuestion() + - shuffleQuestions() + - checkAnswer(answer) + - hasEnded() + - filterQuestionsByDifficulty(difficulty) + - averageDifficulty() +- Pass all Jasmine unit tests + +## DOM & Interaction (index.js) +- Display current question and choices +- Update progress bar and question count +- Handle answer selection and next button +- Show final results view +- Implement restart quiz functionality + +## Timer +- Implement countdown timer with setInterval / clearInterval +- Display remaining time during quiz +- Stop timer when quiz ends +- Restart timer when quiz restarts + +## Completion +- All features implemented and working +- All tests passing +- Repository ready for submission + + +# Detailed Quiz App Requirements + +## Question Class + +### Class Definition +- Question class must be defined +- Constructor must receive 4 arguments: + 1. text (string) + 2. choices (array of strings) + 3. answer (string) + 4. difficulty (number) + +### Properties +- text → assigned from 1st argument +- choices → assigned from 2nd argument +- answer → assigned from 3rd argument +- difficulty → assigned from 4th argument + +### shuffleChoices() Method +- Must be defined +- Must be a function +- Must receive no arguments +- Must shuffle the items in the choices array + +--- + +## Quiz Class + +### Class Definition +- Quiz class must be defined +- Constructor must receive 3 arguments: + 1. questions (array of Question objects) + 2. timeLimit (integer) + 3. timeRemaining (integer) + +### Properties +- questions → assigned from 1st argument +- timeLimit → assigned from 2nd argument +- timeRemaining → assigned from 3rd argument +- correctAnswers → initially 0 +- currentQuestionIndex → initially 0 + +### getQuestion() Method +- Must be defined +- Must be a function +- Must return questions[currentQuestionIndex] + +### moveToNextQuestion() Method +- Must be defined +- Must be a function +- Must increment currentQuestionIndex by 1 + +### shuffleQuestions() Method +- Must be defined +- Must be a function +- Must shuffle the questions array + +### checkAnswer(answer) Method +- Must be defined +- Must be a function +- Must receive 1 argument (answer) +- Must compare answer with current question’s answer +- Must increment correctAnswers if answer is correct + +### hasEnded() Method +- Must be defined +- Must be a function +- Must return false if currentQuestionIndex < questions.length +- Must return true if currentQuestionIndex === questions.length + +### filterQuestionsByDifficulty(difficulty) Method +- Must be defined +- Must be a function +- Must receive 1 argument (number 1–3) +- Must filter questions by difficulty +- Must not modify questions if difficulty is invalid + +### averageDifficulty() Method +- Must be defined +- Must be a function +- Must receive no arguments +- Must return the average difficulty of all questions diff --git a/src/index.js b/src/index.js index 03737ba3..970d73ca 100644 --- a/src/index.js +++ b/src/index.js @@ -126,14 +126,39 @@ document.addEventListener("DOMContentLoaded", () => { // Hint 1: You can use the `document.createElement()` method to create a new element. // Hint 2: You can use the `element.type`, `element.name`, and `element.value` properties to set the type, name, and value of an element. // Hint 3: You can use the `element.appendChild()` method to append an element to the choices container. - // Hint 4: You can use the `element.innerText` property to set the inner text of an element. + // Hint 4: You can use the `element.innerText` property to set the inner text of an element. - } +} - - function nextButtonHandler () { - let selectedAnswer; // A variable to store the selected answer value +function nextButtonHandler() { + // 1. Get all choice inputs + const choices = document.querySelectorAll('input[name="answer"]'); + + let selectedAnswer = null; + + // 2. Find which one is checked + choices.forEach(choice => { + if (choice.checked) { + selectedAnswer = choice.value; + } + }); + + // 3. If no answer selected, do nothing + if (!selectedAnswer) return; + + // 4. Check answer and move to next question + quiz.checkAnswer(selectedAnswer); + quiz.moveToNextQuestion(); + + // 5. Show next question (or end screen if finished) + if (!quiz.hasEnded()) { + showQuestion(); + } else { + showResults(); + } +} + @@ -149,26 +174,47 @@ document.addEventListener("DOMContentLoaded", () => { // 3. If an answer is selected (`selectedAnswer`), check if it is correct and move to the next question - // Check if selected answer is correct by calling the quiz method `checkAnswer()` with the selected answer. - // Move to the next question by calling the quiz method `moveToNextQuestion()`. - // Show the next question by calling the function `showQuestion()`. - } + // Check if selected answer is correct by calling the quiz method `checkAnswer()` with the selected answer. + // Move to the next question by calling the quiz method `moveToNextQuestion()`. + // Show the next question by calling the function `showQuestion()`. - function showResults() { +function showResults() { + // 1. Hide quiz view + quizView.style.display = "none"; - // YOUR CODE HERE: - // - // 1. Hide the quiz view (div#quizView) - quizView.style.display = "none"; + // 2. Show end view + endView.style.display = "block"; - // 2. Show the end view (div#endView) - endView.style.display = "flex"; - - // 3. Update the result container (div#result) inner text to show the number of correct answers out of total questions - resultContainer.innerText = `You scored 1 out of 1 correct answers!`; // This value is hardcoded as a placeholder - } - -}); \ No newline at end of file + // 3. Display final score + resultContainer.innerText = quiz.correctAnswers; +} + +}); + +const INITIAL_TIME = quiz.timeLimit; + +function restartQuiz() { + // reset quiz state + quiz.currentQuestionIndex = 0; + quiz.score = 0; + + // 1. Reset timeRemaining + quiz.timeRemaining = quiz.timeLimit; + + // 2. Update timer text + timerText.innerText = quiz.timeRemaining; + + // 3. Restart timer + clearInterval(timerInterval); + startTimer(); + + // show first question again + showQuestion(); + + // switch views + endView.style.display = "none"; + quizView.style.display = "block"; +} diff --git a/src/question.js b/src/question.js index 68f6631a..c51ed4ae 100644 --- a/src/question.js +++ b/src/question.js @@ -1,7 +1,17 @@ class Question { - // YOUR CODE HERE: - // - // 1. constructor (text, choices, answer, difficulty) + constructor(text, choices, answer, difficulty) { + this.text = text; + this.choices = choices; + this.answer = answer; + this.difficulty = difficulty; + } - // 2. shuffleChoices() -} \ No newline at end of file + shuffleChoices() { + for (let i = this.choices.length - 1; i > 0; i--) { + const randomIndex = Math.floor(Math.random() * (i + 1)); + + [this.choices[i], this.choices[randomIndex]] = + [this.choices[randomIndex], this.choices[i]]; + } + } +} diff --git a/src/quiz.js b/src/quiz.js index d94cfd14..2cd166da 100644 --- a/src/quiz.js +++ b/src/quiz.js @@ -1,15 +1,55 @@ class Quiz { - // YOUR CODE HERE: - // - // 1. constructor (questions, timeLimit, timeRemaining) + constructor(questions, timeLimit, timeRemaining) { + this.questions = questions; + this.timeLimit = timeLimit; + this.timeRemaining = timeRemaining; + this.currentQuestionIndex = 0; + } - // 2. getQuestion() - - // 3. moveToNextQuestion() + getQuestion() { + return this.questions[this.currentQuestionIndex]; + } - // 4. shuffleQuestions() + moveToNextQuestion() { + this.currentQuestionIndex++; + } - // 5. checkAnswer(answer) + shuffleQuestions() { + for (let i = this.questions.length - 1; i > 0; i--) { + const randomIndex = Math.floor(Math.random() * (i + 1)); + [this.questions[i], this.questions[randomIndex]] = + [this.questions[randomIndex], this.questions[i]]; + } + } - // 6. hasEnded() -} \ No newline at end of file + checkAnswer(answer) { + const currentQuestion = this.getQuestion(); + return currentQuestion.answer === answer; + } + + hasEnded() { + return this.currentQuestionIndex >= this.questions.length; + } + + filterQuestionsByDifficulty(difficulty) { + if (difficulty < 1 || difficulty > 3 || typeof difficulty !== "number") { + return; // do nothing if invalid + } + + this.questions = this.questions.filter(question => { + return question.difficulty === difficulty; + }); +} + +averageDifficulty() { + if (this.questions.length === 0) return 0; + + const totalDifficulty = this.questions.reduce((sum, question) => { + return sum + question.difficulty; + }, 0); + + return totalDifficulty / this.questions.length; +} + + +} From 8c8baf660b963b187c1b9cbabb6e49f197f53cb3 Mon Sep 17 00:00:00 2001 From: ilbrandoric <240859022+ilbrandoric@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:27:42 +0100 Subject: [PATCH 2/4] partial version sumitted --- README.md | 135 ++++++++++++++++++++++++++++++++++++++++++++ src/Requirements.md | 134 ------------------------------------------- 2 files changed, 135 insertions(+), 134 deletions(-) delete mode 100644 src/Requirements.md diff --git a/README.md b/README.md index e58dbd54..fb8c5d61 100644 --- a/README.md +++ b/README.md @@ -1 +1,136 @@ # Project: JavaScript Quiz + +# Quiz App Mini-Project Requirements + +## General +- Build a browser-based Quiz app using JavaScript, OOP, and DOM +- Work in teams of 2 using Live Share for collaboration +- Commit changes regularly and push to GitHub +- Submit the final GitHub repository link + +## Code Structure & Quality +- Use classes to organize data and functionality +- Keep code clean, readable, and well-organized +- Use descriptive variable names and proper file structure +- Remove unused code and maintain correct indentation + +## Question Class (src/Question.js) +- Constructor with: text, choices, answer, difficulty +- Properties: text, choices, answer, difficulty +- Implement shuffleChoices() method +- Pass all Jasmine unit tests + +## Quiz Class (src/Quiz.js) +- Constructor with: questions, timeLimit, timeRemaining +- Properties: questions, timeLimit, timeRemaining, correctAnswers, currentQuestionIndex +- Implement methods: + - getQuestion() + - moveToNextQuestion() + - shuffleQuestions() + - checkAnswer(answer) + - hasEnded() + - filterQuestionsByDifficulty(difficulty) + - averageDifficulty() +- Pass all Jasmine unit tests + +## DOM & Interaction (index.js) +- Display current question and choices +- Update progress bar and question count +- Handle answer selection and next button +- Show final results view +- Implement restart quiz functionality + +## Timer +- Implement countdown timer with setInterval / clearInterval +- Display remaining time during quiz +- Stop timer when quiz ends +- Restart timer when quiz restarts + +## Completion +- All features implemented and working +- All tests passing +- Repository ready for submission + + +# Detailed Quiz App Requirements + +## Question Class + +### Class Definition +- Question class must be defined +- Constructor must receive 4 arguments: + 1. text (string) + 2. choices (array of strings) + 3. answer (string) + 4. difficulty (number) + +### Properties +- text → assigned from 1st argument +- choices → assigned from 2nd argument +- answer → assigned from 3rd argument +- difficulty → assigned from 4th argument + +### shuffleChoices() Method +- Must be defined +- Must be a function +- Must receive no arguments +- Must shuffle the items in the choices array + +--- + +## Quiz Class + +### Class Definition +- Quiz class must be defined +- Constructor must receive 3 arguments: + 1. questions (array of Question objects) + 2. timeLimit (integer) + 3. timeRemaining (integer) + +### Properties +- questions → assigned from 1st argument +- timeLimit → assigned from 2nd argument +- timeRemaining → assigned from 3rd argument +- correctAnswers → initially 0 +- currentQuestionIndex → initially 0 + +### getQuestion() Method +- Must be defined +- Must be a function +- Must return questions[currentQuestionIndex] + +### moveToNextQuestion() Method +- Must be defined +- Must be a function +- Must increment currentQuestionIndex by 1 + +### shuffleQuestions() Method +- Must be defined +- Must be a function +- Must shuffle the questions array + +### checkAnswer(answer) Method +- Must be defined +- Must be a function +- Must receive 1 argument (answer) +- Must compare answer with current question’s answer +- Must increment correctAnswers if answer is correct + +### hasEnded() Method +- Must be defined +- Must be a function +- Must return false if currentQuestionIndex < questions.length +- Must return true if currentQuestionIndex === questions.length + +### filterQuestionsByDifficulty(difficulty) Method +- Must be defined +- Must be a function +- Must receive 1 argument (number 1–3) +- Must filter questions by difficulty +- Must not modify questions if difficulty is invalid + +### averageDifficulty() Method +- Must be defined +- Must be a function +- Must receive no arguments +- Must return the average difficulty of all questions diff --git a/src/Requirements.md b/src/Requirements.md deleted file mode 100644 index 328e2b60..00000000 --- a/src/Requirements.md +++ /dev/null @@ -1,134 +0,0 @@ -# Quiz App Mini-Project Requirements - -## General -- Build a browser-based Quiz app using JavaScript, OOP, and DOM -- Work in teams of 2 using Live Share for collaboration -- Commit changes regularly and push to GitHub -- Submit the final GitHub repository link - -## Code Structure & Quality -- Use classes to organize data and functionality -- Keep code clean, readable, and well-organized -- Use descriptive variable names and proper file structure -- Remove unused code and maintain correct indentation - -## Question Class (src/Question.js) -- Constructor with: text, choices, answer, difficulty -- Properties: text, choices, answer, difficulty -- Implement shuffleChoices() method -- Pass all Jasmine unit tests - -## Quiz Class (src/Quiz.js) -- Constructor with: questions, timeLimit, timeRemaining -- Properties: questions, timeLimit, timeRemaining, correctAnswers, currentQuestionIndex -- Implement methods: - - getQuestion() - - moveToNextQuestion() - - shuffleQuestions() - - checkAnswer(answer) - - hasEnded() - - filterQuestionsByDifficulty(difficulty) - - averageDifficulty() -- Pass all Jasmine unit tests - -## DOM & Interaction (index.js) -- Display current question and choices -- Update progress bar and question count -- Handle answer selection and next button -- Show final results view -- Implement restart quiz functionality - -## Timer -- Implement countdown timer with setInterval / clearInterval -- Display remaining time during quiz -- Stop timer when quiz ends -- Restart timer when quiz restarts - -## Completion -- All features implemented and working -- All tests passing -- Repository ready for submission - - -# Detailed Quiz App Requirements - -## Question Class - -### Class Definition -- Question class must be defined -- Constructor must receive 4 arguments: - 1. text (string) - 2. choices (array of strings) - 3. answer (string) - 4. difficulty (number) - -### Properties -- text → assigned from 1st argument -- choices → assigned from 2nd argument -- answer → assigned from 3rd argument -- difficulty → assigned from 4th argument - -### shuffleChoices() Method -- Must be defined -- Must be a function -- Must receive no arguments -- Must shuffle the items in the choices array - ---- - -## Quiz Class - -### Class Definition -- Quiz class must be defined -- Constructor must receive 3 arguments: - 1. questions (array of Question objects) - 2. timeLimit (integer) - 3. timeRemaining (integer) - -### Properties -- questions → assigned from 1st argument -- timeLimit → assigned from 2nd argument -- timeRemaining → assigned from 3rd argument -- correctAnswers → initially 0 -- currentQuestionIndex → initially 0 - -### getQuestion() Method -- Must be defined -- Must be a function -- Must return questions[currentQuestionIndex] - -### moveToNextQuestion() Method -- Must be defined -- Must be a function -- Must increment currentQuestionIndex by 1 - -### shuffleQuestions() Method -- Must be defined -- Must be a function -- Must shuffle the questions array - -### checkAnswer(answer) Method -- Must be defined -- Must be a function -- Must receive 1 argument (answer) -- Must compare answer with current question’s answer -- Must increment correctAnswers if answer is correct - -### hasEnded() Method -- Must be defined -- Must be a function -- Must return false if currentQuestionIndex < questions.length -- Must return true if currentQuestionIndex === questions.length - -### filterQuestionsByDifficulty(difficulty) Method -- Must be defined -- Must be a function -- Must receive 1 argument (number 1–3) -- Must filter questions by difficulty -- Must not modify questions if difficulty is invalid - -### averageDifficulty() Method -- Must be defined -- Must be a function -- Must receive no arguments -- Must return the average difficulty of all questions From 0129a639a25d9597d30de75fe24d253e91f98878 Mon Sep 17 00:00:00 2001 From: Tchioleca Date: Fri, 23 Jan 2026 02:26:25 +0000 Subject: [PATCH 3/4] Revamp quiz UI, add reset button, and improve logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updated JS logic replaced placeholder questions refreshed UI with basic glassmorphism so it stands out more (still needs fixes — quiz card overflows on long text) VS Code AI added Copilot instructions — I didn’t touch it… might break added a restart button (kinda cheated...it just reloads the page) --- .github/copilot-instructions.md | 47 ++++++ index.html | 4 +- src/index.js | 225 ++++++++++++-------------- src/quiz.js | 9 +- styles/style.css | 277 +++++++++++++++++--------------- 5 files changed, 300 insertions(+), 262 deletions(-) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..688c9632 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,47 @@ +# Copilot Instructions for JavaScript Quiz Project + +## Project Overview +This project is a browser-based Quiz application built using JavaScript, Object-Oriented Programming (OOP), and the Document Object Model (DOM). The application is structured to facilitate collaboration and maintain high code quality. + +## Architecture +- **Main Components**: + - **Question Class** (`src/Question.js`): Manages individual quiz questions, including properties like text, choices, answer, and difficulty. Implements a method to shuffle answer choices. + - **Quiz Class** (`src/Quiz.js`): Handles the overall quiz logic, including tracking questions, managing time limits, and checking answers. + - **DOM Interaction** (`src/index.js`): Responsible for rendering the quiz interface, updating the UI based on user interactions, and displaying results. + +- **Data Flow**: + - The `Quiz` class orchestrates the flow of questions and user interactions, while the `Question` class encapsulates the details of each question. + +## Developer Workflows +- **Building and Testing**: + - Use Jasmine for unit testing. Ensure all tests pass before committing changes. + - Run tests using the command: `npm test` (if applicable, adjust based on your setup). + +- **Debugging**: + - Utilize browser developer tools to inspect elements and debug JavaScript code. + - Console logging is encouraged for tracking variable states and flow. + +## Project Conventions +- **Code Structure**: + - Organize code into classes for clarity and reusability. + - Maintain a clean and readable code style with proper indentation and descriptive variable names. + +- **File Naming**: + - Use camelCase for JavaScript files and classes (e.g., `Question.js`, `Quiz.js`). + +## Integration Points +- **External Dependencies**: + - Ensure to include Jasmine for testing. Follow the setup instructions in the `README.md` for proper integration. + +- **Cross-Component Communication**: + - The `Quiz` class communicates with multiple `Question` instances, managing their lifecycle and interactions. + +## Examples of Patterns +- **Shuffling Choices**: + - The `shuffleChoices()` method in the `Question` class demonstrates how to manipulate arrays effectively. + +- **Timer Implementation**: + - Use `setInterval` and `clearInterval` for managing the quiz timer, as outlined in the `README.md`. + +## Conclusion +This document serves as a foundational guide for AI agents to navigate and contribute effectively to the JavaScript Quiz project. For any unclear sections or additional details needed, please provide feedback for further refinement. \ No newline at end of file diff --git a/index.html b/index.html index 534cd886..921110bd 100644 --- a/index.html +++ b/index.html @@ -39,7 +39,9 @@

JavaScript Quiz

- + + + diff --git a/src/index.js b/src/index.js index 970d73ca..f3d6829b 100644 --- a/src/index.js +++ b/src/index.js @@ -3,119 +3,146 @@ document.addEventListener("DOMContentLoaded", () => { // View divs const quizView = document.querySelector("#quizView"); const endView = document.querySelector("#endView"); - // Quiz view elements const progressBar = document.querySelector("#progressBar"); const questionCount = document.querySelector("#questionCount"); const questionContainer = document.querySelector("#question"); const choiceContainer = document.querySelector("#choices"); const nextButton = document.querySelector("#nextButton"); + const divContainer=document.querySelector(".container"); + // added funct to the js for the button : + const resetBtn = document.querySelector("#resetBtn"); // End view elements const resultContainer = document.querySelector("#result"); - - /************ SET VISIBILITY OF VIEWS ************/ - // Show the quiz view (div#quizView) and hide the end view (div#endView) quizView.style.display = "block"; endView.style.display = "none"; - - + /************ QUIZ DATA ************/ // Array with the quiz questions const questions = [ - new Question("What is 2 + 2?", ["3", "4", "5", "6"], "4", 1), - new Question("What is the capital of France?", ["Miami", "Paris", "Oslo", "Rome"], "Paris", 1), - new Question("Who created JavaScript?", ["Plato", "Brendan Eich", "Lea Verou", "Bill Gates"], "Brendan Eich", 2), - new Question("What is the mass–energy equivalence equation?", ["E = mc^2", "E = m*c^2", "E = m*c^3", "E = m*c"], "E = mc^2", 3), + new Question("Wich of these is NOT a valid HTML tagg ?", ["
", "", "
", ""], "", 1), + new Question("What does console.log([ ] == false) output?", ["true", "false", "undefined", "It throws an error"], "true", 1), + new Question("Why are software errors called “bugs”?", ["Programmers used the word as a joke", "Early computers attracted insects because of heat", "It comes from a math term meaning “glitch”", "A real moth was found inside an early computer, causing a malfunction"], "A real moth was found inside an early computer, causing a malfunction", 2), + new Question("During the Ironhack program, students receive a welcome goodies pack.Which item is most likely included?", ["A paid ChatGPT-GO yearly subscription", "A fully configured MacBook Pro", "A Costum mechanical keyboar and mousepad", "A branded hoodie"], "A branded hoodie", 3), // Add more questions here + new Question(" What does www stand for in a website browser?", ["World Wide Web", "Web Wide World", "Wide World Web", "World Web Wide"], "World Wide Web", 4), ]; const quizDuration = 120; // 120 seconds (2 minutes) - - /************ QUIZ INSTANCE ************/ // Create a new Quiz instance object const quiz = new Quiz(questions, quizDuration, quizDuration); // Shuffle the quiz questions quiz.shuffleQuestions(); - - /************ SHOW INITIAL CONTENT ************/ - // Convert the time remaining in seconds to minutes and seconds, and pad the numbers with zeros if needed - const minutes = Math.floor(quiz.timeRemaining / 60).toString().padStart(2, "0"); - const seconds = (quiz.timeRemaining % 60).toString().padStart(2, "0"); - // Display the time remaining in the time remaining container const timeRemainingContainer = document.getElementById("timeRemaining"); - timeRemainingContainer.innerText = `${minutes}:${seconds}`; - + + + divContainer.style.position="relative" + timeRemainingContainer.style.position="absolute" + timeRemainingContainer.style.top="50px" + timeRemainingContainer.style.right="20px" + + // Show first question showQuestion(); - - /************ TIMER ************/ - - let timer; - - + let timer= setInterval(()=>{ + + quiz.timeRemaining -= 1; + if(quiz.timeRemaining<=0){ + quiz.hasEnded() + showResults(); + timeRemainingContainer.innerText="" + const minutes = Math.floor(quiz.timeLimit / 60).toString().padStart(2, "0"); + const seconds = (quiz.timeLimit % 60).toString().padStart(2, "0"); + timeRemainingContainer.innerText = `${minutes}:${seconds}`; + //endView.style.display = "block"; + // quizView.style.display = "none"; + clearInterval(timer) + } + const minutes = Math.floor(quiz.timeRemaining / 60).toString().padStart(2, "0"); + const seconds = (quiz.timeRemaining % 60).toString().padStart(2, "0"); + timeRemainingContainer.innerText = `${minutes}:${seconds}`; + },1000); /************ EVENT LISTENERS ************/ + /*confusing logic for the reset button just added a page reset ... kind works right ? */ +resetBtn.addEventListener("click", () => { + window.location.reload(); +}); nextButton.addEventListener("click", nextButtonHandler); - - + /************ FUNCTIONS ************/ - // showQuestion() - Displays the current question and its choices // nextButtonHandler() - Handles the click on the next button // showResults() - Displays the end view and the quiz results - - - function showQuestion() { // If the quiz has ended, show the results if (quiz.hasEnded()) { showResults(); return; } - // Clear the previous question text and question choices questionContainer.innerText = ""; choiceContainer.innerHTML = ""; - // Get the current question from the quiz by calling the Quiz class method `getQuestion()` const question = quiz.getQuestion(); // Shuffle the choices of the current question by calling the method 'shuffleChoices()' on the question object question.shuffleChoices(); - // YOUR CODE HERE: // // 1. Show the question // Update the inner text of the question container element and show the question text - - + questionContainer.innerText=question.text + console.log(question) // 2. Update the green progress bar // Update the green progress bar (div#progressBar) width so that it shows the percentage of questions answered - progressBar.style.width = `65%`; // This value is hardcoded as a placeholder + console.log(quiz.currentQuestionIndex) + console.log(quiz.questions.length) + + progressBar.style.width = `${((quiz.currentQuestionIndex+1)/(quiz.questions.length))*100}%`; // This value is hardcoded as a placeholder + progressBar.style.width = `${((quiz.currentQuestionIndex)/(quiz.questions.length))*100}%`; // This value is hardcoded as a placeholder // 3. Update the question count text // Update the question count (div#questionCount) show the current question out of total questions - questionCount.innerText = `Question 1 of 10`; // This value is hardcoded as a placeholder - - + questionCount.innerText = `${quiz.currentQuestionIndex+1} of ${quiz.questions.length}`; // This value is hardcoded as a placeholder + console.log(questionCount) // 4. Create and display new radio input element with a label for each choice. // Loop through the current question `choices`. +question.choices.forEach((element, index) => { + const input = document.createElement("input"); + input.type = "radio"; + input.name = "choice"; + input.value = element; + input.id = `choice-${index}`; + + const label = document.createElement("label"); + label.setAttribute("for", input.id); + label.textContent = element; + + const br = document.createElement("br"); + + choiceContainer.appendChild(input); + choiceContainer.appendChild(label); + choiceContainer.appendChild(br); +}); + + // For each choice create a new radio input with a label, and append it to the choice container. // Each choice should be displayed as a radio input element with a label: /* @@ -126,95 +153,45 @@ document.addEventListener("DOMContentLoaded", () => { // Hint 1: You can use the `document.createElement()` method to create a new element. // Hint 2: You can use the `element.type`, `element.name`, and `element.value` properties to set the type, name, and value of an element. // Hint 3: You can use the `element.appendChild()` method to append an element to the choices container. - // Hint 4: You can use the `element.innerText` property to set the inner text of an element. - -} - - -function nextButtonHandler() { - // 1. Get all choice inputs - const choices = document.querySelectorAll('input[name="answer"]'); - - let selectedAnswer = null; - - // 2. Find which one is checked - choices.forEach(choice => { - if (choice.checked) { - selectedAnswer = choice.value; - } - }); - - // 3. If no answer selected, do nothing - if (!selectedAnswer) return; - - // 4. Check answer and move to next question - quiz.checkAnswer(selectedAnswer); - quiz.moveToNextQuestion(); - - // 5. Show next question (or end screen if finished) - if (!quiz.hasEnded()) { - showQuestion(); - } else { - showResults(); + // Hint 4: You can use the `element.innerText` property to set the inner text of an element. + } -} - - - - + + function nextButtonHandler () { + let selectedAnswer; // A variable to store the selected answer value // YOUR CODE HERE: - // + const allChoices=document.querySelectorAll("#choices input") // 1. Get all the choice elements. You can use the `document.querySelectorAll()` method. - - + allChoices.forEach(singleChoice => { + if(singleChoice.checked){ + selectedAnswer=singleChoice.value + } + }); + if(selectedAnswer){ + quiz.checkAnswer(selectedAnswer); + quiz.moveToNextQuestion(); + showQuestion(); + } // 2. Loop through all the choice elements and check which one is selected // Hint: Radio input elements have a property `.checked` (e.g., `element.checked`). // When a radio input gets selected the `.checked` property will be set to true. // You can use check which choice was selected by checking if the `.checked` property is true. - // 3. If an answer is selected (`selectedAnswer`), check if it is correct and move to the next question - // Check if selected answer is correct by calling the quiz method `checkAnswer()` with the selected answer. - // Move to the next question by calling the quiz method `moveToNextQuestion()`. - // Show the next question by calling the function `showQuestion()`. - - - - -function showResults() { - // 1. Hide quiz view - quizView.style.display = "none"; - - // 2. Show end view - endView.style.display = "block"; - - // 3. Display final score - resultContainer.innerText = quiz.correctAnswers; -} - -}); - -const INITIAL_TIME = quiz.timeLimit; - -function restartQuiz() { - // reset quiz state - quiz.currentQuestionIndex = 0; - quiz.score = 0; - - // 1. Reset timeRemaining - quiz.timeRemaining = quiz.timeLimit; - - // 2. Update timer text - timerText.innerText = quiz.timeRemaining; - - // 3. Restart timer - clearInterval(timerInterval); - startTimer(); - - // show first question again - showQuestion(); - - // switch views - endView.style.display = "none"; - quizView.style.display = "block"; -} + // Check if selected answer is correct by calling the quiz method `checkAnswer()` with the selected answer. + // Move to the next question by calling the quiz method `moveToNextQuestion()`. + // Show the next question by calling the function `showQuestion()`. + } + function showResults() { + // YOUR CODE HERE: + // + // 1. Hide the quiz view (div#quizView) + quizView.style.display = "none"; + // 2. Show the end view (div#endView) + endView.style.display = "flex"; + + // 3. Update the result container (div#result) inner text to show the number of correct answers out of total questions + resultContainer.innerText = `You scored ${quiz.correctAnswers} out of ${quiz.questions.length} correct answers!`; // This value is hardcoded as a placeholder + } + +}); diff --git a/src/quiz.js b/src/quiz.js index 2cd166da..a914fade 100644 --- a/src/quiz.js +++ b/src/quiz.js @@ -4,6 +4,8 @@ class Quiz { this.timeLimit = timeLimit; this.timeRemaining = timeRemaining; this.currentQuestionIndex = 0; + this.correctAnswers = 0; + } getQuestion() { @@ -22,10 +24,11 @@ class Quiz { } } - checkAnswer(answer) { - const currentQuestion = this.getQuestion(); - return currentQuestion.answer === answer; +checkAnswer(answer) { + if (this.getQuestion().answer === answer) { + this.correctAnswers++; } +} hasEnded() { return this.currentQuestionIndex >= this.questions.length; diff --git a/styles/style.css b/styles/style.css index 8de97e38..4cd8e5c0 100644 --- a/styles/style.css +++ b/styles/style.css @@ -1,172 +1,181 @@ -/* CSS Reset */ +/* CSS RESET +Needs some more polish (moving gradient progress bar and what not: +location of timmer outside the main container for better visibility +longer question overflow the cards outside main div box , neeeds fixing +)*/ * { - margin: 0; - padding: 0; - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } +/* GLOBAL */ body { - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - background-color: #f4f4f4; - color: #333; - line-height: 1.6; - padding: 20px; -} - -header { - padding: 0 20px; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #0f2027, #203a43, #2c5364); + color: #ffffff; + line-height: 1.6; + padding: 20px; + min-height: 100vh; } +/* CONTAINER (GLASS CARD) */ .container { - height: 540px; - max-width: 600px; - margin: auto; - padding: 20px; - background: #fff; - box-shadow: 0 5px 15px rgba(0,0,0,0.1); -} - -#quizView, #endView { - overflow-y: auto; - padding: 20px; - box-sizing: border-box; - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; -} - -.view { - text-align: center; - margin-top: 20px; -} - -button { - color: white; - border: none; - border-radius: 5px; - padding: 10px 20px; - cursor: pointer; - font-size: 16px; - width: 160px; -} - -.button-primary { - background-color: #4caf50; -} - -.button-primary:hover { - background-color: #46a049; -} - -.button-secondary { - background-color: #333; + height: 560px; + max-width: 620px; + margin: auto; + padding: 24px; + border-radius: 16px; + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); + border: 1px solid rgba(255, 255, 255, 0.25); + box-shadow: 0 25px 45px rgba(0, 0, 0, 0.3); + position: relative; +} + +/* VIEWS */ +#quizView, +#endView { + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + text-align: center; +} + +/* HEADERS / TEXT */ +header h1 { + font-size: 28px; + font-weight: 600; + letter-spacing: 1px; + text-align: center; +} + +#question { + font-size: 20px; + font-weight: 500; + margin: 20px 0; + color: #ffffff; + text-align: center; + +} + +/* TIMER */ +#timeRemaining { + position: absolute; + top: 18px; + right: 24px; + font-size: 14px; + font-style: italic; + color: rgba(255, 255, 255, 0.85); } -.button-secondary:hover { - background-color: #1e1e1e; -} -.title { - margin-top: 20px; - margin-bottom: -12px; +/* PROGRESS BAR */ +#progress { + width: 100%; + background: rgba(255, 255, 255, 0.25); + border-radius: 12px; + overflow: hidden; + margin-bottom: 10px; + margin-top: 10px; } - -button:hover { - background-color: #4cae4c; +#progressBar { + height: 14px; + background: linear-gradient(90deg, #00c6ff, #0072ff); + width: 0%; + transition: width 0.4s ease; + border-radius: 12px; } -ul { - list-style-type: none; - padding: 0; +/* QUESTION COUNT */ +#questionCount { + font-weight: bold; + margin-bottom: 12px; + color: rgba(255, 255, 255, 0.85); } -li { - margin: 10px 0; +/* CHOICES */ +#choices { + width: 100%; + margin-top: 10px; + text-align: center; } -input[type="radio"] { - margin-right: 10px; +#choices input[type="radio"] { + display: none; } -.emphasis, #startQuestionsCount, #questionCount, #resultQuestionsCount { - font-size: 16px; - font-weight: bold; - margin: 0 auto; - margin-bottom: 10px; +#choices label { + display: block; + padding: 14px 18px; + margin-bottom: 12px; + border-radius: 12px; + cursor: pointer; + background: rgba(255, 255, 255, 0.18); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.25); + color: #ffffff; + transition: all 0.25s ease; } -.content { - min-height: 300px; - display: flex; - flex-direction: column; +#choices label:hover { + background: rgba(255, 255, 255, 0.28); + transform: translateY(-1px); } -#choices { - min-width: 25px; - margin: 0 auto; - text-align: left; +#choices input[type="radio"]:checked + label { + background: linear-gradient(135deg, #00c6ff, #0072ff); + border-color: rgba(255, 255, 255, 0.6); + box-shadow: 0 8px 20px rgba(0, 114, 255, 0.4); } -#quizDescription, #question, #result { - font-size: 18px; - font-style: italic; - color: #333; - margin: 0 auto; - margin-top: 20px; - margin-bottom: 12px; +/* BUTTONS */ +button { + border: none; + border-radius: 14px; + padding: 14px 26px; + cursor: pointer; + font-size: 16px; + width: 180px; + color: white; + background: rgba(65, 225, 236, 0.87); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid rgb(61, 217, 238); + transition: all 0.25s ease; } -#quizDescription { - margin-bottom: 20px; +button:hover { + transform: translateY(-2px); + background: rgba(255, 255, 255, 0.3); } - -#progress { - width: 100%; - background-color: #ddd; - border-radius: 8px; - overflow: hidden; - margin-bottom: 5px; +/* PRIMARY / SECONDARY */ +.button-primary { + background: linear-gradient(135deg, #00c6ff, #0072ff); + border: none; } -#progressBar { - height: 20px; - background-color: #4caf50; - width: 0%; - border-radius: 8px; +.button-primary:hover { + box-shadow: 0 10px 25px rgba(0, 114, 255, 0.45); } -#result-progress { - width: 100%; - background-color: #ddd; - border-radius: 8px; - overflow: hidden; - margin-bottom: 5px; +.button-secondary { + background: rgba(0, 0, 0, 0.35); } -.divider { - width: 100%; - height: 20px; - background-color: #ddd; - border-radius: 8px; - overflow: hidden; - margin-bottom: 5px; +.button-secondary:hover { + background: rgba(0, 0, 0, 0.55); } -#resultProgressBar { - width: 100%; - height: 20px; - background-color: #4caf50; - width: 100%; - border-radius: 8px; +/* RESULTS */ +#result { + font-size: 22px; + font-weight: 500; + margin: 20px 0; + color: #ffffff; } - -#timeRemaining { - font-size: 14px; - font-style: italic; - color: #333; - margin: 0 auto; - margin-top: -35px; - margin-bottom: 12px; -} \ No newline at end of file From cd4159d7a2bc92619b67cfe5cf12c1d677242aef Mon Sep 17 00:00:00 2001 From: Tchioleca Date: Fri, 23 Jan 2026 03:21:31 +0000 Subject: [PATCH 4/4] =?UTF-8?q?updated=20JS=20logic=20replaced=20placehold?= =?UTF-8?q?er=20questions=20refreshed=20UI=20with=20basic=20glassmorphism?= =?UTF-8?q?=20so=20it=20stands=20out=20more=20(still=20needs=20fixes=20?= =?UTF-8?q?=E2=80=94=20quiz=20card=20overflows=20on=20long=20text)=20VS=20?= =?UTF-8?q?Code=20AI=20added=20Copilot=20instructions=20=E2=80=94=20I=20di?= =?UTF-8?q?dn=E2=80=99t=20touch=20it=E2=80=A6=20might=20break=20added=20a?= =?UTF-8?q?=20restart=20button=20(kinda=20cheated...it=20just=20reloads=20?= =?UTF-8?q?the=20page)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index f3d6829b..eaed34b7 100644 --- a/src/index.js +++ b/src/index.js @@ -31,7 +31,7 @@ document.addEventListener("DOMContentLoaded", () => { // Add more questions here new Question(" What does www stand for in a website browser?", ["World Wide Web", "Web Wide World", "Wide World Web", "World Web Wide"], "World Wide Web", 4), ]; - const quizDuration = 120; // 120 seconds (2 minutes) + const quizDuration = 260; // 260 seconds (4 minutes and 20 seconds) /************ QUIZ INSTANCE ************/ // Create a new Quiz instance object @@ -63,8 +63,8 @@ document.addEventListener("DOMContentLoaded", () => { const minutes = Math.floor(quiz.timeLimit / 60).toString().padStart(2, "0"); const seconds = (quiz.timeLimit % 60).toString().padStart(2, "0"); timeRemainingContainer.innerText = `${minutes}:${seconds}`; - //endView.style.display = "block"; - // quizView.style.display = "none"; + endView.style.display = "block"; + quizView.style.display = "none"; clearInterval(timer) } const minutes = Math.floor(quiz.timeRemaining / 60).toString().padStart(2, "0"); @@ -124,7 +124,7 @@ resetBtn.addEventListener("click", () => { // 4. Create and display new radio input element with a label for each choice. // Loop through the current question `choices`. -question.choices.forEach((element, index) => { + question.choices.forEach((element, index) => { const input = document.createElement("input"); input.type = "radio"; input.name = "choice";