From d725a7e19ba52a72427ac85304ae7cd77d5aa4bc Mon Sep 17 00:00:00 2001 From: kimseunghun Date: Wed, 7 Jul 2021 22:41:54 +0900 Subject: [PATCH 1/5] =?UTF-8?q?etc=20:=20commit=20=ED=85=9C=ED=94=8C?= =?UTF-8?q?=EB=A6=BF=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmessage.txt | 26 ++++++++++++++++++++++++++ .prettierrc | 11 +++++++++++ index.html | 8 ++------ src/App.js | 7 +++++++ src/components/TodoCount.js | 0 src/components/TodoInput.js | 11 +++++++++++ src/components/TodoItem.js | 0 src/components/TodoList.js | 0 src/index.js | 3 +++ 9 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 .gitmessage.txt create mode 100644 .prettierrc create mode 100644 src/App.js create mode 100644 src/components/TodoCount.js create mode 100644 src/components/TodoInput.js create mode 100644 src/components/TodoItem.js create mode 100644 src/components/TodoList.js create mode 100644 src/index.js diff --git a/.gitmessage.txt b/.gitmessage.txt new file mode 100644 index 00000000..25ef09dc --- /dev/null +++ b/.gitmessage.txt @@ -0,0 +1,26 @@ +################ +# <타입> : <제목> 의 형식으로 제목을 아래 공백줄에 작성 +# 제목은 50자 이내 / 변경사항이 "무엇"인지 명확히 작성 / 끝에 마침표 금지 +# 예) feat: 로그인 기능 추가 + +# 바로 아래 공백은 지우지 마세요 (제목과 본문의 분리를 위함) + +################ +# 본문(구체적인 내용)을 아랫줄에 작성 +# 여러 줄의 메시지를 작성할 땐 "-"로 구분 (한 줄은 72자 이내) + +################ +# 꼬릿말(footer)을 아랫줄에 작성 (현재 커밋과 관련된 이슈 번호 추가 등) +# 예) Close #7 + +################ +# feat : 새로운 기능 추가 +# fix : 버그 수정 +# docs : 문서 수정 +# test : 테스트 코드 추가 +# refact : 코드 리팩토링 +# style : 코드 의미에 영향을 주지 않는 변경사항 +# chore : 빌드 부분 혹은 패키지 매니저 수정사항 +# design : CSS 등 사용자 UI 디자인 변경 +# etc : 기타변경 +################ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..95e0c571 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,11 @@ +{ + "printWidth": 120, + "tabWidth": 2, + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "semi": true, + "useTabs": false, + "arrowParens": "avoid", + "endOfLine": "lf" +} diff --git a/index.html b/index.html index 13a02fdb..083fa4b3 100644 --- a/index.html +++ b/index.html @@ -5,16 +5,12 @@ 이벤트 - TODOS +

TODOS

