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