diff --git a/index.html b/index.html index cdba29c..bfcfe3a 100644 --- a/index.html +++ b/index.html @@ -23,38 +23,7 @@

Open


- +
@@ -62,26 +31,15 @@

Done


- +
+ + + + + diff --git a/js/constant.js b/js/constant.js new file mode 100644 index 0000000..d01d417 --- /dev/null +++ b/js/constant.js @@ -0,0 +1,2 @@ +const OPEN = 'open'; +const DONE = 'done'; diff --git a/js/index.js b/js/index.js index 4ff0861..273f474 100644 --- a/js/index.js +++ b/js/index.js @@ -1 +1,18 @@ -console.log('작성 시작'); +document.addEventListener('DOMContentLoaded', () => { + const taskViewModel = new TaskViewModel(); + const subjectViewModel = new SubjectViewModel(taskViewModel); + + const openSubject1 = new Subject('Opened Subject 1', OPEN); + taskViewModel.addTask('task 1', openSubject1.getId()); + taskViewModel.addTask('task 2', openSubject1.getId()); + subjectViewModel.addSubject(openSubject1); + + const openSubject2 = new Subject('Opened Subject 2', OPEN); + taskViewModel.addTask('task 1', openSubject2.getId()); + subjectViewModel.addSubject(openSubject2); + + const doneSubject1 = new Subject('Done Subject 1', DONE); + taskViewModel.addTask('task 1', doneSubject1.getId()); + taskViewModel.addTask('task 2', doneSubject1.getId()); + subjectViewModel.addSubject(doneSubject1); +}); diff --git a/js/models/subject.js b/js/models/subject.js new file mode 100644 index 0000000..23efc1c --- /dev/null +++ b/js/models/subject.js @@ -0,0 +1,28 @@ +class Subject { + constructor(title = 'New Subject', state = OPEN) { + this.title = title; + this.taskList = []; + this.state = state; + this.id = Math.random().toString(36).substring(2); // [todo] make random id function + } + + addTask(task) { + this.taskList.push(task); + } + + getTitle() { + return this.title; + } + + getState() { + return this.state; + } + + getTaskList() { + return this.taskList; + } + + getId() { + return this.id; + } +} diff --git a/js/models/task.js b/js/models/task.js new file mode 100644 index 0000000..ea37578 --- /dev/null +++ b/js/models/task.js @@ -0,0 +1,10 @@ +class Task { + constructor(title, subjectId) { + this.title = title; + this.subjectId = subjectId; + } + + getTitle() { + return this.title; + } +} diff --git a/js/viewModels/subjectViewModel.js b/js/viewModels/subjectViewModel.js new file mode 100644 index 0000000..89f1ee9 --- /dev/null +++ b/js/viewModels/subjectViewModel.js @@ -0,0 +1,59 @@ +class SubjectViewModel { + constructor(taskViewModel) { + this.subjectList = []; + this.taskViewModel = taskViewModel; + } + + addSubject(subject) { + this.subjectList.push(subject); + this.render(); + } + + render() { + const columnList = [OPEN, DONE]; + + columnList.forEach((column) => { + const subjectListElement = document.getElementById( + `${column}-subject-list` + ); + subjectListElement.innerHTML = ''; + + this.subjectList.forEach((subject) => { + const subjectId = subject.getId(); + const taskListElementId = `${subjectId}-task-list`; + if (subject.getState() !== column) return; + + const subjectElement = document.createElement('li'); + subjectElement.classList.add('card'); + subjectElement.innerHTML = ` +
+

${subject.getTitle()}

+
+
+
    +
+
+ `; + subjectListElement.appendChild(subjectElement); + + const taskListElement = document.getElementById(taskListElementId); + this.renderTasks(subjectId, taskListElement); + }); + }); + } + + renderTasks(subjectId, taskListElement) { + this.taskViewModel.getTasksBySubject(subjectId).forEach((task) => { + const taskElement = document.createElement('li'); + taskElement.className = 'task'; + const checkboxElement = document.createElement('input'); + checkboxElement.type = 'checkbox'; + const titleElement = document.createElement('p'); + titleElement.innerText = task.getTitle(); + + taskElement.appendChild(checkboxElement); + taskElement.appendChild(titleElement); + taskListElement.appendChild(taskElement); + }); + } +} diff --git a/js/viewModels/taskViewModel.js b/js/viewModels/taskViewModel.js new file mode 100644 index 0000000..48b2a2b --- /dev/null +++ b/js/viewModels/taskViewModel.js @@ -0,0 +1,17 @@ +class TaskViewModel { + constructor() { + this.taskList = new Map(); + } + + addTask(title, subjectId) { + const task = new Task(title, subjectId); + if (!this.taskList.has(subjectId)) { + this.taskList.set(subjectId, []); + } + this.taskList.get(subjectId).push(task); + } + + getTasksBySubject(subjectId) { + return this.taskList.get(subjectId) || []; + } +} diff --git a/todo.md b/todo.md index c35f4fa..34bb4ce 100644 --- a/todo.md +++ b/todo.md @@ -4,14 +4,14 @@ | -------- | ---------------------------------- | ----------------------------------- | | high | **기본 레이아웃** | 헤더, column(open, done) 배치 | | | | CSS 스타일 적용 | -| high | **데이터 구조 작성** | 카드 및 태스크 class 정의 | -| high | **카드 추가** | 카드 추가 버튼과 모달 구현 | -| | | 카드 추가 버튼 이벤트 핸들러 작성 | -| high | **카드 삭제** | 카드 삭제 버튼 구현 | -| | | 카드 삭제 버튼 이벤트 핸들러 작성 | -| high | **카드 상태 토글** | 카드 완료 체크박스 추가 | -| | | 카드 상태에 따른 스타일 변경 | -| | | 카드 상태 변경 이벤트 핸들러 작성 | +| high | **데이터 구조 작성** | 목표 및 태스크 class 정의 | +| high | **목표 추가** | 목표 추가 버튼과 모달 구현 | +| | | 목표 추가 버튼 이벤트 핸들러 작성 | +| high | **목표 삭제** | 목표 삭제 버튼 구현 | +| | | 목표 삭제 버튼 이벤트 핸들러 작성 | +| high | **목표 상태 토글** | 목표 완료 체크박스 추가 | +| | | 목표 상태에 따른 스타일 변경 | +| | | 목표 상태 변경 이벤트 핸들러 작성 | | high | **태스크 추가** | 태스크 input 필드 구현 | | | | submit 이벤트 핸들러 작성 | | high | **태스크 삭제** | 태스크 삭제 버튼 구현 |