/** * 밍글 스튜디오 - 예약 현황 캘린더 * Google Apps Script 프록시를 통해 캘린더 데이터를 가져와 표시 */ (function() { 'use strict'; var APPS_SCRIPT_URL = 'https://script.google.com/macros/s/AKfycbwoaoSmEskbJod4gR5NjLnpWSkhIDUYaGBYk0y1Q865TzaJ4gctSrTOWXxRnVa7J9AASA/exec'; var currentYear, currentMonth; var calTitle = document.getElementById('calTitle'); var calBody = document.getElementById('calBody'); var prevBtn = document.getElementById('prevMonth'); var nextBtn = document.getElementById('nextMonth'); function init() { var now = new Date(); currentYear = now.getFullYear(); currentMonth = now.getMonth() + 1; prevBtn.addEventListener('click', function() { changeMonth(-1); }); nextBtn.addEventListener('click', function() { changeMonth(1); }); renderCalendar(); } function changeMonth(delta) { currentMonth += delta; if (currentMonth > 12) { currentMonth = 1; currentYear++; } else if (currentMonth < 1) { currentMonth = 12; currentYear--; } renderCalendar(); } function renderCalendar() { updateTitle(); // 매번 새로 불러오기 buildGrid([]); showLoading(); fetchBookedDates(currentYear, currentMonth, function(dates) { buildGrid(dates); hideLoading(); }); } function showLoading() { calBody.classList.add('loading'); // 기존 오버레이 제거 var existing = calBody.querySelector('.cal-loading-overlay'); if (existing) existing.remove(); var overlay = document.createElement('div'); overlay.className = 'cal-loading-overlay'; overlay.innerHTML = '
불러오는 중...'; calBody.appendChild(overlay); } function hideLoading() { calBody.classList.remove('loading'); var overlay = calBody.querySelector('.cal-loading-overlay'); if (overlay) overlay.remove(); } // --- 제목 업데이트 --- function updateTitle() { var monthNames = ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월']; calTitle.textContent = currentYear + '년 ' + monthNames[currentMonth - 1]; } // --- API 호출 --- function fetchBookedDates(year, month, callback) { if (!APPS_SCRIPT_URL) { callback([]); return; } var url = APPS_SCRIPT_URL + '?year=' + year + '&month=' + month; fetch(url) .then(function(res) { return res.json(); }) .then(function(data) { callback(data.bookedDates || []); }) .catch(function() { callback([]); }); } // --- 그리드 렌더링 --- function buildGrid(bookedDates) { calBody.innerHTML = ''; var firstDay = new Date(currentYear, currentMonth - 1, 1).getDay(); var daysInMonth = new Date(currentYear, currentMonth, 0).getDate(); var today = new Date(); var todayStr = today.getFullYear() + '-' + String(today.getMonth() + 1).padStart(2, '0') + '-' + String(today.getDate()).padStart(2, '0'); var bookedSet = {}; for (var b = 0; b < bookedDates.length; b++) { bookedSet[bookedDates[b]] = true; } var fragment = document.createDocumentFragment(); for (var e = 0; e < firstDay; e++) { var emptyCell = document.createElement('div'); emptyCell.className = 'cal-cell empty'; fragment.appendChild(emptyCell); } for (var d = 1; d <= daysInMonth; d++) { var dateStr = currentYear + '-' + String(currentMonth).padStart(2, '0') + '-' + String(d).padStart(2, '0'); var cell = document.createElement('div'); cell.className = 'cal-cell'; var dayNum = document.createElement('span'); dayNum.className = 'day-num'; dayNum.textContent = d; var cellDate = new Date(currentYear, currentMonth - 1, d); var isPast = cellDate < new Date(today.getFullYear(), today.getMonth(), today.getDate()); if (dateStr === todayStr) { cell.classList.add('today'); } else if (isPast) { cell.classList.add('past'); } else if (bookedSet[dateStr]) { cell.classList.add('booked'); } else { cell.classList.add('available'); } cell.appendChild(dayNum); fragment.appendChild(cell); } calBody.appendChild(fragment); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();