pb-sxp-ui 1.20.26 → 1.20.28
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/dist/index.cjs +466 -396
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +355 -291
- package/dist/index.js +466 -396
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +6 -6
- package/dist/index.min.cjs.map +1 -1
- package/dist/index.min.js +6 -6
- package/dist/index.min.js.map +1 -1
- package/dist/pb-ui.js +466 -396
- package/dist/pb-ui.js.map +1 -1
- package/dist/pb-ui.min.js +6 -6
- package/dist/pb-ui.min.js.map +1 -1
- package/es/core/components/StructurePage/index.d.ts +4 -0
- package/es/core/components/StructurePage/index.js +8 -1
- package/es/core/components/SxpPageRender/Modal/index.d.ts +1 -0
- package/es/core/components/SxpPageRender/Modal/index.js +3 -3
- package/es/core/components/SxpPageRender/index.d.ts +1 -0
- package/es/core/components/SxpPageRender/typing.d.ts +1 -0
- package/es/core/index.d.ts +6 -0
- package/es/core/index.js +10 -0
- package/es/materials/sxp/popup/AddToCart/index.d.ts +1 -27
- package/es/materials/sxp/popup/AddToCart/index.js +117 -173
- package/es/materials/sxp/popup/AddToCart/index.new.d.ts +8 -0
- package/es/materials/sxp/popup/AddToCart/index.new.js +174 -0
- package/es/materials/sxp/popup/AddToCart/index.old.d.ts +33 -0
- package/es/materials/sxp/popup/AddToCart/index.old.js +299 -0
- package/es/materials/sxp/popup/AddToCart/material.js +1 -54
- package/es/materials/sxp/popup/CommodityDetailDiroNew/index.js +48 -53
- package/lib/core/components/StructurePage/index.d.ts +4 -0
- package/lib/core/components/StructurePage/index.js +8 -1
- package/lib/core/components/SxpPageRender/Modal/index.d.ts +1 -0
- package/lib/core/components/SxpPageRender/Modal/index.js +3 -3
- package/lib/core/components/SxpPageRender/index.d.ts +1 -0
- package/lib/core/components/SxpPageRender/typing.d.ts +1 -0
- package/lib/core/index.d.ts +6 -0
- package/lib/core/index.js +10 -5
- package/lib/materials/sxp/popup/AddToCart/index.d.ts +1 -27
- package/lib/materials/sxp/popup/AddToCart/index.js +115 -171
- package/lib/materials/sxp/popup/AddToCart/index.new.d.ts +8 -0
- package/lib/materials/sxp/popup/AddToCart/index.new.js +176 -0
- package/lib/materials/sxp/popup/AddToCart/index.old.d.ts +33 -0
- package/lib/materials/sxp/popup/AddToCart/index.old.js +301 -0
- package/lib/materials/sxp/popup/AddToCart/material.js +1 -54
- package/lib/materials/sxp/popup/CommodityDetailDiroNew/index.js +48 -53
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -187,6 +187,14 @@ function uuid(len, radix) {
|
|
|
187
187
|
}
|
|
188
188
|
return uuid.join('');
|
|
189
189
|
}
|
|
190
|
+
const getIndexByblockType = (type, index) => {
|
|
191
|
+
if (type === 'CommodityCarouselBlock' || type === 'CopyBlock') {
|
|
192
|
+
return 'initial';
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
return index;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
190
198
|
const generateRandomString = (length) => {
|
|
191
199
|
let result = '';
|
|
192
200
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
@@ -246,6 +254,70 @@ const setFontForText = (textContent, style) => {
|
|
|
246
254
|
}
|
|
247
255
|
return content;
|
|
248
256
|
};
|
|
257
|
+
function getBrowserInfo() {
|
|
258
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
259
|
+
const userAgent = self.navigator.userAgent;
|
|
260
|
+
if (!userAgent)
|
|
261
|
+
return null;
|
|
262
|
+
if (/edge\/([\d\.]+)/i.exec(userAgent))
|
|
263
|
+
return `Edge ${(_a = /edge\/([\d\.]+)/i.exec(userAgent)) === null || _a === void 0 ? void 0 : _a[1]}`;
|
|
264
|
+
if (/edg\/([\d\.]+)/i.exec(userAgent))
|
|
265
|
+
return `Edge(Chromium) ${(_b = /edge\/([\d\.]+)/i.exec(userAgent)) === null || _b === void 0 ? void 0 : _b[1]}`;
|
|
266
|
+
if (/msie/i.test(userAgent))
|
|
267
|
+
return `Internet Explorer ${(_c = /msie ([\d\.]+)/i.exec(userAgent)) === null || _c === void 0 ? void 0 : _c[1]}`;
|
|
268
|
+
if (/Trident/i.test(userAgent))
|
|
269
|
+
return `Internet Explorer ${(_d = /rv:([\d\.]+)/i.exec(userAgent)) === null || _d === void 0 ? void 0 : _d[1]}`;
|
|
270
|
+
if (/chrome/i.test(userAgent))
|
|
271
|
+
return `Chrome ${(_e = /chrome\/([\d\.]+)/i.exec(userAgent)) === null || _e === void 0 ? void 0 : _e[1]}`;
|
|
272
|
+
if (/firefox/i.test(userAgent))
|
|
273
|
+
return `Firefox ${(_f = /firefox\/([\d\.]+)/i.exec(userAgent)) === null || _f === void 0 ? void 0 : _f[1]}`;
|
|
274
|
+
if (/safari/i.test(userAgent))
|
|
275
|
+
return `Safari ${(_g = /version\/([\d\.]+)/i.exec(userAgent)) === null || _g === void 0 ? void 0 : _g[1]}`;
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
function getSystem() {
|
|
279
|
+
var _a, _b, _c;
|
|
280
|
+
const userAgent = self.navigator.userAgent;
|
|
281
|
+
if (!userAgent)
|
|
282
|
+
return null;
|
|
283
|
+
if (/iphone/i.test(userAgent))
|
|
284
|
+
return `IOS ${(_a = userAgent.match(/OS\s(.*?)\slike/)) === null || _a === void 0 ? void 0 : _a[1]}`;
|
|
285
|
+
if (/android/i.test(userAgent))
|
|
286
|
+
return `Android ${(_b = userAgent.match(/Android\s(.*?)\;/)) === null || _b === void 0 ? void 0 : _b[1]}`;
|
|
287
|
+
if (/windows/i.test(userAgent))
|
|
288
|
+
return `Windows ${(_c = userAgent.match(/Windows\s(.*?)\;/)) === null || _c === void 0 ? void 0 : _c[1]}`;
|
|
289
|
+
if (/mac/i.test(userAgent))
|
|
290
|
+
return 'Mac OS';
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
function getDevice$1() {
|
|
294
|
+
const userAgent = self.navigator.userAgent;
|
|
295
|
+
if (!userAgent)
|
|
296
|
+
return null;
|
|
297
|
+
if (/iphone/i.test(userAgent))
|
|
298
|
+
return 'iPhone';
|
|
299
|
+
if (/android/i.test(userAgent)) {
|
|
300
|
+
// var index1 = userAgent.indexOf(';');
|
|
301
|
+
// var index2 = userAgent.indexOf(';', index1 + 1);
|
|
302
|
+
// var index3 = userAgent.indexOf(';', index2 + 1);
|
|
303
|
+
// var index4 = userAgent.indexOf(';', index3 + 1);
|
|
304
|
+
// if (index2 !== -1 && index3 !== -1) {
|
|
305
|
+
// var value1 = userAgent.substring(index3 + 1, index4);
|
|
306
|
+
// return `${value1}`;
|
|
307
|
+
// }
|
|
308
|
+
const index1 = userAgent.indexOf('(');
|
|
309
|
+
const index2 = userAgent.indexOf(')');
|
|
310
|
+
if (index1 !== -1 && index2 !== -1) {
|
|
311
|
+
const value = userAgent.substring(index1 + 1, index2);
|
|
312
|
+
return `${value}`;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (/windows/i.test(userAgent))
|
|
316
|
+
return 'Windows';
|
|
317
|
+
if (/mac/i.test(userAgent))
|
|
318
|
+
return 'Mac';
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
249
321
|
function getCookie(val) {
|
|
250
322
|
// const expirationDate = new Date();
|
|
251
323
|
// expirationDate.setDate(expirationDate.getDate() + 100);
|
|
@@ -307,6 +379,33 @@ function deleteCookie(name, path = '/', domain = '') {
|
|
|
307
379
|
document.cookie = `${name}=; ${expiration}${pathPart}${domainPart}`;
|
|
308
380
|
console.log(`已尝试删除Cookie: ${name}`);
|
|
309
381
|
}
|
|
382
|
+
function setCookie(name, value, days = 0, path = '/', domain = '', secure = false, sameSite = 'Lax') {
|
|
383
|
+
let cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
384
|
+
// 设置过期时间
|
|
385
|
+
if (days) {
|
|
386
|
+
const date = new Date();
|
|
387
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
388
|
+
cookieString += `; expires=${date.toUTCString()}`;
|
|
389
|
+
}
|
|
390
|
+
// 设置路径
|
|
391
|
+
if (path) {
|
|
392
|
+
cookieString += `; path=${path}`;
|
|
393
|
+
}
|
|
394
|
+
// 设置域名
|
|
395
|
+
if (domain) {
|
|
396
|
+
cookieString += `; domain=${domain}`;
|
|
397
|
+
}
|
|
398
|
+
// 设置Secure标志
|
|
399
|
+
if (secure) {
|
|
400
|
+
cookieString += '; secure';
|
|
401
|
+
}
|
|
402
|
+
// 设置SameSite属性
|
|
403
|
+
if (sameSite) {
|
|
404
|
+
cookieString += `; samesite=${sameSite}`;
|
|
405
|
+
}
|
|
406
|
+
// 设置Cookie
|
|
407
|
+
document.cookie = cookieString;
|
|
408
|
+
}
|
|
310
409
|
function getUrlParamByKey(key) {
|
|
311
410
|
var _a, _b;
|
|
312
411
|
const queryString = location.search.slice(1);
|
|
@@ -322,6 +421,24 @@ function getUrlParamByKey(key) {
|
|
|
322
421
|
return (_b = params[key]) !== null && _b !== void 0 ? _b : '';
|
|
323
422
|
}
|
|
324
423
|
|
|
424
|
+
var tool = /*#__PURE__*/Object.freeze({
|
|
425
|
+
__proto__: null,
|
|
426
|
+
deleteCookie: deleteCookie,
|
|
427
|
+
generateRandomString: generateRandomString,
|
|
428
|
+
getBrowserInfo: getBrowserInfo,
|
|
429
|
+
getCookie: getCookie,
|
|
430
|
+
getDevice: getDevice$1,
|
|
431
|
+
getIndexByblockType: getIndexByblockType,
|
|
432
|
+
getScreenReader: getScreenReader,
|
|
433
|
+
getSystem: getSystem,
|
|
434
|
+
getUid: getUid,
|
|
435
|
+
getUrlParamByKey: getUrlParamByKey,
|
|
436
|
+
setCookie: setCookie,
|
|
437
|
+
setFontForText: setFontForText,
|
|
438
|
+
splitUrlParams: splitUrlParams,
|
|
439
|
+
uuid: uuid
|
|
440
|
+
});
|
|
441
|
+
|
|
325
442
|
function unzip(b64Data) {
|
|
326
443
|
const strData = atob(b64Data);
|
|
327
444
|
const charData = strData.split('').map(function (x) {
|
|
@@ -506,6 +623,18 @@ const refreshFeSessionId = () => {
|
|
|
506
623
|
const getFeSessionId = () => {
|
|
507
624
|
return window.localStorage.getItem(feRealSessionIdKey);
|
|
508
625
|
};
|
|
626
|
+
// 删除sessionID
|
|
627
|
+
const removeFeSessionId = () => {
|
|
628
|
+
window.localStorage.removeItem(feRealSessionIdKey);
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
var sessionStore = /*#__PURE__*/Object.freeze({
|
|
632
|
+
__proto__: null,
|
|
633
|
+
getFeSessionId: getFeSessionId,
|
|
634
|
+
refreshFeSessionId: refreshFeSessionId,
|
|
635
|
+
removeFeSessionId: removeFeSessionId,
|
|
636
|
+
storeAndLoadFeSessionId: storeAndLoadFeSessionId
|
|
637
|
+
});
|
|
509
638
|
|
|
510
639
|
/*
|
|
511
640
|
* @Author: binruan@chatlabs.com
|
|
@@ -529,6 +658,9 @@ const storeAndLoadFeUserId = () => {
|
|
|
529
658
|
}
|
|
530
659
|
return fakeUserId;
|
|
531
660
|
};
|
|
661
|
+
const removeFeUserId = () => {
|
|
662
|
+
window.localStorage.removeItem(FAKE_USER_KEY);
|
|
663
|
+
};
|
|
532
664
|
const getFeUserState = () => {
|
|
533
665
|
const fakeUserState = window.localStorage.getItem(FAKE_USER_STATE);
|
|
534
666
|
if (lodash.isEmpty(fakeUserState)) {
|
|
@@ -558,6 +690,24 @@ const setUserConsentResult = () => {
|
|
|
558
690
|
window.localStorage.setItem(USER_CONSENT_RESULT_KEY, 'true');
|
|
559
691
|
};
|
|
560
692
|
|
|
693
|
+
var localStore = /*#__PURE__*/Object.freeze({
|
|
694
|
+
__proto__: null,
|
|
695
|
+
AGREE_POLICY: AGREE_POLICY,
|
|
696
|
+
CCONTSENT_STATE: CCONTSENT_STATE,
|
|
697
|
+
FAKE_USER_KEY: FAKE_USER_KEY,
|
|
698
|
+
FAKE_USER_STATE: FAKE_USER_STATE,
|
|
699
|
+
SLIDE_SKIP_STATE: SLIDE_SKIP_STATE,
|
|
700
|
+
USER_CONSENT_RESULT_KEY: USER_CONSENT_RESULT_KEY,
|
|
701
|
+
getContsentState: getContsentState,
|
|
702
|
+
getFeUserState: getFeUserState,
|
|
703
|
+
getSlideSkipState: getSlideSkipState,
|
|
704
|
+
getUserConsentResult: getUserConsentResult,
|
|
705
|
+
removeFeUserId: removeFeUserId,
|
|
706
|
+
setSlideSkipState: setSlideSkipState,
|
|
707
|
+
setUserConsentResult: setUserConsentResult,
|
|
708
|
+
storeAndLoadFeUserId: storeAndLoadFeUserId
|
|
709
|
+
});
|
|
710
|
+
|
|
561
711
|
/*
|
|
562
712
|
* @Author: binruan@chatlabs.com
|
|
563
713
|
* @Date: 2024-03-20 10:27:31
|
|
@@ -1766,6 +1916,23 @@ var DATA_TYPE;
|
|
|
1766
1916
|
DATA_TYPE["ARRAY_NUMBER"] = "array-number";
|
|
1767
1917
|
})(DATA_TYPE || (DATA_TYPE = {}));
|
|
1768
1918
|
|
|
1919
|
+
/*
|
|
1920
|
+
* @Author: binruan@chatlabs.com
|
|
1921
|
+
* @Date: 2024-03-20 10:27:31
|
|
1922
|
+
* @LastEditors: binruan@chatlabs.com
|
|
1923
|
+
* @LastEditTime: 2024-03-20 13:56:49
|
|
1924
|
+
* @FilePath: \pb-sxp-ui\src\core\hooks\index.ts
|
|
1925
|
+
*
|
|
1926
|
+
*/
|
|
1927
|
+
|
|
1928
|
+
var index$4 = /*#__PURE__*/Object.freeze({
|
|
1929
|
+
__proto__: null,
|
|
1930
|
+
get DATA_TYPE () { return DATA_TYPE; },
|
|
1931
|
+
useDataSource: useDataSource,
|
|
1932
|
+
useEditor: useEditor,
|
|
1933
|
+
useSxpDataSource: useSxpDataSource
|
|
1934
|
+
});
|
|
1935
|
+
|
|
1769
1936
|
const DataSourceContext = React.createContext({ $store: {}, options: [], configs: [] });
|
|
1770
1937
|
const DataSourceProvider = ({ children, isSsr, enable }) => {
|
|
1771
1938
|
const [options, setOptions] = React.useState([]);
|
|
@@ -10545,7 +10712,7 @@ function useVisibleHeight() {
|
|
|
10545
10712
|
*
|
|
10546
10713
|
*/
|
|
10547
10714
|
const closeIcon$1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAjhJREFUWEfFlztOw0AQhmeWiJ4CCmpQ5DiRQsIJyAWg5A0lR0AIChDiCJS8ER0cADgBeRSxt4CCDgkaKiq8i+zYeWx2413HEWmiJJv9v535Z2aN8M8vFPT9z3zETD0aAUChUJjwvPFHAJhBhB3Hqd6OAsK2yyucwykAvP38eJX398Z3AJDLlVYR8ToU9Rhj25TWr9KEsKy5dULIGQCMtfZly45TvwsAstm56UwG6wA4FUFwzrdctxZBDcWSy5XWEPG8I84/GcMipdWPtgcsaz5PCHtKG0IuTiqUvjT9U/WYMG2IOPE+AP+LtCB0xKUAAyA2Xbd2o2OG0NQXvTnvhL17D7EPtH9TRCIWwkRcGYGIQgYBABuqPuHXOQBc6pw80lBGwBQiiXhsBHQhkoprA6iM6acjhDQKu5YJZW6XeOI3XJdpvfsdTu52VfXEekD8owQiXGIubpSCbhDbLu8DwKEAd+A41SOdPpE4BS0viFOtvV2iKWqUgn5x/tmS70xR01GuDSCKc86/OCcLgTyyZ0ScDGNhFAktAJV4NFJ9YyaFiAWIE+9uVkkgBgLoig8DMWAa9ro9ynkUdlW5maZDCmB6clmz0k1HH4Cs1Ezbq2p2yEpUuBOKTSZZex00RUWIrltxuuK6EOGDSbGIOPZicpMx6fny650377qNRgBgWeVFQuA+6UjVgREhGIMlSqsPUQqIbZdOOIdZQmCv2axRnU1N1+TzJYsxOEaEV8ep7frPZ7Gd0FTEdP0ft0/kMNdg0eoAAAAASUVORK5CYII=';
|
|
10548
|
-
const Modal = ({ visible, onClose, children, modalStyle, padding, popup, schema, fullHeight, isFullScreen = false, openState }) => {
|
|
10715
|
+
const Modal = ({ visible, onClose, children, modalStyle, padding, popup, schema, fullHeight, isFullScreen = false, openState, showCloseButton = true }) => {
|
|
10549
10716
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
10550
10717
|
const { visibleHeight, bottomHeight } = useVisibleHeight();
|
|
10551
10718
|
const touchRef = React.useRef(null);
|
|
@@ -10725,8 +10892,8 @@ const Modal = ({ visible, onClose, children, modalStyle, padding, popup, schema,
|
|
|
10725
10892
|
setScrollTop(15 - ((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.scrollTop));
|
|
10726
10893
|
}
|
|
10727
10894
|
})), child()),
|
|
10728
|
-
React.createElement("button", { className: 'modal-icon-wrapper', role: 'button', "aria-label": 'close button', onClick: onClose, style: { top: scrollTop } },
|
|
10729
|
-
React.createElement("img", { src: (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.popupCloseIcon) || closeIcon$1, alt: 'close button', className: 'modal-icon' }))))))), modalEleRef.current);
|
|
10895
|
+
showCloseButton && (React.createElement("button", { className: 'modal-icon-wrapper', role: 'button', "aria-label": 'close button', onClick: onClose, style: { top: scrollTop } },
|
|
10896
|
+
React.createElement("img", { src: (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.popupCloseIcon) || closeIcon$1, alt: 'close button', className: 'modal-icon' })))))))), modalEleRef.current);
|
|
10730
10897
|
};
|
|
10731
10898
|
var Modal$1 = React.memo(Modal);
|
|
10732
10899
|
|
|
@@ -11914,18 +12081,248 @@ var settingRender$d = [
|
|
|
11914
12081
|
}
|
|
11915
12082
|
];
|
|
11916
12083
|
|
|
12084
|
+
const AddToCartPopup$1 = ({ isActive = true }) => {
|
|
12085
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
12086
|
+
const { popupDetailData, globalConfig } = useSxpDataSource();
|
|
12087
|
+
const [productData, setProductData] = React.useState(null);
|
|
12088
|
+
const [selectedOptions, setSelectedOptions] = React.useState({});
|
|
12089
|
+
const [selectedVariant, setSelectedVariant] = React.useState(null);
|
|
12090
|
+
const [quantity, setQuantity] = React.useState(1);
|
|
12091
|
+
const [loading, setLoading] = React.useState(true);
|
|
12092
|
+
const [error, setError] = React.useState(null);
|
|
12093
|
+
const [showImagePreview, setShowImagePreview] = React.useState(false);
|
|
12094
|
+
const [previewImageUrl, setPreviewImageUrl] = React.useState('');
|
|
12095
|
+
// 获取商品数据
|
|
12096
|
+
const data = popupDetailData;
|
|
12097
|
+
const product = (_e = (_b = (_a = data === null || data === void 0 ? void 0 : data.video) === null || _a === void 0 ? void 0 : _a.bindProduct) !== null && _b !== void 0 ? _b : (_d = (_c = data === null || data === void 0 ? void 0 : data.video) === null || _c === void 0 ? void 0 : _c.bindProducts) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : data === null || data === void 0 ? void 0 : data.product;
|
|
12098
|
+
// Shopify 配置
|
|
12099
|
+
const shopifyConfig = window.__SHOPIFY_CONFIG__;
|
|
12100
|
+
const shopifyDomain = ((_f = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopify) === null || _f === void 0 ? void 0 : _f.domain) || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopifyDomain) || (shopifyConfig === null || shopifyConfig === void 0 ? void 0 : shopifyConfig.domain) || 'dev-store-749237498237498636.myshopify.com';
|
|
12101
|
+
const storefrontToken = ((_g = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopify) === null || _g === void 0 ? void 0 : _g.storefrontAccessToken) || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.storefrontAccessToken) || (shopifyConfig === null || shopifyConfig === void 0 ? void 0 : shopifyConfig.storefrontAccessToken) || '77d894c490f79430ce7bd0a7efdff6b7';
|
|
12102
|
+
const productId = (product === null || product === void 0 ? void 0 : product.shopifyId) || (product === null || product === void 0 ? void 0 : product.itemId) || '';
|
|
12103
|
+
// 查询 Shopify 商品数据
|
|
12104
|
+
const fetchProductData = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
12105
|
+
var _k;
|
|
12106
|
+
if (!productId || !shopifyDomain || !storefrontToken) {
|
|
12107
|
+
setLoading(false);
|
|
12108
|
+
return;
|
|
12109
|
+
}
|
|
12110
|
+
setLoading(true);
|
|
12111
|
+
setError(null);
|
|
12112
|
+
try {
|
|
12113
|
+
const query = `
|
|
12114
|
+
query getProduct($id: ID!) {
|
|
12115
|
+
product(id: $id) {
|
|
12116
|
+
id
|
|
12117
|
+
title
|
|
12118
|
+
images(first: 10) {
|
|
12119
|
+
edges {
|
|
12120
|
+
node {
|
|
12121
|
+
url
|
|
12122
|
+
}
|
|
12123
|
+
}
|
|
12124
|
+
}
|
|
12125
|
+
options {
|
|
12126
|
+
name
|
|
12127
|
+
values
|
|
12128
|
+
}
|
|
12129
|
+
variants(first: 100) {
|
|
12130
|
+
edges {
|
|
12131
|
+
node {
|
|
12132
|
+
id
|
|
12133
|
+
title
|
|
12134
|
+
availableForSale
|
|
12135
|
+
quantityAvailable
|
|
12136
|
+
price {
|
|
12137
|
+
amount
|
|
12138
|
+
currencyCode
|
|
12139
|
+
}
|
|
12140
|
+
image {
|
|
12141
|
+
url
|
|
12142
|
+
}
|
|
12143
|
+
selectedOptions {
|
|
12144
|
+
name
|
|
12145
|
+
value
|
|
12146
|
+
}
|
|
12147
|
+
}
|
|
12148
|
+
}
|
|
12149
|
+
}
|
|
12150
|
+
}
|
|
12151
|
+
}
|
|
12152
|
+
`;
|
|
12153
|
+
const fullProductId = productId.startsWith('gid://') ? productId : `gid://shopify/Product/${productId}`;
|
|
12154
|
+
const response = yield fetch(`https://${shopifyDomain}/api/2024-01/graphql.json`, {
|
|
12155
|
+
method: 'POST',
|
|
12156
|
+
headers: {
|
|
12157
|
+
'Content-Type': 'application/json',
|
|
12158
|
+
'X-Shopify-Storefront-Access-Token': storefrontToken
|
|
12159
|
+
},
|
|
12160
|
+
body: JSON.stringify({
|
|
12161
|
+
query,
|
|
12162
|
+
variables: { id: fullProductId }
|
|
12163
|
+
})
|
|
12164
|
+
});
|
|
12165
|
+
const result = yield response.json();
|
|
12166
|
+
if (result.errors) {
|
|
12167
|
+
throw new Error(result.errors[0].message);
|
|
12168
|
+
}
|
|
12169
|
+
console.log('[AddToCart] Shopify Product Data:', result.data.product);
|
|
12170
|
+
console.log('[AddToCart] Options:', (_k = result.data.product) === null || _k === void 0 ? void 0 : _k.options);
|
|
12171
|
+
setProductData(result.data.product);
|
|
12172
|
+
}
|
|
12173
|
+
catch (err) {
|
|
12174
|
+
setError(err instanceof Error ? err.message : 'Failed to load product');
|
|
12175
|
+
console.error('[AddToCartPopup] 加载失败:', err);
|
|
12176
|
+
}
|
|
12177
|
+
finally {
|
|
12178
|
+
setLoading(false);
|
|
12179
|
+
}
|
|
12180
|
+
}), [productId, shopifyDomain, storefrontToken]);
|
|
12181
|
+
React.useEffect(() => {
|
|
12182
|
+
if (isActive) {
|
|
12183
|
+
fetchProductData();
|
|
12184
|
+
}
|
|
12185
|
+
}, [isActive, fetchProductData]);
|
|
12186
|
+
// 根据选中的规格匹配 variant
|
|
12187
|
+
React.useEffect(() => {
|
|
12188
|
+
if (!productData)
|
|
12189
|
+
return;
|
|
12190
|
+
const variants = productData.variants.edges.map(edge => edge.node);
|
|
12191
|
+
const optionsCount = productData.options.length;
|
|
12192
|
+
const selectedCount = Object.keys(selectedOptions).length;
|
|
12193
|
+
if (selectedCount === 0 || selectedCount < optionsCount) {
|
|
12194
|
+
setSelectedVariant(null);
|
|
12195
|
+
return;
|
|
12196
|
+
}
|
|
12197
|
+
const matchedVariant = variants.find(variant => {
|
|
12198
|
+
return variant.selectedOptions.every(option => {
|
|
12199
|
+
return selectedOptions[option.name] === option.value;
|
|
12200
|
+
});
|
|
12201
|
+
});
|
|
12202
|
+
setSelectedVariant(matchedVariant || null);
|
|
12203
|
+
// 当 variant 改变时,如果有库存数量限制,确保数量不超过库存
|
|
12204
|
+
if ((matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.quantityAvailable) !== undefined && matchedVariant.quantityAvailable > 0) {
|
|
12205
|
+
setQuantity(prev => Math.min(prev, matchedVariant.quantityAvailable));
|
|
12206
|
+
}
|
|
12207
|
+
}, [selectedOptions, productData]);
|
|
12208
|
+
// 处理规格选择
|
|
12209
|
+
const handleOptionSelect = (optionName, value) => {
|
|
12210
|
+
setSelectedOptions(prev => (Object.assign(Object.assign({}, prev), { [optionName]: value })));
|
|
12211
|
+
};
|
|
12212
|
+
// 处理加购
|
|
12213
|
+
const handleAddToCart = () => {
|
|
12214
|
+
if (!selectedVariant) {
|
|
12215
|
+
alert('Please select all options');
|
|
12216
|
+
return;
|
|
12217
|
+
}
|
|
12218
|
+
// 提取 variant ID(去掉 gid://shopify/ProductVariant/ 前缀)
|
|
12219
|
+
const variantId = selectedVariant.id.replace('gid://shopify/ProductVariant/', '');
|
|
12220
|
+
console.log('[AddToCart] 添加到购物车:', {
|
|
12221
|
+
variantId,
|
|
12222
|
+
quantity,
|
|
12223
|
+
shopifyDomain,
|
|
12224
|
+
selectedVariant
|
|
12225
|
+
});
|
|
12226
|
+
// 使用 Shopify 的 /cart/add 接口,通过查询参数添加商品
|
|
12227
|
+
// 这种方式会跳转到购物车页面而不是结算页面
|
|
12228
|
+
const params = new URLSearchParams({
|
|
12229
|
+
id: variantId,
|
|
12230
|
+
quantity: quantity.toString()
|
|
12231
|
+
});
|
|
12232
|
+
const cartUrl = `https://${shopifyDomain}/cart/add?${params.toString()}`;
|
|
12233
|
+
console.log('[AddToCart] 跳转到购物车 URL:', cartUrl);
|
|
12234
|
+
window.location.href = cartUrl;
|
|
12235
|
+
};
|
|
12236
|
+
// 计算总价
|
|
12237
|
+
const totalPrice = selectedVariant
|
|
12238
|
+
? (parseFloat(selectedVariant.price.amount) * quantity).toFixed(2)
|
|
12239
|
+
: '0.00';
|
|
12240
|
+
if (loading) {
|
|
12241
|
+
return (React.createElement("div", { className: 'add-to-cart-popup' },
|
|
12242
|
+
React.createElement("div", { className: 'loading' }, "Loading...")));
|
|
12243
|
+
}
|
|
12244
|
+
if (error) {
|
|
12245
|
+
return (React.createElement("div", { className: 'add-to-cart-popup' },
|
|
12246
|
+
React.createElement("div", { className: 'error' }, error)));
|
|
12247
|
+
}
|
|
12248
|
+
if (!productData) {
|
|
12249
|
+
return null;
|
|
12250
|
+
}
|
|
12251
|
+
const mainImage = ((_h = productData.images.edges[0]) === null || _h === void 0 ? void 0 : _h.node.url) || '';
|
|
12252
|
+
const variantImage = ((_j = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.image) === null || _j === void 0 ? void 0 : _j.url) || mainImage;
|
|
12253
|
+
const maxQuantity = (selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) || 999; // 如果没有库存数据,默认允许最多 999
|
|
12254
|
+
return (React.createElement("div", { className: 'add-to-cart-popup' },
|
|
12255
|
+
React.createElement("div", { className: 'popup-content' },
|
|
12256
|
+
React.createElement("div", { className: 'product-header' },
|
|
12257
|
+
React.createElement("div", { className: 'product-title' }, productData.title)),
|
|
12258
|
+
React.createElement("div", { className: 'variant-detail' },
|
|
12259
|
+
React.createElement("div", { className: 'variant-image-container', onClick: () => {
|
|
12260
|
+
if (variantImage) {
|
|
12261
|
+
setPreviewImageUrl(variantImage);
|
|
12262
|
+
setShowImagePreview(true);
|
|
12263
|
+
}
|
|
12264
|
+
}, style: { cursor: 'pointer' } },
|
|
12265
|
+
React.createElement("img", { src: variantImage, alt: 'Selected variant', className: 'variant-image' })),
|
|
12266
|
+
React.createElement("div", { className: 'variant-info' },
|
|
12267
|
+
React.createElement("div", { className: 'variant-specs-row' },
|
|
12268
|
+
React.createElement("div", { className: 'variant-specs' }, Object.keys(selectedOptions).length > 0 ? (Object.entries(selectedOptions).map(([key, value]) => (React.createElement("span", { key: key, className: 'spec-item' }, value)))) : (React.createElement("span", { className: 'spec-placeholder' }, "Please select options"))),
|
|
12269
|
+
selectedVariant && selectedVariant.quantityAvailable !== undefined && (React.createElement("div", { className: 'stock-info' },
|
|
12270
|
+
"Available: ",
|
|
12271
|
+
selectedVariant.quantityAvailable))),
|
|
12272
|
+
React.createElement("div", { className: 'variant-price-row' },
|
|
12273
|
+
React.createElement("div", { className: 'price' },
|
|
12274
|
+
"$",
|
|
12275
|
+
totalPrice),
|
|
12276
|
+
React.createElement("div", { className: 'quantity-selector' },
|
|
12277
|
+
React.createElement("button", { className: 'qty-btn', onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1 }, "\u2212"),
|
|
12278
|
+
React.createElement("span", { className: 'qty-value' }, quantity),
|
|
12279
|
+
React.createElement("button", { className: 'qty-btn', onClick: () => setQuantity(quantity + 1), disabled: !selectedVariant || quantity >= maxQuantity }, "+"))))),
|
|
12280
|
+
React.createElement("div", { className: 'variant-options' }, productData.options.map(option => (React.createElement("div", { key: option.name, className: 'option-group' },
|
|
12281
|
+
React.createElement("div", { className: 'option-label' }, option.name),
|
|
12282
|
+
React.createElement("div", { className: 'option-values' }, option.values.map(value => {
|
|
12283
|
+
// 检查这个选项是否可选(availableForSale = true,如果有 quantityAvailable 则还需 > 0)
|
|
12284
|
+
const isAvailable = productData.variants.edges.some(({ node: variant }) => {
|
|
12285
|
+
const hasThisOption = variant.selectedOptions.some(opt => opt.name === option.name && opt.value === value);
|
|
12286
|
+
if (!hasThisOption || !variant.availableForSale)
|
|
12287
|
+
return false;
|
|
12288
|
+
// 如果有 quantityAvailable 字段,则需要检查库存
|
|
12289
|
+
if (variant.quantityAvailable !== undefined) {
|
|
12290
|
+
return variant.quantityAvailable > 0;
|
|
12291
|
+
}
|
|
12292
|
+
// 没有 quantityAvailable 字段时,只要 availableForSale 为 true 就可选
|
|
12293
|
+
return true;
|
|
12294
|
+
});
|
|
12295
|
+
const isSelected = selectedOptions[option.name] === value;
|
|
12296
|
+
return (React.createElement("button", { key: value, className: `option-btn ${isSelected ? 'selected' : ''} ${!isAvailable ? 'disabled' : ''}`, onClick: () => isAvailable && handleOptionSelect(option.name, value), disabled: !isAvailable }, value));
|
|
12297
|
+
}))))))),
|
|
12298
|
+
React.createElement("div", { className: 'popup-footer' },
|
|
12299
|
+
React.createElement("button", { className: 'add-to-cart-btn', onClick: handleAddToCart, disabled: !selectedVariant }, "Add To Cart")),
|
|
12300
|
+
showImagePreview && previewImageUrl && (React.createElement(Modal$1, { visible: showImagePreview, padding: 0, isFullScreen: true, onClose: () => setShowImagePreview(false) },
|
|
12301
|
+
React.createElement("div", { style: {
|
|
12302
|
+
width: '100%',
|
|
12303
|
+
height: '100%',
|
|
12304
|
+
display: 'flex',
|
|
12305
|
+
alignItems: 'center',
|
|
12306
|
+
justifyContent: 'center',
|
|
12307
|
+
backgroundColor: 'rgba(0, 0, 0, 0.9)'
|
|
12308
|
+
}, onClick: () => setShowImagePreview(false) },
|
|
12309
|
+
React.createElement("img", { src: previewImageUrl, alt: 'Preview', style: {
|
|
12310
|
+
maxWidth: '100%',
|
|
12311
|
+
maxHeight: '100%',
|
|
12312
|
+
objectFit: 'contain'
|
|
12313
|
+
} }))))));
|
|
12314
|
+
};
|
|
12315
|
+
|
|
11917
12316
|
const CommodityDetailDiroNew$1 = (_a) => {
|
|
11918
|
-
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
|
|
11919
|
-
var { style,
|
|
11920
|
-
|
|
11921
|
-
|
|
11922
|
-
const {
|
|
11923
|
-
React.useState(false);
|
|
11924
|
-
React.useState(false);
|
|
11925
|
-
React.useState(true);
|
|
12317
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5;
|
|
12318
|
+
var { style, rec, viewTime, isPost, bottom_image, tipText, swiper, commodityStyles, buttonStyle, index, commodityGroup, popupBg, iframeIcon, commodityImgRatio, iframeBgColor, isActive = true } = _a, props = __rest(_a, ["style", "rec", "viewTime", "isPost", "bottom_image", "tipText", "swiper", "commodityStyles", "buttonStyle", "index", "commodityGroup", "popupBg", "iframeIcon", "commodityImgRatio", "iframeBgColor", "isActive"]);
|
|
12319
|
+
const { sxpParameter, popupCurTimeRef, popupDetailData, setPopupDetailData, isPreview, bffFbReport, checkCommodityIndexRef, globalConfig, ctaEvent } = useSxpDataSource();
|
|
12320
|
+
useEditor();
|
|
12321
|
+
const { productView } = useEventReport();
|
|
11926
12322
|
const [showModal, setShowModal] = React.useState(false);
|
|
11927
12323
|
const curTimeRef = React.useRef(null);
|
|
11928
12324
|
const [show3DModal, setShow3DModal] = React.useState(false);
|
|
12325
|
+
const [showAddToCart, setShowAddToCart] = React.useState(false);
|
|
11929
12326
|
const [checkCommodityIndex, setCheckCommodityIndex] = React.useState((_b = popupDetailData === null || popupDetailData === void 0 ? void 0 : popupDetailData.multiCheckIndex) !== null && _b !== void 0 ? _b : 0);
|
|
11930
12327
|
const swiperRef = React.useRef();
|
|
11931
12328
|
const [swiperActiveIndex, setSwiperActiveIndex] = React.useState(0);
|
|
@@ -11942,30 +12339,30 @@ const CommodityDetailDiroNew$1 = (_a) => {
|
|
|
11942
12339
|
cta = p === null || p === void 0 ? void 0 : p.bindCta;
|
|
11943
12340
|
}
|
|
11944
12341
|
const handleLink = (e) => {
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
11957
|
-
|
|
11958
|
-
|
|
11959
|
-
|
|
11960
|
-
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
target_url: product.link
|
|
11965
|
-
});
|
|
11966
|
-
}
|
|
11967
|
-
window.location.href = window.getJointUtmLink(product.link);
|
|
12342
|
+
e.preventDefault();
|
|
12343
|
+
// 上报点击事件
|
|
12344
|
+
ctaEvent === null || ctaEvent === void 0 ? void 0 : ctaEvent({
|
|
12345
|
+
eventSubject: 'clickCta',
|
|
12346
|
+
eventDescription: 'User clicked the CTA'
|
|
12347
|
+
}, data, product, position);
|
|
12348
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
12349
|
+
eventName: 'ClickCTA',
|
|
12350
|
+
product: product ? [product] : undefined,
|
|
12351
|
+
contentType: 'product',
|
|
12352
|
+
data,
|
|
12353
|
+
position,
|
|
12354
|
+
cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
|
|
12355
|
+
cta_action_type: 'open_internal_popup',
|
|
12356
|
+
target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
|
|
12357
|
+
target_url: product === null || product === void 0 ? void 0 : product.link
|
|
12358
|
+
});
|
|
12359
|
+
if (!isPost) {
|
|
12360
|
+
productView(data, product, cta, viewTime || curTimeRef.current, position);
|
|
11968
12361
|
}
|
|
12362
|
+
// 更新 popupDetailData,确保 AddToCart 组件能获取到商品数据
|
|
12363
|
+
setPopupDetailData === null || setPopupDetailData === void 0 ? void 0 : setPopupDetailData(Object.assign(Object.assign({}, data), { video: Object.assign(Object.assign({}, data === null || data === void 0 ? void 0 : data.video), { bindProduct: product }), index: position }));
|
|
12364
|
+
// 打开 AddToCart 弹窗
|
|
12365
|
+
setShowAddToCart(true);
|
|
11969
12366
|
};
|
|
11970
12367
|
React.useEffect(() => {
|
|
11971
12368
|
var _a, _b;
|
|
@@ -11986,7 +12383,7 @@ const CommodityDetailDiroNew$1 = (_a) => {
|
|
|
11986
12383
|
rec: recData,
|
|
11987
12384
|
position
|
|
11988
12385
|
});
|
|
11989
|
-
}, [isActive, bffFbReport, isPost]);
|
|
12386
|
+
}, [isActive, bffFbReport, isPost, data, product, position]);
|
|
11990
12387
|
React.useEffect(() => {
|
|
11991
12388
|
if (!isActive || isPost)
|
|
11992
12389
|
return;
|
|
@@ -12114,13 +12511,13 @@ Made in Italy` })));
|
|
|
12114
12511
|
swiperRef.current.swiper.slideTo(0);
|
|
12115
12512
|
swiperRef.current.swiper.autoplay.start();
|
|
12116
12513
|
}
|
|
12117
|
-
}, []);
|
|
12514
|
+
}, [popupCurTimeRef, checkCommodityIndexRef]);
|
|
12118
12515
|
const renderCommodityGroup = React.useCallback(() => {
|
|
12119
12516
|
var _a, _b, _c;
|
|
12120
12517
|
if (isPost)
|
|
12121
12518
|
return;
|
|
12122
12519
|
return (React.createElement(CommodityGroup$1, { products: (_a = data === null || data === void 0 ? void 0 : data.video) === null || _a === void 0 ? void 0 : _a.bindProducts, data: commodityGroup, defImg: (_c = (_b = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _b !== void 0 ? _b : bottom_image) !== null && _c !== void 0 ? _c : '', style: { padding: '0 19px' }, onCLick: handleClick, popupDetailData: popupDetailData, check: checkCommodityIndex }));
|
|
12123
|
-
}, [checkCommodityIndex]);
|
|
12520
|
+
}, [checkCommodityIndex, isPost, (_w = data === null || data === void 0 ? void 0 : data.video) === null || _w === void 0 ? void 0 : _w.bindProducts, commodityGroup, sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image, bottom_image, handleClick, popupDetailData]);
|
|
12124
12521
|
const getDotsAlign = React.useMemo(() => {
|
|
12125
12522
|
const dotsAlignClass = {
|
|
12126
12523
|
left: 'commondityDetail-swiper-clickable-left',
|
|
@@ -12130,24 +12527,24 @@ Made in Italy` })));
|
|
|
12130
12527
|
return dotsAlignClass === null || dotsAlignClass === void 0 ? void 0 : dotsAlignClass[swiper === null || swiper === void 0 ? void 0 : swiper.dotsAlign];
|
|
12131
12528
|
}, [swiper === null || swiper === void 0 ? void 0 : swiper.dotsAlign]);
|
|
12132
12529
|
const iframeUrl = product === null || product === void 0 ? void 0 : product.remark;
|
|
12530
|
+
const isAlly = React.useMemo(() => getScreenReader(), []);
|
|
12133
12531
|
const handleMouseEnter = React.useCallback(() => {
|
|
12134
12532
|
if (swiperRef.current && swiperRef.current.swiper && isAlly) {
|
|
12135
12533
|
swiperRef.current.swiper.autoplay.stop();
|
|
12136
12534
|
}
|
|
12137
|
-
}, []);
|
|
12535
|
+
}, [isAlly]);
|
|
12138
12536
|
const handleMouseLeave = React.useCallback(() => {
|
|
12139
12537
|
if (swiperRef.current && swiperRef.current.swiper && isAlly) {
|
|
12140
12538
|
swiperRef.current.swiper.autoplay.start();
|
|
12141
12539
|
}
|
|
12142
|
-
}, []);
|
|
12540
|
+
}, [isAlly]);
|
|
12143
12541
|
const handleSlideChange = React.useCallback((swiper) => {
|
|
12144
12542
|
setSwiperActiveIndex(swiper.activeIndex);
|
|
12145
12543
|
}, []);
|
|
12146
|
-
const isAlly = React.useMemo(() => getScreenReader(), []);
|
|
12147
12544
|
return (React.createElement("div", { className: 'pb-commondityDiroNew' },
|
|
12148
12545
|
React.createElement("div", Object.assign({ className: css.css(Object.assign(Object.assign({}, style), { transform: 'translate3d(0px, 0px, 0px)' })) }, props),
|
|
12149
12546
|
React.createElement("div", { style: { position: 'relative' }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
|
|
12150
|
-
product && ((
|
|
12547
|
+
product && ((_x = product === null || product === void 0 ? void 0 : product.homePage) === null || _x === void 0 ? void 0 : _x.length) > 0 && (React.createElement(Swiper, Object.assign({ height: height, modules: [Pagination, Autoplay, ...(isAlly ? [Navigation, A11y, Mousewheel, Keyboard] : [])], pagination: {
|
|
12151
12548
|
clickable: true,
|
|
12152
12549
|
bulletActiveClass: 'swipe-item-active-bullet',
|
|
12153
12550
|
clickableClass: getDotsAlign,
|
|
@@ -12164,7 +12561,7 @@ Made in Italy` })));
|
|
|
12164
12561
|
: {}), { loop: true, ref: swiperRef, onSlideChange: handleSlideChange, autoplay: {
|
|
12165
12562
|
delay: (swiper === null || swiper === void 0 ? void 0 : swiper.delay) * 1000
|
|
12166
12563
|
}, className: css.css(Object.assign(Object.assign({ '.swiper-pagination': {
|
|
12167
|
-
bottom: (
|
|
12564
|
+
bottom: (_y = swiper === null || swiper === void 0 ? void 0 : swiper.dotsMarginBottom) !== null && _y !== void 0 ? _y : 0,
|
|
12168
12565
|
fontSize: '14px'
|
|
12169
12566
|
} }, ((swiper === null || swiper === void 0 ? void 0 : swiper.dotsBgColor) && {
|
|
12170
12567
|
'.swiper-pagination-bullet': {
|
|
@@ -12176,7 +12573,7 @@ Made in Italy` })));
|
|
|
12176
12573
|
backgroundColor: `${swiper === null || swiper === void 0 ? void 0 : swiper.dotsActiveColor}!important`,
|
|
12177
12574
|
opacity: 1
|
|
12178
12575
|
}
|
|
12179
|
-
}))) }), (
|
|
12576
|
+
}))) }), (_z = product === null || product === void 0 ? void 0 : product.homePage) === null || _z === void 0 ? void 0 : _z.map((src, srcKey) => {
|
|
12180
12577
|
var _a;
|
|
12181
12578
|
return (React.createElement(SwiperSlide, { key: srcKey, "aria-hidden": srcKey !== swiperActiveIndex },
|
|
12182
12579
|
React.createElement("div", { style: {
|
|
@@ -12192,7 +12589,7 @@ Made in Italy` })));
|
|
|
12192
12589
|
objectPosition: `50% ${(swiper === null || swiper === void 0 ? void 0 : swiper.translateY) ? (swiper === null || swiper === void 0 ? void 0 : swiper.translateY) + 50 : 50}%`
|
|
12193
12590
|
}, src: (_a = src !== null && src !== void 0 ? src : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _a !== void 0 ? _a : bottom_image }))));
|
|
12194
12591
|
}))),
|
|
12195
|
-
!((
|
|
12592
|
+
!((_0 = product === null || product === void 0 ? void 0 : product.homePage) === null || _0 === void 0 ? void 0 : _0.length) && (React.createElement("div", { className: css.css({
|
|
12196
12593
|
height,
|
|
12197
12594
|
width
|
|
12198
12595
|
}) },
|
|
@@ -12200,7 +12597,7 @@ Made in Italy` })));
|
|
|
12200
12597
|
objectFit: 'cover',
|
|
12201
12598
|
width: '100%',
|
|
12202
12599
|
height: '100%'
|
|
12203
|
-
}), src: (
|
|
12600
|
+
}), src: (_1 = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _1 !== void 0 ? _1 : bottom_image, alt: 'pdp image' }))),
|
|
12204
12601
|
(iframeUrl || !product) && iframeIcon && (React.createElement("div", { style: {
|
|
12205
12602
|
display: 'flex',
|
|
12206
12603
|
alignItems: 'center',
|
|
@@ -12217,7 +12614,7 @@ Made in Italy` })));
|
|
|
12217
12614
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top' },
|
|
12218
12615
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top-left' },
|
|
12219
12616
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top-left-title', style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title), dangerouslySetInnerHTML: {
|
|
12220
|
-
__html: setFontForText((
|
|
12617
|
+
__html: setFontForText((_2 = product === null || product === void 0 ? void 0 : product.title) !== null && _2 !== void 0 ? _2 : 'Large Dior Toujours BagLarge', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title)
|
|
12221
12618
|
} }),
|
|
12222
12619
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-collection', hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.collection) || (product === null || product === void 0 ? void 0 : product.collection) === ''), style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection), dangerouslySetInnerHTML: {
|
|
12223
12620
|
__html: setFontForText((product === null || product === void 0 ? void 0 : product.collection) || 'Black Macrocannage CalfskinLarge', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection)
|
|
@@ -12227,11 +12624,11 @@ Made in Italy` })));
|
|
|
12227
12624
|
__html: priceText !== null && priceText !== void 0 ? priceText : ''
|
|
12228
12625
|
} }),
|
|
12229
12626
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top-right-price', hidden: !!product && !(product === null || product === void 0 ? void 0 : product.taxInfo), style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo), dangerouslySetInnerHTML: {
|
|
12230
|
-
__html: setFontForText((
|
|
12627
|
+
__html: setFontForText((_3 = product === null || product === void 0 ? void 0 : product.taxInfo) !== null && _3 !== void 0 ? _3 : '税费', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo)
|
|
12231
12628
|
} }))),
|
|
12232
|
-
React.createElement("a", { "aria-label": (
|
|
12629
|
+
React.createElement("a", { "aria-label": (_4 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _4 !== void 0 ? _4 : 'Shop now', role: 'button', tabIndex: 0, onClick: handleLink, className: 'pb-commondityDiroNew-btn', style: buttonStyle },
|
|
12233
12630
|
React.createElement("span", { dangerouslySetInnerHTML: {
|
|
12234
|
-
__html: setFontForText((
|
|
12631
|
+
__html: setFontForText((_5 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _5 !== void 0 ? _5 : 'Shop now', buttonStyle)
|
|
12235
12632
|
} })),
|
|
12236
12633
|
productInfoText({ isPost }))),
|
|
12237
12634
|
React.createElement(Modal$1, { visible: showModal, onClose: () => setShowModal(false) },
|
|
@@ -12243,7 +12640,9 @@ Made in Italy` })));
|
|
|
12243
12640
|
height: 'calc(100% - 50px)',
|
|
12244
12641
|
marginTop: '50px',
|
|
12245
12642
|
border: 'none'
|
|
12246
|
-
} })))
|
|
12643
|
+
} }))),
|
|
12644
|
+
showAddToCart && (React.createElement(Modal$1, { visible: showAddToCart, padding: 0, isFullScreen: false, onClose: () => setShowAddToCart(false) },
|
|
12645
|
+
React.createElement(AddToCartPopup$1, { isActive: true })))));
|
|
12247
12646
|
};
|
|
12248
12647
|
var CommodityDetailDiroNewComponent = React.memo(CommodityDetailDiroNew$1);
|
|
12249
12648
|
|
|
@@ -13245,296 +13644,6 @@ var interactionRender$d = () => {
|
|
|
13245
13644
|
React.createElement("li", null, "\u65E0\u5E93\u5B58\u6216\u4E0D\u53EF\u552E\u5356\u7684\u89C4\u683C\u81EA\u52A8\u7F6E\u7070\u4E0D\u53EF\u9009"))));
|
|
13246
13645
|
};
|
|
13247
13646
|
|
|
13248
|
-
const AddToCartPopup$1 = (_a) => {
|
|
13249
|
-
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
13250
|
-
var { style, isActive = true, index, shopifyDomain = '', storefrontAccessToken = '', variantStyles = {}, buttonStyle = {}, quantityStyle = {}, texts = {}, popupBg = {} } = _a, props = __rest(_a, ["style", "isActive", "index", "shopifyDomain", "storefrontAccessToken", "variantStyles", "buttonStyle", "quantityStyle", "texts", "popupBg"]);
|
|
13251
|
-
const { sxpParameter, popupDetailData, isPreview, bffFbReport, globalConfig } = useSxpDataSource();
|
|
13252
|
-
useEventReport();
|
|
13253
|
-
const curTimeRef = React.useRef(null);
|
|
13254
|
-
const [productData, setProductData] = React.useState(null);
|
|
13255
|
-
const [selectedOptions, setSelectedOptions] = React.useState({});
|
|
13256
|
-
const [selectedVariant, setSelectedVariant] = React.useState(null);
|
|
13257
|
-
const [quantity, setQuantity] = React.useState(1);
|
|
13258
|
-
const [loading, setLoading] = React.useState(true);
|
|
13259
|
-
const [error, setError] = React.useState(null);
|
|
13260
|
-
// 获取当前弹窗商品数据(自动从 popupDetailData 获取)
|
|
13261
|
-
const data = popupDetailData;
|
|
13262
|
-
const product = (_c = (_b = data === null || data === void 0 ? void 0 : data.video) === null || _b === void 0 ? void 0 : _b.bindProduct) !== null && _c !== void 0 ? _c : (_e = (_d = data === null || data === void 0 ? void 0 : data.video) === null || _d === void 0 ? void 0 : _d.bindProducts) === null || _e === void 0 ? void 0 : _e[0];
|
|
13263
|
-
product === null || product === void 0 ? void 0 : product.bindCta;
|
|
13264
|
-
const position = (_g = (_f = popupDetailData === null || popupDetailData === void 0 ? void 0 : popupDetailData.index) !== null && _f !== void 0 ? _f : index) !== null && _g !== void 0 ? _g : 0;
|
|
13265
|
-
// Shopify配置 - 优先级:props > globalConfig > 默认值
|
|
13266
|
-
const finalShopifyDomain = shopifyDomain || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopifyDomain) || 'dev-store-749237498237498636.myshopify.com';
|
|
13267
|
-
const finalStorefrontToken = storefrontAccessToken || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.storefrontAccessToken) || '77d894c490f79430ce7bd0a7efdff6b7';
|
|
13268
|
-
// 自动从商品数据获取 Shopify Product ID
|
|
13269
|
-
const productId = (product === null || product === void 0 ? void 0 : product.itemId) || '';
|
|
13270
|
-
// 文案
|
|
13271
|
-
const finalTexts = {
|
|
13272
|
-
addToCart: texts.addToCart || 'Add to Cart',
|
|
13273
|
-
selectOptions: texts.selectOptions || 'Please select options',
|
|
13274
|
-
loading: texts.loading || 'Loading...',
|
|
13275
|
-
error: texts.error || 'Failed to load product',
|
|
13276
|
-
color: texts.color || 'Color',
|
|
13277
|
-
size: texts.size || 'Size',
|
|
13278
|
-
material: texts.material || 'Material',
|
|
13279
|
-
style: texts.style || 'Style'
|
|
13280
|
-
};
|
|
13281
|
-
// 查询Shopify商品数据
|
|
13282
|
-
const fetchProductData = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
13283
|
-
var _m;
|
|
13284
|
-
if (!productId || !finalShopifyDomain || !finalStorefrontToken) {
|
|
13285
|
-
console.log('[AddToCartPopup] 缺少必要配置:', {
|
|
13286
|
-
productId,
|
|
13287
|
-
shopifyDomain: finalShopifyDomain,
|
|
13288
|
-
hasToken: !!finalStorefrontToken
|
|
13289
|
-
});
|
|
13290
|
-
setLoading(false);
|
|
13291
|
-
return;
|
|
13292
|
-
}
|
|
13293
|
-
console.log('[AddToCartPopup] 开始加载商品数据:', {
|
|
13294
|
-
productId,
|
|
13295
|
-
shopifyDomain: finalShopifyDomain
|
|
13296
|
-
});
|
|
13297
|
-
setLoading(true);
|
|
13298
|
-
setError(null);
|
|
13299
|
-
try {
|
|
13300
|
-
const query = `
|
|
13301
|
-
query getProduct($id: ID!) {
|
|
13302
|
-
product(id: $id) {
|
|
13303
|
-
id
|
|
13304
|
-
title
|
|
13305
|
-
images(first: 10) {
|
|
13306
|
-
edges {
|
|
13307
|
-
node {
|
|
13308
|
-
url
|
|
13309
|
-
}
|
|
13310
|
-
}
|
|
13311
|
-
}
|
|
13312
|
-
options {
|
|
13313
|
-
name
|
|
13314
|
-
values
|
|
13315
|
-
}
|
|
13316
|
-
variants(first: 100) {
|
|
13317
|
-
edges {
|
|
13318
|
-
node {
|
|
13319
|
-
id
|
|
13320
|
-
title
|
|
13321
|
-
availableForSale
|
|
13322
|
-
quantityAvailable
|
|
13323
|
-
price {
|
|
13324
|
-
amount
|
|
13325
|
-
currencyCode
|
|
13326
|
-
}
|
|
13327
|
-
image {
|
|
13328
|
-
url
|
|
13329
|
-
}
|
|
13330
|
-
selectedOptions {
|
|
13331
|
-
name
|
|
13332
|
-
value
|
|
13333
|
-
}
|
|
13334
|
-
}
|
|
13335
|
-
}
|
|
13336
|
-
}
|
|
13337
|
-
}
|
|
13338
|
-
}
|
|
13339
|
-
`;
|
|
13340
|
-
// 确保 Product ID 格式正确
|
|
13341
|
-
const formattedProductId = productId.startsWith('gid://')
|
|
13342
|
-
? productId
|
|
13343
|
-
: `gid://shopify/Product/${productId}`;
|
|
13344
|
-
console.log('[AddToCartPopup] 使用的 Product ID:', formattedProductId);
|
|
13345
|
-
const response = yield fetch(`https://${finalShopifyDomain}/api/2024-01/graphql.json`, {
|
|
13346
|
-
method: 'POST',
|
|
13347
|
-
headers: {
|
|
13348
|
-
'Content-Type': 'application/json',
|
|
13349
|
-
'X-Shopify-Storefront-Access-Token': finalStorefrontToken
|
|
13350
|
-
},
|
|
13351
|
-
body: JSON.stringify({
|
|
13352
|
-
query,
|
|
13353
|
-
variables: { id: formattedProductId }
|
|
13354
|
-
})
|
|
13355
|
-
});
|
|
13356
|
-
if (!response.ok) {
|
|
13357
|
-
throw new Error(`HTTP ${response.status}`);
|
|
13358
|
-
}
|
|
13359
|
-
const result = yield response.json();
|
|
13360
|
-
if (result.errors) {
|
|
13361
|
-
console.error('[AddToCartPopup] GraphQL 错误:', result.errors);
|
|
13362
|
-
throw new Error(result.errors[0].message);
|
|
13363
|
-
}
|
|
13364
|
-
if (!((_m = result.data) === null || _m === void 0 ? void 0 : _m.product)) {
|
|
13365
|
-
console.error('[AddToCartPopup] 未找到商品');
|
|
13366
|
-
throw new Error('Product not found');
|
|
13367
|
-
}
|
|
13368
|
-
console.log('[AddToCartPopup] 商品数据加载成功:', result.data.product.title);
|
|
13369
|
-
setProductData(result.data.product);
|
|
13370
|
-
}
|
|
13371
|
-
catch (err) {
|
|
13372
|
-
const errorMessage = err instanceof Error ? err.message : finalTexts.error;
|
|
13373
|
-
setError(errorMessage);
|
|
13374
|
-
console.error('[AddToCartPopup] 加载失败:', err);
|
|
13375
|
-
}
|
|
13376
|
-
finally {
|
|
13377
|
-
setLoading(false);
|
|
13378
|
-
}
|
|
13379
|
-
}), [productId, finalShopifyDomain, finalStorefrontToken, finalTexts.error]);
|
|
13380
|
-
React.useEffect(() => {
|
|
13381
|
-
if (isActive) {
|
|
13382
|
-
fetchProductData();
|
|
13383
|
-
}
|
|
13384
|
-
}, [isActive, fetchProductData]);
|
|
13385
|
-
// 根据选中的规格匹配variant
|
|
13386
|
-
React.useEffect(() => {
|
|
13387
|
-
if (!productData)
|
|
13388
|
-
return;
|
|
13389
|
-
const variants = productData.variants.edges.map(edge => edge.node);
|
|
13390
|
-
const optionsCount = productData.options.length;
|
|
13391
|
-
const selectedCount = Object.keys(selectedOptions).length;
|
|
13392
|
-
if (selectedCount === 0 || selectedCount < optionsCount) {
|
|
13393
|
-
setSelectedVariant(null);
|
|
13394
|
-
return;
|
|
13395
|
-
}
|
|
13396
|
-
const matchedVariant = variants.find(variant => {
|
|
13397
|
-
return variant.selectedOptions.every(option => selectedOptions[option.name] === option.value);
|
|
13398
|
-
});
|
|
13399
|
-
setSelectedVariant(matchedVariant || null);
|
|
13400
|
-
setQuantity(1);
|
|
13401
|
-
}, [selectedOptions, productData]);
|
|
13402
|
-
// 处理规格选择
|
|
13403
|
-
const handleOptionSelect = React.useCallback((optionName, value) => {
|
|
13404
|
-
setSelectedOptions(prev => {
|
|
13405
|
-
const newOptions = Object.assign({}, prev);
|
|
13406
|
-
if (newOptions[optionName] === value) {
|
|
13407
|
-
delete newOptions[optionName];
|
|
13408
|
-
}
|
|
13409
|
-
else {
|
|
13410
|
-
newOptions[optionName] = value;
|
|
13411
|
-
}
|
|
13412
|
-
return newOptions;
|
|
13413
|
-
});
|
|
13414
|
-
}, []);
|
|
13415
|
-
// 处理数量变化
|
|
13416
|
-
const handleQuantityChange = React.useCallback((delta) => {
|
|
13417
|
-
setQuantity(prev => {
|
|
13418
|
-
var _a;
|
|
13419
|
-
const newQuantity = prev + delta;
|
|
13420
|
-
const maxQuantity = (_a = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) !== null && _a !== void 0 ? _a : 999;
|
|
13421
|
-
return Math.max(1, Math.min(newQuantity, maxQuantity));
|
|
13422
|
-
});
|
|
13423
|
-
}, [selectedVariant]);
|
|
13424
|
-
// 检查某个规格值是否可用
|
|
13425
|
-
const isOptionValueAvailable = React.useCallback((optionName, value) => {
|
|
13426
|
-
if (!productData)
|
|
13427
|
-
return false;
|
|
13428
|
-
const variants = productData.variants.edges.map(edge => edge.node);
|
|
13429
|
-
const tempOptions = Object.assign(Object.assign({}, selectedOptions), { [optionName]: value });
|
|
13430
|
-
return variants.some(variant => {
|
|
13431
|
-
const matches = variant.selectedOptions.every(option => !tempOptions[option.name] || tempOptions[option.name] === option.value);
|
|
13432
|
-
const hasStock = variant.quantityAvailable === null || variant.quantityAvailable > 0;
|
|
13433
|
-
return matches && variant.availableForSale && hasStock;
|
|
13434
|
-
});
|
|
13435
|
-
}, [productData, selectedOptions]);
|
|
13436
|
-
// 处理加购
|
|
13437
|
-
const handleAddToCart = React.useCallback(() => {
|
|
13438
|
-
var _a;
|
|
13439
|
-
if (!selectedVariant || quantity === 0)
|
|
13440
|
-
return;
|
|
13441
|
-
const variantId = selectedVariant.id.split('/').pop();
|
|
13442
|
-
const cartUrl = `https://${finalShopifyDomain}/cart/add?id=${variantId}&quantity=${quantity}`;
|
|
13443
|
-
console.log('[AddToCartPopup] 加购:', {
|
|
13444
|
-
variantId,
|
|
13445
|
-
quantity,
|
|
13446
|
-
cartUrl
|
|
13447
|
-
});
|
|
13448
|
-
// 上报事件
|
|
13449
|
-
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
13450
|
-
eventName: 'AddToCart',
|
|
13451
|
-
product: product ? [product] : undefined,
|
|
13452
|
-
contentType: 'product',
|
|
13453
|
-
data,
|
|
13454
|
-
position,
|
|
13455
|
-
content_id: (_a = product === null || product === void 0 ? void 0 : product.itemId) !== null && _a !== void 0 ? _a : '',
|
|
13456
|
-
value: parseFloat(selectedVariant.price.amount) * quantity,
|
|
13457
|
-
currency: selectedVariant.price.currencyCode,
|
|
13458
|
-
contents: [{
|
|
13459
|
-
id: variantId,
|
|
13460
|
-
quantity
|
|
13461
|
-
}]
|
|
13462
|
-
});
|
|
13463
|
-
// 跳转到Shopify购物车页面
|
|
13464
|
-
window.location.href = cartUrl;
|
|
13465
|
-
}, [selectedVariant, quantity, finalShopifyDomain, bffFbReport, product, data, position]);
|
|
13466
|
-
// 计算总价
|
|
13467
|
-
const totalPrice = React.useMemo(() => {
|
|
13468
|
-
if (!selectedVariant)
|
|
13469
|
-
return null;
|
|
13470
|
-
const price = parseFloat(selectedVariant.price.amount);
|
|
13471
|
-
const total = price * quantity;
|
|
13472
|
-
return total.toFixed(2);
|
|
13473
|
-
}, [selectedVariant, quantity]);
|
|
13474
|
-
// 初始化时间
|
|
13475
|
-
React.useEffect(() => {
|
|
13476
|
-
const initTime = () => {
|
|
13477
|
-
curTimeRef.current = new Date();
|
|
13478
|
-
};
|
|
13479
|
-
initTime();
|
|
13480
|
-
window.addEventListener('pageshow', initTime);
|
|
13481
|
-
return () => {
|
|
13482
|
-
window.removeEventListener('pageshow', initTime);
|
|
13483
|
-
};
|
|
13484
|
-
}, []);
|
|
13485
|
-
// 加载中
|
|
13486
|
-
if (loading) {
|
|
13487
|
-
return (React.createElement("div", { className: "add-to-cart-popup-loading", style: style },
|
|
13488
|
-
React.createElement("div", null, finalTexts.loading)));
|
|
13489
|
-
}
|
|
13490
|
-
// 错误状态
|
|
13491
|
-
if (error || !productData) {
|
|
13492
|
-
return (React.createElement("div", { className: "add-to-cart-popup-error", style: style },
|
|
13493
|
-
React.createElement("div", null,
|
|
13494
|
-
finalTexts.error,
|
|
13495
|
-
": ",
|
|
13496
|
-
error || 'Product not found')));
|
|
13497
|
-
}
|
|
13498
|
-
const mainImage = ((_h = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.image) === null || _h === void 0 ? void 0 : _h.url) || ((_j = productData.images.edges[0]) === null || _j === void 0 ? void 0 : _j.node.url) || ((_k = product === null || product === void 0 ? void 0 : product.homePage) === null || _k === void 0 ? void 0 : _k[0]) || '';
|
|
13499
|
-
const hasAllOptionsSelected = productData.options.length === Object.keys(selectedOptions).length;
|
|
13500
|
-
const isAddToCartDisabled = !selectedVariant || quantity === 0;
|
|
13501
|
-
return (React.createElement("div", Object.assign({ className: "add-to-cart-popup-container", style: style }, props),
|
|
13502
|
-
React.createElement("div", { className: "variant-detail-section" },
|
|
13503
|
-
React.createElement("div", { className: "variant-image-wrapper" },
|
|
13504
|
-
React.createElement("img", { src: mainImage, alt: productData.title, className: "variant-image" })),
|
|
13505
|
-
React.createElement("div", { className: "variant-info-wrapper" },
|
|
13506
|
-
React.createElement("h2", { className: "product-title-text", style: variantStyles.title, dangerouslySetInnerHTML: {
|
|
13507
|
-
__html: setFontForText(productData.title, variantStyles.title)
|
|
13508
|
-
} }),
|
|
13509
|
-
selectedVariant && (React.createElement(React.Fragment, null,
|
|
13510
|
-
React.createElement("div", { className: "selected-options-tags" }, selectedVariant.selectedOptions.map(option => (React.createElement("span", { key: option.name, className: "option-tag", style: variantStyles.selectedOption },
|
|
13511
|
-
option.name,
|
|
13512
|
-
": ",
|
|
13513
|
-
option.value)))),
|
|
13514
|
-
React.createElement("div", { className: "price-display" },
|
|
13515
|
-
React.createElement("span", { className: "price-value", style: variantStyles.price, dangerouslySetInnerHTML: {
|
|
13516
|
-
__html: setFontForText(`${selectedVariant.price.currencyCode} $${totalPrice}`, variantStyles.price)
|
|
13517
|
-
} })),
|
|
13518
|
-
React.createElement("div", { className: "quantity-selector-wrapper", style: quantityStyle },
|
|
13519
|
-
React.createElement("button", { className: "quantity-btn quantity-decrease", onClick: () => handleQuantityChange(-1), disabled: quantity <= 1, "aria-label": "Decrease quantity" }, "-"),
|
|
13520
|
-
React.createElement("input", { type: "number", value: quantity, readOnly: true, className: "quantity-input-field", "aria-label": "Quantity" }),
|
|
13521
|
-
React.createElement("button", { className: "quantity-btn quantity-increase", onClick: () => handleQuantityChange(1), disabled: quantity >= ((_l = selectedVariant.quantityAvailable) !== null && _l !== void 0 ? _l : 999), "aria-label": "Increase quantity" }, "+")))),
|
|
13522
|
-
!hasAllOptionsSelected && (React.createElement("div", { className: "no-selection-hint", style: variantStyles.option }, finalTexts.selectOptions)))),
|
|
13523
|
-
React.createElement("div", { className: "variant-options-section" }, productData.options.map(option => (React.createElement("div", { key: option.name, className: "option-group-wrapper" },
|
|
13524
|
-
React.createElement("h3", { className: "option-group-name", style: variantStyles.option, dangerouslySetInnerHTML: {
|
|
13525
|
-
__html: setFontForText(option.name, variantStyles.option)
|
|
13526
|
-
} }),
|
|
13527
|
-
React.createElement("div", { className: "option-values-grid" }, option.values.map(value => {
|
|
13528
|
-
const isSelected = selectedOptions[option.name] === value;
|
|
13529
|
-
const isAvailable = isOptionValueAvailable(option.name, value);
|
|
13530
|
-
return (React.createElement("button", { key: value, className: `option-value-button ${isSelected ? 'selected' : ''} ${!isAvailable ? 'disabled' : ''}`, onClick: () => isAvailable && handleOptionSelect(option.name, value), disabled: !isAvailable, "aria-label": `${option.name}: ${value}`, "aria-pressed": isSelected }, value));
|
|
13531
|
-
})))))),
|
|
13532
|
-
React.createElement("button", { className: `add-to-cart-button ${isAddToCartDisabled ? 'disabled' : ''}`, style: buttonStyle, onClick: handleAddToCart, disabled: isAddToCartDisabled, "aria-label": finalTexts.addToCart },
|
|
13533
|
-
React.createElement("span", { dangerouslySetInnerHTML: {
|
|
13534
|
-
__html: setFontForText(finalTexts.addToCart, buttonStyle)
|
|
13535
|
-
} }))));
|
|
13536
|
-
};
|
|
13537
|
-
|
|
13538
13647
|
/*
|
|
13539
13648
|
* @Author: tao
|
|
13540
13649
|
* @Date: 2026-01-12
|
|
@@ -13550,60 +13659,7 @@ const AddToCartPopup = createMaterial(AddToCartPopup$1, {
|
|
|
13550
13659
|
interactionRender: interactionRender$d
|
|
13551
13660
|
},
|
|
13552
13661
|
defaulSetting: {
|
|
13553
|
-
props: {
|
|
13554
|
-
shopifyDomain: '',
|
|
13555
|
-
storefrontAccessToken: '',
|
|
13556
|
-
variantStyles: {
|
|
13557
|
-
title: {
|
|
13558
|
-
color: '#000',
|
|
13559
|
-
fontSize: 20,
|
|
13560
|
-
fontWeight: 600,
|
|
13561
|
-
marginBottom: 12
|
|
13562
|
-
},
|
|
13563
|
-
price: {
|
|
13564
|
-
color: '#000',
|
|
13565
|
-
fontSize: 24,
|
|
13566
|
-
fontWeight: 700,
|
|
13567
|
-
marginBottom: 16
|
|
13568
|
-
},
|
|
13569
|
-
option: {
|
|
13570
|
-
color: '#111',
|
|
13571
|
-
fontSize: 16,
|
|
13572
|
-
fontWeight: 600,
|
|
13573
|
-
marginBottom: 12
|
|
13574
|
-
},
|
|
13575
|
-
selectedOption: {
|
|
13576
|
-
fontSize: 14,
|
|
13577
|
-
color: '#374151'
|
|
13578
|
-
}
|
|
13579
|
-
},
|
|
13580
|
-
buttonStyle: {
|
|
13581
|
-
backgroundColor: '#000',
|
|
13582
|
-
color: '#fff',
|
|
13583
|
-
fontSize: 16,
|
|
13584
|
-
height: 52,
|
|
13585
|
-
fontWeight: 600,
|
|
13586
|
-
textAlign: 'center',
|
|
13587
|
-
textTransform: 'uppercase'
|
|
13588
|
-
},
|
|
13589
|
-
quantityStyle: {
|
|
13590
|
-
gap: 12
|
|
13591
|
-
},
|
|
13592
|
-
texts: {
|
|
13593
|
-
addToCart: 'Add to Cart',
|
|
13594
|
-
selectOptions: 'Please select options',
|
|
13595
|
-
loading: 'Loading...',
|
|
13596
|
-
error: 'Failed to load product',
|
|
13597
|
-
color: 'Color',
|
|
13598
|
-
size: 'Size',
|
|
13599
|
-
material: 'Material',
|
|
13600
|
-
style: 'Style'
|
|
13601
|
-
},
|
|
13602
|
-
popupBg: {
|
|
13603
|
-
horizontalMargin: 0,
|
|
13604
|
-
bottomMargin: 0
|
|
13605
|
-
}
|
|
13606
|
-
},
|
|
13662
|
+
props: {},
|
|
13607
13663
|
style: {}
|
|
13608
13664
|
},
|
|
13609
13665
|
w: 100,
|
|
@@ -19699,7 +19755,7 @@ const StructurePage = (_a) => {
|
|
|
19699
19755
|
return res.json();
|
|
19700
19756
|
})
|
|
19701
19757
|
.then((result) => {
|
|
19702
|
-
var _a, _b, _c, _d;
|
|
19758
|
+
var _a, _b, _c, _d, _e;
|
|
19703
19759
|
if (result.code === '0' || result.code === '00000') {
|
|
19704
19760
|
// 判断数据结构:CMS 模式和普通模式可能不同
|
|
19705
19761
|
let multiCtaData = null;
|
|
@@ -19718,6 +19774,14 @@ const StructurePage = (_a) => {
|
|
|
19718
19774
|
console.error('[StructurePage] No multiCta data found in response:', result);
|
|
19719
19775
|
setError(result.message || 'No multiCta data found');
|
|
19720
19776
|
}
|
|
19777
|
+
// 存储 Shopify 配置信息到 window 对象,供 AddToCart 弹窗使用
|
|
19778
|
+
if ((_e = result.data) === null || _e === void 0 ? void 0 : _e.shopify) {
|
|
19779
|
+
window.__SHOPIFY_CONFIG__ = {
|
|
19780
|
+
domain: result.data.shopify.domain,
|
|
19781
|
+
storefrontAccessToken: result.data.shopify.storefrontAccessToken
|
|
19782
|
+
};
|
|
19783
|
+
console.log('[StructurePage] Shopify config stored:', window.__SHOPIFY_CONFIG__);
|
|
19784
|
+
}
|
|
19721
19785
|
}
|
|
19722
19786
|
else {
|
|
19723
19787
|
setError(result.message || 'Failed to load data');
|
|
@@ -19899,7 +19963,13 @@ const StructurePage = (_a) => {
|
|
|
19899
19963
|
var index$3 = /*#__PURE__*/Object.freeze({
|
|
19900
19964
|
__proto__: null,
|
|
19901
19965
|
EditorCore: EditorCore,
|
|
19902
|
-
|
|
19966
|
+
Pagebuilder: Pagebuilder,
|
|
19967
|
+
StructurePage: StructurePage,
|
|
19968
|
+
createMaterial: createMaterial,
|
|
19969
|
+
hooks: index$4,
|
|
19970
|
+
localStore: localStore,
|
|
19971
|
+
sessionStore: sessionStore,
|
|
19972
|
+
tool: tool
|
|
19903
19973
|
});
|
|
19904
19974
|
|
|
19905
19975
|
/*
|