diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html
index ee3ef64fd..f070333e0 100644
--- a/Sprint-3/todo-list/index.html
+++ b/Sprint-3/todo-list/index.html
@@ -1,18 +1,22 @@
-
-
- Title here
-
+
+
+ Todo List
+
+
+
+
+
diff --git a/Sprint-3/todo-list/script.js b/Sprint-3/todo-list/script.js
index 61982a54f..ec44df7e3 100644
--- a/Sprint-3/todo-list/script.js
+++ b/Sprint-3/todo-list/script.js
@@ -1,25 +1,117 @@
+function calculateDaysLeft(dateString) {
+ const today = new Date();
+ const deadline = new Date(dateString);
+ today.setHours(0, 0, 0, 0);
+ deadline.setHours(0, 0, 0, 0);
+
+ const diffTime = deadline - today;
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+
+ if (diffDays > 1) return { text: `${diffDays} days left`, status: "normal" };
+ if (diffDays === 1) return { text: "1 day left", status: "normal" };
+ if (diffDays === 0) return { text: "Due today", status: "due-today" };
+ return { text: "Overdue", status: "overdue" };
+}
+
+function createTodoElement(todoText, completed = false, deadline = "") {
+ const li = document.createElement("li");
+ li.innerText = todoText;
+ if (completed) {
+ li.style.textDecoration = "line-through";
+ }
+
+ // Show deadline countdown if provided
+ if (deadline) {
+ const countdownInfo = calculateDaysLeft(deadline);
+ const countdown = document.createElement("small");
+ countdown.style.display = "block";
+ countdown.style.fontSize = "0.8em";
+
+ if (countdownInfo.status === "overdue") {
+ countdown.style.color = "red";
+ } else if (countdownInfo.status === "due-today") {
+ countdown.style.color = "orange";
+ } else {
+ countdown.style.color = "#555";
+ }
+
+ countdown.innerText = countdownInfo.text;
+ li.appendChild(countdown);
+ }
+
+ const span = document.createElement("span");
+ span.className = "badge bg-primary rounded-pill";
+
+ const tickIcon = document.createElement("i");
+ tickIcon.className = "fa fa-check";
+ tickIcon.setAttribute("aria-hidden", "true");
+ tickIcon.addEventListener("click", () => {
+ if (li.style.textDecoration === "line-through") {
+ li.style.textDecoration = "";
+ } else {
+ li.style.textDecoration = "line-through";
+ }
+ });
+
+ const binIcon = document.createElement("i");
+ binIcon.className = "fa fa-trash";
+ binIcon.setAttribute("aria-hidden", "true");
+ binIcon.addEventListener("click", () => {
+ li.remove();
+ });
+
+ span.appendChild(tickIcon);
+ span.appendChild(binIcon);
+ li.appendChild(span);
+
+ return li;
+}
+
function populateTodoList(todos) {
- let list = document.getElementById("todo-list");
- // Write your code to create todo list elements with completed and delete buttons here, all todos should display inside the "todo-list" element.
+ const list = document.getElementById("todo-list");
+ list.innerHTML = "";
+ todos.forEach(todo => {
+ const li = createTodoElement(todo.task, todo.completed, todo.deadline || "");
+ list.appendChild(li);
+ });
}
-// These are the same todos that currently display in the HTML
-// You will want to remove the ones in the current HTML after you have created them using JavaScript
let todos = [
- { task: "Wash the dishes", completed: false },
- { task: "Do the shopping", completed: false },
+ { task: "Wash the dishes", completed: false, deadline: "" },
+ { task: "Do the shopping", completed: false, deadline: "" },
];
populateTodoList(todos);
-// This function will take the value of the input field and add it as a new todo to the bottom of the todo list. These new todos will need the completed and delete buttons adding like normal.
function addNewTodo(event) {
- // The code below prevents the page from refreshing when we click the 'Add Todo' button.
event.preventDefault();
- // Write your code here... and remember to reset the input field to be blank after creating a todo!
+ const input = document.getElementById("todoInput");
+ const dateInput = document.getElementById("todoDate");
+
+ const value = input.value.trim();
+ const deadline = dateInput.value;
+
+ if (value) {
+ const li = createTodoElement(value, false, deadline);
+ document.getElementById("todo-list").appendChild(li);
+ }
+
+ input.value = "";
+ dateInput.value = "";
}
-// Advanced challenge: Write a fucntion that checks the todos in the todo list and deletes the completed ones (we can check which ones are completed by seeing if they have the line-through styling applied or not).
function deleteAllCompletedTodos() {
- // Write your code here...
+ const list = document.getElementById("todo-list");
+ const completedItems = list.querySelectorAll("li");
+ completedItems.forEach(li => {
+ if (li.style.textDecoration === "line-through") {
+ li.remove();
+ }
+ });
}
+
+// Event listeners
+document.querySelector("form").addEventListener("submit", addNewTodo);
+document
+ .getElementById("remove-all-completed")
+ .addEventListener("click", deleteAllCompletedTodos);
diff --git a/Sprint-3/todo-list/style.css b/Sprint-3/todo-list/style.css
index 8b1378917..8d535c2f5 100644
--- a/Sprint-3/todo-list/style.css
+++ b/Sprint-3/todo-list/style.css
@@ -1 +1,83 @@
+/* Reset and basic styling */
+body {
+ font-family: Arial, sans-serif;
+ background-color: #f8f8f8;
+ margin: 0;
+ padding: 2rem;
+ color: #333;
+}
+form {
+ margin-bottom: 1rem;
+}
+
+input[type="text"],
+input[type="date"] {
+ padding: 0.5rem;
+ font-size: 1rem;
+ margin-right: 0.5rem;
+}
+
+button.btn {
+ padding: 0.5rem 1rem;
+ font-size: 1rem;
+ cursor: pointer;
+ margin-right: 0.5rem;
+ border: none;
+ border-radius: 4px;
+ background-color: #0077cc;
+ color: white;
+ transition: background-color 0.2s ease;
+}
+
+button.btn:hover {
+ background-color: #005fa3;
+}
+
+#todo-list {
+ list-style-type: none;
+ padding-left: 0;
+}
+
+#todo-list li {
+ padding: 0.5rem 1rem;
+ margin-bottom: 0.5rem;
+ background-color: white;
+ border-radius: 4px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+#todo-list li small {
+ margin-top: 0.2rem;
+}
+
+.badge {
+ display: flex;
+ gap: 0.5rem;
+ cursor: pointer;
+}
+
+.badge i {
+ padding: 0.2rem 0.4rem;
+ border-radius: 4px;
+ background-color: #e0e0e0;
+ color: #333;
+ transition: background-color 0.2s ease, color 0.2s ease;
+}
+
+.badge i:hover {
+ background-color: #0077cc;
+ color: white;
+}
+
+/* Remove all completed button styling */
+#remove-all-completed {
+ background-color: #cc0000;
+}
+
+#remove-all-completed:hover {
+ background-color: #a30000;
+}