From ca5e7525f97ccb72d47bc34286e16ae79d73757d Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Thu, 4 Sep 2025 10:58:52 +0900 Subject: [PATCH] =?UTF-8?q?Alpine.js=20=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0:=20=EB=A9=94=EB=AA=A8=20=EA=B8=B0=EB=8A=A5=EC=9D=84?= =?UTF-8?q?=20=EB=A9=94=EC=9D=B8=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/static/js/todos.js | 62 ++++++++++++++++++++++++++++++------- frontend/todos.html | 20 ++++++------ 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/frontend/static/js/todos.js b/frontend/static/js/todos.js index 3750285..8af43cb 100644 --- a/frontend/static/js/todos.js +++ b/frontend/static/js/todos.js @@ -35,6 +35,10 @@ function todosApp() { currentTodo: null, currentTodoComments: [], + // 메모 상태 (각 할일별) + todoMemos: {}, + showMemoForTodo: {}, + // 폼 데이터 scheduleForm: { start_date: '', @@ -505,9 +509,11 @@ function todosApp() { async loadTodoMemos(todoId) { try { const response = await window.api.get(`/todos/${todoId}/comments`); - return response || []; + this.todoMemos[todoId] = response || []; + return this.todoMemos[todoId]; } catch (error) { console.error('❌ 메모 로드 실패:', error); + this.todoMemos[todoId] = []; return []; } }, @@ -519,6 +525,9 @@ function todosApp() { content: content.trim() }); + // 메모 목록 새로고침 + await this.loadTodoMemos(todoId); + console.log('✅ 메모 추가 완료'); return response; @@ -527,6 +536,26 @@ function todosApp() { alert('메모 추가 중 오류가 발생했습니다.'); throw error; } + }, + + // 메모 토글 + toggleMemo(todoId) { + this.showMemoForTodo[todoId] = !this.showMemoForTodo[todoId]; + + // 메모가 처음 열릴 때만 로드 + if (this.showMemoForTodo[todoId] && !this.todoMemos[todoId]) { + this.loadTodoMemos(todoId); + } + }, + + // 특정 할일의 메모 개수 가져오기 + getTodoMemoCount(todoId) { + return this.todoMemos[todoId] ? this.todoMemos[todoId].length : 0; + }, + + // 특정 할일의 메모 목록 가져오기 + getTodoMemos(todoId) { + return this.todoMemos[todoId] || []; } }; } @@ -558,12 +587,19 @@ document.addEventListener('DOMContentLoaded', () => { } }); -// 캘린더 컴포넌트 +// 캘린더 컴포넌트 (메인 컴포넌트에 통합) function calendarComponent() { return { currentDate: new Date(), + init() { + // 부모 컴포넌트 참조 설정 + this.parentApp = this.$el.closest('[x-data*="todosApp"]').__x.$data; + }, + get calendarDays() { + if (!this.parentApp) return []; + const year = this.currentDate.getFullYear(); const month = this.currentDate.getMonth(); const firstDay = new Date(year, month, 1); @@ -584,7 +620,7 @@ function calendarComponent() { const isToday = dateString === todayString; // 해당 날짜의 할일들 찾기 - const dayTodos = this.$parent.todos.filter(todo => { + const dayTodos = this.parentApp.todos.filter(todo => { if (!todo.start_date) return false; const todoDate = new Date(todo.start_date).toISOString().slice(0, 10); return todoDate === dateString && (todo.status === 'scheduled' || todo.status === 'active'); @@ -621,28 +657,32 @@ function calendarComponent() { }, selectDate(dateString) { - this.$parent.scheduleForm.start_date = dateString; + if (this.parentApp) { + this.parentApp.scheduleForm.start_date = dateString; + } }, selectDelayDate(dateString) { - this.$parent.delayForm.delayed_until = dateString; + if (this.parentApp) { + this.parentApp.delayForm.delayed_until = dateString; + } }, getSelectedDateTodos() { - if (!this.$parent.scheduleForm.start_date) return []; - return this.$parent.todos.filter(todo => { + if (!this.parentApp || !this.parentApp.scheduleForm.start_date) return []; + return this.parentApp.todos.filter(todo => { if (!todo.start_date) return false; const todoDate = new Date(todo.start_date).toISOString().slice(0, 10); - return todoDate === this.$parent.scheduleForm.start_date && (todo.status === 'scheduled' || todo.status === 'active'); + return todoDate === this.parentApp.scheduleForm.start_date && (todo.status === 'scheduled' || todo.status === 'active'); }); }, getDelayDateTodos() { - if (!this.$parent.delayForm.delayed_until) return []; - return this.$parent.todos.filter(todo => { + if (!this.parentApp || !this.parentApp.delayForm.delayed_until) return []; + return this.parentApp.todos.filter(todo => { if (!todo.start_date) return false; const todoDate = new Date(todo.start_date).toISOString().slice(0, 10); - return todoDate === this.$parent.delayForm.delayed_until && (todo.status === 'scheduled' || todo.status === 'active'); + return todoDate === this.parentApp.delayForm.delayed_until && (todo.status === 'scheduled' || todo.status === 'active'); }); } }; diff --git a/frontend/todos.html b/frontend/todos.html index 5b5af19..ae3a5a3 100644 --- a/frontend/todos.html +++ b/frontend/todos.html @@ -457,7 +457,7 @@