- +
    diff --git a/src/App.js b/src/App.js new file mode 100644 index 00000000..65d90310 --- /dev/null +++ b/src/App.js @@ -0,0 +1,7 @@ +import TodoInput from './components/TodoInput.js'; + +export default class App { + constructor(){ + this.input = new TodoInput(); + } +} \ No newline at end of file diff --git a/src/components/TodoCount.js b/src/components/TodoCount.js new file mode 100644 index 00000000..e69de29b diff --git a/src/components/TodoInput.js b/src/components/TodoInput.js new file mode 100644 index 00000000..c2b6c169 --- /dev/null +++ b/src/components/TodoInput.js @@ -0,0 +1,11 @@ +export default class TodoInput { + constructor() { + this.input = document.querySelector('#new-todo-title"'); + this.input.addEventListener('keyup', () => { + this.addTodo(); + }); + } + addTodo() { + console.loog(1); + } +} diff --git a/src/components/TodoItem.js b/src/components/TodoItem.js new file mode 100644 index 00000000..e69de29b diff --git a/src/components/TodoList.js b/src/components/TodoList.js new file mode 100644 index 00000000..e69de29b diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..6266ac05 --- /dev/null +++ b/src/index.js @@ -0,0 +1,3 @@ +import App from './App.js'; + +new App(); From 7b64bde166602dc9d0ce5b8716c1b2e39feb1b77 Mon Sep 17 00:00:00 2001 From: kimseunghun Date: Mon, 12 Jul 2021 05:20:20 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat=20:=20todoItem=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 27 ++++++++++++++++++++++++--- src/components/TodoInput.js | 17 ++++++++++------- src/components/TodoList.js | 24 ++++++++++++++++++++++++ src/utills/storage.js | 12 ++++++++++++ 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/utills/storage.js diff --git a/src/App.js b/src/App.js index 65d90310..d182adde 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,28 @@ import TodoInput from './components/TodoInput.js'; - +import TodoList from './components/TodoList.js'; +import { storage } from './utills/storage.js'; export default class App { constructor(){ - this.input = new TodoInput(); + this.todoItems = storage.get('todo') || []; + + this.setState = updatedItems => { + storage.set('todo', this.todoItems) + this.todoItems = updatedItems; + new TodoList(this.todoItems); + }; + + + this.init(); + + } + + init(){ + new TodoInput({ + onAdd: (todo) => { + this.todoItems.push(todo); + this.setState(this.todoItems) + } + }); + new TodoList(this.todoItems); } -} \ No newline at end of file +} diff --git a/src/components/TodoInput.js b/src/components/TodoInput.js index c2b6c169..65463b0b 100644 --- a/src/components/TodoInput.js +++ b/src/components/TodoInput.js @@ -1,11 +1,14 @@ export default class TodoInput { - constructor() { - this.input = document.querySelector('#new-todo-title"'); - this.input.addEventListener('keyup', () => { - this.addTodo(); - }); + constructor({ onAdd }) { + this.todoInput = document.querySelector('#new-todo-title'); + this.todoInput.addEventListener('keydown', (event) => this.addTodoItem(event, onAdd)); } - addTodo() { - console.loog(1); + + addTodoItem(event, onAdd){ + const $newTodoTarget = event.target; + if(event.key !== "Enter") return + if($newTodoTarget.value === "") return alert("할일을 입력해주세요.") + onAdd($newTodoTarget.value); + $newTodoTarget.value=""; } } diff --git a/src/components/TodoList.js b/src/components/TodoList.js index e69de29b..6d8e5222 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -0,0 +1,24 @@ +export default class TodoList { + constructor(todoItems) { + this.todoList = document.querySelector('#todo-list'); + this.todoItems = todoItems; + console.log(todoItems) + this.render(); + } + render(){ + const todoItemTemplate = (text) => { + return ` +
  • +
    + + + +
    + +
  • + ` + } + const template = this.todoItems.map((todo)=>todoItemTemplate(todo)); + this.todoList.innerHTML = template.join(""); + } +} diff --git a/src/utills/storage.js b/src/utills/storage.js new file mode 100644 index 00000000..a51f40ac --- /dev/null +++ b/src/utills/storage.js @@ -0,0 +1,12 @@ +export const storage = { + get: (KEY, defaultData = []) => { + try { + return JSON.parse(window.localStorage.getItem(KEY)) + } catch (e) { + return defaultData + } + }, + set: (KEY, value) => { + window.localStorage.setItem(KEY, JSON.stringify(value)) + } +} \ No newline at end of file From d2517bfd2b2ad28e9be9b830c4d380a82fae71d6 Mon Sep 17 00:00:00 2001 From: kimseunghun Date: Mon, 12 Jul 2021 08:13:34 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat=20:=20item=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 38 +++++++++++++++++++++++-------------- src/components/TodoInput.js | 18 +++++++++--------- src/components/TodoList.js | 16 ++++++++-------- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/App.js b/src/App.js index d182adde..39773a49 100644 --- a/src/App.js +++ b/src/App.js @@ -2,27 +2,37 @@ import TodoInput from './components/TodoInput.js'; import TodoList from './components/TodoList.js'; import { storage } from './utills/storage.js'; export default class App { - constructor(){ - this.todoItems = storage.get('todo') || []; - + constructor() { + this.todoItems = storage.get('todo') || []; + this.todoInput = new TodoInput(); + this.todoList = new TodoList(); + this.setState = updatedItems => { - storage.set('todo', this.todoItems) + storage.set('todo', this.todoItems); this.todoItems = updatedItems; - new TodoList(this.todoItems); + this.todoList.render(this.todoItems) }; - this.init(); - } - - init(){ - new TodoInput({ - onAdd: (todo) => { + + init() { + this.todoInput.setEvent({ + onAdd: todo => { this.todoItems.push(todo); - this.setState(this.todoItems) - } + this.setState(this.todoItems); + }, + }); + this.todoList.render(this.todoItems) + this.todoList.setEvent({ + onDelete: (event) => { + const item = event.target + if (!item.classList.contains('destroy')) return; + const id = Number(item.closest('li').dataset.id); + const itemIdx = this.todoItems.findIndex((i) => i.id === id); + this.todoItems.splice(itemIdx, 1); + this.setState(this.todoItems); + }, }); - new TodoList(this.todoItems); } } diff --git a/src/components/TodoInput.js b/src/components/TodoInput.js index 65463b0b..183f3bc8 100644 --- a/src/components/TodoInput.js +++ b/src/components/TodoInput.js @@ -1,14 +1,14 @@ export default class TodoInput { - constructor({ onAdd }) { - this.todoInput = document.querySelector('#new-todo-title'); - this.todoInput.addEventListener('keydown', (event) => this.addTodoItem(event, onAdd)); + setEvent({onAdd}){ + const todoInput = document.querySelector('#new-todo-title'); + todoInput.addEventListener('keydown', event => this.addTodoItem(event, onAdd)); } - - addTodoItem(event, onAdd){ + addTodoItem(event, onAdd) { const $newTodoTarget = event.target; - if(event.key !== "Enter") return - if($newTodoTarget.value === "") return alert("할일을 입력해주세요.") - onAdd($newTodoTarget.value); - $newTodoTarget.value=""; + if (event.key === 'Enter') { + if ($newTodoTarget.value === '') return alert('할일을 입력하세여.'); + onAdd($newTodoTarget.value); + $newTodoTarget.value = ''; + } } } diff --git a/src/components/TodoList.js b/src/components/TodoList.js index 6d8e5222..64dd94e8 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -1,14 +1,11 @@ export default class TodoList { - constructor(todoItems) { + constructor() { this.todoList = document.querySelector('#todo-list'); - this.todoItems = todoItems; - console.log(todoItems) - this.render(); } - render(){ - const todoItemTemplate = (text) => { + render(todoItems){ + const todoItemTemplate = (id, text) => { return ` -
  • +
  • @@ -18,7 +15,10 @@ export default class TodoList {
  • ` } - const template = this.todoItems.map((todo)=>todoItemTemplate(todo)); + const template = todoItems.map((todo,id)=>todoItemTemplate(id,todo)); this.todoList.innerHTML = template.join(""); } + setEvent({onDelete}){ + this.todoList.addEventListener('click', onDelete); + } } From decc2f19bec80724003c2a3e88da831aa01f18e9 Mon Sep 17 00:00:00 2001 From: kimseunghun Date: Mon, 12 Jul 2021 18:18:17 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat=20:=20count=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 19 +++++++++++++++++-- src/components/TodoCount.js | 9 +++++++++ src/components/TodoItem.js | 0 src/components/TodoList.js | 15 ++++++++------- 4 files changed, 34 insertions(+), 9 deletions(-) delete mode 100644 src/components/TodoItem.js diff --git a/src/App.js b/src/App.js index 39773a49..979b2539 100644 --- a/src/App.js +++ b/src/App.js @@ -1,24 +1,33 @@ import TodoInput from './components/TodoInput.js'; import TodoList from './components/TodoList.js'; +import TodoCount from './components/TodoCount.js'; import { storage } from './utills/storage.js'; export default class App { constructor() { this.todoItems = storage.get('todo') || []; this.todoInput = new TodoInput(); this.todoList = new TodoList(); + this.todoCount = new TodoCount(); this.setState = updatedItems => { storage.set('todo', this.todoItems); this.todoItems = updatedItems; this.todoList.render(this.todoItems) + this.todoCount.showCount(this.todoItems.length) }; this.init(); } init() { + this.setState(this.todoItems); this.todoInput.setEvent({ - onAdd: todo => { + onAdd: text => { + const todo = { + id: new Date(), + text, + completed:false, + } this.todoItems.push(todo); this.setState(this.todoItems); }, @@ -26,13 +35,19 @@ export default class App { this.todoList.render(this.todoItems) this.todoList.setEvent({ onDelete: (event) => { - const item = event.target + const item = event.target; if (!item.classList.contains('destroy')) return; const id = Number(item.closest('li').dataset.id); const itemIdx = this.todoItems.findIndex((i) => i.id === id); this.todoItems.splice(itemIdx, 1); this.setState(this.todoItems); }, + onCompleted : (event) =>{ + const item = event.target; + if (!item.classList.contains('toggle')) return; + const itemIdx = this.todoItems.findIndex((i) => i.id === id); + console.log(itemIdx) + } }); } } diff --git a/src/components/TodoCount.js b/src/components/TodoCount.js index e69de29b..650824d8 100644 --- a/src/components/TodoCount.js +++ b/src/components/TodoCount.js @@ -0,0 +1,9 @@ +export default class TodoCount{ + constructor(){ + this.count = document.querySelector('.todo-count strong'); + } + showCount(count){ + console.log(count) + this.count.innerHTML = count; + } +} \ No newline at end of file diff --git a/src/components/TodoItem.js b/src/components/TodoItem.js deleted file mode 100644 index e69de29b..00000000 diff --git a/src/components/TodoList.js b/src/components/TodoList.js index 64dd94e8..50088d73 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -3,22 +3,23 @@ export default class TodoList { this.todoList = document.querySelector('#todo-list'); } render(todoItems){ - const todoItemTemplate = (id, text) => { + const todoItemTemplate = (todo) => { return ` -
  • +
  • - - + +
    - +
  • ` } - const template = todoItems.map((todo,id)=>todoItemTemplate(id,todo)); + const template = todoItems.map((todo)=>todoItemTemplate(todo)); this.todoList.innerHTML = template.join(""); } - setEvent({onDelete}){ + setEvent({onDelete,onCompleted}){ this.todoList.addEventListener('click', onDelete); + this.todoList.addEventListener('click', onCompleted); } } From 2e89fca265f056a5c408619ab0fd92fd7d5dbc11 Mon Sep 17 00:00:00 2001 From: kimseunghun Date: Mon, 12 Jul 2021 19:43:51 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat=20:=20=20=EC=B2=B4=ED=81=AC=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=EB=A5=BC=20=ED=81=B4=EB=A6=AD=ED=95=98=EC=97=AC=20com?= =?UTF-8?q?plete=20=EC=83=81=ED=83=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 21 ++++++++++++--------- src/components/TodoList.js | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/App.js b/src/App.js index 979b2539..272f6068 100644 --- a/src/App.js +++ b/src/App.js @@ -24,7 +24,7 @@ export default class App { this.todoInput.setEvent({ onAdd: text => { const todo = { - id: new Date(), + id: Date.now(), text, completed:false, } @@ -35,18 +35,21 @@ export default class App { this.todoList.render(this.todoItems) this.todoList.setEvent({ onDelete: (event) => { - const item = event.target; - if (!item.classList.contains('destroy')) return; - const id = Number(item.closest('li').dataset.id); - const itemIdx = this.todoItems.findIndex((i) => i.id === id); + const target = event.target; + if (!target.classList.contains('destroy')) return; + const id = Number(target.closest('li').dataset.id); + const itemIdx = this.todoItems.findIndex((item) => item.id === id); this.todoItems.splice(itemIdx, 1); this.setState(this.todoItems); }, onCompleted : (event) =>{ - const item = event.target; - if (!item.classList.contains('toggle')) return; - const itemIdx = this.todoItems.findIndex((i) => i.id === id); - console.log(itemIdx) + const target = event.target; + if (!target.classList.contains('toggle')) return; + const id = Number(target.closest('li').dataset.id); + console.log(id) + const item = this.todoItems.find((todoItem) => todoItem.id === id); + item.completed = !item.completed; + this.setState(this.todoItems); } }); } diff --git a/src/components/TodoList.js b/src/components/TodoList.js index 50088d73..7ff076c4 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -5,9 +5,9 @@ export default class TodoList { render(todoItems){ const todoItemTemplate = (todo) => { return ` -
  • +
  • - +