diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..8643fb6af 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,35 @@ -function setAlarm() {} + +let countdown; +function setAlarm() { +clearInterval(countdown); +const inputField = document.getElementById("alarmSet"); +const timeRemainingHeading = document.getElementById("timeRemaining"); +let totalSeconds = parseInt(inputField.value); +if (isNaN(totalSeconds)) return; +function updateDisplay(secondsLeft) { + const minutes = Math.floor(secondsLeft / 60); + const seconds = secondsLeft % 60; + const formattedMinutes = String(minutes).padStart(2, "0"); + const formattedSeconds = String(seconds).padStart(2, "0"); + + timeRemainingHeading.innerText = `Time Remaining: ${formattedMinutes}:${formattedSeconds}`; + updateDisplay(totalSeconds); + } + countdown = setInterval(() => { + totalSeconds--; + + if (totalSeconds > 0) { + updateDisplay(totalSeconds); + } + + if (totalSeconds === 0) { + playAlarm(); + clearInterval(countdown); + updateDisplay(totalSeconds); + } + }, 1000); +} +window.setAlarm = setAlarm; // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 48e2e80d9..9b71b5b6e 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Title here + Alarm Clock
diff --git a/Sprint-3/alarmclock/package.json b/Sprint-3/alarmclock/package.json index e1331e071..940fb8df3 100644 --- a/Sprint-3/alarmclock/package.json +++ b/Sprint-3/alarmclock/package.json @@ -13,5 +13,8 @@ "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", + "devDependencies": { + "jsdom": "^24.0.0" + } } diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..6c5b41350 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,13 +3,15 @@ - Title here + Quote Generator + -

hello there

-

-

- +
+

+

