@blux.ai/web-sdk 2.2.12 → 2.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tsbuildinfo.noEmit +1 -1
- package/dist/BluxClient.js +61 -11
- package/dist/BluxClient.js.map +1 -1
- package/dist/package.js +1 -1
- package/package.json +1 -1
- package/scripts/cafe24/.tsbuildinfo.noEmit +1 -0
- package/scripts/cafe24/dist/.temp/index.d.ts +1 -0
- package/scripts/cafe24/dist/blux_collector.js +1 -0
- package/scripts/cafe24/dist/custom_scripts/daiso.d.ts +1 -0
- package/scripts/cafe24/dist/custom_scripts/daiso.js +114 -0
- package/scripts/cafe24/dist/custom_scripts/nerdy.d.ts +16 -0
- package/scripts/cafe24/dist/custom_scripts/nerdy.js +734 -0
- package/scripts/cafe24/dist/custom_scripts/vogoplay.d.ts +6 -0
- package/scripts/cafe24/dist/custom_scripts/vogoplay.js +147 -0
- package/scripts/cafe24/dist/deploy_all.d.ts +1 -0
- package/scripts/cafe24/dist/tsconfig.tsbuildinfo +1 -0
- package/scripts/sdk/.tsbuildinfo.noEmit +1 -0
- package/scripts/sdk/dist/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
import { BluxClient, AddCustomEvent, AddProductDetailViewEvent, UserRec, ItemRelatedRec, } from "@blux.ai/web-sdk";
|
|
2
|
+
const applicationId = "67583cfeef849a320553be6c";
|
|
3
|
+
const bluxApiKey = "oCpWEtItYbYoC1E0fBHTgFG55W5oNxV3x7qXRm-5z6c";
|
|
4
|
+
const bluxClient = new BluxClient({ applicationId, bluxApiKey });
|
|
5
|
+
const cafe24Client = CAFE24API.init({
|
|
6
|
+
client_id: "gRSxaEXKARIpFrRcpAEhJB",
|
|
7
|
+
version: "2023-06-01",
|
|
8
|
+
});
|
|
9
|
+
const useItemRecommendation = true; // 상품 추천을 사용하는 경우 지표 수집을 위해 true로 변경
|
|
10
|
+
const BLUX_ATTRIBUTES = {
|
|
11
|
+
section: "blux-section",
|
|
12
|
+
recommendation_id: "blux-rec-id",
|
|
13
|
+
};
|
|
14
|
+
const HOMEPAGE_FROM = "homepage";
|
|
15
|
+
const HOMEPAGE_REC_REQUEST_LIMIT = 18;
|
|
16
|
+
const HOMEPAGE_ITEMS_TO_SHOW = 2;
|
|
17
|
+
const SESSION_STORAGE_PREV_SECTION_KEY = "prev_section";
|
|
18
|
+
const SESSION_STORAGE_RECOMMENDATION_ID_KEY = "recommendation_id";
|
|
19
|
+
const SESSION_STORAGE_BLUX_ENTER_PDP_FROM_CATEGORY_PAGE_KEY = "blux_enter_pdp_from_category_page";
|
|
20
|
+
const SESSION_STORAGE_BLUX_CATEGORY_REC_REJECT_TIMESTAMP_KEY = "blux_category_rec_reject_timestamp";
|
|
21
|
+
const SESSION_STORAGE_BLUX_RECENTLY_CLICKED_ITEM_ID_FROM_CATEGORY_PAGE_KEY = "blux_recently_clicked_item_id_from_category_page";
|
|
22
|
+
const LOCAL_STORAGE_BLUX_REF_KEY = "blux_ref";
|
|
23
|
+
const CATEGORY_FROM = "category_page";
|
|
24
|
+
const PRODUCT_DETAIL_PAGE_PATH = "/product/detail";
|
|
25
|
+
const PRODUCT_LIST_PAGE_PATH = "/product/list";
|
|
26
|
+
const ORDER_FORM_PAGE_PATH = "/order/orderform";
|
|
27
|
+
// Recommendation Call Types
|
|
28
|
+
const HOMEPAGE_CALL_TYPE = "user-recommendations";
|
|
29
|
+
const PRODUCT_DETAIL_PAGE_CLOTHING_CALL_TYPE = "related-items-clothing";
|
|
30
|
+
const PRODUCT_DETAIL_PAGE_HOODY_CALL_TYPE = "related-items-hoodysweater";
|
|
31
|
+
const PRODUCT_DETAIL_PAGE_ACCESSORY_CALL_TYPE = "related-items-accessory";
|
|
32
|
+
const CATEGORY_PAGE_CALL_TYPE = "category-recommendations";
|
|
33
|
+
const OTHER_CATEGORY_FROM = "product_detail_page-other_category";
|
|
34
|
+
const SAME_CATEGORY_FROM = "product_detail_page-same_category";
|
|
35
|
+
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
|
|
36
|
+
const PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW = 7;
|
|
37
|
+
const CATEGORY_PAGE_ITEMS_TO_SHOW = 6;
|
|
38
|
+
const CAROUSEL_ITEM_DISTANCE = 20;
|
|
39
|
+
const SAME_CATEGORY_TITLE = "지금 주목해야 할 BEST";
|
|
40
|
+
const OTHER_CATEGORY_TITLE = "함께 보면 좋은 상품";
|
|
41
|
+
async function getCustomerIDInfo() {
|
|
42
|
+
return await new Promise((resolve, reject) => {
|
|
43
|
+
cafe24Client.getCustomerIDInfo((error, data) => {
|
|
44
|
+
if (error) {
|
|
45
|
+
return reject(error);
|
|
46
|
+
}
|
|
47
|
+
resolve(data.id);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function getAllParentNodes(node) {
|
|
52
|
+
const parents = [];
|
|
53
|
+
let currentNode = node;
|
|
54
|
+
while (currentNode.parentNode) {
|
|
55
|
+
currentNode = currentNode.parentNode;
|
|
56
|
+
parents.push(currentNode);
|
|
57
|
+
}
|
|
58
|
+
return parents;
|
|
59
|
+
}
|
|
60
|
+
function handleSectionClick(event) {
|
|
61
|
+
const clickedElement = event.target;
|
|
62
|
+
const recSectionElements = Array.from(document.querySelectorAll(`[${BLUX_ATTRIBUTES.section}]`));
|
|
63
|
+
const allParentNodes = getAllParentNodes(clickedElement);
|
|
64
|
+
const clickedRecSectionElement = recSectionElements.find((el) => allParentNodes.includes(el));
|
|
65
|
+
if (clickedRecSectionElement) {
|
|
66
|
+
const prevSection = clickedRecSectionElement.getAttribute(BLUX_ATTRIBUTES.section);
|
|
67
|
+
const recommendationId = clickedRecSectionElement.getAttribute(BLUX_ATTRIBUTES.recommendation_id);
|
|
68
|
+
if (prevSection) {
|
|
69
|
+
sessionStorage.setItem(SESSION_STORAGE_PREV_SECTION_KEY, prevSection);
|
|
70
|
+
}
|
|
71
|
+
if (recommendationId) {
|
|
72
|
+
sessionStorage.setItem(SESSION_STORAGE_RECOMMENDATION_ID_KEY, recommendationId);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
sessionStorage.removeItem(SESSION_STORAGE_PREV_SECTION_KEY);
|
|
77
|
+
sessionStorage.removeItem(SESSION_STORAGE_RECOMMENDATION_ID_KEY);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function getItemIdOnProductDetailPage() {
|
|
81
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
82
|
+
return (searchParams.get("product_no") ??
|
|
83
|
+
document
|
|
84
|
+
.querySelector('meta[property="product:productId"]')
|
|
85
|
+
?.getAttribute("content") ??
|
|
86
|
+
null);
|
|
87
|
+
}
|
|
88
|
+
const getCartAddMutationObserver = function (type) {
|
|
89
|
+
return new MutationObserver((mutations) => {
|
|
90
|
+
const cartAddConfirmLayer = Array.from(document.querySelectorAll("div.content")).filter((el) => el.outerText.includes("장바구니 담기가 완료되었습니다."));
|
|
91
|
+
const isCartAdded = cartAddConfirmLayer.length === 1;
|
|
92
|
+
if (isCartAdded) {
|
|
93
|
+
if (type === "mobile") {
|
|
94
|
+
document.getElementsByClassName("action_up")[0].className = "action_up";
|
|
95
|
+
document.getElementById("fog").style.display = "none";
|
|
96
|
+
Array.from(document.getElementsByClassName("close_popup")).forEach((el) => el.addEventListener("click", () => {
|
|
97
|
+
document.body.style.position = "static";
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const calculateDiscountRate = function (originalPrice, discountPrice) {
|
|
104
|
+
return ((originalPrice - discountPrice) / originalPrice) * 100;
|
|
105
|
+
};
|
|
106
|
+
async function collectEvents() {
|
|
107
|
+
try {
|
|
108
|
+
const customerIDInfo = await getCustomerIDInfo();
|
|
109
|
+
const userId = customerIDInfo.member_id;
|
|
110
|
+
if (userId) {
|
|
111
|
+
await bluxClient.signIn(userId);
|
|
112
|
+
}
|
|
113
|
+
// 상품 추천을 사용하는 경우에만 추천 구좌에 대한 클릭 이벤트 리스너 등록
|
|
114
|
+
if (useItemRecommendation) {
|
|
115
|
+
document.addEventListener("click", handleSectionClick);
|
|
116
|
+
}
|
|
117
|
+
const { pathname } = window.location;
|
|
118
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
119
|
+
const categoryNo = searchParams.get("cate_no");
|
|
120
|
+
const isProductDetailPage = pathname.includes(PRODUCT_DETAIL_PAGE_PATH);
|
|
121
|
+
const isCategoryPage = pathname.includes(PRODUCT_LIST_PAGE_PATH) && categoryNo;
|
|
122
|
+
const isOrderFormPage = pathname.includes(ORDER_FORM_PAGE_PATH);
|
|
123
|
+
/* NERDY Specific */
|
|
124
|
+
// 카테고리 페이지 이외의 페이지 진입 시
|
|
125
|
+
// 또는
|
|
126
|
+
// 상품 상세 페이지 -> 카테고리 페이지 진입이 아닌 경우
|
|
127
|
+
// '카테고리 페이지에서 왔는지' 여부 초기화
|
|
128
|
+
if (!isCategoryPage ||
|
|
129
|
+
!localStorage
|
|
130
|
+
.getItem(LOCAL_STORAGE_BLUX_REF_KEY)
|
|
131
|
+
?.includes(PRODUCT_DETAIL_PAGE_PATH)) {
|
|
132
|
+
sessionStorage.setItem(SESSION_STORAGE_BLUX_ENTER_PDP_FROM_CATEGORY_PAGE_KEY, "false");
|
|
133
|
+
}
|
|
134
|
+
if (isProductDetailPage) {
|
|
135
|
+
// Cafe24 상품 상세 페이지
|
|
136
|
+
const itemId = getItemIdOnProductDetailPage();
|
|
137
|
+
const recommendationId = sessionStorage.getItem(SESSION_STORAGE_RECOMMENDATION_ID_KEY) ??
|
|
138
|
+
undefined;
|
|
139
|
+
if (recommendationId) {
|
|
140
|
+
sessionStorage.removeItem(SESSION_STORAGE_RECOMMENDATION_ID_KEY);
|
|
141
|
+
}
|
|
142
|
+
const prevSection = sessionStorage.getItem(SESSION_STORAGE_PREV_SECTION_KEY) ?? undefined;
|
|
143
|
+
if (prevSection) {
|
|
144
|
+
sessionStorage.removeItem(SESSION_STORAGE_PREV_SECTION_KEY);
|
|
145
|
+
}
|
|
146
|
+
if (itemId) {
|
|
147
|
+
bluxClient.sendEvent(new AddProductDetailViewEvent({
|
|
148
|
+
item_id: itemId,
|
|
149
|
+
recommendation_id: recommendationId,
|
|
150
|
+
prev_section: prevSection,
|
|
151
|
+
}));
|
|
152
|
+
/* NERDY Specific */
|
|
153
|
+
// 카테고리 페이지 추천에 사용될 '최근 본 상품' 정보 저장
|
|
154
|
+
// 카테고리 페이지 추천 구좌를 통해 진입한 경우에는 (카테고리 페이지 추천 구좌 유지를 위해) '최근 본 상품' 정보 갱신 생략
|
|
155
|
+
if (localStorage
|
|
156
|
+
.getItem(LOCAL_STORAGE_BLUX_REF_KEY)
|
|
157
|
+
?.includes(PRODUCT_LIST_PAGE_PATH) &&
|
|
158
|
+
prevSection !== "category_page") {
|
|
159
|
+
sessionStorage.setItem(SESSION_STORAGE_BLUX_RECENTLY_CLICKED_ITEM_ID_FROM_CATEGORY_PAGE_KEY, itemId);
|
|
160
|
+
}
|
|
161
|
+
/* NERDY Specific */
|
|
162
|
+
// 카테고리 페이지에서 왔는지 여부 저장
|
|
163
|
+
const isEnterPdpFromCategoryPage = localStorage
|
|
164
|
+
.getItem(LOCAL_STORAGE_BLUX_REF_KEY)
|
|
165
|
+
?.includes(PRODUCT_LIST_PAGE_PATH)
|
|
166
|
+
? "true"
|
|
167
|
+
: "false";
|
|
168
|
+
sessionStorage.setItem(SESSION_STORAGE_BLUX_ENTER_PDP_FROM_CATEGORY_PAGE_KEY, isEnterPdpFromCategoryPage);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (isOrderFormPage) {
|
|
172
|
+
// Cafe24 주문서 페이지
|
|
173
|
+
bluxClient.sendEvent(new AddCustomEvent({
|
|
174
|
+
event_type: "orderform_view",
|
|
175
|
+
event_properties: {},
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.error("[BluxClient] Error during initialization and event handling.", error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const fetchProductsInfo = (item_ids) => {
|
|
184
|
+
const productNoQueries = item_ids.join(",");
|
|
185
|
+
return new Promise((resolve, reject) => {
|
|
186
|
+
CAFE24API.get(`/api/v2/products?embed=discountprice,variants&fields=discountprice,product_no,product_name,detail_image,list_image,small_image,price,sold_out,variants&product_no=${productNoQueries}&display=T&selling=T&limit=50`, (err, response) => {
|
|
187
|
+
if (err) {
|
|
188
|
+
reject(err);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
resolve(response.products);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
const fetchProductInfo = (item_id) => {
|
|
197
|
+
return new Promise((resolve, reject) => {
|
|
198
|
+
CAFE24API.get(`/api/v2/products/${item_id}?fields=product_no,category&display=T&selling=T`, (err, response) => {
|
|
199
|
+
if (err) {
|
|
200
|
+
reject(err);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
resolve(response.product);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
const getPrimaryCategory = function (categoryNos) {
|
|
209
|
+
const ACCESSORY_CATEGORIES = [201, 54, 200, 42, 132, 70, 123];
|
|
210
|
+
const isAccessory = ACCESSORY_CATEGORIES.some((el) => categoryNos.includes(el));
|
|
211
|
+
if (isAccessory)
|
|
212
|
+
return "accessory";
|
|
213
|
+
return "clothing";
|
|
214
|
+
};
|
|
215
|
+
const getProductsInfo = async (item_ids) => {
|
|
216
|
+
const products = await fetchProductsInfo(item_ids);
|
|
217
|
+
return item_ids
|
|
218
|
+
.map((item_id) => products.find((p) => p.product_no.toString() === item_id))
|
|
219
|
+
.filter((p) => p !== undefined);
|
|
220
|
+
};
|
|
221
|
+
const getTimestampDiff = (timestampString) => {
|
|
222
|
+
const now = new Date();
|
|
223
|
+
const diff = now.getTime() - parseInt(timestampString, 10);
|
|
224
|
+
return diff;
|
|
225
|
+
};
|
|
226
|
+
const getMobileSlideTemplate = function (title, productInfos, from, recommendationId) {
|
|
227
|
+
const carouselMobileTemplate = document.createElement("div");
|
|
228
|
+
carouselMobileTemplate.innerHTML = `<div style="
|
|
229
|
+
display: flex;
|
|
230
|
+
flex-direction: column;
|
|
231
|
+
width: calc(100% - 20px);
|
|
232
|
+
margin: auto;
|
|
233
|
+
user-select:none;
|
|
234
|
+
margin-top:35px;
|
|
235
|
+
margin-bottom:40px;
|
|
236
|
+
margin-left: 20px;
|
|
237
|
+
letter-spacing: -0.2px;
|
|
238
|
+
">
|
|
239
|
+
<span style="margin-bottom:20px; font-size:17px; font-weight:600;">${title}</span>
|
|
240
|
+
<div class="blux-mobile-slide" style="position:relative; width:100%; margin:auto; overflow:auto; padding-bottom:30px;">
|
|
241
|
+
<div style="display:flex; width: 400%; flex-direction:row;" ${BLUX_ATTRIBUTES.section}="${from}" ${BLUX_ATTRIBUTES.recommendation_id}="${recommendationId}">
|
|
242
|
+
${productInfos.slice(0, 10).map((el) => `<a style="width:19%; margin-right: 1%; height:100%; display: flex; flex-direction: column;" href="/product/detail.html?product_no=${el.product_no}&from=${from}&recommendationId=${recommendationId}">
|
|
243
|
+
<img style="width:100%; height: 100%; margin-bottom:16px;" src="${el.small_image}" />
|
|
244
|
+
<span style="color:#555555; width:100%; font-size: 13px; font-weight:400; height:32px; overflow:hidden; display: -webkit-box; text-overflow: ellipsis; -webkit-box-orient: vertical; -webkit-line-clamp: 2; margin-bottom:15px;">${el.product_name}</span>
|
|
245
|
+
<div style="display:flex; flex-direction:row; font-size: 13px; font-weight:500">
|
|
246
|
+
<span style="color: #FF2E00; margin-right:4px; display: ${calculateDiscountRate(el.price, el.discountprice["mobile_discount_price"]) !== 0
|
|
247
|
+
? "block"
|
|
248
|
+
: "none"}">${calculateDiscountRate(el.price, el.discountprice["mobile_discount_price"]).toFixed()}%</span>
|
|
249
|
+
<span>${Number(el.discountprice["mobile_discount_price"]).toLocaleString("en")}원</span>
|
|
250
|
+
</div>
|
|
251
|
+
</a>`)}
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
`.replaceAll("</a>,", "</a>");
|
|
256
|
+
return carouselMobileTemplate;
|
|
257
|
+
};
|
|
258
|
+
const getMobileHomepageSlideTemplate = function (productInfos, recommendationId, deviceType) {
|
|
259
|
+
const carouselMobileTemplate = document.createElement("div");
|
|
260
|
+
carouselMobileTemplate.innerHTML = `<ul class="prdNeo">
|
|
261
|
+
|
|
262
|
+
<div id="blux-mobile-homepage-carousel-container" ${BLUX_ATTRIBUTES.section}="${HOMEPAGE_FROM}" ${BLUX_ATTRIBUTES.recommendation_id}="${recommendationId}">
|
|
263
|
+
${Array.from({ length: HOMEPAGE_REC_REQUEST_LIMIT / HOMEPAGE_ITEMS_TO_SHOW }, (_, index) => `<div id="blux-mobile-homepage-carousel-${index + 1}" style="display:${index === 0 ? "" : "none"};>
|
|
264
|
+
${productInfos
|
|
265
|
+
.slice(index * HOMEPAGE_ITEMS_TO_SHOW, (index + 1) * HOMEPAGE_ITEMS_TO_SHOW)
|
|
266
|
+
.map((el) => `<li id="anchorBoxId_${el.product_no}" class="pList xans-record-">
|
|
267
|
+
<div class="box" style="display: flex; flex-wrap: wrap; align-items: center; padding: 0; margin-bottom: 8px;">
|
|
268
|
+
<div class="thumbnail on">
|
|
269
|
+
${deviceType === "mobile"
|
|
270
|
+
? `<a
|
|
271
|
+
href="/product/detail.html?product_no=${el.product_no}&from=${HOMEPAGE_FROM}&recommendationId=${recommendationId}"
|
|
272
|
+
><img
|
|
273
|
+
src="${el.detail_image}"
|
|
274
|
+
/>
|
|
275
|
+
</a>`
|
|
276
|
+
: `<a href="/skin-skin38/product/detail.html?product_no=${el.product_no}&from=${HOMEPAGE_FROM}&recommendationId=${recommendationId}"><img src="${el.detail_image}" /></a>`}
|
|
277
|
+
</div>
|
|
278
|
+
<div class="description">
|
|
279
|
+
${deviceType === "mobile"
|
|
280
|
+
? `<strong class="name product_name" style="display: block; line-height: 1.3; word-wrap: break-word; margin: 0 0 7px;">
|
|
281
|
+
<a
|
|
282
|
+
href="/product/detail.html?product_no=${el.product_no}&from=${HOMEPAGE_FROM}&recommendationId=${recommendationId}"
|
|
283
|
+
style="display: inline; color: #1b1b1b;"
|
|
284
|
+
>${el.product_name}</a>
|
|
285
|
+
</strong>`
|
|
286
|
+
: `<div class="name">
|
|
287
|
+
<a
|
|
288
|
+
href="/skin-skin38/product/detail.html?product_no=${el.product_no}&from=${HOMEPAGE_FROM}&recommendationId=${recommendationId}"
|
|
289
|
+
class="product_name"
|
|
290
|
+
style="display: inline"
|
|
291
|
+
>${el.product_name}</a>
|
|
292
|
+
</div>`}
|
|
293
|
+
<div class="priceGroup">
|
|
294
|
+
<div class="dc_rate rate50" style="display: ${calculateDiscountRate(el.price, el.discountprice["mobile_discount_price"]) !== 0
|
|
295
|
+
? "block"
|
|
296
|
+
: "none"}">${calculateDiscountRate(el.price, el.discountprice["mobile_discount_price"]).toFixed()}%</div>
|
|
297
|
+
<div class="prs prsBold">${Number(el.discountprice["mobile_discount_price"]).toLocaleString("en")}<span>원</span></div>
|
|
298
|
+
<div class="prs prsLine">${Number(el.price).toLocaleString("en")}<span>원</span></div>
|
|
299
|
+
</div>
|
|
300
|
+
<div class="ico_wish">
|
|
301
|
+
<img
|
|
302
|
+
src="/web/upload/icon_202409121050358700.png"
|
|
303
|
+
class="icon_img ec-product-listwishicon"
|
|
304
|
+
alt="관심상품 등록 전"
|
|
305
|
+
productno="${el.product_no}"
|
|
306
|
+
icon_status="off"
|
|
307
|
+
login_status="T"
|
|
308
|
+
individual-set="F"
|
|
309
|
+
/>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</li>`)}
|
|
314
|
+
</div>`)}
|
|
315
|
+
</div>
|
|
316
|
+
</ul>
|
|
317
|
+
`
|
|
318
|
+
.replaceAll("</a>,", "</a>")
|
|
319
|
+
.replaceAll(",<li", "<li")
|
|
320
|
+
.replaceAll("</div>,", "</div>");
|
|
321
|
+
return carouselMobileTemplate;
|
|
322
|
+
};
|
|
323
|
+
export const getMobileCategoryPageSlideTemplate = function (productInfos, recommendationId) {
|
|
324
|
+
const carouselMobileTemplate = document.createElement("div");
|
|
325
|
+
carouselMobileTemplate.innerHTML = `<div
|
|
326
|
+
class="blux-mobile-category-page-slide"
|
|
327
|
+
style="
|
|
328
|
+
display: flex;
|
|
329
|
+
flex-direction: column;
|
|
330
|
+
width: calc(100% - 20px);
|
|
331
|
+
user-select:none;
|
|
332
|
+
padding-left: 20px;
|
|
333
|
+
letter-spacing: -0.2px;
|
|
334
|
+
overflow: hidden;
|
|
335
|
+
max-height: 0;
|
|
336
|
+
transition: max-height 0.3s ease-in-out;
|
|
337
|
+
">
|
|
338
|
+
<div style="display: flex; justify-content:space-between; align-items: center; width: 100%; margin-bottom:12px;">
|
|
339
|
+
<span style="font-size:16px; font-weight:500; line-height:30px;">이런 상품은 어떠세요?</span>
|
|
340
|
+
<div id="blux-mobile-category-page-slide-close-button" style="display: flex; align-items: center;">
|
|
341
|
+
<span style="font-size:12px; font-weight:300; color:#999999; margin-right:6px;">하루 동안 닫기</span>
|
|
342
|
+
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
343
|
+
<line x1="3" y1="3" x2="21" y2="21" stroke="#999999" stroke-width="2" stroke-linecap="round"/>
|
|
344
|
+
<line x1="3" y1="21" x2="21" y2="3" stroke="#999999" stroke-width="2" stroke-linecap="round"/>
|
|
345
|
+
</svg>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
<div class="blux-mobile-slide" style="position:relative; width:100%; margin:auto; overflow:auto; padding-bottom:30px;">
|
|
349
|
+
<div style="display:flex; width: 190%; flex-direction:row;" ${BLUX_ATTRIBUTES.section}="${CATEGORY_FROM}" ${BLUX_ATTRIBUTES.recommendation_id}="${recommendationId}">
|
|
350
|
+
${productInfos.slice(0, CATEGORY_PAGE_ITEMS_TO_SHOW).map((el) => `<a style="width:30%; margin-right: 1%; height:100%; display: flex; flex-direction: column;" href="/product/detail.html?product_no=${el.product_no}&from=${CATEGORY_FROM}&recommendationId=${recommendationId}">
|
|
351
|
+
<img style="width:100%; height: 100%; margin-bottom:10px;" src="${el.small_image}" />
|
|
352
|
+
<span style="color:#555555; width:100%; font-size: 12px; font-weight:300; height: 12px; display: -webkit-box; text-overflow: ellipsis; -webkit-box-orient: vertical; -webkit-line-clamp: 1; line-height: 12px; overflow: hidden; margin-bottom: 10px;">${el.product_name}</span>
|
|
353
|
+
<div style="display:flex; flex-direction:row; font-size: 13px; font-weight:600; line-height: 13px;">
|
|
354
|
+
<span style="color: #FF2E00; margin-right:4px; display: ${calculateDiscountRate(el.price, el.discountprice["mobile_discount_price"]) !== 0
|
|
355
|
+
? "block"
|
|
356
|
+
: "none"}">${calculateDiscountRate(el.price, el.discountprice["mobile_discount_price"]).toFixed()}%</span>
|
|
357
|
+
<span>${Number(el.discountprice["mobile_discount_price"]).toLocaleString("en")}원</span>
|
|
358
|
+
</div>
|
|
359
|
+
</a>`)}
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
</div>
|
|
364
|
+
`
|
|
365
|
+
.replaceAll("</a>,", "</a>")
|
|
366
|
+
.replaceAll("</div>,", "</div>");
|
|
367
|
+
return carouselMobileTemplate;
|
|
368
|
+
};
|
|
369
|
+
const getPcCarouselTemplate = function (sameCategoryRecProdInfo, sameCategoryRecId, otherCategoryRecProdInfo, otherCategoryRecId) {
|
|
370
|
+
const pcCarouselTemplate = document.createElement("div");
|
|
371
|
+
const displayedSameCategoryProducts = sameCategoryRecProdInfo.map((el, idx) => ({ info: el, index: idx }));
|
|
372
|
+
const displayedOtherCategoryProducts = otherCategoryRecProdInfo.map((el, idx) => ({ info: el, index: idx }));
|
|
373
|
+
pcCarouselTemplate.innerHTML = `<div style="
|
|
374
|
+
display: flex;
|
|
375
|
+
flex-direction: column;
|
|
376
|
+
width: auto;
|
|
377
|
+
margin: auto;
|
|
378
|
+
user-select: none;
|
|
379
|
+
margin-top: 80px;
|
|
380
|
+
padding: 0 30px;
|
|
381
|
+
">
|
|
382
|
+
<div style="display: flex; margin-bottom:20px; font-size:20px; font-weight:600; display: inline">
|
|
383
|
+
<span id="blux-tab1-button" style="margin-right: 22px; font-size:20px; font-weight:600; cursor:pointer">${SAME_CATEGORY_TITLE}</span>
|
|
384
|
+
<span id="blux-tab2-button" style="font-size:20px; font-weight:600; color: #999999; cursor:pointer">${OTHER_CATEGORY_TITLE}</span>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<div id="blux-container" style="position:relative; width:98%; overflow:hidden; padding-left:20px">
|
|
388
|
+
<div id="blux-prevButton" style="position:absolute; top:35%; left:0; z-index: 1; background-color: rgba(0,0,0,0.5);
|
|
389
|
+
width: 36px;
|
|
390
|
+
height: 36px;
|
|
391
|
+
border-radius: 50px;
|
|
392
|
+
opacity: 0.5;
|
|
393
|
+
display: none;
|
|
394
|
+
justify-content: center;
|
|
395
|
+
align-items: center;
|
|
396
|
+
cursor:pointer">
|
|
397
|
+
<svg width="12" height="20" viewBox="0 0 12 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
398
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.7073 0.292893C12.0978 0.683417 12.0978 1.31658 11.7073 1.70711L3.41436 10L11.7073 18.2929C12.0978 18.6834 12.0978 19.3166 11.7073 19.7071C11.3167 20.0976 10.6836 20.0976 10.293 19.7071L0.585938 10L10.293 0.292893C10.6836 -0.0976311 11.3167 -0.0976311 11.7073 0.292893Z" fill="white"/>
|
|
399
|
+
</svg>
|
|
400
|
+
</div>
|
|
401
|
+
<div id="blux-nextButton" style="position:absolute; top:35%; right:0; z-index: 1; background-color: rgba(0,0,0,0.5);
|
|
402
|
+
width: 36px;
|
|
403
|
+
height: 36px;
|
|
404
|
+
border-radius: 50px;
|
|
405
|
+
opacity: 0.5;
|
|
406
|
+
display: flex;
|
|
407
|
+
justify-content: center;
|
|
408
|
+
align-items: center;
|
|
409
|
+
cursor:pointer">
|
|
410
|
+
<svg width="12" height="20" viewBox="0 0 12 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
411
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.292742 19.7071C-0.0977821 19.3166 -0.097782 18.6834 0.292742 18.2929L8.58564 10L0.292743 1.7071C-0.0977805 1.31658 -0.0977804 0.683415 0.292743 0.292891C0.683268 -0.0976324 1.31643 -0.0976323 1.70696 0.292892L11.4141 10L1.70696 19.7071C1.31643 20.0976 0.683267 20.0976 0.292742 19.7071Z" fill="white"/>
|
|
412
|
+
</svg>
|
|
413
|
+
</div>
|
|
414
|
+
<div id="blux-carousel" ${BLUX_ATTRIBUTES.section}="${SAME_CATEGORY_FROM}" ${BLUX_ATTRIBUTES.recommendation_id}="${sameCategoryRecId}" style="width:100%; height:100%; display:flex; flex-direction:row; transition: transform 0.5s ease-in-out";>
|
|
415
|
+
${displayedSameCategoryProducts.map((el) => `<a class="blux-carousel-item" style="flex: 0 0 calc((100% - ${CAROUSEL_ITEM_DISTANCE * (PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW - 1)}px) / ${PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW}); margin-right: ${CAROUSEL_ITEM_DISTANCE}px; height:100%; display: flex; flex-direction: column;" href="/product/detail.html?product_no=${el.info.product_no}&from=${SAME_CATEGORY_FROM}&recommendationId=${sameCategoryRecId}">
|
|
416
|
+
<img style="width:100%; height: 100%; margin-bottom:16px;" src="${el.info.small_image}" alt="Z.Ai 퍼스널MD 추천 상품 / 상품명 : ${el.info.product_name}"/>
|
|
417
|
+
<span style="color:#555555; font-size: 14px; font-weight:400; padding-bottom:12px; line-height:21px; height:40px;">${el.info.product_name}</span>
|
|
418
|
+
<div style="display:flex; flex-direction:row; font-size: 15px; font-weight:500">
|
|
419
|
+
<span style="color: #FF2E00; margin-right:4px; display: ${calculateDiscountRate(el.info.price, el.info.discountprice["pc_discount_price"]) !== 0
|
|
420
|
+
? "block"
|
|
421
|
+
: "none"}">${calculateDiscountRate(el.info.price, el.info.discountprice["pc_discount_price"]).toFixed()}%</span>
|
|
422
|
+
<span>${Number(el.info.discountprice["pc_discount_price"]).toLocaleString("en")}원</span>
|
|
423
|
+
</div>
|
|
424
|
+
</a>`)}
|
|
425
|
+
</div>
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
<div id="blux-container2" style="position:relative; width:98%; overflow:hidden; padding-left:20px; display:none">
|
|
429
|
+
<div id="blux-prevButton2" style="position:absolute; top:35%; left:0; z-index: 1; background-color: rgba(0,0,0,0.5);
|
|
430
|
+
width: 36px;
|
|
431
|
+
height: 36px;
|
|
432
|
+
border-radius: 50px;
|
|
433
|
+
opacity: 0.5;
|
|
434
|
+
display: none;
|
|
435
|
+
justify-content: center;
|
|
436
|
+
align-items: center;
|
|
437
|
+
cursor:pointer">
|
|
438
|
+
<svg width="12" height="20" viewBox="0 0 12 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
439
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.7073 0.292893C12.0978 0.683417 12.0978 1.31658 11.7073 1.70711L3.41436 10L11.7073 18.2929C12.0978 18.6834 12.0978 19.3166 11.7073 19.7071C11.3167 20.0976 10.6836 20.0976 10.293 19.7071L0.585938 10L10.293 0.292893C10.6836 -0.0976311 11.3167 -0.0976311 11.7073 0.292893Z" fill="white"/>
|
|
440
|
+
</svg>
|
|
441
|
+
</div>
|
|
442
|
+
<div id="blux-nextButton2" style="position:absolute; top:35%; right:0; z-index: 1; background-color: rgba(0,0,0,0.5);
|
|
443
|
+
width: 36px;
|
|
444
|
+
height: 36px;
|
|
445
|
+
border-radius: 50px;
|
|
446
|
+
opacity: 0.5;
|
|
447
|
+
display: flex;
|
|
448
|
+
justify-content: center;
|
|
449
|
+
align-items: center;
|
|
450
|
+
cursor:pointer">
|
|
451
|
+
<svg width="12" height="20" viewBox="0 0 12 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
452
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.292742 19.7071C-0.0977821 19.3166 -0.097782 18.6834 0.292742 18.2929L8.58564 10L0.292743 1.7071C-0.0977805 1.31658 -0.0977804 0.683415 0.292743 0.292891C0.683268 -0.0976324 1.31643 -0.0976323 1.70696 0.292892L11.4141 10L1.70696 19.7071C1.31643 20.0976 0.683267 20.0976 0.292742 19.7071Z" fill="white"/>
|
|
453
|
+
</svg>
|
|
454
|
+
</div>
|
|
455
|
+
<div id="blux-carousel2" ${BLUX_ATTRIBUTES.section}="${OTHER_CATEGORY_FROM}" ${BLUX_ATTRIBUTES.recommendation_id}="${otherCategoryRecId}" style="width:100%; height:100%; display:flex; flex-direction:row; transition: transform 0.5s ease-in-out";>
|
|
456
|
+
${displayedOtherCategoryProducts.map((el) => `<a class="blux-carousel-item2" style="flex: 0 0 calc((100% - ${CAROUSEL_ITEM_DISTANCE * (PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW - 1)}px) / ${PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW}); margin-right: ${CAROUSEL_ITEM_DISTANCE}px; height:100%; display: flex; flex-direction: column;" href="/product/detail.html?product_no=${el.info.product_no}&from=${OTHER_CATEGORY_FROM}&recommendationId=${otherCategoryRecId}">
|
|
457
|
+
<img style="width:100%; height: 100%; margin-bottom:16px;" src="${el.info.small_image}" alt="Z.Ai 퍼스널MD 추천 상품 / 상품명 : ${el.info.product_name}"/>
|
|
458
|
+
<span style="color:#555555; font-size: 14px; font-weight:400; padding-bottom:12px; line-height:21px; height:40px;">${el.info.product_name}</span>
|
|
459
|
+
<div style="display:flex; flex-direction:row; font-size: 15px; font-weight:500">
|
|
460
|
+
<span style="color: #FF2E00; margin-right:4px; display: ${calculateDiscountRate(el.info.price, el.info.discountprice["pc_discount_price"]) !== 0
|
|
461
|
+
? "block"
|
|
462
|
+
: "none"}">${calculateDiscountRate(el.info.price, el.info.discountprice["pc_discount_price"]).toFixed()}%</span>
|
|
463
|
+
<span>${Number(el.info.discountprice["pc_discount_price"]).toLocaleString("en")}원</span>
|
|
464
|
+
</div>
|
|
465
|
+
</a>`)}
|
|
466
|
+
</div>
|
|
467
|
+
</div>
|
|
468
|
+
</div>
|
|
469
|
+
`.replaceAll("</a>,", "</a>");
|
|
470
|
+
return pcCarouselTemplate;
|
|
471
|
+
};
|
|
472
|
+
async function makeRecSections() {
|
|
473
|
+
const { pathname } = window.location;
|
|
474
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
475
|
+
const categoryNo = searchParams.get("cate_no");
|
|
476
|
+
const deviceType = window.location.host.startsWith("m") ? "mobile" : "pc";
|
|
477
|
+
const isHomepage = pathname === "/";
|
|
478
|
+
const isProductDetailPage = pathname.includes(PRODUCT_DETAIL_PAGE_PATH);
|
|
479
|
+
const isCategoryPage = pathname.includes(PRODUCT_LIST_PAGE_PATH) && categoryNo;
|
|
480
|
+
if (isHomepage) {
|
|
481
|
+
// 홈페이지
|
|
482
|
+
const homepageRecPosition = document.getElementById("blux_home_rec");
|
|
483
|
+
const userRec = await bluxClient.getUserRec(new UserRec({
|
|
484
|
+
call_type: HOMEPAGE_CALL_TYPE,
|
|
485
|
+
limit: 18,
|
|
486
|
+
}));
|
|
487
|
+
const userRecProdNos = userRec.item_ids;
|
|
488
|
+
const userRecProdInfo = await getProductsInfo(userRecProdNos);
|
|
489
|
+
const userRecId = userRec.recommendation_id; // web-sdk 버전 1.2.0 초과로 올리면 assert 제거 가능
|
|
490
|
+
if (!homepageRecPosition || !homepageRecPosition.parentNode)
|
|
491
|
+
throw Error("homepageRecPosition should exist");
|
|
492
|
+
// [Mobile] ITEMS FOR YOU 구좌
|
|
493
|
+
homepageRecPosition.parentNode.insertBefore(getMobileHomepageSlideTemplate(userRecProdInfo, userRecId, deviceType), homepageRecPosition.nextSibling);
|
|
494
|
+
const bluxHomepageRecUpdateButton = document.querySelector("#blux_home_rec .main_prd_top a.main_cate_link");
|
|
495
|
+
if (!bluxHomepageRecUpdateButton)
|
|
496
|
+
throw Error("bluxHomepageRecUpdateButton should exist");
|
|
497
|
+
console.log("bluxHomepageRecUpdateButton", bluxHomepageRecUpdateButton);
|
|
498
|
+
const bluxMobileHomepageCarousels = Array.from({ length: HOMEPAGE_REC_REQUEST_LIMIT / HOMEPAGE_ITEMS_TO_SHOW }, (_, idx) => document.getElementById(`blux-mobile-homepage-carousel-${idx + 1}`));
|
|
499
|
+
let currentOffset = 0;
|
|
500
|
+
bluxHomepageRecUpdateButton.addEventListener("click", () => {
|
|
501
|
+
currentOffset++;
|
|
502
|
+
if (currentOffset === HOMEPAGE_REC_REQUEST_LIMIT / HOMEPAGE_ITEMS_TO_SHOW)
|
|
503
|
+
currentOffset = 0;
|
|
504
|
+
console.log("currentOffset", currentOffset);
|
|
505
|
+
bluxMobileHomepageCarousels.forEach((carousel, idx) => {
|
|
506
|
+
if (!carousel)
|
|
507
|
+
return;
|
|
508
|
+
carousel.style.display = idx === currentOffset ? "" : "none";
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
else if (isProductDetailPage) {
|
|
513
|
+
// 상품 상세 페이지
|
|
514
|
+
// Get Product No.(Item ID), Product Primary Category(`clothing` or `accessory`)
|
|
515
|
+
const productNo = getItemIdOnProductDetailPage();
|
|
516
|
+
if (!productNo)
|
|
517
|
+
throw Error("productNo should exist");
|
|
518
|
+
const productCategories = (await fetchProductInfo(productNo)).category.map((el) => el.category_no);
|
|
519
|
+
const productPrimaryCategory = getPrimaryCategory(productCategories);
|
|
520
|
+
// CartAdd Mutation Observer
|
|
521
|
+
const cartAddMutationObserver = getCartAddMutationObserver(deviceType);
|
|
522
|
+
cartAddMutationObserver.observe(document.body, {
|
|
523
|
+
subtree: true,
|
|
524
|
+
childList: true,
|
|
525
|
+
});
|
|
526
|
+
// Fetch Related Items Recommendations
|
|
527
|
+
const sameCategoryRec = await bluxClient.getItemRelatedRec(new ItemRelatedRec({
|
|
528
|
+
call_type: PRODUCT_DETAIL_PAGE_HOODY_CALL_TYPE,
|
|
529
|
+
item_id: productNo,
|
|
530
|
+
limit: 14,
|
|
531
|
+
}));
|
|
532
|
+
const sameCategoryRecProdNos = sameCategoryRec.item_ids;
|
|
533
|
+
const sameCategoryRecProdInfo = await getProductsInfo(sameCategoryRecProdNos);
|
|
534
|
+
const sameCategoryRecId = sameCategoryRec.recommendation_id; // web-sdk 버전 1.2.0 초과로 올리면 assert 제거 가능
|
|
535
|
+
const otherCategoryRec = await bluxClient.getItemRelatedRec(new ItemRelatedRec({
|
|
536
|
+
call_type: productPrimaryCategory === "clothing"
|
|
537
|
+
? PRODUCT_DETAIL_PAGE_ACCESSORY_CALL_TYPE
|
|
538
|
+
: PRODUCT_DETAIL_PAGE_CLOTHING_CALL_TYPE,
|
|
539
|
+
item_id: productNo,
|
|
540
|
+
limit: 14,
|
|
541
|
+
}));
|
|
542
|
+
const otherCategoryRecProdNos = otherCategoryRec.item_ids;
|
|
543
|
+
const otherCategoryRecProdInfo = await getProductsInfo(otherCategoryRecProdNos);
|
|
544
|
+
const otherCategoryRecId = otherCategoryRec.recommendation_id; // web-sdk 버전 1.2.0 초과로 올리면 assert 제거 가능
|
|
545
|
+
const pdpRecPosition = document.getElementById("prdReview")?.nextSibling;
|
|
546
|
+
if (!pdpRecPosition?.parentNode)
|
|
547
|
+
throw Error("pdpRecPosition.parentNode should exist");
|
|
548
|
+
if (deviceType === "pc") {
|
|
549
|
+
pdpRecPosition.parentNode.insertBefore(getPcCarouselTemplate(sameCategoryRecProdInfo, sameCategoryRecId, otherCategoryRecProdInfo, otherCategoryRecId), pdpRecPosition);
|
|
550
|
+
let currentIndex = 0;
|
|
551
|
+
const bluxContainer = document.getElementById("blux-container");
|
|
552
|
+
const items = document.querySelectorAll(".blux-carousel-item");
|
|
553
|
+
const itemWidth = items[0].offsetWidth +
|
|
554
|
+
parseInt(window.getComputedStyle(items[0]).marginRight);
|
|
555
|
+
const bluxCarousel = document.getElementById("blux-carousel");
|
|
556
|
+
const bluxPrevButton = document.getElementById("blux-prevButton");
|
|
557
|
+
const bluxNextButton = document.getElementById("blux-nextButton");
|
|
558
|
+
if (!bluxContainer || !bluxCarousel || !bluxPrevButton || !bluxNextButton)
|
|
559
|
+
throw Error("bluxContainer, bluxCarousel, bluxPrevButton, bluxNextButton should exist");
|
|
560
|
+
bluxPrevButton.addEventListener("click", () => {
|
|
561
|
+
bluxNextButton.style.display = "flex";
|
|
562
|
+
if (currentIndex > 0) {
|
|
563
|
+
currentIndex--;
|
|
564
|
+
bluxCarousel.style.transform = `translateX(-${currentIndex * itemWidth}px)`;
|
|
565
|
+
}
|
|
566
|
+
if (currentIndex === 0)
|
|
567
|
+
bluxPrevButton.style.display = "none";
|
|
568
|
+
});
|
|
569
|
+
bluxNextButton.addEventListener("click", () => {
|
|
570
|
+
bluxPrevButton.style.display = "flex";
|
|
571
|
+
if (currentIndex <
|
|
572
|
+
bluxCarousel.childElementCount - PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW) {
|
|
573
|
+
currentIndex++;
|
|
574
|
+
bluxCarousel.style.transform = `translateX(-${currentIndex * itemWidth}px)`;
|
|
575
|
+
}
|
|
576
|
+
if (currentIndex ===
|
|
577
|
+
bluxCarousel.childElementCount - PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW)
|
|
578
|
+
bluxNextButton.style.display = "none";
|
|
579
|
+
});
|
|
580
|
+
// [PC] "함께 보면 좋은 상품" 구좌 (Tab 구현)
|
|
581
|
+
let currentIndex2 = 0;
|
|
582
|
+
const bluxContainer2 = document.getElementById("blux-container2");
|
|
583
|
+
const items2 = document.querySelectorAll(".blux-carousel-item");
|
|
584
|
+
const itemWidth2 = items2[0].offsetWidth +
|
|
585
|
+
parseInt(window.getComputedStyle(items2[0]).marginRight);
|
|
586
|
+
const bluxCarousel2 = document.getElementById("blux-carousel2");
|
|
587
|
+
const bluxPrevButton2 = document.getElementById("blux-prevButton2");
|
|
588
|
+
const bluxNextButton2 = document.getElementById("blux-nextButton2");
|
|
589
|
+
if (!bluxContainer2 ||
|
|
590
|
+
!bluxCarousel2 ||
|
|
591
|
+
!bluxPrevButton2 ||
|
|
592
|
+
!bluxNextButton2)
|
|
593
|
+
throw Error("bluxContainer2, bluxCarousel2, bluxPrevButton2, bluxNextButton2 should exist");
|
|
594
|
+
bluxPrevButton2.addEventListener("click", () => {
|
|
595
|
+
bluxNextButton2.style.display = "flex";
|
|
596
|
+
if (currentIndex2 > 0) {
|
|
597
|
+
currentIndex2--;
|
|
598
|
+
bluxCarousel2.style.transform = `translateX(-${currentIndex2 * itemWidth2}px)`;
|
|
599
|
+
}
|
|
600
|
+
if (currentIndex2 === 0)
|
|
601
|
+
bluxPrevButton2.style.display = "none";
|
|
602
|
+
});
|
|
603
|
+
bluxNextButton2.addEventListener("click", () => {
|
|
604
|
+
bluxPrevButton2.style.display = "flex";
|
|
605
|
+
if (currentIndex2 <
|
|
606
|
+
bluxCarousel2.childElementCount - PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW) {
|
|
607
|
+
currentIndex2++;
|
|
608
|
+
bluxCarousel2.style.transform = `translateX(-${currentIndex2 * itemWidth2}px)`;
|
|
609
|
+
}
|
|
610
|
+
if (currentIndex2 ===
|
|
611
|
+
bluxCarousel2.childElementCount - PRODUCT_DETAIL_PAGE_ITEMS_TO_SHOW)
|
|
612
|
+
bluxNextButton2.style.display = "none";
|
|
613
|
+
});
|
|
614
|
+
// 구좌 Tab 전환
|
|
615
|
+
const bluxTab1Button = document.getElementById("blux-tab1-button");
|
|
616
|
+
const bluxTab2Button = document.getElementById("blux-tab2-button");
|
|
617
|
+
if (!bluxTab1Button || !bluxTab2Button)
|
|
618
|
+
throw Error("bluxTab1Button, bluxTab2Button should exist");
|
|
619
|
+
bluxTab1Button.addEventListener("click", () => {
|
|
620
|
+
bluxContainer.style.display = "block";
|
|
621
|
+
bluxContainer2.style.display = "none";
|
|
622
|
+
bluxTab1Button.style.color = "black";
|
|
623
|
+
bluxTab2Button.style.color = "#999999";
|
|
624
|
+
});
|
|
625
|
+
bluxTab2Button.addEventListener("click", () => {
|
|
626
|
+
bluxContainer.style.display = "none";
|
|
627
|
+
bluxContainer2.style.display = "block";
|
|
628
|
+
bluxTab1Button.style.color = "#999999";
|
|
629
|
+
bluxTab2Button.style.color = "black";
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
else if (deviceType === "mobile") {
|
|
633
|
+
pdpRecPosition.parentNode.insertBefore(getMobileSlideTemplate(SAME_CATEGORY_TITLE, sameCategoryRecProdInfo, SAME_CATEGORY_FROM, sameCategoryRecId), pdpRecPosition);
|
|
634
|
+
// [Mobile] "함께 보면 좋은 상품" 구좌
|
|
635
|
+
pdpRecPosition.parentNode.insertBefore(getMobileSlideTemplate(OTHER_CATEGORY_TITLE, otherCategoryRecProdInfo, OTHER_CATEGORY_FROM, otherCategoryRecId), pdpRecPosition);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
else if (isCategoryPage) {
|
|
639
|
+
// 카테고리 페이지
|
|
640
|
+
const bluxCategoryRecRejectTimestamp = sessionStorage.getItem(SESSION_STORAGE_BLUX_CATEGORY_REC_REJECT_TIMESTAMP_KEY);
|
|
641
|
+
const bluxEnterPdpFromCategoryPage = sessionStorage.getItem(SESSION_STORAGE_BLUX_ENTER_PDP_FROM_CATEGORY_PAGE_KEY);
|
|
642
|
+
if (bluxEnterPdpFromCategoryPage === "true" && // 카테고리 페이지 -> 상품 상세 페이지 -> 카테고리 페이지 와 같이 탐색한 경우 그리고
|
|
643
|
+
(!bluxCategoryRecRejectTimestamp || // "하루 동안 닫기" 버튼을 누르지 않은 경우 또는
|
|
644
|
+
getTimestampDiff(bluxCategoryRecRejectTimestamp) > ONE_DAY_IN_SECONDS) // "하루 동안 닫기" 버튼을 누르고 24시간이 지난 경우에만 카테고리 페이지 추천 구좌 노출
|
|
645
|
+
) {
|
|
646
|
+
const ulElement = document.querySelector("ul.prdNeo.grid2");
|
|
647
|
+
// CSS 수정 (추천 구좌 노출 시 기존 상품 목록의 width가 변경되는 것을 방지)
|
|
648
|
+
ulElement.style.width = "100%";
|
|
649
|
+
// 현재 카테고리 페이지에 노출된 상품들의 productNo 목록 추출
|
|
650
|
+
const displayedProductNos = Array.from(ulElement.querySelectorAll("li"))
|
|
651
|
+
.map((li) => {
|
|
652
|
+
return li.id.startsWith("anchorBoxId_")
|
|
653
|
+
? li.id.split("anchorBoxId_")[1]
|
|
654
|
+
: null;
|
|
655
|
+
})
|
|
656
|
+
.filter((id) => id !== null); // null 값은 제외
|
|
657
|
+
// sessionStorage에서 최근 본 상품 ID 불러오기
|
|
658
|
+
const recentlyClickedProductNoFromCategoryPage = sessionStorage.getItem(SESSION_STORAGE_BLUX_RECENTLY_CLICKED_ITEM_ID_FROM_CATEGORY_PAGE_KEY);
|
|
659
|
+
// 0, 1 -> 1
|
|
660
|
+
// 2, 3 -> 3
|
|
661
|
+
const recPosition = Math.floor(displayedProductNos.indexOf(recentlyClickedProductNoFromCategoryPage) / 2) *
|
|
662
|
+
2 +
|
|
663
|
+
1;
|
|
664
|
+
// 1 -> 0, 1, 2, 3
|
|
665
|
+
// 3 -> 2, 3, 4, 5
|
|
666
|
+
const neighborProductNos = displayedProductNos.slice(recPosition - 1, recPosition + 3);
|
|
667
|
+
// 최근 본 상품이 현재 카테고리 페이지에 노출된 상품인지 확인
|
|
668
|
+
if (recentlyClickedProductNoFromCategoryPage &&
|
|
669
|
+
displayedProductNos.includes(recentlyClickedProductNoFromCategoryPage)) {
|
|
670
|
+
// 최근 본 상품에 대한 연관 추천 상품 요청
|
|
671
|
+
const categoryPageRec = await bluxClient.getItemRelatedRec(new ItemRelatedRec({
|
|
672
|
+
call_type: CATEGORY_PAGE_CALL_TYPE,
|
|
673
|
+
item_id: recentlyClickedProductNoFromCategoryPage,
|
|
674
|
+
limit: CATEGORY_PAGE_ITEMS_TO_SHOW * 2,
|
|
675
|
+
}));
|
|
676
|
+
// 추천 상품에서 구좌 근방의 상품 제외
|
|
677
|
+
const categoryPageRecProdNos = categoryPageRec.item_ids.filter((item_id) => !neighborProductNos.includes(item_id));
|
|
678
|
+
const categoryPageRecProdInfo = await getProductsInfo(categoryPageRecProdNos);
|
|
679
|
+
const categoryPageRecId = categoryPageRec.recommendation_id; // web-sdk 버전 1.2.0 초과로 올리면 assert 제거 가능
|
|
680
|
+
// DOM에 추천 구좌 추가
|
|
681
|
+
document
|
|
682
|
+
.getElementById(`anchorBoxId_${displayedProductNos[recPosition]}`)
|
|
683
|
+
?.insertAdjacentElement("afterend", getMobileCategoryPageSlideTemplate(categoryPageRecProdInfo, categoryPageRecId));
|
|
684
|
+
const bluxMobileCategoryPageSlide = document.querySelector(".blux-mobile-category-page-slide");
|
|
685
|
+
const recentlyClickedProductFromCategoryPage = document.getElementById(`anchorBoxId_${recentlyClickedProductNoFromCategoryPage}`);
|
|
686
|
+
// "하루 동안 닫기" 버튼 처리
|
|
687
|
+
const closeButton = document.getElementById("blux-mobile-category-page-slide-close-button");
|
|
688
|
+
if (!closeButton)
|
|
689
|
+
throw Error("closeButton should exist");
|
|
690
|
+
closeButton.addEventListener("click", () => {
|
|
691
|
+
if (!bluxMobileCategoryPageSlide)
|
|
692
|
+
throw Error("bluxMobileCategoryPageSlide should exist");
|
|
693
|
+
bluxMobileCategoryPageSlide.remove();
|
|
694
|
+
sessionStorage.setItem(SESSION_STORAGE_BLUX_CATEGORY_REC_REJECT_TIMESTAMP_KEY, Date.now().toFixed());
|
|
695
|
+
});
|
|
696
|
+
window.addEventListener("scroll", function onScroll() {
|
|
697
|
+
if (recentlyClickedProductFromCategoryPage.getBoundingClientRect()
|
|
698
|
+
.top <= 55) {
|
|
699
|
+
// 최근 본 상품이 뷰의 상단에 위치하면 추천 구좌 노출
|
|
700
|
+
setTimeout(() => {
|
|
701
|
+
bluxMobileCategoryPageSlide.style.maxHeight = "100vh";
|
|
702
|
+
}, 100);
|
|
703
|
+
// 이벤트 핸들러 제거 (한 번만 실행하고 싶다면)
|
|
704
|
+
window.removeEventListener("scroll", onScroll);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
// 최근 본 상품이 뷰의 상단에 위치하도록 스크롤
|
|
708
|
+
window.scrollTo({
|
|
709
|
+
top: recentlyClickedProductFromCategoryPage.offsetTop + 55, // 55px은 카테고리 페이지의 상단 메뉴 높이
|
|
710
|
+
behavior: "smooth", // 부드러운 스크롤 효과
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
const setScreenSize = function () {
|
|
717
|
+
let vh = window.innerHeight * 0.01;
|
|
718
|
+
document.documentElement.style.setProperty("--vh", `${vh}px`);
|
|
719
|
+
let vw = window.innerWidth * 0.01;
|
|
720
|
+
document.documentElement.style.setProperty("--vw", `${vw}px`);
|
|
721
|
+
};
|
|
722
|
+
async function main() {
|
|
723
|
+
// const { member_id: user_id } = await getCustomerIDInfo();
|
|
724
|
+
// if (user_id !== "3394512358@k") return;
|
|
725
|
+
if (document.readyState == "complete") {
|
|
726
|
+
window.addEventListener("resize", setScreenSize);
|
|
727
|
+
makeRecSections();
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
window.addEventListener("load", () => makeRecSections());
|
|
731
|
+
}
|
|
732
|
+
collectEvents();
|
|
733
|
+
}
|
|
734
|
+
main();
|