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; + } +}