+ +
diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..d4ee0b000 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -491,3 +491,16 @@ const quotes = [ ]; // call pickFromArray with the quotes array to check you get a random quote +const quoteText = document.getElementById('quote'); +const authorText = document.getElementById('author'); +const newQuoteBtn = document.getElementById('new-quote'); + +function displayNewQuote() { + const randomQuote = pickFromArray(quotes); + quoteText.textContent = randomQuote.quote; + authorText.textContent = `- ${randomQuote.author}`; +} + +newQuoteBtn.addEventListener('click', displayNewQuote); + +displayNewQuote(); \ No newline at end of file diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..fe0ed3227 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,16 @@ /** Write your CSS in here **/ +body { + background-color: #ffa500; /* That bright orange */ + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; +} + +#quote-container { /* If you wrap your p tags in a div */ + background: white; + padding: 40px; + border-radius: 8px; + max-width: 600px; +} \ No newline at end of file diff --git a/Sprint-3/reading-list/index.html b/Sprint-3/reading-list/index.html index dbdb0f471..88102fc1f 100644 --- a/Sprint-3/reading-list/index.html +++ b/Sprint-3/reading-list/index.html @@ -4,7 +4,7 @@ - Title here + Reading List
diff --git a/Sprint-3/reading-list/script.js b/Sprint-3/reading-list/script.js index 6024d73a0..9487102f6 100644 --- a/Sprint-3/reading-list/script.js +++ b/Sprint-3/reading-list/script.js @@ -21,3 +21,14 @@ const books = [ }, ]; +const readingList = document.querySelector("#reading-list"); + +books.forEach((book) => { + const li = document.createElement("li"); + li.textContent = `${book.title} by ${book.author}`; + const img = document.createElement("img"); + img.src = book.bookCoverImage; + li.appendChild(img); + li.style.backgroundColor = book.alreadyRead ? "green" : "red"; + readingList.appendChild(li); +}); \ No newline at end of file diff --git a/Sprint-3/reading-list/style.css b/Sprint-3/reading-list/style.css index 74406e64f..2e804d984 100644 --- a/Sprint-3/reading-list/style.css +++ b/Sprint-3/reading-list/style.css @@ -1,159 +1,27 @@ -/** - * Base styles to use at the start of the class - * - * Module: HTML/CSS - * Lesson: 1,2 - * Class: Scotland 2017 - */ - -html, -body { - font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont, - "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; -} - -.site-footer { - margin-top: 4em; -} - -.site-footer p { - border-top: 1px solid #dccdc6; - padding-top: 2em; - padding-bottom: 2em; -} - -.navbar-brand > img { - max-height: 40px; - width: auto; -} - -.navbar-light .navbar-nav .nav-link { - color: #292b2c; - font-weight: 600; - text-transform: uppercase; -} - -/* Buttons */ -.btn { - border-radius: 0.15em; -} - -/* Alert */ -.alert { - position: relative; - margin-top: 2em; - margin-bottom: 3em; - padding-top: 1.5em; - padding-bottom: 1.5em; - border: 1px solid #dccdc6; - border-radius: 0; - font-size: 0.85rem; - line-height: 1.3em; - background: transparent; - color: #292b2c; -} - -.alert:before { - content: ""; - position: absolute; - left: -1px; - top: 0; - height: 100%; - width: 1px; - background: #ce5f31; -} - -/* Jumbotron */ -.jumbotron { - border-radius: 0; -} - -/* Headings */ -.heading-underline { - position: relative; - margin-bottom: 2em; - padding-bottom: 0.5em; - border-bottom: 1px solid #dccdc6; - font-size: 1rem; - font-weight: 600; - text-transform: uppercase; -} - -.heading-underline:before { - content: ""; - position: absolute; - bottom: -1px; - left: 0; - width: 25%; - height: 1px; - max-width: 100px; - background: #ce5f31; +/* Base styles from your class file */ +html, body { + font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + padding: 20px; } -/* Article */ -.article { - margin-bottom: 2em; +#reading-list { + list-style-type: none; + padding: 0; + max-width: 600px; } -.article-title { - margin-bottom: 0.5em; - font-weight: 700; -} - -.article-read-more a { - font-size: 0.85em; - font-weight: 700; - text-decoration: uppercase; -} - -.article-read-more a:hover, -.article-read-more a:focus { - text-decoration: none; -} - -.article-read-more .fa { - margin-right: 0.5em; - color: #ce5f31; -} - -.article-read-more:last-child { - margin-bottom: 0; -} - -.red { - background-color: red; -} - -.addArticle { - margin-bottom: 10px; -} - -#addArticleBtn { - margin-left: 20px; - height: 37px; -} - -.colorButton { +#reading-list li { + display: flex; + flex-direction: column; + padding: 20px; margin-bottom: 20px; - margin-right: 20px; - width: 100px; - height: 50px; -} - -#blueBtn { - background: #588fbd; -} - -#orangeBtn { - background: #f0ad4e; -} - -#greenBtn { - background: #87ca8a; + font-weight: 600; + } -@media screen and (min-width: 992px) { - .navbar-brand > img { - max-height: 80px; - } +#reading-list img { + width: 150px; + height: auto; + margin-top: 15px; + display: block; } diff --git a/Sprint-3/slideshow/index.html b/Sprint-3/slideshow/index.html index 50f2eb1c0..a1f24da47 100644 --- a/Sprint-3/slideshow/index.html +++ b/Sprint-3/slideshow/index.html @@ -3,12 +3,20 @@ - Title here + Slideshow + - cat-pic +
+ cat-pic width: 400px; height: 300px; +
+
+ + + +
diff --git a/Sprint-3/slideshow/package.json b/Sprint-3/slideshow/package.json index 306353179..c7c9ddd47 100644 --- a/Sprint-3/slideshow/package.json +++ b/Sprint-3/slideshow/package.json @@ -13,5 +13,8 @@ "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", + "devDependencies": { + "jsdom": "^29.1.1" + } } diff --git a/Sprint-3/slideshow/slideshow.js b/Sprint-3/slideshow/slideshow.js index 063ceefb5..95da544a7 100644 --- a/Sprint-3/slideshow/slideshow.js +++ b/Sprint-3/slideshow/slideshow.js @@ -4,5 +4,46 @@ const images = [ "./assets/cute-cat-c.jpg", ]; +let currentIndex = 0; +let intervalId = null; -// Write your code here \ No newline at end of file +const imgElement = document.querySelector("#carousel-img"); +const forwardBtn = document.querySelector("#forward-btn"); +const backwardBtn = document.querySelector("#backward-btn"); +const autoForwardBtn = document.querySelector("#auto-forward"); +const autoBackBtn = document.querySelector("#auto-backward"); +const stopBtn = document.querySelector("#stop"); + +function updateImage() { + imgElement.src = images[currentIndex]; +} +function moveForward() { + currentIndex = (currentIndex + 1) % images.length; + updateImage(); +} + +function moveBackward() { + currentIndex = (currentIndex - 1 + images.length) % images.length; + updateImage(); +} + +forwardBtn.addEventListener("click", moveForward); +backwardBtn.addEventListener("click", moveBackward); + +function startAuto(directionFn) { + // Disable buttons as required by tests + autoForwardBtn.disabled = true; + autoBackBtn.disabled = true; + + intervalId = setInterval(directionFn, 2000); +} + +autoForwardBtn.addEventListener("click", () => startAuto(moveForward)); +autoBackBtn.addEventListener("click", () => startAuto(moveBackward)); + +stopBtn.addEventListener("click", () => { + clearInterval(intervalId); + // Re-enable buttons + autoForwardBtn.disabled = false; + autoBackBtn.disabled = false; +}); \ No newline at end of file diff --git a/Sprint-3/slideshow/style.css b/Sprint-3/slideshow/style.css index 63cedf2d2..022063f3d 100644 --- a/Sprint-3/slideshow/style.css +++ b/Sprint-3/slideshow/style.css @@ -1 +1,21 @@ -/** Write your CSS in here **/ +#carousel-img { + /* This locks every "next" image to these exact dimensions */ + width: 500px; + height: 350px; + display: block; + margin: 0 auto; +} + +.slideshow-frame { + width: 500px; + height: 350px; + margin: 0 auto; + border: 2px solid black; +} + +.slideshow-controls { + display: flex; + justify-content: center; + gap: 10px; + margin-top: 20px; +} \ No newline at end of file diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 4d12c4654..4144aaf95 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -15,6 +15,8 @@

