(() => { const ELEMENT_SELECTOR = { HELPER_KEY: '[shopby-helper-key="cart-helper-key"]', ACTION: 'shopby-action', SELECTED_COUNT: 'shopby-selected-count', CHECKED_CART_NOS_AS_STRING: 'shopby-checked-cart-nos-as-string', DELIVERY_GROUP_IDX: 'shopby-delivery-group-idx', IS_INVALID_PRODUCT: 'shopby-is-invalid-product', CART_NO: 'shopby-cart-no', CART_PRODUCTS: 'cart-products-v2', CHECKBOX_PER_DELIVERY_GROUP_SLOT: '[slot="checkboxPerDeliveryGroup"]', CHECKBOX_PER_CART_NO_SLOT: '[slot="checkboxPerCartNo"]', }; const { pageHelper, EventManager, actions, utils } = ShopbySkin; const containerEl = document.querySelector(ELEMENT_SELECTOR.HELPER_KEY); const cartProductsEl = containerEl.querySelector(ELEMENT_SELECTOR.CART_PRODUCTS); const cartHelper = pageHelper.cartHelper(); cartHelper.initialize({ helperKey: 'cart-helper-key', }); const handleOrder = async ({ helper, cartNos, products }) => { const { data: { orderSheetNo }, } = await helper.orderSheetAction.makeOrderSheet({ cartNos, products, }); const ordersheetUri = `/pages/order/order-sheet-form.html?ordersheetNo=${orderSheetNo}`; if (utils.isSignedIn()) { location.href = ordersheetUri; } else { const url = new URL(location.href); url.pathname = '/pages/sign-in/sign-in.html'; url.searchParams.set('from', encodeURIComponent(ordersheetUri)); location.href = url.toString(); } }; const CLICK_EVENT_HANDLER_MAP = { TOGGLE_ALL: ({ helper, target }) => { helper.cartAction.updateIsAllChecked(target.checked); }, TOGGLE_CHECKBOX_PER_DELIVERY_GROUP: ({ helper, target }) => { const labelEl = target.closest(ELEMENT_SELECTOR.CHECKBOX_PER_DELIVERY_GROUP_SLOT); const deliveryGroupIdx = Number(labelEl.getAttribute(ELEMENT_SELECTOR.DELIVERY_GROUP_IDX) ?? -1); const isInvalidProduct = labelEl.getAttribute(ELEMENT_SELECTOR.IS_INVALID_PRODUCT) === 'true'; helper.cartAction.updateIsDeliveryGroupChecked({ deliveryGroupIdx: isInvalidProduct ? -1 : deliveryGroupIdx, isChecked: target.checked, }); }, TOGGLE_CHECKBOX_PER_CART_NO: ({ helper, target }) => { const labelEl = target.closest(ELEMENT_SELECTOR.CHECKBOX_PER_CART_NO_SLOT); helper.cartAction.updateIsCartNoChecked({ cartNo: Number(labelEl.getAttribute(ELEMENT_SELECTOR.CART_NO) ?? 0), isChecked: target.checked, }); }, DELETE_SELECTED_ITEMS: async ({ helper, target }) => { const selectedCount = Number(target.getAttribute(ELEMENT_SELECTOR.SELECTED_COUNT)); const checkedCartNos = target.getAttribute(ELEMENT_SELECTOR.CHECKED_CART_NOS_AS_STRING)?.split?.(',')?.map(Number) ?? []; if (!selectedCount) { EventManager.fire('MODAL_ALERT_OPEN', { noticeType: 'CAUTION', message: `선택하신 상품이 없습니다.`, }); return; } const { data } = await helper.cartAction.deletableRequiredOption(); if (!data) { EventManager.fire('MODAL_ALERT_OPEN', { noticeType: 'CAUTION', message: '선택옵션은 단독 주문이 불가합니다. 필수옵션 취소 필요 시 선택옵션을 먼저 취소해주시거나, 함께 취소해주세요.', }); return; } EventManager.fire('MODAL_CONFIRM_OPEN', { noticeType: 'WARNING', message: `선택하신 ${selectedCount}개의 상품을 삭제하시겠습니까?`, confirmLabel: '삭제', onConfirm: async () => { EventManager.fire('UPDATE_CART_PRODUCT'); await helper.cartAction.deleteCartNos(checkedCartNos); helper.cartAction.fetchCartDetail(); }, }); }, ORDER: ({ helper }) => { const { data: checkedCartNos } = helper.cartAction.fetchCheckedCartNos(); const { data: checkedProducts } = helper.cartAction.fetchCheckedProducts(); const invalidCartNos = Array.from( containerEl.querySelectorAll('[slot="deliveryGroup"][shopby-delivery-group-idx="-1"]') ).flatMap((el) => { const cartNoEls = el.querySelectorAll('[shopby-cart-no]'); return Array.from(cartNoEls).flatMap((el) => Number(el.getAttribute('shopby-cart-no'))); }); const hasInvalidCartNo = invalidCartNos.some((no) => checkedCartNos.includes(no)); const editingEl = containerEl.querySelector('[shopby-status="EDITING"]'); if (editingEl) { EventManager.fire('MODAL_ALERT_OPEN', { noticeType: 'CAUTION', message: `변경중인 옵션이 있습니다.`, onClose: () => { editingEl?.focus?.(); }, }); return; } if (!checkedCartNos.length) { EventManager.fire('MODAL_ALERT_OPEN', { noticeType: 'CAUTION', message: `선택된 상품이 없습니다.`, }); return; } if (hasInvalidCartNo) { EventManager.fire('MODAL_ALERT_OPEN', { noticeType: 'CAUTION', message: `선택하신 상품에 구매불가한 상품이 있습니다.`, }); return; } handleOrder({ cartNos: checkedCartNos, products: checkedProducts, helper, }); }, ORDER_ALL: async ({ helper }) => { const editingEl = containerEl.querySelector('[shopby-status="EDITING"]'); if (editingEl) { EventManager.fire('MODAL_ALERT_OPEN', { noticeType: 'CAUTION', message: `변경중인 옵션이 있습니다.`, onClose: () => { editingEl?.focus?.(); }, }); return; } const { data } = await helper.cartAction.fetchAllValidProducts(); const cartNos = data.map(({ cartNo }) => cartNo); handleOrder({ cartNos, products: data, helper, }); }, }; const clickEventListener = ({ target }) => { const actionType = target.getAttribute(ELEMENT_SELECTOR.ACTION); CLICK_EVENT_HANDLER_MAP[actionType]?.({ target, helper: cartHelper, }); }; containerEl.addEventListener('click', clickEventListener); // 네이버 주문 const naverPay = { action: null, usable: false, el: document.querySelector('#naver-pay'), getVisibility: (visible) => (visible ? 'visible' : 'hidden'), getTotalCount: (data) => Object.keys(data)?.length || 0, handleReceiverCheckingStatus: (data) => { const { el, action, getTotalCount, getVisibility, usable } = naverPay; const totalCount = getTotalCount(data); const showsNaverPayButton = usable && totalCount > 0; const visibility = getVisibility(showsNaverPayButton); if (el) { el.style.visibility = visibility; return; } if (!showsNaverPayButton) { return; } action.showNaverPayButton({ containerElementId: 'naver-pay', isCartPage: true, }); }, handleReceiverCheckedProducts: (data) => { const items = data.map(({ productNo, optionNo, orderCnt, optionInputs, channelType }) => ({ productNo, optionNo, orderCnt, optionInputs, channelType: channelType || utils.getQueryParams()?.channelType, })); naverPay.action.prepareNaverPay({ items }); }, setNaverPayAction: async ({ env, clientId, orderConfig }) => { naverPay.action = await actions.getNaverPayAction({ mallProfile: env, clientId, platform: utils.isMobileDevice ? 'MOBILE_WEB' : 'PC', }); naverPay.usable = Boolean(orderConfig.naverPay); }, }; EventManager.on('UPDATE_CART_PRODUCT', cartProductsEl?.showLoadingSpinner); EventManager.on('ON_UPDATED_CART_PRODUCT', cartProductsEl?.hideLoadingSpinner); EventManager.on('QUERY_CART_CHECKED_PRODUCTS', naverPay.handleReceiverCheckedProducts); EventManager.on('QUERY_CART_CHECKING_STATUS_PER_CART_NO', naverPay.handleReceiverCheckingStatus); EventManager.on('PAGE_LOAD_COMPLETED', (commonData) => { cartHelper.cartAction.fetchCartDetail(); naverPay.setNaverPayAction(commonData); // 외부스크립트 등록 기능. 삭제금지 ShopbyExternalScript?.setPageScriptType('CART'); }); EventManager.on('QUERY_CART_DETAIL', (cart) => { // 외부스크립트 등록 기능. 삭제금지 ShopbyExternalScript?.setGlobalObjectSb({ cart }); }); })();