(() => { const { pageHelper, EventManager, utils, actions, constants } = ShopbySkin; const eventDetailHelper = pageHelper.eventDetailHelper(); const { replaceHistory, isSignIn, moveTo } = utils; const containerEl = document.querySelector('[shopby-helper-key="event-detail-helper-key"]'); const { event: eventNoOrId, pageSize, pageNumber, sectionNo } = utils.getQueryParams(location); const eventDetailRequest = { eventKey: eventNoOrId, }; const eventDetailProductRequest = { sortType: 'ADMIN_SETTING', soldOut: true, includeStopProduct: true, }; const searchParams = new URLSearchParams(location.search); const eventDetailProductRequestParamType = [ 'event', 'sectionNo', 'pageNumber', 'pageSize', 'sortType', 'direction', 'soldOut', 'includeStopProduct', ]; const redirectLoginPage = () => { moveTo({ url: `${constants.PAGE.SIGN_IN}?from=${encodeURIComponent(location.href)}`, }); }; const convertEventDetailRequestParam = (params, filterTypes) => Object.fromEntries(params?.filter(([key]) => !filterTypes.includes(key))); eventDetailHelper.initialize({ helperKey: 'event-detail-helper-key', }); const likeHelper = { toggleClassName: (likeEl) => { likeEl.classList.toggle('is-active'); }, toggleLikeStatus: async (likeEl) => { const productNo = likeEl.getAttribute('shopby-product-no') ?? 0; await actions.toggleLikeStatus({ productNo: Number(productNo), }); }, }; const CLICK_EVENT_HANDLER_MAP = { HANDLE_COUPON_BTN_CLICK: () => { if (!isSignIn()) { ShopbySkin.EventManager.fire('MODAL_CONFIRM_OPEN', { noticeType: 'CAUTION', message: '로그인하셔야 본 서비스를 이용하실 수 있습니다.', onConfirm: redirectLoginPage, }); return; } const { coupon, eventNo } = document.querySelector('event-detail-product-list-v2').store.state ?? {}; ShopbySkin.EventManager.fire('OPEN_LAYER_MODAL', { title: '쿠폰받기', name: 'coupon-download', data: { coupons: coupon?.coupons?.filter(({ downloadable }) => downloadable) ?? [], eventNo, }, isFull: true, onClose: () => null, }); }, HANDLE_SECTION_ID_CLICK: ({ target, helper }) => { const tabId = target.getAttribute('shopby-tab-id'); const currentSectionNo = target.getAttribute('shopby-section-no'); const { eventNo } = document.querySelector('event-detail-product-list-v2').store.state ?? {}; helper.eventAction.selectEventCategoryV2({ tabId, sectionNo: currentSectionNo }); searchParams.set('sectionNo', currentSectionNo); searchParams.set('pageNumber', 1); const param = Object.fromEntries(searchParams); replaceHistory({ query: param, }); const { event, ...rest } = param; eventDetailHelper.eventAction.fetchEventDetailProducts({ ...eventDetailProductRequest, ...rest, eventNo, sectionNo: currentSectionNo, pageSize, pageNumber: 1, }); scrollTo({ top: 0, behavior: 'smooth', }); }, LIKE_PRODUCT: ({ target }) => { if (!isSignIn()) { ShopbySkin.EventManager.fire('MODAL_CONFIRM_OPEN', { noticeType: 'CAUTION', message: '로그인하셔야 본 서비스를 이용하실 수 있습니다.', onConfirm: redirectLoginPage, }); return; } const likeEl = target.closest('[shopby-product-no]'); likeHelper.toggleClassName(likeEl); likeHelper.toggleLikeStatus(likeEl); }, }; const CHANGE_EVENT_HANDLER_MAP = { HANDLE_SORT_CHANGE: ({ target, helper }) => { const paramArray = Array.from(searchParams.entries()); const eventDetailRequestParam = convertEventDetailRequestParam( paramArray, eventDetailProductRequestParamType ); helper.eventAction.fetchEventDetailV2({ ...eventDetailRequestParam, ...eventDetailRequest, sortType: target.value, }); }, }; EventManager.fire('INIT_EVENT_PRODUCT_SECTION_SLIDER', { spaceBetween: 12, direction: 'horizontal', effect: 'slide', slidesPerView: 'auto', }); EventManager.on('PAGE_LOAD_COMPLETED', () => { const paramArray = Array.from(searchParams.entries()); const eventDetailRequestParam = convertEventDetailRequestParam(paramArray, eventDetailProductRequestParamType); eventDetailHelper.eventAction.fetchEventDetailV2({ ...eventDetailRequestParam, ...eventDetailRequest }); EventManager.on('QUERY_DISPLAY_EVENTS_EVENT_NO', (data) => { EventManager.fire('CHANGE_SUB_TITLE', { subTitle: data?.label, }); const currentSectionNo = sectionNo ?? data.listOfExhibition[0]?.sectionNo; if (!currentSectionNo) { return; } searchParams.set('sectionNo', currentSectionNo); const param = Object.fromEntries(searchParams); replaceHistory({ query: param, }); const { event, ...rest } = param; eventDetailHelper.eventAction.fetchEventDetailProducts({ ...eventDetailProductRequest, ...rest, eventNo: data.eventNo, sectionNo: currentSectionNo, pageSize, pageNumber, }); }); }); const clickEventListener = ({ target }) => { const actionType = target.getAttribute('shopby-action') ?? target.closest('button')?.getAttribute('shopby-action'); CLICK_EVENT_HANDLER_MAP[actionType]?.({ helper: eventDetailHelper, target, }); }; const changeEventListener = ({ target }) => { const actionType = target.getAttribute('shopby-action'); CHANGE_EVENT_HANDLER_MAP[actionType]?.({ helper: eventDetailHelper, target, }); }; const handleInfiniteScroll = () => { // 0.5초 디바운싱 효과를 위한 isLoading 체크 if (handleInfiniteScroll.isLoading) return; const scrollTop = window.scrollY || document.documentElement.scrollTop; const windowHeight = window.innerHeight; const documentHeight = document.documentElement.scrollHeight; // 페이지 하단 300px 전에 다음 페이지 로드 if (scrollTop + windowHeight >= documentHeight - 300) { const moreBtn = document.querySelector('more-view-button button'); if (moreBtn) { handleInfiniteScroll.isLoading = true; moreBtn.click(); setTimeout(() => { handleInfiniteScroll.isLoading = false; }, 1000); } } }; window.addEventListener('scroll', handleInfiniteScroll, { passive: true }); containerEl.addEventListener('click', clickEventListener); containerEl.addEventListener('change', changeEventListener); })();