My ToDo List

+ +
@@ -25,12 +27,15 @@

My ToDo List

This is a template for the To-do list item. It can simplify the creation of list item node in JS script. --> + diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json index ce181158a..1e6403d8b 100644 --- a/Sprint-3/todo-list/package.json +++ b/Sprint-3/todo-list/package.json @@ -18,6 +18,7 @@ "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", "devDependencies": { "http-server": "^14.1.1", - "jest": "^30.0.4" + "jest": "^30.0.4", + "jsdom": "^29.1.1" } } diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index ba0b2ceae..c786daa38 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -7,12 +7,16 @@ const todos = []; // Set up tasks to be performed once on page load window.addEventListener("load", () => { document.getElementById("add-task-btn").addEventListener("click", addNewTodo); + document.getElementById("clear-completed-btn").addEventListener("click", () => { + Todos.deleteCompleted(todos); + populateTodoList(); + }); // Populate sample data - Todos.addTask(todos, "Wash the dishes", false); - Todos.addTask(todos, "Do the shopping", true); + Todos.addTask(todos, "Wash the dishes","2026-05-01", false); + Todos.addTask(todos, "Do the shopping","2026-05-02", true); - render(); + populateTodoList(); }); @@ -20,15 +24,45 @@ window.addEventListener("load", () => { // append a new task to the todo list. function addNewTodo() { const taskInput = document.getElementById("new-task-input"); + const deadlineInput = document.getElementById("task-deadline"); const task = taskInput.value.trim(); + const deadline = deadlineInput.value; if (task) { - Todos.addTask(todos, task, false); - render(); + Todos.addTask(todos, task, deadline, false); + populateTodoList(); } taskInput.value = ""; + deadlineInput.value = ""; +} +function createListItem(todo, index) { + const li = todoListItemTemplate.cloneNode(true); + + // FIX: This line ensures the date string is actually added to the UI + const deadlineDisplay = todo.deadline ? ` (Due: ${todo.deadline})` : ""; + li.querySelector(".description").textContent = todo.task + deadlineDisplay; + + if (todo.completed) { + li.classList.add("completed"); + // Requirement: Checkbox becomes ticked ✅ + li.querySelector(".complete-btn span").className = "fa-solid fa-square-check"; + } + + // Action listeners... + li.querySelector('.complete-btn').addEventListener("click", () => { + Todos.toggleCompletedOnTask(todos, index); + populateTodoList(); + }); + + li.querySelector('.delete-btn').addEventListener("click", () => { + Todos.deleteTask(todos, index); + populateTodoList(); + }); + + return li; } + // Note: // - Store the reference to the