From 19ea0841aa6b383148ee5fbfeefbb2934d7fe009 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:07:48 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat=20:=20html=20=EB=BC=88=EB=8C=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index d241b1b..6aa1598 100644 --- a/index.html +++ b/index.html @@ -1,14 +1,20 @@ - - - - - Vanilla Todo - - + + + + ToDo List App + + + +
+
+ +
+ + +
+
- -
- - + + From efa97830b605797ad9c52120c3a0e4e5f55bf667 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:10:36 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat=20:=20js=EC=97=90=EC=84=9C=20=EC=A1=B0?= =?UTF-8?q?=EC=9E=91=ED=95=A0=20=EB=8F=94=20=EC=9A=94=EC=86=8C=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 유일한 요소 -> document.getElementById로 접근 --- script.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/script.js b/script.js index 52d54cd..b965bb8 100644 --- a/script.js +++ b/script.js @@ -1 +1,10 @@ //CEOS 19기 프론트엔드 파이팅🔥 ദ്ദി˶ˊᵕˋ˵) + +document.addEventListener('DOMContentLoaded', function () { + /* 조작할 DOM 요소 아이디로 참조 -> + 달력 / 섹션 추가 버튼 / 섹션명 입력 인풋 필드 / 섹션 컨테이너 */ + const datePicker = document.getElementById('datePicker'); + const addSectionBtn = document.getElementById('addSectionBtn'); + const sectionInput = document.getElementById('sectionInput'); + const todoSectionsDiv = document.getElementById('todoSections'); +}); From 60d33b66100677052683553177e964a7036893e6 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:17:40 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat=20:=20=EB=A1=9C=EC=BB=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EC=A7=80=EC=97=90=EC=84=9C=20set=20/get?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/script.js b/script.js index b965bb8..6e01ac0 100644 --- a/script.js +++ b/script.js @@ -7,4 +7,15 @@ document.addEventListener('DOMContentLoaded', function () { const addSectionBtn = document.getElementById('addSectionBtn'); const sectionInput = document.getElementById('sectionInput'); const todoSectionsDiv = document.getElementById('todoSections'); + + // 로컬 스토리지에서 특정 날짜 투두 리스트 가져오기 + function getSectionsForDate(date) { + const sectionsJSON = localStorage.getItem(date); + return sectionsJSON ? JSON.parse(sectionsJSON) : []; + } + + // 로컬 스토리지에 특정 날짜 투두 리스트 업데이트하기 + function saveSectionsForDate(date, sections) { + localStorage.setItem(date, JSON.stringify(sections)); + } }); From 6c038d058b5cbbc929a05815f4772d14d8b9a8e2 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:39:40 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat=20:=20=ED=8A=B9=EC=A0=95=20=20?= =?UTF-8?q?=ED=88=AC=EB=91=90=EB=A6=AC=EC=8A=A4=ED=8A=B8=EC=9D=98=20?= =?UTF-8?q?=EC=84=B9=EC=85=98,=20=EC=95=84=EC=9D=B4=ED=85=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80/=EC=82=AD=EC=A0=9C/=ED=99=94=EB=A9=B4=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script.js | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/script.js b/script.js index 6e01ac0..104418d 100644 --- a/script.js +++ b/script.js @@ -8,6 +8,121 @@ document.addEventListener('DOMContentLoaded', function () { const sectionInput = document.getElementById('sectionInput'); const todoSectionsDiv = document.getElementById('todoSections'); + // dom 로딩 완료 후, -> 날짜 선택-> 해당 날짜의 투두리스트 화면에 로드 + datePicker.addEventListener('change', loadSectionsForDate); + // dom 로딩 완료 후, -> 섹션 추가되면, -> 섹션 추가 + addSectionBtn.addEventListener('click', addTodoSection); + + // ** 함수 기능 : 로컬 스토리지에서 선택된 날의 전체 투두리스트 불러오기 -> html로 띄우기 + function loadSectionsForDate() { + const selectedDate = datePicker.value; + todoSectionsDiv.innerHTML = ''; // 특정 날 투두리스트 불러올 준비 + + // 로컬 스토리지에서 존재하는 섹션들 파악 + const sections = getSectionsForDate(selectedDate); + + sections.forEach((section, index) => { + // 모든 섹션을 화면에 보여주기위해 모든 존재하는 섹션에 대해 각각 createSectionDiv 호출 + const sectionDiv = createSectionDiv(section, index); + // 호출 결과(섹션별 준비된 구조) -> html에 추가 + todoSectionsDiv.appendChild(sectionDiv); + }); + } + + // 투두 리스트 섹션 기능 1. 섹션 추가 / 2. 섹션 삭제 + // 투두 리스트 섹션 추가 + function addTodoSection() { + const selectedDate = datePicker.value; + const sectionName = sectionInput.value.trim(); + if (!selectedDate || !sectionName) { + alert('날짜를 선택하고 섹션 이름을 입력해주세요.'); + return; + } + + const sections = getSectionsForDate(selectedDate); + sections.push({ name: sectionName, items: [] }); + saveSectionsForDate(selectedDate, sections); + // 로컬 스토리지에 추가한 섹션 -> loadSectionsForDate()로 html에 반영하기 + loadSectionsForDate(); + sectionInput.value = ''; + } + + // 투두 리스트 섹션 삭제 + function deleteSection(sectionIndex) { + const selectedDate = datePicker.value; + let sections = getSectionsForDate(selectedDate); + sections.splice(sectionIndex, 1); + // 로컬 스토리지에서 삭제한 섹션 -> loadSectionsForDate()로 html에 반영하기 + saveSectionsForDate(selectedDate, sections); + loadSectionsForDate(); + } + + // 투두 리스트 아이템 기능 1. 아이템 추가 / 2. 아이템 삭제 + function addTodoItem(sectionIndex, itemText) { + if (!itemText.trim()) return; + const selectedDate = datePicker.value; + const sections = getSectionsForDate(selectedDate); + sections[sectionIndex].items.push(itemText); + saveSectionsForDate(selectedDate, sections); + loadSectionsForDate(); + } + + function deleteTodoItem(sectionIndex, itemIndex) { + const selectedDate = datePicker.value; + let sections = getSectionsForDate(selectedDate); + sections[sectionIndex].items.splice(itemIndex, 1); + saveSectionsForDate(selectedDate, sections); + loadSectionsForDate(); + } + + // createSectionDiv : html에 특정 섹션 표시하기 위해, 필요한 모든 요소 구조 준비 + + function createSectionDiv(section, index) { + const sectionDiv = document.createElement('div'); + sectionDiv.className = 'todo-section'; + + const sectionTitle = document.createElement('h3'); + + const deleteSectionBtn = document.createElement('button'); + deleteSectionBtn.textContent = '섹션 삭제'; + deleteSectionBtn.onclick = () => deleteSection(index); + sectionTitle.appendChild(deleteSectionBtn); + + sectionDiv.appendChild(sectionTitle); + + // 선택된 섹션에 할 일 아이템들을 먼저 추가 + section.items.forEach((item, itemIndex) => { + const itemDiv = document.createElement('div'); + itemDiv.className = 'todo-item'; + itemDiv.textContent = item; + + const deleteItemBtn = document.createElement('button'); + deleteItemBtn.textContent = '완료'; + deleteItemBtn.onclick = () => deleteTodoItem(index, itemIndex); + itemDiv.appendChild(deleteItemBtn); + + sectionDiv.appendChild(itemDiv); + + return sectionDiv; + }); + + // 현재 할 일 아이템들 아래에 할 일 추가를 위한 입력 필드와 버튼 추가 + const itemInput = document.createElement('input'); + itemInput.type = 'text'; + itemInput.placeholder = '할 일 추가'; + sectionDiv.appendChild(itemInput); + + const addItemBtn = document.createElement('button'); + addItemBtn.textContent = '+'; + addItemBtn.onclick = () => addTodoItem(index, itemInput.value); + sectionDiv.appendChild(addItemBtn); + + /* 할일 아이템 요소들 다 추가된 만들어진 섹션 요소 반환해서 + 섹션을 loadSectionsForDate()에서 forEach()로 화면에 표시할 수 있도록 함 + */ + return sectionDiv; + } + // 로컬 스토리지에서 특정 날짜 투두 리스트 가져오기 function getSectionsForDate(date) { const sectionsJSON = localStorage.getItem(date); From d1f6521c984167621a2d83cd269c99eb329b6be5 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:42:01 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat=20:=20=EB=82=A8=EC=9D=80=20=ED=95=A0?= =?UTF-8?q?=20=EC=9D=BC=EC=9D=98=20=EC=88=98=20=EC=84=B9=EC=85=98=20?= =?UTF-8?q?=ED=83=80=EC=9D=B4=ED=8B=80=EC=97=90=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/script.js b/script.js index 104418d..9ac5cd6 100644 --- a/script.js +++ b/script.js @@ -83,6 +83,9 @@ document.addEventListener('DOMContentLoaded', function () { const sectionTitle = document.createElement('h3'); + // 섹션 타이틀 업데이트 함수 호출해서 섹션 별 할일 개수 타이틀에 반영 + updateSectionTitle(sectionTitle, section, index); + const deleteSectionBtn = document.createElement('button'); deleteSectionBtn.textContent = '섹션 삭제'; deleteSectionBtn.onclick = () => deleteSection(index); @@ -134,3 +137,14 @@ document.addEventListener('DOMContentLoaded', function () { localStorage.setItem(date, JSON.stringify(sections)); } }); + +// 남은 할 일의 수 섹션 타이틀에 반영해주는 함수 +function updateSectionTitle(sectionTitle, section, index) { + const remainingCount = countSectionItems(section); // 남은 할 일 수 계산 + sectionTitle.textContent = `${section.name} (남은 할 일: ${remainingCount})`; +} + +function countSectionItems(section) { + // 완료되지 않은 할 일의 수를 계산 + return section.items.filter((item) => !item.completed).length; +} \ No newline at end of file From 99ad41a29cfe8bf44c0a8d27e9240425b11be287 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:44:04 +0900 Subject: [PATCH 6/7] =?UTF-8?q?style=20:=20css=20=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- style.css | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/style.css b/style.css index 599136a..ef37893 100644 --- a/style.css +++ b/style.css @@ -1 +1,89 @@ /* 본인의 디자인 감각을 최대한 발휘해주세요! */ +@font-face { + font-family: 'SejonghospitalBold'; + src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2312-1@1.1/SejonghospitalBold.woff2') + format('woff2'); +} +body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + font-family: SejonghospitalBold, sans-serif; +} + +html { + width: 100%; + height: 95%; + margin: 0; + padding: 0; + font-family: SejonghospitalBold, sans-serif; +} + +#app { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-content: space-around; + width: 80%; + height: 98%; + + margin: 30px auto; + + padding: 20px auto; + overflow-y: auto; +} + +.calendar-section, +.todo-section, +.add-item { + width: 100%; /* 컨테이너 내부 너비 */ + box-sizing: border-box; /* 패딩과 보더가 너비에 포함되도록 설정 */ +} + +.todo-section { + margin-bottom: 20px 10px; + border: 1px solid #ccc; + padding: 10px; + border-radius: 5px; +} + +input[type='text'], +input[type='date'], +button { + font-family: SejonghospitalBold, sans-serif; + padding: 8px; + margin: 5px 0; + border-radius: 5px; + border: 1px solid #ccc; +} + +button { + background-color: #007bff; + color: white; + cursor: pointer; +} + +button:hover { + background-color: #0056b3; +} + +.todo-section h3 { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-content: space-around; + font-size: 13px; +} +.todo-item { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-content: space-around; + font-size: 10px; +} + +#todoSections { + max-height: 98vh; + overflow-y: auto; +} From 3c19bcc9a98ca9387395ebb345b0f5b29c766575 Mon Sep 17 00:00:00 2001 From: jinnyleeis <101055312+jinnyleeis@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:47:01 +0900 Subject: [PATCH 7/7] =?UTF-8?q?docs=20:=20=EB=B0=B0=ED=8F=AC=20=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EC=97=85=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 846a729..1ac71ed 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 1주차 미션: Vanilla-Todo +배포 링크 : https://vanilla-todo-19th-five.vercel.app/ + # 서론 안녕하세요 🙌🏻 19기 프론트엔드 운영진 **변지혜**입니다.