diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..421d47f Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..ba1b604 --- /dev/null +++ b/index.html @@ -0,0 +1,30 @@ + + + + + 투두 앱 + + + + +

To do list

+ + +
+ + +
+ + +
+ + + +
+ + + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..b10c708 --- /dev/null +++ b/script.js @@ -0,0 +1,127 @@ +document.addEventListener("DOMContentLoaded", () => { + const todoInput = document.getElementById("todoInput"); + const addBtn = document.getElementById("addBtn"); + const todoList = document.getElementById("todoList"); + const selectedDateInput = document.getElementById("selectedDateInput"); + const countDisplay = document.getElementById("countDisplay"); + const title = document.getElementById("title"); // h1 선택 + + //데이터 로드 & 초기화 + let todos = JSON.parse(localStorage.getItem("todos")) || []; + + // 날짜 입력 기본값: 오늘 + selectedDateInput.value = getToday(); + + // 초기 렌더링 + renderTodos(todos); + + /*투두 추가기능*/ + addBtn.addEventListener("click", () => { + const text = todoInput.value.trim(); + const date = selectedDateInput.value; + + if (text === "" || date === "") { + alert("할 일과 날짜를 입력하세요!"); + return; + } + + const todo = { + id: Date.now(), + text, + date, + completed: false, // 완료 여부 추가 + }; + + todos.push(todo); + saveTodos(); + filterByDate(date); + + todoInput.value = ""; + selectedDateInput.value = date; // 날짜 유지 + }); + + /* 날짜별 조회 기능 */ + selectedDateInput.addEventListener("change", () => { + filterByDate(selectedDateInput.value); + }); + + function filterByDate(date) { + if (!date) return; + + const filtered = todos.filter((t) => t.date === date); + renderTodos(filtered); + countDisplay.textContent = `${filtered.length}개`; + } + + /* 제목 클릭시 오늘 날짜로 조회 기능 */ + title.addEventListener("click", () => { + selectedDateInput.value = getToday(); // 날짜 오늘로 초기화 + filterByDate(selectedDateInput.value); // 조회 버튼 없이 바로 조회 + }); + + /* 투두 렌더링 */ + function renderTodos(list) { + todoList.innerHTML = ""; + + if (!list || list.length === 0) { + const empty = document.createElement("li"); + empty.textContent = "표시할 할 일이 없습니다."; + empty.style.listStyle = "none"; + todoList.appendChild(empty); + return; + } + + list.forEach((todo) => { + const li = document.createElement("li"); + li.dataset.id = todo.id; + + // 투두 완료 체크박스 + const checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.checked = todo.completed; + checkbox.addEventListener("change", () => { + todo.completed = checkbox.checked; + saveTodos(); + renderTodos(list); // 상태 업데이트 후 다시 렌더링 + }); + + // 할 일 텍스트 + const span = document.createElement("span"); + span.textContent = todo.text; + if (todo.completed) { + span.style.textDecoration = "line-through"; // 완료시 취소선 + span.style.color = "gray"; + } + + //삭제 버튼 + const delBtn = document.createElement("button"); + delBtn.textContent = "삭제"; + delBtn.classList.add("deleteBtn"); + delBtn.addEventListener("click", () => { + todos = todos.filter((t) => t.id !== todo.id); + saveTodos(); + renderTodos(todos); + }); + + // li에 요소 추가 + li.appendChild(checkbox); + li.appendChild(span); + li.appendChild(delBtn); + todoList.appendChild(li); + }); + } + + /* 로컬 스토리지 저장 */ + function saveTodos() { + localStorage.setItem("todos", JSON.stringify(todos)); + } +}); + +/* 오늘 날짜 반환 */ +function getToday() { + const today = new Date(); + const year = today.getFullYear(); + const month = String(today.getMonth() + 1).padStart(2, "0"); + const day = String(today.getDate()).padStart(2, "0"); + return `${year}-${month}-${day}`; +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..c59102d --- /dev/null +++ b/style.css @@ -0,0 +1,93 @@ +@import url("https://cdn.jsdelivr.net/npm/pretendard/dist/web/static/pretendard.css"); +body { + font-family: "Pretendard", "Noto Sans KR", sans-serif; + background-color: #f5f6fa; + margin: 0; + padding: 40px; + /*todo list들이 세로로 배열되도록*/ + display: flex; + flex-direction: column; + align-items: center; +} + +#title { + color: #636161; + font-size: 28px; + margin-bottom: 20px; + cursor: pointer; +} +#title:hover { + color: purple; +} +#inputDiv { + width: 320px; +} + +#todoInput { + padding: 7px 10px; + font-size: 16px; + border: 1px solid #ddd; + border-radius: 8px; +} + +#todoInput:focus { + border-color: #4a90e2; +} + +#addBtn { + margin-left: 4px; + padding: 5px 10px; + font-size: 16px; + background-color: #4a90e2; + color: white; + border: none; + border-radius: 8px; + cursor: pointer; +} + +#addBtn:hover { + background-color: #357abd; +} +#countDisplay { + width: 30px; + margin-left: 10px; + font-size: large; +} +/* 리스트 */ +#todoList { + margin-top: 20px; + padding: 0; +} + +#todoList li { + width: 320px; + display: flex; + justify-content: space-between; + align-items: center; + background: white; + margin: 6px 0; + padding: 12px 16px; + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + font-size: 16px; + color: #444; +} + +/* 삭제 버튼 */ +.deleteBtn { + background-color: transparent; + color: #e74c3c; + border: none; + font-size: 14px; + cursor: pointer; + width: 40px; + flex-shrink: 0; +} + +.deleteBtn:hover { + color: #c0392b; +} + +#get-by-date { + margin-bottom: 50px; +}