From 915884241932a1d7675c8c0d54c51c66f6ed870d Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Thu, 19 Mar 2026 20:41:19 +0000 Subject: [PATCH 1/2] quote generator app is ready --- Sprint-3/quote-generator/index.html | 34 ++++-- Sprint-3/quote-generator/package.json | 10 +- Sprint-3/quote-generator/quotes.js | 54 ++++++++- Sprint-3/quote-generator/quotes.test.js | 3 + Sprint-3/quote-generator/style.css | 148 +++++++++++++++++++++++- 5 files changed, 234 insertions(+), 15 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..1f6ae4f73 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -1,15 +1,35 @@ - + - Title here - + Quote Generator App + -

hello there

-

-

- +
+
+

Quote Generator

+
+ +
+

+

+
+ +
+
+ +
+
+ + Auto-play: OFF +
+
+
+ diff --git a/Sprint-3/quote-generator/package.json b/Sprint-3/quote-generator/package.json index 0f6f98917..8a9bdb901 100644 --- a/Sprint-3/quote-generator/package.json +++ b/Sprint-3/quote-generator/package.json @@ -4,7 +4,7 @@ "license": "CC-BY-SA-4.0", "description": "You must update this package", "scripts": { - "test": "jest --config=../jest.config.js quote-generator" + "test": "jest --env=jsdom" }, "repository": { "type": "git", @@ -13,5 +13,11 @@ "bugs": { "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme" + "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "dependencies": { + "jsdom": "^20.0.3" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1" + } } diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..dade31b31 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -15,11 +15,6 @@ // --------------- // pickFromArray(['a','b','c','d']) // maybe returns 'c' -// You don't need to change this function -function pickFromArray(choices) { - return choices[Math.floor(Math.random() * choices.length)]; -} - // A list of quotes you can use in your app. // DO NOT modify this array, otherwise the tests may break! const quotes = [ @@ -491,3 +486,52 @@ const quotes = [ ]; // call pickFromArray with the quotes array to check you get a random quote + +// Function to pick a random quote +function pickFromArray() { + const quoteEl = document.getElementById("quote"); + const authorEl = document.getElementById("author"); + const randomIndex = Math.floor(Math.random() * quotes.length); + + quoteEl.textContent = `" ${quotes[randomIndex].quote} "`; + authorEl.textContent = `-- ${quotes[randomIndex].author} --`; + return randomIndex; +} + +// Setup function for browser only +function setupQuoteApp() { + const button = document.getElementById("new-quote"); + const autoplayCheckbox = document.getElementById("autoplay"); + const autoplayStatus = document.getElementById("autoplay-status"); + + // Don't call pickFromArray here for Jest test + if (typeof window !== "undefined" && window.document) { + pickFromArray(); + + button.addEventListener("click", () => pickFromArray()); + + let autoplayInterval = null; + autoplayCheckbox.addEventListener("change", () => { + if (autoplayCheckbox.checked) { + autoplayInterval = setInterval(pickFromArray, 5000); + autoplayStatus.textContent = "Auto-play: ON"; + autoplayStatus.style.color = "#4CAF50"; + } else { + clearInterval(autoplayInterval); + autoplayInterval = null; + autoplayStatus.textContent = "Auto-play: OFF"; + autoplayStatus.style.color = "brown"; + } + }); + } +} + +// Only run setup in browser environment +if (typeof window !== "undefined") { + window.addEventListener("DOMContentLoaded", setupQuoteApp); +} + +// Export function for Jest tests +if (typeof module !== "undefined") { + module.exports = pickFromArray; +} diff --git a/Sprint-3/quote-generator/quotes.test.js b/Sprint-3/quote-generator/quotes.test.js index f7b128bf7..d0631cb58 100644 --- a/Sprint-3/quote-generator/quotes.test.js +++ b/Sprint-3/quote-generator/quotes.test.js @@ -2,6 +2,9 @@ There are some Tests in this file that will help you work out if your code is working. */ +require("@testing-library/jest-dom"); +// @jest-environment jsdom +const pickFromArray = require("./quotes.js"); const path = require("path"); const { JSDOM } = require("jsdom"); diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..55a6bfb47 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,147 @@ -/** Write your CSS in here **/ +/* Reset */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; +} + +body { + min-height: 100vh; + background: #abd5e9; + display: flex; + justify-content: center; + align-items: center; + padding: 15px; +} + +.container { + background: rgba(221, 221, 221, 0.4); + padding: 10px; + border-radius: 16px; + width: 100%; + max-width: 420px; + text-align: center; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2); + display: flex; + flex-direction: column; + min-height: 450px; +} + +.header { + flex: 0 0 25%; /* 25% of container height */ + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 15px; +} + +.header h1 { + font-size: 1.8rem; + color: #333; +} + +.quote-box { + flex: 1 0 50%; /* take remaining middle space */ + background: #f4f4f4; + padding: 10px; + border-radius: 12px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + margin: 10px 0; + + min-height: 100px; + transition: all 0.3s ease; + word-wrap: break-word; + text-align: center; +} + +.quote-box p { + margin: 0; + font-size: 1rem; + line-height: 1.4; +} + +.bottom-controls { + flex: 0 0 25%; + display: flex; + flex-direction: column; + justify-content: center; + gap: 10px; + margin-bottom: 0px; +} + +.button button { + width: 100%; + padding: 10px; + font-size: large; + border: none; + border-radius: 10px; + background: rgb(3, 73, 195); + color: #fff; + cursor: pointer; + transition: 0.3s ease; +} + +.button button:hover { + background: #4259c8; + transform: scale(1.03); + font-weight: bold; +} + +.autoplay-container { + display: flex; + justify-content: center; + align-items: center; + gap: 10px; +} + +.autoplay-container label { + display: flex; + align-items: center; + gap: 5px; + cursor: pointer; +} + +.autoplay-container input[type="checkbox"] { + width: 18px; + height: 18px; + cursor: pointer; +} + +#autoplay-status { + font-weight: bold; + color: brown; +} + +/* Responsive */ +@media (min-width: 600px) { + .container { + padding: 40px 35px; + } + .header h1 { + font-size: 2rem; + } + .quote-box p { + font-size: 1.1rem; + } +} + +@media (min-width: 992px) { + .container { + max-width: 500px; + } + .header h1 { + font-size: 2.2rem; + } + .quote-box p { + font-size: 1.2rem; + } + .button button { + width: auto; + padding: 12px 25px; + } +} From efe814da68475f1cf5ed49e28f3aca7508866774 Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Mon, 30 Mar 2026 21:38:02 +0100 Subject: [PATCH 2/2] quotes function been upadated --- Sprint-3/quote-generator/index.html | 10 ++-- Sprint-3/quote-generator/quotes.js | 75 +++++++++++++++++++---------- Sprint-3/quote-generator/style.css | 9 +++- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 1f6ae4f73..0bf7e3472 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -11,12 +11,10 @@

