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 `
+
+
+
+ ${todo.text}
+
+
+
+
+ `
+ }
+ 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