(() => { const { EventManager, utils, constants } = ShopbySkin; const sectionId = document.currentScript.getAttribute('shopby-section-id'); const containerEl = document.querySelector( `[shopby-section-id="${sectionId}"]`, ); const displayProductActionMap = { // NOTE: 좋아요버튼 클릭 PRODUCT_LIKE_BTN: ({ sectionId, event }) => { event?.preventDefault?.(); const btn = event.target.closest('[shopby-product-no]'); const productNo = Number(btn.getAttribute('shopby-product-no') ?? 0); utils.isSignIn() ? EventManager.fire('MUTATE_LIKE_PRODUCT', { productNo, sectionId, onSuccess: (like) => { const likeBtns = document.querySelectorAll( `[shopby-product-no="${productNo}"]`, ); likeBtns?.forEach((btn) => { like ? btn.classList.add('is-active') : btn.classList.remove('is-active'); }); }, }) : EventManager.fire('MODAL_CONFIRM_OPEN', { message: `로그인하셔야 본 서비스를 이용하실 수 있습니다.`, noticeType: constants.NOTICE_MODAL_TYPE.WARNING, onConfirm: () => { const nextUrl = `${location.origin}/pages/sign-in/sign-in.html`; location.href = `${nextUrl}?from=${encodeURIComponent(location.href)}`; }, }); }, // NOTE: 상품터치시 상품상세로 이동전 성인상품인지 확인을 위한 이벤트 MOVE_PRODUCT_DETAIL: ({ event }) => { if (!utils.isAdultVerified(event)) { EventManager.fire('MODAL_CONFIRM_OPEN', { message: '성인인증이 필요한 상품입니다.', noticeType: 'CAUTION', onConfirm: () => { location.href = '/pages/intro/adult-certification.html'; }, }); } }, }; const clickEventListener = (e) => { const btn = e.target.closest('[shopby-action]') || e.target.parentElement.closest('[shopby-action]'); const action = btn?.getAttribute('shopby-action'); displayProductActionMap[action]?.({ sectionId, event: e, }); }; const customDisplayProductParams = { querystring: { pageNumber: 1, pageSize: 0, hasTotalCount: true, hasOptionValues: true, soldout: false, includeStopProduct: false, }, }; // [Aaron] 기존 진열관리로 사용했던 신상품은 SB측 요청으로 // 어드민 진열관리를 별도 사용하지 않고, 실질적으로 상품등록순으로 렌더 if (sectionId === 'SC0004') { const params = { queryString: { pageNumber: 1, pageSize: 6, 'filter.soldout': false, 'filter.saleStatus': 'ALL_CONDITIONS', 'order.by': 'RECENT_PRODUCT', 'order.direction': 'DESC', excludeCategoryNos: '846988', }, }; callShopApi('/products/search?', 'GET', params).then(({ result, statusCode }) => { if (!result) return if (statusCode >= 400 || !statusCode) return const renderData = {}; renderData.products = result.items; renderData.sectionId = 'SC0004'; renderData.displayConfig = { displayType: 'GALLERY', }; const customDisplayHtml = renderHtml($(containerEl), renderData); $(containerEl).append(customDisplayHtml); $(containerEl) .find('.product-section') .velocity({ opacity: 1 }, { duration: 500 }); }); } else { getDisplaySectionData(sectionId, customDisplayProductParams).then( ({ result: customDisplayProductData, statusCode }) => { // [KR] 없는데이터라면 기능 실행 하지 않음 if (!customDisplayProductData) return false; if (statusCode >= 400 || !statusCode) return false; // [Aaron] 관리자에서 설정한 상품 노출 개수만큼 노출되도록 상품 배열 슬라이스 const displayWidth = customDisplayProductData.displayConfig.displayWidth; const displayHeight = customDisplayProductData.displayConfig.displayHeight; let sliceCnt; if (customDisplayProductData.displayConfig.displayType === 'SWIPE') sliceCnt = displayWidth; if (customDisplayProductData.displayConfig.displayType === 'GALLERY') sliceCnt = displayWidth * displayHeight; // [KR] 인기 상품을 한눈에 영역의 경우 설정된 상품개수 모두 표시한다. if (sectionId === 'SC0002') { sliceCnt = customDisplayProductData.products.length; } const sliceProductArr = customDisplayProductData.products.slice( 0, sliceCnt, ); // 상품진열 데이터 재가공 const reworkCustomDisplayProductData = { ...customDisplayProductData, products: sliceProductArr, }; const customDisplayHtml = renderHtml( $(containerEl), reworkCustomDisplayProductData, ); $(containerEl).append(customDisplayHtml); // SC0001 전시 상품만 타이머 노출 if (sectionId === 'SC0001') { if (reworkCustomDisplayProductData.products.length > 0) setTimer(); } $(containerEl) .find('.product-section') .velocity({ opacity: 1 }, { duration: 500 }); if (customDisplayProductData.displayConfig.displayType === 'SWIPE') { if (sectionId === 'SC0002') { const swiperOptions = { id: `product_slide_${sectionId}`, direction: 'horizontal', effect: 'slide', slidesPerView: 1.6, spaceBetween: 16, slidesOffsetBefore: 16, slidesOffsetAfter: 16, autoplay: { delay: 4000, disableOnIneraction: false, }, pagination: { el: '.swiper-pagination', clickable: true, }, }; utils.initSwiper(swiperOptions); } else { const swiperOptions = { id: `product_slide_${sectionId}`, direction: 'horizontal', effect: 'slide', slidesPerView: 1.6, spaceBetween: 16, slidesOffsetBefore: 16, slidesOffsetAfter: 16, pagination: { el: '.swiper-pagination', clickable: true, }, }; utils.initSwiper(swiperOptions); } } }, ); } containerEl.addEventListener('click', clickEventListener); containerEl.removeEventListener('unload', clickEventListener); // 즉시할인 타이머 (즉시할인 적용상품) function setTimer() { try { // 상품 진열 목록 중 타임딜 섹션 추출 const firstMainSectionParams = { querystring: { pageNumber: 1, pageSize: 0, hasTotalCount: true, hasOptionValues: true, soldout: false, includeStopProduct: false, }, }; getDisplaySectionData('SC0001', firstMainSectionParams).then( ({ result, statusCode }) => { result?.products.forEach((product, index) => { const timeSaleEl = document.querySelectorAll('.product-timesale'); // 즉시 할인가 종료시간 const endSaleYmdt = product.immediateDiscountEndYmdt; if (endSaleYmdt === null) { // 할인종료시간 데이터가 없을 경우 타임세일 영역 숨김처리 $(timeSaleEl[index]).hide(); } else { const getEndSaleTime = new Date(endSaleYmdt).getTime(); // 즉시할인 종료시간이 현재 시간을 지나지 않았을 경우에만 타이머 실행 if ( endSaleYmdt && new Date(endSaleYmdt).getTime() > new Date().getTime() ) { $('.countdown').removeClass('dn'); let target_date = new Date(endSaleYmdt).getTime() + 1000 * 3600 * 48; let timerHtml = getCountdown(getEndSaleTime); // [Jay] 상품에 해당하는 카운트 다운 요소에 html 추가 $(timeSaleEl[index]).find('.countDown').html(timerHtml); let timer = setInterval(async function () { let current_date = new Date().getTime(); if (getEndSaleTime > current_date) { $('.countdown').removeClass('dn'); let timerHtml = getCountdown(getEndSaleTime); // [Jay] 상품에 해당하는 카운트 다운 요소에 html 추가 $(timeSaleEl[index]).find('.countDown').html(timerHtml); } else { clearInterval(timer); } }, 1000); } } }); // eslint-disable-next-line no-inner-declarations function getCountdown(getEndSaleTime, currentDate) { let days, hours, minutes, seconds; let current_date = !currentDate ? new Date().getTime() : currentDate; // find the amount of "seconds" between now and target let seconds_left = getEndSaleTime - current_date; // 타이머가 0초가 될 경우 타이머 영역 비노출 처리 if (Number.isNaN(seconds_left) || Number(seconds_left) === 0) { $('.countdown').addClass('dn'); } // 남은 일자를 시간으로 합산 days = Math.floor(seconds_left / (1000 * 60 * 60 * 24)); hours = Math.floor( (seconds_left % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), ); const hoursCalc = days * 24 + hours; hours = pad(hoursCalc); minutes = pad( Math.floor((seconds_left % (1000 * 60 * 60)) / (1000 * 60)), ); seconds = pad(Math.floor((seconds_left % (1000 * 60)) / 1000)); let divideHours = [...hours]; let divideMinutes = [...minutes]; let divideSecond = [...seconds]; let timerHtml = '' + days + 'DAY ' + divideHours[0] + divideHours[1] + ':' + divideMinutes[0] + divideMinutes[1] + ':' + divideSecond[0] + divideSecond[1] + ''; return timerHtml; } // eslint-disable-next-line no-inner-declarations function pad(n) { return (n < 10 ? '0' : '') + n; } }, ); } catch (error) { console.log(error); } } /** * [Aaron] 진열 상품 조회 * @param sectionId 상품 진열 ID * @param params */ async function getDisplaySectionData(sectionId, params) { try { const result = await callShopApi( `/display/sections/ids/${sectionId}`, 'GET', params, ); return result; } catch (e) { throw new Error(e); } } })();