Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions Sprint-3/quote-generator/index.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title here</title>
<script defer src="quotes.js"></script>
<title>Quote Generator App</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>hello there</h1>
<p id="quote"></p>
<p id="author"></p>
<button type="button" id="new-quote">New quote</button>
<div class="container">
<div class="header">
<h1>Quote Generator</h1>
</div>
<div class="quote-box">
<p>" <span id="quote"></span> "</p>
<p>-- <span id="author"></span> --</p>
</div>
<div class="bottom-controls">
<div class="button">
<button type="button" id="new-quote">New quote</button>
</div>
<div class="autoplay-container">
<label for="autoplay">
<input type="checkbox" id="autoplay" />
Auto-play :
</label>
<span id="autoplay-status"> OFF</span>
</div>
</div>
</div>
<script src="quotes.js"></script>
</body>
</html>
10 changes: 8 additions & 2 deletions Sprint-3/quote-generator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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"
}
}
77 changes: 72 additions & 5 deletions Sprint-3/quote-generator/quotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down Expand Up @@ -491,3 +486,75 @@ const quotes = [
];

// call pickFromArray with the quotes array to check you get a random quote

// 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");

if (!quoteEl || !authorEl || !quote) return;

quoteEl.textContent = quote.quote;
authorEl.textContent = quote.author;
}

// 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");

if (!button || !autoplayCheckbox || !autoplayStatus) return;

let autoplayInterval = null;

// Show first quote on page load
renderQuote(pickFromArray(quotes));

// 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");
}
});
}
Comment on lines +529 to +550
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For your reference:
https://chatgpt.com/share/69cae7dd-695c-8331-bb13-1ff731f13143

Suggestion made by ChatGPT how else you could implement this.

Note: I don't know how long ChatGPT will keep this chat available.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll try to use more CSS and reduce JavaScript in my projects and coursework. Whenever CSS can handle a feature, I won’t rely on JavaScript for it. Pseudo-elements like ::before and ::after are really powerful and useful for this approach. Thanks for the feedback and guidance.


// Initialize app only when DOM is fully loaded (browser environment)
if (typeof window !== "undefined") {
window.addEventListener("DOMContentLoaded", setupQuoteApp);
}

// Export function for Jest testing environment
if (typeof module !== "undefined") {
module.exports = pickFromArray;
}
3 changes: 3 additions & 0 deletions Sprint-3/quote-generator/quotes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
153 changes: 152 additions & 1 deletion Sprint-3/quote-generator/style.css
Original file line number Diff line number Diff line change
@@ -1 +1,152 @@
/** 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: rgb(206, 202, 202);
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-on {
color: #4caf50;
font-weight: bold;
}

.autoplay-off {
color: brown;
font-weight: bold;
}

/* 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;
}
}
Loading