diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..f26a1c0fa 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -1,15 +1,26 @@ - - - - Title here - - - -

hello there

+ + + + + Quote generator app + + + + + +
+

Quote Generator

- - +
+ + +
+

+
+ + + \ No newline at end of file diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..21b637774 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -1,3 +1,93 @@ +const newQuoteBtn = document.querySelector("#new-quote"); +const quote = document.querySelector("#quote"); +const author = document.querySelector("#author"); +const autoPlayToggle = document.querySelector("#auto-play-toggle"); +const autoPlayStatus = document.querySelector("#auto-play-status"); + +let seenQuotes = new Set(); +let autoPlayIntervalDuration = 10000; // 10 second interval duration +let autoPlayIntervalId = null; +let countdownIntervalId = null; + +// only show quotes that have not yet been seen +const getUnseenQuotes = () => { + // clear seenQuotes if all quotes have been displayed + if (seenQuotes.size === quotes.length) seenQuotes.clear(); + + // loop until index is not in seenQuotes + let index; + do { + index = Math.floor(Math.random() * quotes.length); + } while (seenQuotes.has(index)); + + seenQuotes.add(index); + return quotes[index]; +}; + +const displayQuote = () => { + const currentQuote = getUnseenQuotes(); + quote.innerText = currentQuote.quote; + author.innerText = currentQuote.author; + + if (autoPlayIntervalId) startCountDown(); +}; + +const startCountDown = () => { + let timeLeft = autoPlayIntervalDuration / 1000; + autoPlayStatus.innerText = `auto-play:ON - Quote will change in ${timeLeft} seconds`; + + if (countdownIntervalId) clearInterval(countdownIntervalId); + + countdownIntervalId = setInterval(() => { + timeLeft--; + autoPlayStatus.innerText = `auto-play:ON - Quote will change in ${timeLeft} seconds`; + if (timeLeft === 0) { + clearInterval(countdownIntervalId); + countdownIntervalId = null; + } + }, 1000); +}; + +const runInterval = () => { + displayQuote(); + startCountDown(); + autoPlayIntervalId = setInterval(displayQuote, autoPlayIntervalDuration); +}; + +const startAutoPlay = () => { + autoPlayStatus.innerText = "auto-play:ON"; + newQuoteBtn.classList.add("disabled"); + newQuoteBtn.disabled = true; + runInterval(); +}; + +const stopAutoPlay = () => { + if (countdownIntervalId) { + clearInterval(countdownIntervalId); + countdownIntervalId = null; + } + + if (autoPlayIntervalId) { + clearInterval(autoPlayIntervalId); + autoPlayIntervalId = null; + } + + autoPlayStatus.innerText = ""; + newQuoteBtn.classList.remove("disabled"); + newQuoteBtn.disabled = false; +}; + +// event listeners +autoPlayToggle.addEventListener("change", () => { + if (autoPlayToggle.checked) { + startAutoPlay(); + } else { + stopAutoPlay(); + } +}); +document.addEventListener("DOMContentLoaded", displayQuote); +newQuoteBtn.addEventListener("click", displayQuote); + // DO NOT EDIT BELOW HERE // pickFromArray is a function which will return one item, at diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..b5b30cb34 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,72 @@ /** Write your CSS in here **/ +* { + box-sizing: border-box; +} + +body { + display: grid; + place-items: center; + min-height: 100vh; + margin: 0; + /* background: linear-gradient(135deg, #667eea, #764ba2); */ + background: linear-gradient(135deg, #2749e1, #61269c); + font-family: Arial, sans-serif; +} + +main { + width: min(90%, 600px); + padding: 40px; + background: white; + border-radius: 20px; + text-align: center; + box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2); +} + +h1 { + margin-bottom: 30px; + color: #333; +} + +#quote { + font-size: 1.5rem; + font-style: italic; + line-height: 1.3; + color: #444; +} + +#author { + margin-top: 20px; + font-size: 1.1rem; + color: #777; +} + +button { + margin-top: 30px; + padding: 12px 25px; + border: none; + border-radius: 25px; + background: #3958e3; + color: white; + font-size: 1rem; + cursor: pointer; +} + +button.disabled { + background-color: #aaa; + cursor: not-allowed; + opacity: 0.7; +} + +button:hover { + background: #5563c1; +} + +.controls { + margin-top: 25px; +} + +#auto-play-status, +#countdown { + color: #666; + font-size: 0.9rem; +}