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..272f6068 --- /dev/null +++ b/src/App.js @@ -0,0 +1,56 @@ +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: text => { + const todo = { + id: Date.now(), + text, + completed:false, + } + this.todoItems.push(todo); + this.setState(this.todoItems); + }, + }); + this.todoList.render(this.todoItems) + this.todoList.setEvent({ + onDelete: (event) => { + 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 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/TodoCount.js b/src/components/TodoCount.js new file mode 100644 index 00000000..650824d8 --- /dev/null +++ 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/TodoInput.js b/src/components/TodoInput.js new file mode 100644 index 00000000..183f3bc8 --- /dev/null +++ b/src/components/TodoInput.js @@ -0,0 +1,14 @@ +export default class TodoInput { + setEvent({onAdd}){ + const todoInput = document.querySelector('#new-todo-title'); + todoInput.addEventListener('keydown', event => this.addTodoItem(event, onAdd)); + } + addTodoItem(event, onAdd) { + const $newTodoTarget = event.target; + 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 new file mode 100644 index 00000000..7ff076c4 --- /dev/null +++ b/src/components/TodoList.js @@ -0,0 +1,25 @@ +export default class TodoList { + constructor() { + this.todoList = document.querySelector('#todo-list'); + } + render(todoItems){ + const todoItemTemplate = (todo) => { + return ` +
  • +
    + + + +
    + +
  • + ` + } + const template = todoItems.map((todo)=>todoItemTemplate(todo)); + this.todoList.innerHTML = template.join(""); + } + setEvent({onDelete,onCompleted}){ + this.todoList.addEventListener('click', onDelete); + this.todoList.addEventListener('click', onCompleted); + } +} 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(); 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