From 26a472c5372eccf97b9b6c5024ff86a7710e83e8 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:27:12 +0000 Subject: [PATCH 1/9] feat html: update structure for quote generator app --- Sprint-3/quote-generator/index.html | 35 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..a954aa9f5 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,13 +3,38 @@ - Title here + Quote generator app + + + + + + + -

hello there

-

-

- +
+

Quote generator app

+

+

+ +
+ + +
+ Auto-play + +
+ +
auto-play: ON
+
+
From 8aaeecd88da59de83a0fed110f47be6db09e81ec Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:27:42 +0000 Subject: [PATCH 2/9] feat css: implement premium glassmorphism design --- Sprint-3/quote-generator/style.css | 236 +++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..69db4c653 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,237 @@ /** Write your CSS in here **/ + +:root { + --primary-color: #6366f1; + --secondary-color: #a855f7; + --accent-color: #ec4899; + --text-color: #1f2937; + --bg-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --glass-bg: rgba(255, 255, 255, 0.95); + --glass-border: rgba(255, 255, 255, 0.3); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), + 0 4px 6px -2px rgba(0, 0, 0, 0.05); + --transition-speed: 0.3s; +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Helvetica, Arial, sans-serif; + background: var(--bg-gradient); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + color: var(--text-color); + padding: 1rem; +} + +.container { + background: var(--glass-bg); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid var(--glass-border); + border-radius: 1.5rem; + padding: 3rem; + width: 100%; + max-width: 600px; + box-shadow: var(--shadow-lg); + text-align: center; + transition: transform var(--transition-speed) ease; +} + +.container:hover { + transform: translateY(-5px); +} + +h1 { + font-size: 2.5rem; + font-weight: 800; + margin-bottom: 2rem; + background: linear-gradient( + to right, + var(--primary-color), + var(--accent-color) + ); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + letter-spacing: -0.025em; +} + +#quote { + font-size: 1.5rem; + line-height: 1.6; + font-weight: 500; + margin-bottom: 1.5rem; + color: #374151; + font-style: italic; + position: relative; + padding: 0 1rem; +} + +#quote::before, +#quote::after { + content: '"'; + font-size: 3rem; + color: var(--primary-color); + opacity: 0.2; + position: absolute; + line-height: 1; +} + +#quote::before { + top: -1rem; + left: -0.5rem; +} + +#quote::after { + bottom: -1.5rem; + right: -0.5rem; +} + +#author { + font-size: 1.1rem; + color: #6b7280; + font-weight: 600; + margin-bottom: 2.5rem; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +#author::before { + content: ""; + display: block; + width: 30px; + height: 2px; + background: linear-gradient( + to right, + var(--primary-color), + var(--secondary-color) + ); +} + +.controls { + display: flex; + flex-direction: column; + gap: 1.5rem; + align-items: center; +} + +button { + background: linear-gradient( + to right, + var(--primary-color), + var(--secondary-color) + ); + color: white; + border: none; + padding: 1rem 2rem; + font-size: 1.1rem; + font-weight: 600; + border-radius: 9999px; + cursor: pointer; + transition: all var(--transition-speed) ease; + box-shadow: 0 4px 6px -1px rgba(99, 102, 241, 0.4); +} + +button:hover { + transform: translateY(-2px); + box-shadow: 0 10px 15px -3px rgba(99, 102, 241, 0.5); + filter: brightness(1.1); +} + +button:active { + transform: translateY(0); +} + +/* Auto-play Switch */ +.auto-play-container { + display: flex; + align-items: center; + gap: 1rem; + background: rgba(0, 0, 0, 0.05); + padding: 0.75rem 1.5rem; + border-radius: 1rem; +} + +.switch-label { + font-weight: 600; + font-size: 0.9rem; + color: #4b5563; +} + +.switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: 0.4s; + border-radius: 34px; +} + +.slider:before { + position: absolute; + content: ""; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background-color: white; + transition: 0.4s; + border-radius: 50%; +} + +input:checked + .slider { + background: linear-gradient( + to right, + var(--primary-color), + var(--secondary-color) + ); +} + +input:focus + .slider { + box-shadow: 0 0 1px var(--primary-color); +} + +input:checked + .slider:before { + transform: translateX(24px); +} + +.status-indicator { + font-size: 0.8rem; + font-weight: 700; + color: var(--accent-color); + opacity: 0; + transform: translateY(10px); + transition: all 0.3s ease; + height: 1.2em; +} + +.status-indicator.active { + opacity: 1; + transform: translateY(0); +} From 5e70e21b75f3c0ea00f9584f215d5a469440479c Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:27:46 +0000 Subject: [PATCH 3/9] feat js: implement quote generator logic and autoplay --- Sprint-3/quote-generator/app.js | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Sprint-3/quote-generator/app.js diff --git a/Sprint-3/quote-generator/app.js b/Sprint-3/quote-generator/app.js new file mode 100644 index 000000000..0be0e3c8d --- /dev/null +++ b/Sprint-3/quote-generator/app.js @@ -0,0 +1,91 @@ +/* globals quotes, pickFromArray */ + +// Constants for configuration +// Sets the time interval for the auto-play feature in milliseconds. +const AUTO_PLAY_INTERVAL_MS = 5000; // 5 seconds for testing/demo + +/** + * Variables to track the auto-play interval state. + */ +let autoPlayIntervalId = null; + +// DOM Elements +const quoteElement = document.querySelector("#quote"); +const authorElement = document.querySelector("#author"); +const newQuoteButton = document.querySelector("#new-quote"); +const autoPlaySwitch = document.querySelector("#auto-play-switch"); +const autoPlayStatus = document.querySelector("#auto-play-status"); + +/** + * Updates the displayed quote and author on the screen. + * Uses the global pickFromArray function and quotes array. + */ +function displayNewQuote() { + const randomQuote = pickFromArray(quotes); + quoteElement.innerText = randomQuote.quote; + authorElement.innerText = randomQuote.author; +} + +/** + * Starts the auto-play functionality. + * Sets an interval to update the quote and shows the status indicator. + */ +function startAutoPlay() { + // Clear any existing interval just in case + if (autoPlayIntervalId) { + clearInterval(autoPlayIntervalId); + } + + // Show status + autoPlayStatus.classList.add("active"); + + // Set interval + autoPlayIntervalId = setInterval(function () { + displayNewQuote(); + }, AUTO_PLAY_INTERVAL_MS); +} + +/** + * Stops the auto-play functionality. + * Clears the interval and hides the status indicator. + */ +function stopAutoPlay() { + if (autoPlayIntervalId) { + clearInterval(autoPlayIntervalId); + autoPlayIntervalId = null; + } + + // Hide status + autoPlayStatus.classList.remove("active"); +} + +/** + * Toggles auto-play based on the checkbox state. + * @param event - The change event from the checkbox. + */ +function handleAutoPlayToggle(event) { + if (event.target.checked) { + startAutoPlay(); + } else { + stopAutoPlay(); + } +} + +// Event Listeners + +// Handle "New Quote" button click +newQuoteButton.addEventListener("click", function () { + displayNewQuote(); + + // If auto-play is on, reset the timer so it doesn't change immediately after manual click + if (autoPlaySwitch.checked) { + startAutoPlay(); + } +}); + +// Handle Auto-play switch toggle +autoPlaySwitch.addEventListener("change", handleAutoPlayToggle); + +// Initial Load +// Display a random quote when the app starts +displayNewQuote(); From 484ea2398105a428c4798e3cd5537782d6d0a85e Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:36:27 +0000 Subject: [PATCH 4/9] style css: update colour palette and typography to match example --- Sprint-3/quote-generator/style.css | 170 +++++++++-------------------- 1 file changed, 54 insertions(+), 116 deletions(-) diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 69db4c653..3d445ed20 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1,15 +1,10 @@ /** Write your CSS in here **/ :root { - --primary-color: #6366f1; - --secondary-color: #a855f7; - --accent-color: #ec4899; - --text-color: #1f2937; - --bg-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - --glass-bg: rgba(255, 255, 255, 0.95); - --glass-border: rgba(255, 255, 255, 0.3); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), - 0 4px 6px -2px rgba(0, 0, 0, 0.05); + --primary-color: #f5ac2d; + --text-color: #f5ac2d; + --bg-color: #f5ac2d; + --card-bg: #ffffff; --transition-speed: 0.3s; } @@ -20,152 +15,101 @@ } body { - font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, - Helvetica, Arial, sans-serif; - background: var(--bg-gradient); + font-family: Georgia, 'Times New Roman', Times, serif; + background-color: var(--bg-color); min-height: 100vh; display: flex; justify-content: center; align-items: center; - color: var(--text-color); padding: 1rem; } .container { - background: var(--glass-bg); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border: 1px solid var(--glass-border); - border-radius: 1.5rem; - padding: 3rem; + background: var(--card-bg); + padding: 3rem 4rem; width: 100%; - max-width: 600px; - box-shadow: var(--shadow-lg); + max-width: 700px; text-align: center; - transition: transform var(--transition-speed) ease; -} - -.container:hover { - transform: translateY(-5px); + position: relative; + /* Simple crisp shadow or none based on flat design of example, keeping slight shadow for visibility */ + box-shadow: 0 4px 6px rgba(0,0,0,0.1); } h1 { - font-size: 2.5rem; - font-weight: 800; - margin-bottom: 2rem; - background: linear-gradient( - to right, - var(--primary-color), - var(--accent-color) - ); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - letter-spacing: -0.025em; + display: none; /* The example image doesn't show a visible title inside the card */ } #quote { - font-size: 1.5rem; - line-height: 1.6; - font-weight: 500; + font-size: 1.8rem; + line-height: 1.4; + color: var(--text-color); margin-bottom: 1.5rem; - color: #374151; - font-style: italic; position: relative; - padding: 0 1rem; + padding-left: 3rem; /* Space for the quote icon */ + text-align: left; } -#quote::before, -#quote::after { - content: '"'; - font-size: 3rem; +#quote::before { + content: '“'; /* Large quote mark using curved quotes */ + font-size: 6rem; color: var(--primary-color); - opacity: 0.2; position: absolute; + top: -1.5rem; + left: -1rem; line-height: 1; -} - -#quote::before { - top: -1rem; - left: -0.5rem; -} - -#quote::after { - bottom: -1.5rem; - right: -0.5rem; + font-family: sans-serif; /* Quote marks often look better in sans-serif or specific fonts */ + opacity: 1; /* Solid colour in example */ } #author { font-size: 1.1rem; - color: #6b7280; - font-weight: 600; + color: var(--text-color); margin-bottom: 2.5rem; - display: flex; - align-items: center; - justify-content: center; - gap: 0.5rem; + text-align: right; + font-style: italic; /* Authors are often italicized in this style */ } +/* Add dash before author if not present in JS, but here we style assuming content */ #author::before { - content: ""; - display: block; - width: 30px; - height: 2px; - background: linear-gradient( - to right, - var(--primary-color), - var(--secondary-color) - ); + content: '- '; } .controls { display: flex; flex-direction: column; - gap: 1.5rem; - align-items: center; + align-items: flex-end; /* Button aligned to right in some designs, or center. Example shows right or center. Let's align right to match typical 'next' flows or keep center if safer. Example looks right-aligned for button. */ } button { - background: linear-gradient( - to right, - var(--primary-color), - var(--secondary-color) - ); + background-color: var(--primary-color); color: white; border: none; - padding: 1rem 2rem; - font-size: 1.1rem; - font-weight: 600; - border-radius: 9999px; + padding: 0.8rem 1.5rem; + font-size: 1rem; + font-family: Arial, sans-serif; cursor: pointer; - transition: all var(--transition-speed) ease; - box-shadow: 0 4px 6px -1px rgba(99, 102, 241, 0.4); + transition: opacity var(--transition-speed) ease; + font-weight: bold; } button:hover { - transform: translateY(-2px); - box-shadow: 0 10px 15px -3px rgba(99, 102, 241, 0.5); - filter: brightness(1.1); -} - -button:active { - transform: translateY(0); + opacity: 0.9; } -/* Auto-play Switch */ +/* Auto-play Switch - adjusting to fit the new theme */ .auto-play-container { display: flex; align-items: center; gap: 1rem; - background: rgba(0, 0, 0, 0.05); - padding: 0.75rem 1.5rem; - border-radius: 1rem; + margin-top: 1rem; /* Separate from main button */ + align-self: flex-end; } .switch-label { - font-weight: 600; + font-weight: normal; font-size: 0.9rem; - color: #4b5563; + color: var(--text-color); + font-family: Arial, sans-serif; } .switch { @@ -188,9 +132,9 @@ button:active { left: 0; right: 0; bottom: 0; - background-color: #ccc; - transition: 0.4s; - border-radius: 34px; + background-color: #e4e4e4; /* Light grey for off */ + transition: .4s; + border-radius: 0; /* Square/Rectangular look or keep rounded? Let's keep rounded for standard UI toggle */ } .slider:before { @@ -201,16 +145,11 @@ button:active { left: 3px; bottom: 3px; background-color: white; - transition: 0.4s; - border-radius: 50%; + transition: .4s; } input:checked + .slider { - background: linear-gradient( - to right, - var(--primary-color), - var(--secondary-color) - ); + background-color: var(--primary-color); } input:focus + .slider { @@ -223,15 +162,14 @@ input:checked + .slider:before { .status-indicator { font-size: 0.8rem; - font-weight: 700; - color: var(--accent-color); + font-weight: bold; + color: var(--primary-color); opacity: 0; - transform: translateY(10px); - transition: all 0.3s ease; - height: 1.2em; + margin-top: 0.5rem; + align-self: flex-end; + font-family: Arial, sans-serif; } .status-indicator.active { opacity: 1; - transform: translateY(0); } From 00423a78d3a82b18c254d07602acf7edc045833e Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 17:38:09 +0000 Subject: [PATCH 5/9] refactor: apply beginner-friendly, self-documenting style with contextual comments --- Sprint-3/quote-generator/app.js | 67 ++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/Sprint-3/quote-generator/app.js b/Sprint-3/quote-generator/app.js index 0be0e3c8d..734f7a486 100644 --- a/Sprint-3/quote-generator/app.js +++ b/Sprint-3/quote-generator/app.js @@ -1,69 +1,74 @@ /* globals quotes, pickFromArray */ -// Constants for configuration -// Sets the time interval for the auto-play feature in milliseconds. -const AUTO_PLAY_INTERVAL_MS = 5000; // 5 seconds for testing/demo +// Use a constant for the auto-play time to make it easy to change later. +const AUTO_PLAY_INTERVAL_MS = 5000; -/** - * Variables to track the auto-play interval state. - */ +// Defines variables to track the state of the app. +// Uses 'let' because the timer ID will change when we start/stop auto-play. let autoPlayIntervalId = null; -// DOM Elements -const quoteElement = document.querySelector("#quote"); -const authorElement = document.querySelector("#author"); -const newQuoteButton = document.querySelector("#new-quote"); -const autoPlaySwitch = document.querySelector("#auto-play-switch"); -const autoPlayStatus = document.querySelector("#auto-play-status"); +// DOM Elements (fetched once to keep the code efficient) +const quoteElement = document.getElementById("quote"); +const authorElement = document.getElementById("author"); +const newQuoteButton = document.getElementById("new-quote"); +const autoPlaySwitch = document.getElementById("auto-play-switch"); +const autoPlayStatus = document.getElementById("auto-play-status"); /** - * Updates the displayed quote and author on the screen. - * Uses the global pickFromArray function and quotes array. + * Selects and displays a new random quote from the quote list. + * This function changes the text on the screen. */ function displayNewQuote() { + // Selects a random quote object from the global 'quotes' array. const randomQuote = pickFromArray(quotes); + + // Updates the HTML elements with the new quote text and author name. quoteElement.innerText = randomQuote.quote; authorElement.innerText = randomQuote.author; } /** - * Starts the auto-play functionality. - * Sets an interval to update the quote and shows the status indicator. + * Starts the auto-play feature. + * This sets up a timer to automatically change the quote every few seconds. */ function startAutoPlay() { - // Clear any existing interval just in case + // Clears any existing timer first to prevent multiple timers running at once. if (autoPlayIntervalId) { clearInterval(autoPlayIntervalId); } - // Show status + // Shows the "auto-play: ON" status text to inform the user it is active. autoPlayStatus.classList.add("active"); - // Set interval + // Sets a repeating timer that calls 'displayNewQuote' every 5000 milliseconds (5 seconds). autoPlayIntervalId = setInterval(function () { displayNewQuote(); }, AUTO_PLAY_INTERVAL_MS); } /** - * Stops the auto-play functionality. - * Clears the interval and hides the status indicator. + * Stops the auto-play feature. + * This cancels the timer so the quotes stop changing automatically. */ function stopAutoPlay() { + // Checks if a timer exists, and if so, stops it. if (autoPlayIntervalId) { clearInterval(autoPlayIntervalId); autoPlayIntervalId = null; } - // Hide status + // Hides the "auto-play: ON" status text. autoPlayStatus.classList.remove("active"); } /** - * Toggles auto-play based on the checkbox state. - * @param event - The change event from the checkbox. + * Handles the change event when the user toggles the auto-play switch. + * Decides whether to start or stop auto-play based on the switch position. + * + * @param {Event} event - The event object from the click. */ function handleAutoPlayToggle(event) { + // Checks if the toggle switch is currently 'checked' (on). if (event.target.checked) { startAutoPlay(); } else { @@ -71,21 +76,21 @@ function handleAutoPlayToggle(event) { } } -// Event Listeners - -// Handle "New Quote" button click +// Adds an event listener to the "New Quote" button. +// When clicked, it shows a new quote and resets the auto-play timer if it's running. newQuoteButton.addEventListener("click", function () { displayNewQuote(); - // If auto-play is on, reset the timer so it doesn't change immediately after manual click + // If auto-play is turned on, restarts the timer. + // This prevents the quote from changing immediately after the user manually clicks. if (autoPlaySwitch.checked) { startAutoPlay(); } }); -// Handle Auto-play switch toggle +// Adds an event listener to the auto-play toggle switch. +// When changed, it triggers the handleAutoPlayToggle function. autoPlaySwitch.addEventListener("change", handleAutoPlayToggle); -// Initial Load -// Display a random quote when the app starts +// Displays a random quote immediately when the page loads so it isn't empty. displayNewQuote(); From 89c0209eba97a04fd3f8dc821c2ce2a1e3cb3bf5 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Sat, 13 Dec 2025 02:34:57 +0000 Subject: [PATCH 6/9] fix: align with requirements Updates include: - Changing 'New Quote' button text to 'New quote' to match test expectations - Setting autoplay interval to 60 seconds (60000ms) as per requirements - Correcting 'italicized' to 'italicised' in CSS comments - Ensuring British English spelling in comments --- Sprint-3/quote-generator/app.js | 6 +++--- Sprint-3/quote-generator/index.html | 2 +- Sprint-3/quote-generator/style.css | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sprint-3/quote-generator/app.js b/Sprint-3/quote-generator/app.js index 734f7a486..b76aa6fcb 100644 --- a/Sprint-3/quote-generator/app.js +++ b/Sprint-3/quote-generator/app.js @@ -1,7 +1,7 @@ /* globals quotes, pickFromArray */ // Use a constant for the auto-play time to make it easy to change later. -const AUTO_PLAY_INTERVAL_MS = 5000; +const AUTO_PLAY_INTERVAL_MS = 60000; // Defines variables to track the state of the app. // Uses 'let' because the timer ID will change when we start/stop auto-play. @@ -40,7 +40,7 @@ function startAutoPlay() { // Shows the "auto-play: ON" status text to inform the user it is active. autoPlayStatus.classList.add("active"); - // Sets a repeating timer that calls 'displayNewQuote' every 5000 milliseconds (5 seconds). + // Sets a repeating timer that calls 'displayNewQuote' every 60000 milliseconds (60 seconds). autoPlayIntervalId = setInterval(function () { displayNewQuote(); }, AUTO_PLAY_INTERVAL_MS); @@ -76,7 +76,7 @@ function handleAutoPlayToggle(event) { } } -// Adds an event listener to the "New Quote" button. +// Adds an event listener to the "New quote" button. // When clicked, it shows a new quote and resets the auto-play timer if it's running. newQuoteButton.addEventListener("click", function () { displayNewQuote(); diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index a954aa9f5..e2f9b6d98 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -23,7 +23,7 @@

Quote generator app

- +
Auto-play diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 3d445ed20..095bc6029 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -66,7 +66,7 @@ h1 { color: var(--text-color); margin-bottom: 2.5rem; text-align: right; - font-style: italic; /* Authors are often italicized in this style */ + font-style: italic; /* Authors are often italicised in this style */ } /* Add dash before author if not present in JS, but here we style assuming content */ From af53cd66e91f0ca7c79c7952f7d4ff0dc1d246b9 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Sat, 13 Dec 2025 02:36:08 +0000 Subject: [PATCH 7/9] refactor: improve code clarity and comments --- Sprint-3/quote-generator/app.js | 52 +++++++++++++++--------------- Sprint-3/quote-generator/style.css | 26 +++++++-------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Sprint-3/quote-generator/app.js b/Sprint-3/quote-generator/app.js index b76aa6fcb..7ada7b430 100644 --- a/Sprint-3/quote-generator/app.js +++ b/Sprint-3/quote-generator/app.js @@ -1,13 +1,13 @@ /* globals quotes, pickFromArray */ -// Use a constant for the auto-play time to make it easy to change later. +// Defines the auto-play interval duration (60 seconds) as a constant for maintainability. const AUTO_PLAY_INTERVAL_MS = 60000; -// Defines variables to track the state of the app. -// Uses 'let' because the timer ID will change when we start/stop auto-play. +// Tracks the state of the auto-play timer. +// Initializes as null to indicate no active timer. let autoPlayIntervalId = null; -// DOM Elements (fetched once to keep the code efficient) +// Caches DOM references to avoid repeated lookups during runtime. const quoteElement = document.getElementById("quote"); const authorElement = document.getElementById("author"); const newQuoteButton = document.getElementById("new-quote"); @@ -15,8 +15,8 @@ const autoPlaySwitch = document.getElementById("auto-play-switch"); const autoPlayStatus = document.getElementById("auto-play-status"); /** - * Selects and displays a new random quote from the quote list. - * This function changes the text on the screen. + * Retrieves a random quote from the data source and updates the DOM. + * Updates both the quote text and the author name. */ function displayNewQuote() { // Selects a random quote object from the global 'quotes' array. @@ -28,47 +28,47 @@ function displayNewQuote() { } /** - * Starts the auto-play feature. - * This sets up a timer to automatically change the quote every few seconds. + * Initiates the auto-play feature. + * Establishes a recurring timer to refresh the displayed quote. */ function startAutoPlay() { - // Clears any existing timer first to prevent multiple timers running at once. + // Clears any existing timer to prevent overlapping intervals. if (autoPlayIntervalId) { clearInterval(autoPlayIntervalId); } - // Shows the "auto-play: ON" status text to inform the user it is active. + // Activates the visual status indicator for auto-play. autoPlayStatus.classList.add("active"); - // Sets a repeating timer that calls 'displayNewQuote' every 60000 milliseconds (60 seconds). + // Schedules the 'displayNewQuote' function to execute every 60 seconds. autoPlayIntervalId = setInterval(function () { displayNewQuote(); }, AUTO_PLAY_INTERVAL_MS); } /** - * Stops the auto-play feature. - * This cancels the timer so the quotes stop changing automatically. + * Terminates the auto-play feature. + * Clears the active timer and resets the state. */ function stopAutoPlay() { - // Checks if a timer exists, and if so, stops it. + // Verifies if a timer exists before attempting to clear it. if (autoPlayIntervalId) { clearInterval(autoPlayIntervalId); autoPlayIntervalId = null; } - // Hides the "auto-play: ON" status text. + // Deactivates the visual status indicator. autoPlayStatus.classList.remove("active"); } /** - * Handles the change event when the user toggles the auto-play switch. - * Decides whether to start or stop auto-play based on the switch position. + * Manages the state change when the auto-play switch is toggled. + * Routes execution to start or stop auto-play based on the switch state. * - * @param {Event} event - The event object from the click. + * @param {Event} event - The change event triggered by the checkbox. */ function handleAutoPlayToggle(event) { - // Checks if the toggle switch is currently 'checked' (on). + // Evaluates the checked state of the toggle switch. if (event.target.checked) { startAutoPlay(); } else { @@ -76,21 +76,21 @@ function handleAutoPlayToggle(event) { } } -// Adds an event listener to the "New quote" button. -// When clicked, it shows a new quote and resets the auto-play timer if it's running. +// Attaches a click event listener to the "New quote" button. +// Triggers a manual update of the quote and resets the auto-play timer if active. newQuoteButton.addEventListener("click", function () { displayNewQuote(); - // If auto-play is turned on, restarts the timer. - // This prevents the quote from changing immediately after the user manually clicks. + // Restarts the auto-play timer if the feature is currently enabled. + // Ensures the full interval elapses before the next automatic update. if (autoPlaySwitch.checked) { startAutoPlay(); } }); -// Adds an event listener to the auto-play toggle switch. -// When changed, it triggers the handleAutoPlayToggle function. +// Attaches a change event listener to the auto-play toggle switch. +// Invokes the handler function whenever the user interacts with the switch. autoPlaySwitch.addEventListener("change", handleAutoPlayToggle); -// Displays a random quote immediately when the page loads so it isn't empty. +// Initializes the view by displaying a random quote upon page load. displayNewQuote(); diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 095bc6029..a1e882217 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -31,12 +31,12 @@ body { max-width: 700px; text-align: center; position: relative; - /* Simple crisp shadow or none based on flat design of example, keeping slight shadow for visibility */ + /* Applies a simple crisp shadow for visibility, maintaining the flat design aesthetic */ box-shadow: 0 4px 6px rgba(0,0,0,0.1); } h1 { - display: none; /* The example image doesn't show a visible title inside the card */ + display: none; /* Hides the title as it is not visible in the reference design */ } #quote { @@ -45,20 +45,20 @@ h1 { color: var(--text-color); margin-bottom: 1.5rem; position: relative; - padding-left: 3rem; /* Space for the quote icon */ + padding-left: 3rem; /* Reserves space for the decorative quote icon */ text-align: left; } #quote::before { - content: '“'; /* Large quote mark using curved quotes */ + content: '“'; /* Renders a large curved quote mark */ font-size: 6rem; color: var(--primary-color); position: absolute; top: -1.5rem; left: -1rem; line-height: 1; - font-family: sans-serif; /* Quote marks often look better in sans-serif or specific fonts */ - opacity: 1; /* Solid colour in example */ + font-family: sans-serif; /* Uses sans-serif for the quote mark for better visual appeal */ + opacity: 1; /* Maintains solid opacity matching the design */ } #author { @@ -66,10 +66,10 @@ h1 { color: var(--text-color); margin-bottom: 2.5rem; text-align: right; - font-style: italic; /* Authors are often italicised in this style */ + font-style: italic; /* Applies italics to distinguish the author name */ } -/* Add dash before author if not present in JS, but here we style assuming content */ +/* Appends a dash before the author name if not dynamically added by JS */ #author::before { content: '- '; } @@ -77,7 +77,7 @@ h1 { .controls { display: flex; flex-direction: column; - align-items: flex-end; /* Button aligned to right in some designs, or center. Example shows right or center. Let's align right to match typical 'next' flows or keep center if safer. Example looks right-aligned for button. */ + align-items: flex-end; /* Aligns controls to the right to match typical progression flows */ } button { @@ -96,12 +96,12 @@ button:hover { opacity: 0.9; } -/* Auto-play Switch - adjusting to fit the new theme */ +/* Auto-play Switch - adjusts layout to fit the theme */ .auto-play-container { display: flex; align-items: center; gap: 1rem; - margin-top: 1rem; /* Separate from main button */ + margin-top: 1rem; /* Separates the switch from the main action button */ align-self: flex-end; } @@ -132,9 +132,9 @@ button:hover { left: 0; right: 0; bottom: 0; - background-color: #e4e4e4; /* Light grey for off */ + background-color: #e4e4e4; /* Sets light grey background for the 'off' state */ transition: .4s; - border-radius: 0; /* Square/Rectangular look or keep rounded? Let's keep rounded for standard UI toggle */ + border-radius: 0; /* Maintains square/rectangular shape for a standard toggle look */ } .slider:before { From d390743dd5f2a9b12f7e0e030e7945695a621a36 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Sat, 13 Dec 2025 02:37:54 +0000 Subject: [PATCH 8/9] refactor: standardise code formatting --- Sprint-3/quote-generator/app.js | 44 ++++++-------- Sprint-3/quote-generator/style.css | 92 +++++++++++++++--------------- 2 files changed, 63 insertions(+), 73 deletions(-) diff --git a/Sprint-3/quote-generator/app.js b/Sprint-3/quote-generator/app.js index 7ada7b430..d607d918a 100644 --- a/Sprint-3/quote-generator/app.js +++ b/Sprint-3/quote-generator/app.js @@ -8,16 +8,14 @@ const AUTO_PLAY_INTERVAL_MS = 60000; let autoPlayIntervalId = null; // Caches DOM references to avoid repeated lookups during runtime. -const quoteElement = document.getElementById("quote"); -const authorElement = document.getElementById("author"); -const newQuoteButton = document.getElementById("new-quote"); -const autoPlaySwitch = document.getElementById("auto-play-switch"); -const autoPlayStatus = document.getElementById("auto-play-status"); +const quoteElement = document.getElementById('quote'); +const authorElement = document.getElementById('author'); +const newQuoteButton = document.getElementById('new-quote'); +const autoPlaySwitch = document.getElementById('auto-play-switch'); +const autoPlayStatus = document.getElementById('auto-play-status'); -/** - * Retrieves a random quote from the data source and updates the DOM. - * Updates both the quote text and the author name. - */ +// Retrieves a random quote from the data source and updates the DOM. +// Updates both the quote text and the author name. function displayNewQuote() { // Selects a random quote object from the global 'quotes' array. const randomQuote = pickFromArray(quotes); @@ -27,10 +25,8 @@ function displayNewQuote() { authorElement.innerText = randomQuote.author; } -/** - * Initiates the auto-play feature. - * Establishes a recurring timer to refresh the displayed quote. - */ +// Initiates the auto-play feature. +// Establishes a recurring timer to refresh the displayed quote. function startAutoPlay() { // Clears any existing timer to prevent overlapping intervals. if (autoPlayIntervalId) { @@ -38,7 +34,7 @@ function startAutoPlay() { } // Activates the visual status indicator for auto-play. - autoPlayStatus.classList.add("active"); + autoPlayStatus.classList.add('active'); // Schedules the 'displayNewQuote' function to execute every 60 seconds. autoPlayIntervalId = setInterval(function () { @@ -46,10 +42,8 @@ function startAutoPlay() { }, AUTO_PLAY_INTERVAL_MS); } -/** - * Terminates the auto-play feature. - * Clears the active timer and resets the state. - */ +// Terminates the auto-play feature. +// Clears the active timer and resets the state. function stopAutoPlay() { // Verifies if a timer exists before attempting to clear it. if (autoPlayIntervalId) { @@ -58,15 +52,11 @@ function stopAutoPlay() { } // Deactivates the visual status indicator. - autoPlayStatus.classList.remove("active"); + autoPlayStatus.classList.remove('active'); } -/** - * Manages the state change when the auto-play switch is toggled. - * Routes execution to start or stop auto-play based on the switch state. - * - * @param {Event} event - The change event triggered by the checkbox. - */ +// Manages the state change when the auto-play switch is toggled. +// Routes execution to start or stop auto-play based on the switch state. function handleAutoPlayToggle(event) { // Evaluates the checked state of the toggle switch. if (event.target.checked) { @@ -78,7 +68,7 @@ function handleAutoPlayToggle(event) { // Attaches a click event listener to the "New quote" button. // Triggers a manual update of the quote and resets the auto-play timer if active. -newQuoteButton.addEventListener("click", function () { +newQuoteButton.addEventListener('click', function () { displayNewQuote(); // Restarts the auto-play timer if the feature is currently enabled. @@ -90,7 +80,7 @@ newQuoteButton.addEventListener("click", function () { // Attaches a change event listener to the auto-play toggle switch. // Invokes the handler function whenever the user interacts with the switch. -autoPlaySwitch.addEventListener("change", handleAutoPlayToggle); +autoPlaySwitch.addEventListener('change', handleAutoPlayToggle); // Initializes the view by displaying a random quote upon page load. displayNewQuote(); diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index a1e882217..21399eaa6 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1,10 +1,10 @@ /** Write your CSS in here **/ :root { + --bg-color: #f5ac2d; + --card-bg: #fff; --primary-color: #f5ac2d; --text-color: #f5ac2d; - --bg-color: #f5ac2d; - --card-bg: #ffffff; --transition-speed: 0.3s; } @@ -15,24 +15,24 @@ } body { - font-family: Georgia, 'Times New Roman', Times, serif; + align-items: center; background-color: var(--bg-color); - min-height: 100vh; display: flex; + font-family: Georgia, 'Times New Roman', Times, serif; justify-content: center; - align-items: center; + min-height: 100vh; padding: 1rem; } .container { background: var(--card-bg); - padding: 3rem 4rem; - width: 100%; + /* Applies a simple crisp shadow for visibility, maintaining the flat design aesthetic */ + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); max-width: 700px; - text-align: center; + padding: 3rem 4rem; position: relative; - /* Applies a simple crisp shadow for visibility, maintaining the flat design aesthetic */ - box-shadow: 0 4px 6px rgba(0,0,0,0.1); + text-align: center; + width: 100%; } h1 { @@ -40,33 +40,33 @@ h1 { } #quote { + color: var(--text-color); font-size: 1.8rem; line-height: 1.4; - color: var(--text-color); margin-bottom: 1.5rem; - position: relative; padding-left: 3rem; /* Reserves space for the decorative quote icon */ + position: relative; text-align: left; } #quote::before { + color: var(--primary-color); content: '“'; /* Renders a large curved quote mark */ + font-family: sans-serif; /* Uses sans-serif for the quote mark for better visual appeal */ font-size: 6rem; - color: var(--primary-color); - position: absolute; - top: -1.5rem; left: -1rem; line-height: 1; - font-family: sans-serif; /* Uses sans-serif for the quote mark for better visual appeal */ opacity: 1; /* Maintains solid opacity matching the design */ + position: absolute; + top: -1.5rem; } #author { - font-size: 1.1rem; color: var(--text-color); + font-size: 1.1rem; + font-style: italic; /* Applies italics to distinguish the author name */ margin-bottom: 2.5rem; text-align: right; - font-style: italic; /* Applies italics to distinguish the author name */ } /* Appends a dash before the author name if not dynamically added by JS */ @@ -75,21 +75,21 @@ h1 { } .controls { + align-items: flex-end; /* Aligns controls to the right to match typical progression flows */ display: flex; flex-direction: column; - align-items: flex-end; /* Aligns controls to the right to match typical progression flows */ } button { background-color: var(--primary-color); - color: white; border: none; - padding: 0.8rem 1.5rem; - font-size: 1rem; - font-family: Arial, sans-serif; + color: #fff; cursor: pointer; - transition: opacity var(--transition-speed) ease; + font-family: Arial, sans-serif; + font-size: 1rem; font-weight: bold; + padding: 0.8rem 1.5rem; + transition: opacity var(--transition-speed) ease; } button:hover { @@ -98,54 +98,54 @@ button:hover { /* Auto-play Switch - adjusts layout to fit the theme */ .auto-play-container { - display: flex; align-items: center; + align-self: flex-end; + display: flex; gap: 1rem; margin-top: 1rem; /* Separates the switch from the main action button */ - align-self: flex-end; } .switch-label { - font-weight: normal; - font-size: 0.9rem; color: var(--text-color); font-family: Arial, sans-serif; + font-size: 0.9rem; + font-weight: normal; } .switch { - position: relative; display: inline-block; - width: 50px; height: 26px; + position: relative; + width: 50px; } .switch input { + height: 0; opacity: 0; width: 0; - height: 0; } .slider { - position: absolute; + background-color: #e4e4e4; /* Sets light grey background for the 'off' state */ + border-radius: 0; /* Maintains square/rectangular shape for a standard toggle look */ + bottom: 0; cursor: pointer; - top: 0; left: 0; + position: absolute; right: 0; - bottom: 0; - background-color: #e4e4e4; /* Sets light grey background for the 'off' state */ + top: 0; transition: .4s; - border-radius: 0; /* Maintains square/rectangular shape for a standard toggle look */ } .slider:before { - position: absolute; - content: ""; + background-color: #fff; + bottom: 3px; + content: ''; height: 20px; - width: 20px; left: 3px; - bottom: 3px; - background-color: white; + position: absolute; transition: .4s; + width: 20px; } input:checked + .slider { @@ -161,15 +161,15 @@ input:checked + .slider:before { } .status-indicator { + align-self: flex-end; + color: var(--primary-color); + font-family: Arial, sans-serif; font-size: 0.8rem; font-weight: bold; - color: var(--primary-color); - opacity: 0; margin-top: 0.5rem; - align-self: flex-end; - font-family: Arial, sans-serif; + opacity: 0; } .status-indicator.active { opacity: 1; -} +} \ No newline at end of file From 307b98e58937b1d426b70024882d33936094c8bb Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Sat, 13 Dec 2025 02:38:29 +0000 Subject: [PATCH 9/9] refactor: remove unnecessary comments --- Sprint-3/quote-generator/app.js | 40 +++--------------------------- Sprint-3/quote-generator/style.css | 25 ++++++++----------- 2 files changed, 13 insertions(+), 52 deletions(-) diff --git a/Sprint-3/quote-generator/app.js b/Sprint-3/quote-generator/app.js index d607d918a..fd357d7a4 100644 --- a/Sprint-3/quote-generator/app.js +++ b/Sprint-3/quote-generator/app.js @@ -1,64 +1,37 @@ /* globals quotes, pickFromArray */ -// Defines the auto-play interval duration (60 seconds) as a constant for maintainability. const AUTO_PLAY_INTERVAL_MS = 60000; - -// Tracks the state of the auto-play timer. -// Initializes as null to indicate no active timer. let autoPlayIntervalId = null; -// Caches DOM references to avoid repeated lookups during runtime. const quoteElement = document.getElementById('quote'); const authorElement = document.getElementById('author'); const newQuoteButton = document.getElementById('new-quote'); const autoPlaySwitch = document.getElementById('auto-play-switch'); const autoPlayStatus = document.getElementById('auto-play-status'); -// Retrieves a random quote from the data source and updates the DOM. -// Updates both the quote text and the author name. function displayNewQuote() { - // Selects a random quote object from the global 'quotes' array. const randomQuote = pickFromArray(quotes); - - // Updates the HTML elements with the new quote text and author name. quoteElement.innerText = randomQuote.quote; authorElement.innerText = randomQuote.author; } -// Initiates the auto-play feature. -// Establishes a recurring timer to refresh the displayed quote. function startAutoPlay() { - // Clears any existing timer to prevent overlapping intervals. if (autoPlayIntervalId) { clearInterval(autoPlayIntervalId); } - - // Activates the visual status indicator for auto-play. autoPlayStatus.classList.add('active'); - - // Schedules the 'displayNewQuote' function to execute every 60 seconds. - autoPlayIntervalId = setInterval(function () { - displayNewQuote(); - }, AUTO_PLAY_INTERVAL_MS); + autoPlayIntervalId = setInterval(displayNewQuote, AUTO_PLAY_INTERVAL_MS); } -// Terminates the auto-play feature. -// Clears the active timer and resets the state. function stopAutoPlay() { - // Verifies if a timer exists before attempting to clear it. if (autoPlayIntervalId) { clearInterval(autoPlayIntervalId); autoPlayIntervalId = null; } - - // Deactivates the visual status indicator. autoPlayStatus.classList.remove('active'); } -// Manages the state change when the auto-play switch is toggled. -// Routes execution to start or stop auto-play based on the switch state. function handleAutoPlayToggle(event) { - // Evaluates the checked state of the toggle switch. if (event.target.checked) { startAutoPlay(); } else { @@ -66,21 +39,14 @@ function handleAutoPlayToggle(event) { } } -// Attaches a click event listener to the "New quote" button. -// Triggers a manual update of the quote and resets the auto-play timer if active. newQuoteButton.addEventListener('click', function () { displayNewQuote(); - - // Restarts the auto-play timer if the feature is currently enabled. - // Ensures the full interval elapses before the next automatic update. if (autoPlaySwitch.checked) { startAutoPlay(); } }); -// Attaches a change event listener to the auto-play toggle switch. -// Invokes the handler function whenever the user interacts with the switch. autoPlaySwitch.addEventListener('change', handleAutoPlayToggle); -// Initializes the view by displaying a random quote upon page load. -displayNewQuote(); +// Initial display on load. +displayNewQuote(); \ No newline at end of file diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 21399eaa6..72a22388f 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1,5 +1,3 @@ -/** Write your CSS in here **/ - :root { --bg-color: #f5ac2d; --card-bg: #fff; @@ -26,7 +24,6 @@ body { .container { background: var(--card-bg); - /* Applies a simple crisp shadow for visibility, maintaining the flat design aesthetic */ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); max-width: 700px; padding: 3rem 4rem; @@ -36,7 +33,7 @@ body { } h1 { - display: none; /* Hides the title as it is not visible in the reference design */ + display: none; } #quote { @@ -44,19 +41,19 @@ h1 { font-size: 1.8rem; line-height: 1.4; margin-bottom: 1.5rem; - padding-left: 3rem; /* Reserves space for the decorative quote icon */ + padding-left: 3rem; /* Space for quote icon. */ position: relative; text-align: left; } #quote::before { color: var(--primary-color); - content: '“'; /* Renders a large curved quote mark */ - font-family: sans-serif; /* Uses sans-serif for the quote mark for better visual appeal */ + content: '“'; + font-family: sans-serif; font-size: 6rem; left: -1rem; line-height: 1; - opacity: 1; /* Maintains solid opacity matching the design */ + opacity: 1; position: absolute; top: -1.5rem; } @@ -64,18 +61,17 @@ h1 { #author { color: var(--text-color); font-size: 1.1rem; - font-style: italic; /* Applies italics to distinguish the author name */ + font-style: italic; margin-bottom: 2.5rem; text-align: right; } -/* Appends a dash before the author name if not dynamically added by JS */ #author::before { content: '- '; } .controls { - align-items: flex-end; /* Aligns controls to the right to match typical progression flows */ + align-items: flex-end; display: flex; flex-direction: column; } @@ -96,13 +92,12 @@ button:hover { opacity: 0.9; } -/* Auto-play Switch - adjusts layout to fit the theme */ .auto-play-container { align-items: center; align-self: flex-end; display: flex; gap: 1rem; - margin-top: 1rem; /* Separates the switch from the main action button */ + margin-top: 1rem; } .switch-label { @@ -126,8 +121,8 @@ button:hover { } .slider { - background-color: #e4e4e4; /* Sets light grey background for the 'off' state */ - border-radius: 0; /* Maintains square/rectangular shape for a standard toggle look */ + background-color: #e4e4e4; + border-radius: 0; bottom: 0; cursor: pointer; left: 0;