/** * 섭취 챌린지 마일리지 요약 페이지 JavaScript * * 주요 기능: * 1. 달력 렌더링 (월별 섭취 현황 표시) * 2. 날짜별 상태 조회 */ $(document).ready(function() { console.log('[마일리지 요약 페이지] 초기화 시작'); // 월 이름 배열 const monthNames = ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"]; console.log('[마일리지 요약 페이지] 월 이름 배열 설정 완료'); // 현재 날짜 및 상태 변수 초기화 let currentDate = new Date(); let isLoading = false; const $calendarContainer = $("#stats-dates"); console.log('[마일리지 요약 페이지] 현재 날짜:', currentDate); // 날짜별 상태 클래스 데이터 - 서버에서 받은 데이터 사용 let dateClasses = {}; console.log('[마일리지 요약 페이지] dateClasses 객체 초기화'); // 서버에서 받은 데이터를 객체 형태로 변환 if (window.initialDateClasses && Array.isArray(window.initialDateClasses)) { console.log('[마일리지 요약 페이지] 서버에서 받은 initialDateClasses 데이터:', window.initialDateClasses); window.initialDateClasses.forEach(item => { if (item.date) { // 상태 클래스들을 조합하여 저장 let classes = []; if (item.statsDone) classes.push(item.statsDone); if (item.statsIng && item.statsIng !== item.statsDone) classes.push(item.statsIng); if (item.stats30done) classes.push(item.stats30done); if (classes.length > 0) { dateClasses[item.date] = classes.join(' '); console.log(`[마일리지 요약 페이지] 날짜 클래스 매핑: ${item.date} => ${dateClasses[item.date]}`); } } }); } else { console.log('[마일리지 요약 페이지] 초기 날짜 클래스 데이터가 없거나 유효하지 않음'); } console.log('[마일리지 요약 페이지] 최종 dateClasses 객체:', dateClasses); /** * 달력을 렌더링하는 함수 * @param {Date} date - 렌더링할 달의 날짜 * @param {String} position - 추가 위치 ('top' 또는 'bottom') */ function renderCalendar(date, position = 'bottom') { console.log(`[마일리지 요약 페이지] 달력 렌더링 시작: ${date.getFullYear()}년 ${date.getMonth() + 1}월, 위치: ${position}`); const $statsDatesElement = $("#stats-dates"); const currentYear = date.getFullYear(); const currentMonth = date.getMonth(); const monthYearText = `${monthNames[currentMonth]} ${currentYear}`; console.log(`[마일리지 요약 페이지] 렌더링할 월/년: ${monthYearText}`); // 이미 해당 월이 렌더링 되어 있는지 확인 if (!$statsDatesElement.html().includes(monthYearText)) { console.log(`[마일리지 요약 페이지] ${monthYearText} 달력 새로 렌더링 시작`); const firstDay = new Date(currentYear, currentMonth, 1).getDay(); const lastDate = new Date(currentYear, currentMonth + 1, 0).getDate(); console.log(`[마일리지 요약 페이지] 첫 요일: ${firstDay}, 마지막 날짜: ${lastDate}`); const today = new Date(); const isCurrentMonth = today.getFullYear() === currentYear && today.getMonth() === currentMonth; const todayDate = today.getDate(); console.log(`[마일리지 요약 페이지] 현재 월 여부: ${isCurrentMonth}, 오늘 날짜: ${todayDate}`); const $monthContainer = $("
").addClass("month-container"); // 월 헤더 추가 const $monthHeader = $("
").addClass("month-header").text(monthYearText); $monthContainer.append($monthHeader); console.log('[마일리지 요약 페이지] 월 헤더 추가 완료'); // 요일 행 추가 const $daysRow = $("
").addClass("stats-days"); const days = ["일", "월", "화", "수", "목", "금", "토"]; $.each(days, function(i, day) { $daysRow.append($("
").text(day)); }); $monthContainer.append($daysRow); console.log('[마일리지 요약 페이지] 요일 행 추가 완료'); // 날짜 그리드 추가 const $datesGrid = $("
").addClass("dates-grid"); // 월 시작 전 빈 셀 추가 for (let i = 0; i < firstDay; i++) { $datesGrid.append($("
")); } console.log(`[마일리지 요약 페이지] 빈 셀 ${firstDay}개 추가 완료`); // 날짜 셀 추가 for (let date = 1; date <= lastDate; date++) { const $dateElement = $("
"); const $dateSpan = $("").text(date); $dateElement.append($dateSpan); // 날짜 형식화: YYYY-MM-DD const fullDate = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(date).padStart(2, '0')}`; // 해당 날짜의 상태 클래스가 있으면 추가 if (dateClasses[fullDate]) { $dateElement.addClass(dateClasses[fullDate]); console.log(`[마일리지 요약 페이지] 날짜 ${fullDate}에 클래스 ${dateClasses[fullDate]} 추가`); } // 오늘 날짜 표시 if (isCurrentMonth && date === todayDate) { $dateElement.addClass("today"); console.log(`[마일리지 요약 페이지] 오늘 날짜 ${fullDate}에 today 클래스 추가`); } $datesGrid.append($dateElement); } console.log(`[마일리지 요약 페이지] ${lastDate}일까지 날짜 셀 추가 완료`); $monthContainer.append($datesGrid); // 위치에 따라 추가 if (position === 'top') { $statsDatesElement.prepend($monthContainer); console.log('[마일리지 요약 페이지] 달력을 상단에 추가'); } else { $statsDatesElement.append($monthContainer); console.log('[마일리지 요약 페이지] 달력을 하단에 추가'); } // 섭취 완료 후 미완료 날짜 스타일 처리 hideAfterStatsDone($datesGrid); console.log('[마일리지 요약 페이지] hideAfterStatsDone 처리 완료'); } else { console.log(`[마일리지 요약 페이지] ${monthYearText} 달력이 이미 렌더링되어 있음`); } } /** * 이전 달을 로드하는 함수 */ function loadPreviousMonth() { console.log('[마일리지 요약 페이지] 이전 달 로드 시작'); const newDate = new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1); console.log(`[마일리지 요약 페이지] 이전 달: ${newDate.getFullYear()}년 ${newDate.getMonth() + 1}월`); renderCalendar(newDate, 'top'); currentDate = newDate; } /** * 다음 달을 로드하는 함수 */ function loadNextMonth() { console.log('[마일리지 요약 페이지] 다음 달 로드 시작'); const newDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1); console.log(`[마일리지 요약 페이지] 다음 달: ${newDate.getFullYear()}년 ${newDate.getMonth() + 1}월`); renderCalendar(newDate, 'bottom'); currentDate = newDate; } /** * 스크롤 이벤트 핸들러 * 스크롤 끝에 도달하면 이전/다음 달 로드 */ function handleScroll() { if (isLoading) { console.log('[마일리지 요약 페이지] 로딩 중이므로 스크롤 이벤트 무시'); return; } const $container = $(this); const scrollTop = $container.scrollTop(); const innerHeight = $container.innerHeight(); const scrollHeight = $container[0].scrollHeight; console.log(`[마일리지 요약 페이지] 스크롤 위치: ${scrollTop}, 컨테이너 높이: ${innerHeight}, 스크롤 전체 높이: ${scrollHeight}`); if (scrollTop === 0) { // 맨 위에 도달하면 이전 달 로드 console.log('[마일리지 요약 페이지] 스크롤 상단 도달, 이전 달 로드'); isLoading = true; const previousScrollHeight = $container[0].scrollHeight; loadPreviousMonth(); $container.scrollTop($container[0].scrollHeight - previousScrollHeight); console.log(`[마일리지 요약 페이지] 스크롤 위치 조정: ${$container[0].scrollHeight - previousScrollHeight}`); isLoading = false; } else if (scrollTop + innerHeight >= scrollHeight - 10) { // 맨 아래에 도달하면 다음 달 로드 console.log('[마일리지 요약 페이지] 스크롤 하단 도달, 다음 달 로드'); isLoading = true; loadNextMonth(); isLoading = false; } } /** * 섭취 완료 후 미완료 날짜 스타일 처리 함수 * @param {jQuery} $datesGrid - 날짜 그리드 요소 */ function hideAfterStatsDone($datesGrid) { console.log('[마일리지 요약 페이지] hideAfterStatsDone 함수 실행'); const statsDoneElements = $datesGrid.find(".stats_done"); console.log(`[마일리지 요약 페이지] stats_done 클래스 요소 수: ${statsDoneElements.length}`); statsDoneElements.each(function(index) { const $nextElement = $(this).next(); console.log(`[마일리지 요약 페이지] stats_done 요소 ${index + 1}, 다음 요소 존재: ${$nextElement.length > 0}`); if ($nextElement.length && !$nextElement.hasClass("stats_done") && !$nextElement.hasClass("stats_30done")) { $(this).addClass("hide-after"); console.log(`[마일리지 요약 페이지] stats_done 요소 ${index + 1}에 hide-after 클래스 추가`); } }); } // 이벤트 리스너 등록 $calendarContainer.on("scroll", handleScroll); console.log('[마일리지 요약 페이지] 스크롤 이벤트 리스너 등록 완료'); // 섭취 완료 버튼 클릭 이벤트 (동적으로 추가된 요소에 대한 이벤트 바인딩) $(document).on("click", ".drug_off", function(e) { e.preventDefault(); const $this = $(this); console.log('[마일리지 요약 페이지] drug_off 클릭 이벤트 발생'); $this.removeClass("drug_off").addClass("drug_on"); $this.text("섭취완료"); console.log('[마일리지 요약 페이지] 클래스 drug_off에서 drug_on으로 변경, 텍스트 "섭취완료"로 변경'); // 섭취 완료 후 클릭 이벤트 제거 $this.css("pointer-events", "none"); console.log('[마일리지 요약 페이지] 클릭 이벤트 제거 (pointer-events: none)'); // 여기에 섭취 완료 API 호출 로직 추가 가능 console.log('[마일리지 요약 페이지] 섭취 완료 API 호출 위치 (아직 구현되지 않음)'); }); // 달력 초기화: 이전 달과 현재 달 모두 렌더링 function initializeCalendar() { console.log('[마일리지 요약 페이지] 달력 초기화 시작'); // 이전 달 렌더링 const prevMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1); console.log(`[마일리지 요약 페이지] 이전 달 렌더링: ${prevMonth.getFullYear()}년 ${prevMonth.getMonth() + 1}월`); renderCalendar(prevMonth, 'top'); // 현재 달 렌더링 console.log(`[마일리지 요약 페이지] 현재 달 렌더링: ${currentDate.getFullYear()}년 ${currentDate.getMonth() + 1}월`); renderCalendar(currentDate, 'bottom'); // 현재 달로 스크롤 포지션 설정 (약간의 지연을 두어 렌더링 완료 후 스크롤) console.log('[마일리지 요약 페이지] 스크롤 위치 설정 지연 시작 (100ms)'); setTimeout(function() { // 이전 달 높이를 찾아서 그 위치로 스크롤 const $monthContainers = $(".month-container"); console.log(`[마일리지 요약 페이지] 월 컨테이너 수: ${$monthContainers.length}`); if ($monthContainers.length > 1) { const firstMonthHeight = $($monthContainers[0]).outerHeight(); console.log(`[마일리지 요약 페이지] 첫 번째 월 높이: ${firstMonthHeight}px`); $calendarContainer.scrollTop(firstMonthHeight); console.log(`[마일리지 요약 페이지] 스크롤 위치 설정: ${firstMonthHeight}px`); } else { console.log('[마일리지 요약 페이지] 월 컨테이너가 충분하지 않아 스크롤 위치 설정 생략'); } }, 100); } // 달력 초기화 함수 호출 initializeCalendar(); console.log('[마일리지 요약 페이지] 초기화 완료'); });