Quote Generator

-
-

-

+

" "

+

-- --

-
@@ -24,9 +22,9 @@

Quote Generator

- Auto-play: OFF + OFF
diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index dade31b31..b184631da 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -487,51 +487,74 @@ const quotes = [ // call pickFromArray with the quotes array to check you get a random quote -// Function to pick a random quote -function pickFromArray() { +// Picks a random quote object from the quotes array +function pickFromArray(quotes) { + const randomIndex = Math.floor(Math.random() * quotes.length); + return quotes[randomIndex]; +} + +// Renders a quote object into the DOM +function renderQuote(quote) { const quoteEl = document.getElementById("quote"); const authorEl = document.getElementById("author"); - const randomIndex = Math.floor(Math.random() * quotes.length); - quoteEl.textContent = `" ${quotes[randomIndex].quote} "`; - authorEl.textContent = `-- ${quotes[randomIndex].author} --`; - return randomIndex; + if (!quoteEl || !authorEl || !quote) return; + + quoteEl.textContent = quote.quote; + authorEl.textContent = quote.author; } -// Setup function for browser only +// Sets up the application, event listeners, and initial state function setupQuoteApp() { const button = document.getElementById("new-quote"); const autoplayCheckbox = document.getElementById("autoplay"); const autoplayStatus = document.getElementById("autoplay-status"); - // Don't call pickFromArray here for Jest test - if (typeof window !== "undefined" && window.document) { - pickFromArray(); + if (!button || !autoplayCheckbox || !autoplayStatus) return; + + let autoplayInterval = null; - button.addEventListener("click", () => pickFromArray()); + // Show first quote on page load + renderQuote(pickFromArray(quotes)); - let autoplayInterval = null; - autoplayCheckbox.addEventListener("change", () => { - if (autoplayCheckbox.checked) { - autoplayInterval = setInterval(pickFromArray, 5000); - autoplayStatus.textContent = "Auto-play: ON"; - autoplayStatus.style.color = "#4CAF50"; - } else { - clearInterval(autoplayInterval); - autoplayInterval = null; - autoplayStatus.textContent = "Auto-play: OFF"; - autoplayStatus.style.color = "brown"; - } - }); + // Handles generating and rendering a new quote + function handleNewQuote() { + renderQuote(pickFromArray(quotes)); } + + // Button click generates a new quote + button.addEventListener("click", handleNewQuote); + + // Toggle autoplay feature + autoplayCheckbox.addEventListener("change", () => { + if (autoplayCheckbox.checked) { + // Start auto-changing quotes every 5 seconds + autoplayInterval = setInterval(handleNewQuote, 5000); + autoplayStatus.textContent = "ON"; + + // Apply ON styling via CSS class + autoplayStatus.classList.add("autoplay-on"); + autoplayStatus.classList.remove("autoplay-off"); + } else { + // Stop auto-changing quotes + clearInterval(autoplayInterval); + autoplayInterval = null; + + autoplayStatus.textContent = "OFF"; + + // Apply OFF styling via CSS class + autoplayStatus.classList.add("autoplay-off"); + autoplayStatus.classList.remove("autoplay-on"); + } + }); } -// Only run setup in browser environment +// Initialize app only when DOM is fully loaded (browser environment) if (typeof window !== "undefined") { window.addEventListener("DOMContentLoaded", setupQuoteApp); } -// Export function for Jest tests +// Export function for Jest testing environment if (typeof module !== "undefined") { module.exports = pickFromArray; } diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 55a6bfb47..a02b2cff7 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -16,7 +16,7 @@ body { } .container { - background: rgba(221, 221, 221, 0.4); + background: rgb(206, 202, 202); padding: 10px; border-radius: 16px; width: 100%; @@ -112,9 +112,14 @@ body { cursor: pointer; } -#autoplay-status { +.autoplay-on { + color: #4caf50; font-weight: bold; +} + +.autoplay-off { color: brown; + font-weight: bold; } /* Responsive */