From 4f1bbe84fe71e4c9efb7f9bc94d004fa52d7fc53 Mon Sep 17 00:00:00 2001 From: Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:27:12 +0000 Subject: [PATCH 1/5] 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 f3fc05624429687e752d8ad30676671f25a110e9 Mon Sep 17 00:00:00 2001 From: Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:27:42 +0000 Subject: [PATCH 2/5] 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 863e63ab49b5e218b97db597cda099de6a7700a0 Mon Sep 17 00:00:00 2001 From: Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:27:46 +0000 Subject: [PATCH 3/5] feat(js): implement quote generator logic and auto-play --- 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 bb6bd58e631ace0fa5d03393ff2c98225d651818 Mon Sep 17 00:00:00 2001 From: Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:36:27 +0000 Subject: [PATCH 4/5] 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 1fe8f721d8c1927dd304be1610f03929305301dc Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Fri, 12 Dec 2025 17:38:09 +0000 Subject: [PATCH 5/5] refactor(js): 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();