(() => {
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);
})();