From 40de866217977ecab38db1fbff0ec948f67bc3a7 Mon Sep 17 00:00:00 2001 From: Amazingca Date: Thu, 30 Apr 2026 23:21:33 -0600 Subject: [PATCH] More of an inital commit --- index.html | 44 ++++++++++++- script.js | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++- style.css | 126 ++++++++++++++++++++++++++++++++++- 3 files changed, 356 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 28e3f7f..aa00f69 100644 --- a/index.html +++ b/index.html @@ -4,9 +4,49 @@ todo - + -

Hello, World!

+
+
+

todo

+ +
+
+
+
+
+ +
+ +
+ +
+
+
+ diff --git a/script.js b/script.js index 3135ddb..f8df07e 100644 --- a/script.js +++ b/script.js @@ -1 +1,189 @@ -window.alert("Welcome!"); +var todos = { + uncompleted: [], + completed: [] +}; +var archived = []; + +if (localStorage.getItem("todos")) { + + todos = JSON.parse(localStorage.getItem("todos")); +} + +if (localStorage.getItem("archived")) { + + archived = JSON.parse(localStorage.getItem("archived")); +} + +// TODO: URL sharing data override here... + +document.getElementById("createTodo").addEventListener("click", () => { + + todos.uncompleted = [ + { + description: "" + } + ].concat(todos.uncompleted); + + hydrateUncompleted(); + backupData(); +}); + +document.getElementById("showCompleted").addEventListener("click", () => { + + document.getElementById("todos-completed").classList.toggle("hidden"); + resizeTextHeights(); +}); + +const backupData = () => { + + localStorage.setItem("todos", JSON.stringify(todos)); + localStorage.setItem("archived", JSON.stringify(archived)); +} + +const todosElement = document.getElementById("todos"); +const completedElement = document.getElementById("todos-completed"); + +const todoElement = (item, index, isCompleted) => { + + let completedText = (isCompleted) ? "completed" : "uncompleted"; + + return ` + +
+ ${(isCompleted) ? '' : ''} +
+
+ +
+

archive

+

delete

+
+
+
+ `; +} + +const resizeTextHeights = () => { + + for (const element of document.querySelectorAll("todo textarea")) { + + element.style.height = "0"; + element.style.height = element.scrollHeight + "px"; + } +} + +const applyListeners = () => { + + resizeTextHeights(); + + for (var i = 0; i < todos.uncompleted.length; i++) { + + let index = i; // fixes scoping issue - what a disaster + + document.getElementById(`todo-uncompleted-${i}-description`).addEventListener("input", (event) => { + + event.target.style.height = "0"; + event.target.style.height = event.target.scrollHeight + "px"; + + todos.uncompleted[index].description = event.target.value; + + backupData(); + }); + + document.getElementById(`todo-uncompleted-${i}-completion`).addEventListener("click", (event) => { + + todos.completed = [ + todos.uncompleted[index] + ].concat(todos.completed); + todos.uncompleted.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + + document.getElementById(`todo-uncompleted-${i}-archive`).addEventListener("click", (event) => { + + archived = [ + todos.uncompleted[index] + ].concat(archived); + todos.uncompleted.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + + document.getElementById(`todo-uncompleted-${i}-delete`).addEventListener("click", (event) => { + + todos.uncompleted.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + } + + for (var i = 0; i < todos.completed.length; i++) { + + let index = i; // fixes scoping issue - what a disaster + + document.getElementById(`todo-completed-${i}-description`).addEventListener("input", (event) => { + + todos.completed[index].description = event.target.value; + + backupData(); + }); + + document.getElementById(`todo-completed-${i}-completion`).addEventListener("click", (event) => { + + todos.uncompleted = [ + todos.completed[index] + ].concat(todos.uncompleted); + todos.completed.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + + document.getElementById(`todo-completed-${i}-archive`).addEventListener("click", (event) => { + + archived = [ + todos.completed[index] + ].concat(archived); + todos.completed.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + + document.getElementById(`todo-completed-${i}-delete`).addEventListener("click", (event) => { + + todos.completed.splice(index, 1); + + hydrateTodos(); + backupData(); + }); + } +} + +const hydrateUncompleted = () => { + + todosElement.innerHTML = todos.uncompleted + .map((x, index) => todoElement(x, index, false)) + .join(""); +} + +const hydrateCompleted = () => { + + completedElement.innerHTML = todos.completed + .map((x, index) => todoElement(x, index, true)) + .join(""); +} + +const hydrateTodos = () => { + + hydrateUncompleted(); + hydrateCompleted(); + + applyListeners(); +}; + +hydrateTodos(); diff --git a/style.css b/style.css index 5b9ab9b..1cfc15a 100644 --- a/style.css +++ b/style.css @@ -1,3 +1,127 @@ +:root { + --text-primary: #000; + --background-primary: #fff; + --background-secondary: #eee; + --background-tertiary: #ccc; +} + body { - background-color: gray; + display: flex; + flex-direction: column; + align-items: center; + color: var(--text-primary); + background-color: var(--background-primary); + font-family: Arial; +} + +h3 { + margin: 0; + user-select: none; +} + +header { + width: 100%; + max-width: 750px; + & > div { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + gap: 0.5rem; + } + & > hr { + border: 1px solid var(--text-primary); + } +} + +nav { + display: flex; + flex-wrap: wrap; + gap: 0.25rem; +} + +#main { + display: flex; + width: 100%; + justify-content: center; + & > div, #todos, #todos-completed { + width: 400px; + display: flex; + flex-direction: column; + gap: 0.25rem; + } +} + +todo { + background-color: var(--background-secondary); + border-radius: 0.5rem; + display: flex; + /* align-items: center; */ + padding: 0.5rem; + gap: 0.5rem; + & .completion { + cursor: pointer; + } + & .data { + flex-grow: 0.97; + & textarea { + width: 100%; + resize: none; + border: unset; + border-radius: 0.25rem; + &:focus-visible { + outline: unset; + } + } + & > div { + margin-top: 0.25rem; + display: flex; + flex-wrap: wrap; + justify-content: right; + gap: 0.5rem; + & > p { + user-select: none; + font-size: 0.9rem; + margin: 0; + cursor: pointer; + &:hover { + text-decoration: underline; + } + } + } + } +} + +button { + background-color: var(--background-secondary); + border: unset; + border-radius: 0.5rem; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + cursor: pointer; +} + +a, a:visited, a:active { + user-select: none; + color: var(--text-primary); + background-color: var(--background-secondary); + text-decoration: none; + padding: 0.25rem; + border-radius: 0.5rem; +} + +button:active, a:hover { + background-color: var(--background-tertiary); +} + +.hidden, +div:has(> #todos-completed.hidden), +#main div:has(#todos-completed.hidden) #showCompleted_close, +#main div:not(:has(#todos-completed.hidden)) #showCompleted_open, +#main div:has(#todos-completed.hidden) hide, +#main div:not(:has(#todos-completed.hidden)) show { + display: none; } -- 2.54.0