/** * 커스텀 팝업 관리 스크립트 * - ShopbySkin API에서 팝업 데이터를 불러와 지정된 popupNo만 오버레이로 표시 * - 오늘 하루 안보기 기능 (로컬스토리지, 팝업별) * - fade in 애니메이션 * - 딤 배경 하나에 여러 팝업 겹쳐서 표시 */ (() => { const { EventManager, actions } = ShopbySkin; // 커스텀 팝업으로 표시할 popupId 목록 (popupId가 null이 아닌 팝업 중 이 배열에 포함된 것만 커스텀 렌더링) const CUSTOM_POPUP_IDS = ['BIG-POP-PC']; const STORAGE_KEY_PREFIX = 'CUSTOM_POPUP_NO_SHOW_'; const NOW = new Date(); /** * 오늘 날짜 문자열 반환 (YYYY-MM-DD) */ const getTodayString = () => { const year = NOW.getFullYear(); const month = String(NOW.getMonth() + 1).padStart(2, '0'); const day = String(NOW.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }; /** * 특정 팝업의 오늘 하루 안보기 체크 */ const shouldHideToday = (popupNo) => { const savedDate = localStorage.getItem(`${STORAGE_KEY_PREFIX}${popupNo}`); return savedDate === getTodayString(); }; /** * 특정 팝업 오늘 하루 안보기 저장 */ const setNoShowToday = (popupNo) => { localStorage.setItem(`${STORAGE_KEY_PREFIX}${popupNo}`, getTodayString()); }; /** * 팝업 콘텐츠 렌더링 (여러 개 겹쳐서 표시) */ const renderPopups = (popups) => { const contentArea = document.getElementById('customPopupContent'); if (!contentArea) return; contentArea.innerHTML = ''; popups.forEach((popup) => { const wrapper = document.createElement('div'); wrapper.className = 'custom-popup-item'; wrapper.setAttribute('data-popup-no', popup.popupNo); wrapper.innerHTML = `
${popup.content}
`; contentArea.appendChild(wrapper); }); }; /** * 팝업 표시 (애니메이션 포함) */ const showPopup = () => { const overlay = document.querySelector('.custom-popup-overlay'); if (!overlay) return; overlay.style.display = 'flex'; document.body.style.overflow = 'hidden'; requestAnimationFrame(() => { requestAnimationFrame(() => { overlay.classList.add('active'); }); }); }; /** * 개별 팝업 닫기 */ const closePopupItem = (popupNo) => { const item = document.querySelector(`.custom-popup-item[data-popup-no="${popupNo}"]`); if (item) { item.style.display = 'none'; } // 모든 팝업이 닫혔으면 오버레이도 닫기 checkAllPopupsClosed(); }; /** * 오버레이 전체 닫기 (애니메이션 포함) */ const closeOverlay = () => { const overlay = document.querySelector('.custom-popup-overlay'); if (!overlay) return; overlay.classList.remove('active'); setTimeout(() => { overlay.style.display = 'none'; document.body.style.overflow = ''; }, 300); }; /** * 모든 팝업이 닫혔는지 확인 */ const checkAllPopupsClosed = () => { const allItems = document.querySelectorAll('.custom-popup-item'); const visibleItems = Array.from(allItems).filter((item) => item.style.display !== 'none'); if (visibleItems.length === 0) { closeOverlay(); } }; /** * 이벤트 바인딩 */ const bindEvents = () => { document.addEventListener('click', (e) => { const action = e.target.dataset.action; const popupNo = e.target.dataset.popupNo; if (action === 'NO_SHOW_TODAY' && popupNo) { setNoShowToday(popupNo); closePopupItem(popupNo); return; } if (action === 'CLOSE' && popupNo) { closePopupItem(popupNo); return; } }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeOverlay(); } }); }; /** * 커스텀 팝업 대상 필터링 * - popupId가 null이 아니고 * - CUSTOM_POPUP_IDS 배열에 포함되어 있으며 * - NORMAL 디자인 타입이고 (MULTI 제외) * - 오늘 하루 안보기 처리되지 않은 팝업만 */ const filterTargetPopups = (popups) => { return popups.filter((popup) => { if (!popup.popupId) return false; if (!CUSTOM_POPUP_IDS.includes(popup.popupId)) return false; if (popup.popupDesignType !== 'NORMAL') return false; if (shouldHideToday(popup.popupNo)) return false; return true; }); }; /** * 실제 팝업 데이터 API 호출 * - ShopbySkin.actions.getDisplayPopups(): /display/popups API 호출 * - 오늘하루 안보기 처리된 팝업은 자동 제외됨 */ const fetchPopups = async () => { try { const { data } = await actions.getDisplayPopups(); return data || []; } catch (e) { console.error('[custom-popup] 팝업 API 호출 실패:', e); return []; } }; /** * 초기화 */ const init = async () => { if (CUSTOM_POPUP_IDS.length === 0) return; const popups = await fetchPopups(); const targetPopups = filterTargetPopups(popups); if (targetPopups.length === 0) return; renderPopups(targetPopups); bindEvents(); showPopup(); }; // 페이지 로드 완료 시 실행 EventManager.on('PAGE_LOAD_COMPLETED', init); })();