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/pb-ui.js
CHANGED
|
@@ -180,6 +180,14 @@
|
|
|
180
180
|
}
|
|
181
181
|
return uuid.join('');
|
|
182
182
|
}
|
|
183
|
+
const getIndexByblockType = (type, index) => {
|
|
184
|
+
if (type === 'CommodityCarouselBlock' || type === 'CopyBlock') {
|
|
185
|
+
return 'initial';
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return index;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
183
191
|
const generateRandomString = (length) => {
|
|
184
192
|
let result = '';
|
|
185
193
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
@@ -239,6 +247,70 @@
|
|
|
239
247
|
}
|
|
240
248
|
return content;
|
|
241
249
|
};
|
|
250
|
+
function getBrowserInfo() {
|
|
251
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
252
|
+
const userAgent = self.navigator.userAgent;
|
|
253
|
+
if (!userAgent)
|
|
254
|
+
return null;
|
|
255
|
+
if (/edge\/([\d\.]+)/i.exec(userAgent))
|
|
256
|
+
return `Edge ${(_a = /edge\/([\d\.]+)/i.exec(userAgent)) === null || _a === void 0 ? void 0 : _a[1]}`;
|
|
257
|
+
if (/edg\/([\d\.]+)/i.exec(userAgent))
|
|
258
|
+
return `Edge(Chromium) ${(_b = /edge\/([\d\.]+)/i.exec(userAgent)) === null || _b === void 0 ? void 0 : _b[1]}`;
|
|
259
|
+
if (/msie/i.test(userAgent))
|
|
260
|
+
return `Internet Explorer ${(_c = /msie ([\d\.]+)/i.exec(userAgent)) === null || _c === void 0 ? void 0 : _c[1]}`;
|
|
261
|
+
if (/Trident/i.test(userAgent))
|
|
262
|
+
return `Internet Explorer ${(_d = /rv:([\d\.]+)/i.exec(userAgent)) === null || _d === void 0 ? void 0 : _d[1]}`;
|
|
263
|
+
if (/chrome/i.test(userAgent))
|
|
264
|
+
return `Chrome ${(_e = /chrome\/([\d\.]+)/i.exec(userAgent)) === null || _e === void 0 ? void 0 : _e[1]}`;
|
|
265
|
+
if (/firefox/i.test(userAgent))
|
|
266
|
+
return `Firefox ${(_f = /firefox\/([\d\.]+)/i.exec(userAgent)) === null || _f === void 0 ? void 0 : _f[1]}`;
|
|
267
|
+
if (/safari/i.test(userAgent))
|
|
268
|
+
return `Safari ${(_g = /version\/([\d\.]+)/i.exec(userAgent)) === null || _g === void 0 ? void 0 : _g[1]}`;
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
function getSystem() {
|
|
272
|
+
var _a, _b, _c;
|
|
273
|
+
const userAgent = self.navigator.userAgent;
|
|
274
|
+
if (!userAgent)
|
|
275
|
+
return null;
|
|
276
|
+
if (/iphone/i.test(userAgent))
|
|
277
|
+
return `IOS ${(_a = userAgent.match(/OS\s(.*?)\slike/)) === null || _a === void 0 ? void 0 : _a[1]}`;
|
|
278
|
+
if (/android/i.test(userAgent))
|
|
279
|
+
return `Android ${(_b = userAgent.match(/Android\s(.*?)\;/)) === null || _b === void 0 ? void 0 : _b[1]}`;
|
|
280
|
+
if (/windows/i.test(userAgent))
|
|
281
|
+
return `Windows ${(_c = userAgent.match(/Windows\s(.*?)\;/)) === null || _c === void 0 ? void 0 : _c[1]}`;
|
|
282
|
+
if (/mac/i.test(userAgent))
|
|
283
|
+
return 'Mac OS';
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
function getDevice$1() {
|
|
287
|
+
const userAgent = self.navigator.userAgent;
|
|
288
|
+
if (!userAgent)
|
|
289
|
+
return null;
|
|
290
|
+
if (/iphone/i.test(userAgent))
|
|
291
|
+
return 'iPhone';
|
|
292
|
+
if (/android/i.test(userAgent)) {
|
|
293
|
+
// var index1 = userAgent.indexOf(';');
|
|
294
|
+
// var index2 = userAgent.indexOf(';', index1 + 1);
|
|
295
|
+
// var index3 = userAgent.indexOf(';', index2 + 1);
|
|
296
|
+
// var index4 = userAgent.indexOf(';', index3 + 1);
|
|
297
|
+
// if (index2 !== -1 && index3 !== -1) {
|
|
298
|
+
// var value1 = userAgent.substring(index3 + 1, index4);
|
|
299
|
+
// return `${value1}`;
|
|
300
|
+
// }
|
|
301
|
+
const index1 = userAgent.indexOf('(');
|
|
302
|
+
const index2 = userAgent.indexOf(')');
|
|
303
|
+
if (index1 !== -1 && index2 !== -1) {
|
|
304
|
+
const value = userAgent.substring(index1 + 1, index2);
|
|
305
|
+
return `${value}`;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (/windows/i.test(userAgent))
|
|
309
|
+
return 'Windows';
|
|
310
|
+
if (/mac/i.test(userAgent))
|
|
311
|
+
return 'Mac';
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
242
314
|
function getCookie(val) {
|
|
243
315
|
// const expirationDate = new Date();
|
|
244
316
|
// expirationDate.setDate(expirationDate.getDate() + 100);
|
|
@@ -300,6 +372,33 @@
|
|
|
300
372
|
document.cookie = `${name}=; ${expiration}${pathPart}${domainPart}`;
|
|
301
373
|
console.log(`已尝试删除Cookie: ${name}`);
|
|
302
374
|
}
|
|
375
|
+
function setCookie(name, value, days = 0, path = '/', domain = '', secure = false, sameSite = 'Lax') {
|
|
376
|
+
let cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
377
|
+
// 设置过期时间
|
|
378
|
+
if (days) {
|
|
379
|
+
const date = new Date();
|
|
380
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
381
|
+
cookieString += `; expires=${date.toUTCString()}`;
|
|
382
|
+
}
|
|
383
|
+
// 设置路径
|
|
384
|
+
if (path) {
|
|
385
|
+
cookieString += `; path=${path}`;
|
|
386
|
+
}
|
|
387
|
+
// 设置域名
|
|
388
|
+
if (domain) {
|
|
389
|
+
cookieString += `; domain=${domain}`;
|
|
390
|
+
}
|
|
391
|
+
// 设置Secure标志
|
|
392
|
+
if (secure) {
|
|
393
|
+
cookieString += '; secure';
|
|
394
|
+
}
|
|
395
|
+
// 设置SameSite属性
|
|
396
|
+
if (sameSite) {
|
|
397
|
+
cookieString += `; samesite=${sameSite}`;
|
|
398
|
+
}
|
|
399
|
+
// 设置Cookie
|
|
400
|
+
document.cookie = cookieString;
|
|
401
|
+
}
|
|
303
402
|
function getUrlParamByKey(key) {
|
|
304
403
|
var _a, _b;
|
|
305
404
|
const queryString = location.search.slice(1);
|
|
@@ -315,6 +414,24 @@
|
|
|
315
414
|
return (_b = params[key]) !== null && _b !== void 0 ? _b : '';
|
|
316
415
|
}
|
|
317
416
|
|
|
417
|
+
var tool = /*#__PURE__*/Object.freeze({
|
|
418
|
+
__proto__: null,
|
|
419
|
+
deleteCookie: deleteCookie,
|
|
420
|
+
generateRandomString: generateRandomString,
|
|
421
|
+
getBrowserInfo: getBrowserInfo,
|
|
422
|
+
getCookie: getCookie,
|
|
423
|
+
getDevice: getDevice$1,
|
|
424
|
+
getIndexByblockType: getIndexByblockType,
|
|
425
|
+
getScreenReader: getScreenReader,
|
|
426
|
+
getSystem: getSystem,
|
|
427
|
+
getUid: getUid,
|
|
428
|
+
getUrlParamByKey: getUrlParamByKey,
|
|
429
|
+
setCookie: setCookie,
|
|
430
|
+
setFontForText: setFontForText,
|
|
431
|
+
splitUrlParams: splitUrlParams,
|
|
432
|
+
uuid: uuid
|
|
433
|
+
});
|
|
434
|
+
|
|
318
435
|
function unzip(b64Data) {
|
|
319
436
|
const strData = atob(b64Data);
|
|
320
437
|
const charData = strData.split('').map(function (x) {
|
|
@@ -499,6 +616,18 @@
|
|
|
499
616
|
const getFeSessionId = () => {
|
|
500
617
|
return window.localStorage.getItem(feRealSessionIdKey);
|
|
501
618
|
};
|
|
619
|
+
// 删除sessionID
|
|
620
|
+
const removeFeSessionId = () => {
|
|
621
|
+
window.localStorage.removeItem(feRealSessionIdKey);
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
var sessionStore = /*#__PURE__*/Object.freeze({
|
|
625
|
+
__proto__: null,
|
|
626
|
+
getFeSessionId: getFeSessionId,
|
|
627
|
+
refreshFeSessionId: refreshFeSessionId,
|
|
628
|
+
removeFeSessionId: removeFeSessionId,
|
|
629
|
+
storeAndLoadFeSessionId: storeAndLoadFeSessionId
|
|
630
|
+
});
|
|
502
631
|
|
|
503
632
|
/*
|
|
504
633
|
* @Author: binruan@chatlabs.com
|
|
@@ -522,6 +651,9 @@
|
|
|
522
651
|
}
|
|
523
652
|
return fakeUserId;
|
|
524
653
|
};
|
|
654
|
+
const removeFeUserId = () => {
|
|
655
|
+
window.localStorage.removeItem(FAKE_USER_KEY);
|
|
656
|
+
};
|
|
525
657
|
const getFeUserState = () => {
|
|
526
658
|
const fakeUserState = window.localStorage.getItem(FAKE_USER_STATE);
|
|
527
659
|
if (lodash.isEmpty(fakeUserState)) {
|
|
@@ -551,6 +683,24 @@
|
|
|
551
683
|
window.localStorage.setItem(USER_CONSENT_RESULT_KEY, 'true');
|
|
552
684
|
};
|
|
553
685
|
|
|
686
|
+
var localStore = /*#__PURE__*/Object.freeze({
|
|
687
|
+
__proto__: null,
|
|
688
|
+
AGREE_POLICY: AGREE_POLICY,
|
|
689
|
+
CCONTSENT_STATE: CCONTSENT_STATE,
|
|
690
|
+
FAKE_USER_KEY: FAKE_USER_KEY,
|
|
691
|
+
FAKE_USER_STATE: FAKE_USER_STATE,
|
|
692
|
+
SLIDE_SKIP_STATE: SLIDE_SKIP_STATE,
|
|
693
|
+
USER_CONSENT_RESULT_KEY: USER_CONSENT_RESULT_KEY,
|
|
694
|
+
getContsentState: getContsentState,
|
|
695
|
+
getFeUserState: getFeUserState,
|
|
696
|
+
getSlideSkipState: getSlideSkipState,
|
|
697
|
+
getUserConsentResult: getUserConsentResult,
|
|
698
|
+
removeFeUserId: removeFeUserId,
|
|
699
|
+
setSlideSkipState: setSlideSkipState,
|
|
700
|
+
setUserConsentResult: setUserConsentResult,
|
|
701
|
+
storeAndLoadFeUserId: storeAndLoadFeUserId
|
|
702
|
+
});
|
|
703
|
+
|
|
554
704
|
/*
|
|
555
705
|
* @Author: binruan@chatlabs.com
|
|
556
706
|
* @Date: 2024-03-20 10:27:31
|
|
@@ -1759,6 +1909,23 @@
|
|
|
1759
1909
|
DATA_TYPE["ARRAY_NUMBER"] = "array-number";
|
|
1760
1910
|
})(DATA_TYPE || (DATA_TYPE = {}));
|
|
1761
1911
|
|
|
1912
|
+
/*
|
|
1913
|
+
* @Author: binruan@chatlabs.com
|
|
1914
|
+
* @Date: 2024-03-20 10:27:31
|
|
1915
|
+
* @LastEditors: binruan@chatlabs.com
|
|
1916
|
+
* @LastEditTime: 2024-03-20 13:56:49
|
|
1917
|
+
* @FilePath: \pb-sxp-ui\src\core\hooks\index.ts
|
|
1918
|
+
*
|
|
1919
|
+
*/
|
|
1920
|
+
|
|
1921
|
+
var index$4 = /*#__PURE__*/Object.freeze({
|
|
1922
|
+
__proto__: null,
|
|
1923
|
+
get DATA_TYPE () { return DATA_TYPE; },
|
|
1924
|
+
useDataSource: useDataSource,
|
|
1925
|
+
useEditor: useEditor,
|
|
1926
|
+
useSxpDataSource: useSxpDataSource
|
|
1927
|
+
});
|
|
1928
|
+
|
|
1762
1929
|
const DataSourceContext = React.createContext({ $store: {}, options: [], configs: [] });
|
|
1763
1930
|
const DataSourceProvider = ({ children, isSsr, enable }) => {
|
|
1764
1931
|
const [options, setOptions] = React.useState([]);
|
|
@@ -10538,7 +10705,7 @@
|
|
|
10538
10705
|
*
|
|
10539
10706
|
*/
|
|
10540
10707
|
const closeIcon$1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAjhJREFUWEfFlztOw0AQhmeWiJ4CCmpQ5DiRQsIJyAWg5A0lR0AIChDiCJS8ER0cADgBeRSxt4CCDgkaKiq8i+zYeWx2413HEWmiJJv9v535Z2aN8M8vFPT9z3zETD0aAUChUJjwvPFHAJhBhB3Hqd6OAsK2yyucwykAvP38eJX398Z3AJDLlVYR8ToU9Rhj25TWr9KEsKy5dULIGQCMtfZly45TvwsAstm56UwG6wA4FUFwzrdctxZBDcWSy5XWEPG8I84/GcMipdWPtgcsaz5PCHtKG0IuTiqUvjT9U/WYMG2IOPE+AP+LtCB0xKUAAyA2Xbd2o2OG0NQXvTnvhL17D7EPtH9TRCIWwkRcGYGIQgYBABuqPuHXOQBc6pw80lBGwBQiiXhsBHQhkoprA6iM6acjhDQKu5YJZW6XeOI3XJdpvfsdTu52VfXEekD8owQiXGIubpSCbhDbLu8DwKEAd+A41SOdPpE4BS0viFOtvV2iKWqUgn5x/tmS70xR01GuDSCKc86/OCcLgTyyZ0ScDGNhFAktAJV4NFJ9YyaFiAWIE+9uVkkgBgLoig8DMWAa9ro9ynkUdlW5maZDCmB6clmz0k1HH4Cs1Ezbq2p2yEpUuBOKTSZZex00RUWIrltxuuK6EOGDSbGIOPZicpMx6fny650377qNRgBgWeVFQuA+6UjVgREhGIMlSqsPUQqIbZdOOIdZQmCv2axRnU1N1+TzJYsxOEaEV8ep7frPZ7Gd0FTEdP0ft0/kMNdg0eoAAAAASUVORK5CYII=';
|
|
10541
|
-
const Modal = ({ visible, onClose, children, modalStyle, padding, popup, schema, fullHeight, isFullScreen = false, openState }) => {
|
|
10708
|
+
const Modal = ({ visible, onClose, children, modalStyle, padding, popup, schema, fullHeight, isFullScreen = false, openState, showCloseButton = true }) => {
|
|
10542
10709
|
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;
|
|
10543
10710
|
const { visibleHeight, bottomHeight } = useVisibleHeight();
|
|
10544
10711
|
const touchRef = React.useRef(null);
|
|
@@ -10718,8 +10885,8 @@
|
|
|
10718
10885
|
setScrollTop(15 - ((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.scrollTop));
|
|
10719
10886
|
}
|
|
10720
10887
|
})), child()),
|
|
10721
|
-
React.createElement("button", { className: 'modal-icon-wrapper', role: 'button', "aria-label": 'close button', onClick: onClose, style: { top: scrollTop } },
|
|
10722
|
-
React.createElement("img", { src: (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.popupCloseIcon) || closeIcon$1, alt: 'close button', className: 'modal-icon' }))))))), modalEleRef.current);
|
|
10888
|
+
showCloseButton && (React.createElement("button", { className: 'modal-icon-wrapper', role: 'button', "aria-label": 'close button', onClick: onClose, style: { top: scrollTop } },
|
|
10889
|
+
React.createElement("img", { src: (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.popupCloseIcon) || closeIcon$1, alt: 'close button', className: 'modal-icon' })))))))), modalEleRef.current);
|
|
10723
10890
|
};
|
|
10724
10891
|
var Modal$1 = React.memo(Modal);
|
|
10725
10892
|
|
|
@@ -11907,18 +12074,248 @@
|
|
|
11907
12074
|
}
|
|
11908
12075
|
];
|
|
11909
12076
|
|
|
12077
|
+
const AddToCartPopup$1 = ({ isActive = true }) => {
|
|
12078
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
12079
|
+
const { popupDetailData, globalConfig } = useSxpDataSource();
|
|
12080
|
+
const [productData, setProductData] = React.useState(null);
|
|
12081
|
+
const [selectedOptions, setSelectedOptions] = React.useState({});
|
|
12082
|
+
const [selectedVariant, setSelectedVariant] = React.useState(null);
|
|
12083
|
+
const [quantity, setQuantity] = React.useState(1);
|
|
12084
|
+
const [loading, setLoading] = React.useState(true);
|
|
12085
|
+
const [error, setError] = React.useState(null);
|
|
12086
|
+
const [showImagePreview, setShowImagePreview] = React.useState(false);
|
|
12087
|
+
const [previewImageUrl, setPreviewImageUrl] = React.useState('');
|
|
12088
|
+
// 获取商品数据
|
|
12089
|
+
const data = popupDetailData;
|
|
12090
|
+
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;
|
|
12091
|
+
// Shopify 配置
|
|
12092
|
+
const shopifyConfig = window.__SHOPIFY_CONFIG__;
|
|
12093
|
+
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';
|
|
12094
|
+
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';
|
|
12095
|
+
const productId = (product === null || product === void 0 ? void 0 : product.shopifyId) || (product === null || product === void 0 ? void 0 : product.itemId) || '';
|
|
12096
|
+
// 查询 Shopify 商品数据
|
|
12097
|
+
const fetchProductData = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
12098
|
+
var _k;
|
|
12099
|
+
if (!productId || !shopifyDomain || !storefrontToken) {
|
|
12100
|
+
setLoading(false);
|
|
12101
|
+
return;
|
|
12102
|
+
}
|
|
12103
|
+
setLoading(true);
|
|
12104
|
+
setError(null);
|
|
12105
|
+
try {
|
|
12106
|
+
const query = `
|
|
12107
|
+
query getProduct($id: ID!) {
|
|
12108
|
+
product(id: $id) {
|
|
12109
|
+
id
|
|
12110
|
+
title
|
|
12111
|
+
images(first: 10) {
|
|
12112
|
+
edges {
|
|
12113
|
+
node {
|
|
12114
|
+
url
|
|
12115
|
+
}
|
|
12116
|
+
}
|
|
12117
|
+
}
|
|
12118
|
+
options {
|
|
12119
|
+
name
|
|
12120
|
+
values
|
|
12121
|
+
}
|
|
12122
|
+
variants(first: 100) {
|
|
12123
|
+
edges {
|
|
12124
|
+
node {
|
|
12125
|
+
id
|
|
12126
|
+
title
|
|
12127
|
+
availableForSale
|
|
12128
|
+
quantityAvailable
|
|
12129
|
+
price {
|
|
12130
|
+
amount
|
|
12131
|
+
currencyCode
|
|
12132
|
+
}
|
|
12133
|
+
image {
|
|
12134
|
+
url
|
|
12135
|
+
}
|
|
12136
|
+
selectedOptions {
|
|
12137
|
+
name
|
|
12138
|
+
value
|
|
12139
|
+
}
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
}
|
|
12143
|
+
}
|
|
12144
|
+
}
|
|
12145
|
+
`;
|
|
12146
|
+
const fullProductId = productId.startsWith('gid://') ? productId : `gid://shopify/Product/${productId}`;
|
|
12147
|
+
const response = yield fetch(`https://${shopifyDomain}/api/2024-01/graphql.json`, {
|
|
12148
|
+
method: 'POST',
|
|
12149
|
+
headers: {
|
|
12150
|
+
'Content-Type': 'application/json',
|
|
12151
|
+
'X-Shopify-Storefront-Access-Token': storefrontToken
|
|
12152
|
+
},
|
|
12153
|
+
body: JSON.stringify({
|
|
12154
|
+
query,
|
|
12155
|
+
variables: { id: fullProductId }
|
|
12156
|
+
})
|
|
12157
|
+
});
|
|
12158
|
+
const result = yield response.json();
|
|
12159
|
+
if (result.errors) {
|
|
12160
|
+
throw new Error(result.errors[0].message);
|
|
12161
|
+
}
|
|
12162
|
+
console.log('[AddToCart] Shopify Product Data:', result.data.product);
|
|
12163
|
+
console.log('[AddToCart] Options:', (_k = result.data.product) === null || _k === void 0 ? void 0 : _k.options);
|
|
12164
|
+
setProductData(result.data.product);
|
|
12165
|
+
}
|
|
12166
|
+
catch (err) {
|
|
12167
|
+
setError(err instanceof Error ? err.message : 'Failed to load product');
|
|
12168
|
+
console.error('[AddToCartPopup] 加载失败:', err);
|
|
12169
|
+
}
|
|
12170
|
+
finally {
|
|
12171
|
+
setLoading(false);
|
|
12172
|
+
}
|
|
12173
|
+
}), [productId, shopifyDomain, storefrontToken]);
|
|
12174
|
+
React.useEffect(() => {
|
|
12175
|
+
if (isActive) {
|
|
12176
|
+
fetchProductData();
|
|
12177
|
+
}
|
|
12178
|
+
}, [isActive, fetchProductData]);
|
|
12179
|
+
// 根据选中的规格匹配 variant
|
|
12180
|
+
React.useEffect(() => {
|
|
12181
|
+
if (!productData)
|
|
12182
|
+
return;
|
|
12183
|
+
const variants = productData.variants.edges.map(edge => edge.node);
|
|
12184
|
+
const optionsCount = productData.options.length;
|
|
12185
|
+
const selectedCount = Object.keys(selectedOptions).length;
|
|
12186
|
+
if (selectedCount === 0 || selectedCount < optionsCount) {
|
|
12187
|
+
setSelectedVariant(null);
|
|
12188
|
+
return;
|
|
12189
|
+
}
|
|
12190
|
+
const matchedVariant = variants.find(variant => {
|
|
12191
|
+
return variant.selectedOptions.every(option => {
|
|
12192
|
+
return selectedOptions[option.name] === option.value;
|
|
12193
|
+
});
|
|
12194
|
+
});
|
|
12195
|
+
setSelectedVariant(matchedVariant || null);
|
|
12196
|
+
// 当 variant 改变时,如果有库存数量限制,确保数量不超过库存
|
|
12197
|
+
if ((matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.quantityAvailable) !== undefined && matchedVariant.quantityAvailable > 0) {
|
|
12198
|
+
setQuantity(prev => Math.min(prev, matchedVariant.quantityAvailable));
|
|
12199
|
+
}
|
|
12200
|
+
}, [selectedOptions, productData]);
|
|
12201
|
+
// 处理规格选择
|
|
12202
|
+
const handleOptionSelect = (optionName, value) => {
|
|
12203
|
+
setSelectedOptions(prev => (Object.assign(Object.assign({}, prev), { [optionName]: value })));
|
|
12204
|
+
};
|
|
12205
|
+
// 处理加购
|
|
12206
|
+
const handleAddToCart = () => {
|
|
12207
|
+
if (!selectedVariant) {
|
|
12208
|
+
alert('Please select all options');
|
|
12209
|
+
return;
|
|
12210
|
+
}
|
|
12211
|
+
// 提取 variant ID(去掉 gid://shopify/ProductVariant/ 前缀)
|
|
12212
|
+
const variantId = selectedVariant.id.replace('gid://shopify/ProductVariant/', '');
|
|
12213
|
+
console.log('[AddToCart] 添加到购物车:', {
|
|
12214
|
+
variantId,
|
|
12215
|
+
quantity,
|
|
12216
|
+
shopifyDomain,
|
|
12217
|
+
selectedVariant
|
|
12218
|
+
});
|
|
12219
|
+
// 使用 Shopify 的 /cart/add 接口,通过查询参数添加商品
|
|
12220
|
+
// 这种方式会跳转到购物车页面而不是结算页面
|
|
12221
|
+
const params = new URLSearchParams({
|
|
12222
|
+
id: variantId,
|
|
12223
|
+
quantity: quantity.toString()
|
|
12224
|
+
});
|
|
12225
|
+
const cartUrl = `https://${shopifyDomain}/cart/add?${params.toString()}`;
|
|
12226
|
+
console.log('[AddToCart] 跳转到购物车 URL:', cartUrl);
|
|
12227
|
+
window.location.href = cartUrl;
|
|
12228
|
+
};
|
|
12229
|
+
// 计算总价
|
|
12230
|
+
const totalPrice = selectedVariant
|
|
12231
|
+
? (parseFloat(selectedVariant.price.amount) * quantity).toFixed(2)
|
|
12232
|
+
: '0.00';
|
|
12233
|
+
if (loading) {
|
|
12234
|
+
return (React.createElement("div", { className: 'add-to-cart-popup' },
|
|
12235
|
+
React.createElement("div", { className: 'loading' }, "Loading...")));
|
|
12236
|
+
}
|
|
12237
|
+
if (error) {
|
|
12238
|
+
return (React.createElement("div", { className: 'add-to-cart-popup' },
|
|
12239
|
+
React.createElement("div", { className: 'error' }, error)));
|
|
12240
|
+
}
|
|
12241
|
+
if (!productData) {
|
|
12242
|
+
return null;
|
|
12243
|
+
}
|
|
12244
|
+
const mainImage = ((_h = productData.images.edges[0]) === null || _h === void 0 ? void 0 : _h.node.url) || '';
|
|
12245
|
+
const variantImage = ((_j = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.image) === null || _j === void 0 ? void 0 : _j.url) || mainImage;
|
|
12246
|
+
const maxQuantity = (selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) || 999; // 如果没有库存数据,默认允许最多 999
|
|
12247
|
+
return (React.createElement("div", { className: 'add-to-cart-popup' },
|
|
12248
|
+
React.createElement("div", { className: 'popup-content' },
|
|
12249
|
+
React.createElement("div", { className: 'product-header' },
|
|
12250
|
+
React.createElement("div", { className: 'product-title' }, productData.title)),
|
|
12251
|
+
React.createElement("div", { className: 'variant-detail' },
|
|
12252
|
+
React.createElement("div", { className: 'variant-image-container', onClick: () => {
|
|
12253
|
+
if (variantImage) {
|
|
12254
|
+
setPreviewImageUrl(variantImage);
|
|
12255
|
+
setShowImagePreview(true);
|
|
12256
|
+
}
|
|
12257
|
+
}, style: { cursor: 'pointer' } },
|
|
12258
|
+
React.createElement("img", { src: variantImage, alt: 'Selected variant', className: 'variant-image' })),
|
|
12259
|
+
React.createElement("div", { className: 'variant-info' },
|
|
12260
|
+
React.createElement("div", { className: 'variant-specs-row' },
|
|
12261
|
+
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"))),
|
|
12262
|
+
selectedVariant && selectedVariant.quantityAvailable !== undefined && (React.createElement("div", { className: 'stock-info' },
|
|
12263
|
+
"Available: ",
|
|
12264
|
+
selectedVariant.quantityAvailable))),
|
|
12265
|
+
React.createElement("div", { className: 'variant-price-row' },
|
|
12266
|
+
React.createElement("div", { className: 'price' },
|
|
12267
|
+
"$",
|
|
12268
|
+
totalPrice),
|
|
12269
|
+
React.createElement("div", { className: 'quantity-selector' },
|
|
12270
|
+
React.createElement("button", { className: 'qty-btn', onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1 }, "\u2212"),
|
|
12271
|
+
React.createElement("span", { className: 'qty-value' }, quantity),
|
|
12272
|
+
React.createElement("button", { className: 'qty-btn', onClick: () => setQuantity(quantity + 1), disabled: !selectedVariant || quantity >= maxQuantity }, "+"))))),
|
|
12273
|
+
React.createElement("div", { className: 'variant-options' }, productData.options.map(option => (React.createElement("div", { key: option.name, className: 'option-group' },
|
|
12274
|
+
React.createElement("div", { className: 'option-label' }, option.name),
|
|
12275
|
+
React.createElement("div", { className: 'option-values' }, option.values.map(value => {
|
|
12276
|
+
// 检查这个选项是否可选(availableForSale = true,如果有 quantityAvailable 则还需 > 0)
|
|
12277
|
+
const isAvailable = productData.variants.edges.some(({ node: variant }) => {
|
|
12278
|
+
const hasThisOption = variant.selectedOptions.some(opt => opt.name === option.name && opt.value === value);
|
|
12279
|
+
if (!hasThisOption || !variant.availableForSale)
|
|
12280
|
+
return false;
|
|
12281
|
+
// 如果有 quantityAvailable 字段,则需要检查库存
|
|
12282
|
+
if (variant.quantityAvailable !== undefined) {
|
|
12283
|
+
return variant.quantityAvailable > 0;
|
|
12284
|
+
}
|
|
12285
|
+
// 没有 quantityAvailable 字段时,只要 availableForSale 为 true 就可选
|
|
12286
|
+
return true;
|
|
12287
|
+
});
|
|
12288
|
+
const isSelected = selectedOptions[option.name] === value;
|
|
12289
|
+
return (React.createElement("button", { key: value, className: `option-btn ${isSelected ? 'selected' : ''} ${!isAvailable ? 'disabled' : ''}`, onClick: () => isAvailable && handleOptionSelect(option.name, value), disabled: !isAvailable }, value));
|
|
12290
|
+
}))))))),
|
|
12291
|
+
React.createElement("div", { className: 'popup-footer' },
|
|
12292
|
+
React.createElement("button", { className: 'add-to-cart-btn', onClick: handleAddToCart, disabled: !selectedVariant }, "Add To Cart")),
|
|
12293
|
+
showImagePreview && previewImageUrl && (React.createElement(Modal$1, { visible: showImagePreview, padding: 0, isFullScreen: true, onClose: () => setShowImagePreview(false) },
|
|
12294
|
+
React.createElement("div", { style: {
|
|
12295
|
+
width: '100%',
|
|
12296
|
+
height: '100%',
|
|
12297
|
+
display: 'flex',
|
|
12298
|
+
alignItems: 'center',
|
|
12299
|
+
justifyContent: 'center',
|
|
12300
|
+
backgroundColor: 'rgba(0, 0, 0, 0.9)'
|
|
12301
|
+
}, onClick: () => setShowImagePreview(false) },
|
|
12302
|
+
React.createElement("img", { src: previewImageUrl, alt: 'Preview', style: {
|
|
12303
|
+
maxWidth: '100%',
|
|
12304
|
+
maxHeight: '100%',
|
|
12305
|
+
objectFit: 'contain'
|
|
12306
|
+
} }))))));
|
|
12307
|
+
};
|
|
12308
|
+
|
|
11910
12309
|
const CommodityDetailDiroNew$1 = (_a) => {
|
|
11911
|
-
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;
|
|
11912
|
-
var { style,
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
const {
|
|
11916
|
-
React.useState(false);
|
|
11917
|
-
React.useState(false);
|
|
11918
|
-
React.useState(true);
|
|
12310
|
+
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;
|
|
12311
|
+
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"]);
|
|
12312
|
+
const { sxpParameter, popupCurTimeRef, popupDetailData, setPopupDetailData, isPreview, bffFbReport, checkCommodityIndexRef, globalConfig, ctaEvent } = useSxpDataSource();
|
|
12313
|
+
useEditor();
|
|
12314
|
+
const { productView } = useEventReport();
|
|
11919
12315
|
const [showModal, setShowModal] = React.useState(false);
|
|
11920
12316
|
const curTimeRef = React.useRef(null);
|
|
11921
12317
|
const [show3DModal, setShow3DModal] = React.useState(false);
|
|
12318
|
+
const [showAddToCart, setShowAddToCart] = React.useState(false);
|
|
11922
12319
|
const [checkCommodityIndex, setCheckCommodityIndex] = React.useState((_b = popupDetailData === null || popupDetailData === void 0 ? void 0 : popupDetailData.multiCheckIndex) !== null && _b !== void 0 ? _b : 0);
|
|
11923
12320
|
const swiperRef = React.useRef();
|
|
11924
12321
|
const [swiperActiveIndex, setSwiperActiveIndex] = React.useState(0);
|
|
@@ -11935,30 +12332,30 @@
|
|
|
11935
12332
|
cta = p === null || p === void 0 ? void 0 : p.bindCta;
|
|
11936
12333
|
}
|
|
11937
12334
|
const handleLink = (e) => {
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
11957
|
-
target_url: product.link
|
|
11958
|
-
});
|
|
11959
|
-
}
|
|
11960
|
-
window.location.href = window.getJointUtmLink(product.link);
|
|
12335
|
+
e.preventDefault();
|
|
12336
|
+
// 上报点击事件
|
|
12337
|
+
ctaEvent === null || ctaEvent === void 0 ? void 0 : ctaEvent({
|
|
12338
|
+
eventSubject: 'clickCta',
|
|
12339
|
+
eventDescription: 'User clicked the CTA'
|
|
12340
|
+
}, data, product, position);
|
|
12341
|
+
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
12342
|
+
eventName: 'ClickCTA',
|
|
12343
|
+
product: product ? [product] : undefined,
|
|
12344
|
+
contentType: 'product',
|
|
12345
|
+
data,
|
|
12346
|
+
position,
|
|
12347
|
+
cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
|
|
12348
|
+
cta_action_type: 'open_internal_popup',
|
|
12349
|
+
target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
|
|
12350
|
+
target_url: product === null || product === void 0 ? void 0 : product.link
|
|
12351
|
+
});
|
|
12352
|
+
if (!isPost) {
|
|
12353
|
+
productView(data, product, cta, viewTime || curTimeRef.current, position);
|
|
11961
12354
|
}
|
|
12355
|
+
// 更新 popupDetailData,确保 AddToCart 组件能获取到商品数据
|
|
12356
|
+
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 }));
|
|
12357
|
+
// 打开 AddToCart 弹窗
|
|
12358
|
+
setShowAddToCart(true);
|
|
11962
12359
|
};
|
|
11963
12360
|
React.useEffect(() => {
|
|
11964
12361
|
var _a, _b;
|
|
@@ -11979,7 +12376,7 @@
|
|
|
11979
12376
|
rec: recData,
|
|
11980
12377
|
position
|
|
11981
12378
|
});
|
|
11982
|
-
}, [isActive, bffFbReport, isPost]);
|
|
12379
|
+
}, [isActive, bffFbReport, isPost, data, product, position]);
|
|
11983
12380
|
React.useEffect(() => {
|
|
11984
12381
|
if (!isActive || isPost)
|
|
11985
12382
|
return;
|
|
@@ -12107,13 +12504,13 @@ Made in Italy` })));
|
|
|
12107
12504
|
swiperRef.current.swiper.slideTo(0);
|
|
12108
12505
|
swiperRef.current.swiper.autoplay.start();
|
|
12109
12506
|
}
|
|
12110
|
-
}, []);
|
|
12507
|
+
}, [popupCurTimeRef, checkCommodityIndexRef]);
|
|
12111
12508
|
const renderCommodityGroup = React.useCallback(() => {
|
|
12112
12509
|
var _a, _b, _c;
|
|
12113
12510
|
if (isPost)
|
|
12114
12511
|
return;
|
|
12115
12512
|
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 }));
|
|
12116
|
-
}, [checkCommodityIndex]);
|
|
12513
|
+
}, [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]);
|
|
12117
12514
|
const getDotsAlign = React.useMemo(() => {
|
|
12118
12515
|
const dotsAlignClass = {
|
|
12119
12516
|
left: 'commondityDetail-swiper-clickable-left',
|
|
@@ -12123,24 +12520,24 @@ Made in Italy` })));
|
|
|
12123
12520
|
return dotsAlignClass === null || dotsAlignClass === void 0 ? void 0 : dotsAlignClass[swiper === null || swiper === void 0 ? void 0 : swiper.dotsAlign];
|
|
12124
12521
|
}, [swiper === null || swiper === void 0 ? void 0 : swiper.dotsAlign]);
|
|
12125
12522
|
const iframeUrl = product === null || product === void 0 ? void 0 : product.remark;
|
|
12523
|
+
const isAlly = React.useMemo(() => getScreenReader(), []);
|
|
12126
12524
|
const handleMouseEnter = React.useCallback(() => {
|
|
12127
12525
|
if (swiperRef.current && swiperRef.current.swiper && isAlly) {
|
|
12128
12526
|
swiperRef.current.swiper.autoplay.stop();
|
|
12129
12527
|
}
|
|
12130
|
-
}, []);
|
|
12528
|
+
}, [isAlly]);
|
|
12131
12529
|
const handleMouseLeave = React.useCallback(() => {
|
|
12132
12530
|
if (swiperRef.current && swiperRef.current.swiper && isAlly) {
|
|
12133
12531
|
swiperRef.current.swiper.autoplay.start();
|
|
12134
12532
|
}
|
|
12135
|
-
}, []);
|
|
12533
|
+
}, [isAlly]);
|
|
12136
12534
|
const handleSlideChange = React.useCallback((swiper) => {
|
|
12137
12535
|
setSwiperActiveIndex(swiper.activeIndex);
|
|
12138
12536
|
}, []);
|
|
12139
|
-
const isAlly = React.useMemo(() => getScreenReader(), []);
|
|
12140
12537
|
return (React.createElement("div", { className: 'pb-commondityDiroNew' },
|
|
12141
12538
|
React.createElement("div", Object.assign({ className: css.css(Object.assign(Object.assign({}, style), { transform: 'translate3d(0px, 0px, 0px)' })) }, props),
|
|
12142
12539
|
React.createElement("div", { style: { position: 'relative' }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
|
|
12143
|
-
product && ((
|
|
12540
|
+
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: {
|
|
12144
12541
|
clickable: true,
|
|
12145
12542
|
bulletActiveClass: 'swipe-item-active-bullet',
|
|
12146
12543
|
clickableClass: getDotsAlign,
|
|
@@ -12157,7 +12554,7 @@ Made in Italy` })));
|
|
|
12157
12554
|
: {}), { loop: true, ref: swiperRef, onSlideChange: handleSlideChange, autoplay: {
|
|
12158
12555
|
delay: (swiper === null || swiper === void 0 ? void 0 : swiper.delay) * 1000
|
|
12159
12556
|
}, className: css.css(Object.assign(Object.assign({ '.swiper-pagination': {
|
|
12160
|
-
bottom: (
|
|
12557
|
+
bottom: (_y = swiper === null || swiper === void 0 ? void 0 : swiper.dotsMarginBottom) !== null && _y !== void 0 ? _y : 0,
|
|
12161
12558
|
fontSize: '14px'
|
|
12162
12559
|
} }, ((swiper === null || swiper === void 0 ? void 0 : swiper.dotsBgColor) && {
|
|
12163
12560
|
'.swiper-pagination-bullet': {
|
|
@@ -12169,7 +12566,7 @@ Made in Italy` })));
|
|
|
12169
12566
|
backgroundColor: `${swiper === null || swiper === void 0 ? void 0 : swiper.dotsActiveColor}!important`,
|
|
12170
12567
|
opacity: 1
|
|
12171
12568
|
}
|
|
12172
|
-
}))) }), (
|
|
12569
|
+
}))) }), (_z = product === null || product === void 0 ? void 0 : product.homePage) === null || _z === void 0 ? void 0 : _z.map((src, srcKey) => {
|
|
12173
12570
|
var _a;
|
|
12174
12571
|
return (React.createElement(SwiperSlide, { key: srcKey, "aria-hidden": srcKey !== swiperActiveIndex },
|
|
12175
12572
|
React.createElement("div", { style: {
|
|
@@ -12185,7 +12582,7 @@ Made in Italy` })));
|
|
|
12185
12582
|
objectPosition: `50% ${(swiper === null || swiper === void 0 ? void 0 : swiper.translateY) ? (swiper === null || swiper === void 0 ? void 0 : swiper.translateY) + 50 : 50}%`
|
|
12186
12583
|
}, 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 }))));
|
|
12187
12584
|
}))),
|
|
12188
|
-
!((
|
|
12585
|
+
!((_0 = product === null || product === void 0 ? void 0 : product.homePage) === null || _0 === void 0 ? void 0 : _0.length) && (React.createElement("div", { className: css.css({
|
|
12189
12586
|
height,
|
|
12190
12587
|
width
|
|
12191
12588
|
}) },
|
|
@@ -12193,7 +12590,7 @@ Made in Italy` })));
|
|
|
12193
12590
|
objectFit: 'cover',
|
|
12194
12591
|
width: '100%',
|
|
12195
12592
|
height: '100%'
|
|
12196
|
-
}), src: (
|
|
12593
|
+
}), src: (_1 = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _1 !== void 0 ? _1 : bottom_image, alt: 'pdp image' }))),
|
|
12197
12594
|
(iframeUrl || !product) && iframeIcon && (React.createElement("div", { style: {
|
|
12198
12595
|
display: 'flex',
|
|
12199
12596
|
alignItems: 'center',
|
|
@@ -12210,7 +12607,7 @@ Made in Italy` })));
|
|
|
12210
12607
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top' },
|
|
12211
12608
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top-left' },
|
|
12212
12609
|
React.createElement("div", { className: 'pb-commondityDiroNew-content-top-left-title', style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title), dangerouslySetInnerHTML: {
|
|
12213
|
-
__html: setFontForText((
|
|
12610
|
+
__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)
|
|
12214
12611
|
} }),
|
|
12215
12612
|
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: {
|
|
12216
12613
|
__html: setFontForText((product === null || product === void 0 ? void 0 : product.collection) || 'Black Macrocannage CalfskinLarge', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection)
|
|
@@ -12220,11 +12617,11 @@ Made in Italy` })));
|
|
|
12220
12617
|
__html: priceText !== null && priceText !== void 0 ? priceText : ''
|
|
12221
12618
|
} }),
|
|
12222
12619
|
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: {
|
|
12223
|
-
__html: setFontForText((
|
|
12620
|
+
__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)
|
|
12224
12621
|
} }))),
|
|
12225
|
-
React.createElement("a", { "aria-label": (
|
|
12622
|
+
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 },
|
|
12226
12623
|
React.createElement("span", { dangerouslySetInnerHTML: {
|
|
12227
|
-
__html: setFontForText((
|
|
12624
|
+
__html: setFontForText((_5 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _5 !== void 0 ? _5 : 'Shop now', buttonStyle)
|
|
12228
12625
|
} })),
|
|
12229
12626
|
productInfoText({ isPost }))),
|
|
12230
12627
|
React.createElement(Modal$1, { visible: showModal, onClose: () => setShowModal(false) },
|
|
@@ -12236,7 +12633,9 @@ Made in Italy` })));
|
|
|
12236
12633
|
height: 'calc(100% - 50px)',
|
|
12237
12634
|
marginTop: '50px',
|
|
12238
12635
|
border: 'none'
|
|
12239
|
-
} })))
|
|
12636
|
+
} }))),
|
|
12637
|
+
showAddToCart && (React.createElement(Modal$1, { visible: showAddToCart, padding: 0, isFullScreen: false, onClose: () => setShowAddToCart(false) },
|
|
12638
|
+
React.createElement(AddToCartPopup$1, { isActive: true })))));
|
|
12240
12639
|
};
|
|
12241
12640
|
var CommodityDetailDiroNewComponent = React.memo(CommodityDetailDiroNew$1);
|
|
12242
12641
|
|
|
@@ -13238,296 +13637,6 @@ Made in Italy` })));
|
|
|
13238
13637
|
React.createElement("li", null, "\u65E0\u5E93\u5B58\u6216\u4E0D\u53EF\u552E\u5356\u7684\u89C4\u683C\u81EA\u52A8\u7F6E\u7070\u4E0D\u53EF\u9009"))));
|
|
13239
13638
|
};
|
|
13240
13639
|
|
|
13241
|
-
const AddToCartPopup$1 = (_a) => {
|
|
13242
|
-
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
13243
|
-
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"]);
|
|
13244
|
-
const { sxpParameter, popupDetailData, isPreview, bffFbReport, globalConfig } = useSxpDataSource();
|
|
13245
|
-
useEventReport();
|
|
13246
|
-
const curTimeRef = React.useRef(null);
|
|
13247
|
-
const [productData, setProductData] = React.useState(null);
|
|
13248
|
-
const [selectedOptions, setSelectedOptions] = React.useState({});
|
|
13249
|
-
const [selectedVariant, setSelectedVariant] = React.useState(null);
|
|
13250
|
-
const [quantity, setQuantity] = React.useState(1);
|
|
13251
|
-
const [loading, setLoading] = React.useState(true);
|
|
13252
|
-
const [error, setError] = React.useState(null);
|
|
13253
|
-
// 获取当前弹窗商品数据(自动从 popupDetailData 获取)
|
|
13254
|
-
const data = popupDetailData;
|
|
13255
|
-
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];
|
|
13256
|
-
product === null || product === void 0 ? void 0 : product.bindCta;
|
|
13257
|
-
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;
|
|
13258
|
-
// Shopify配置 - 优先级:props > globalConfig > 默认值
|
|
13259
|
-
const finalShopifyDomain = shopifyDomain || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopifyDomain) || 'dev-store-749237498237498636.myshopify.com';
|
|
13260
|
-
const finalStorefrontToken = storefrontAccessToken || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.storefrontAccessToken) || '77d894c490f79430ce7bd0a7efdff6b7';
|
|
13261
|
-
// 自动从商品数据获取 Shopify Product ID
|
|
13262
|
-
const productId = (product === null || product === void 0 ? void 0 : product.itemId) || '';
|
|
13263
|
-
// 文案
|
|
13264
|
-
const finalTexts = {
|
|
13265
|
-
addToCart: texts.addToCart || 'Add to Cart',
|
|
13266
|
-
selectOptions: texts.selectOptions || 'Please select options',
|
|
13267
|
-
loading: texts.loading || 'Loading...',
|
|
13268
|
-
error: texts.error || 'Failed to load product',
|
|
13269
|
-
color: texts.color || 'Color',
|
|
13270
|
-
size: texts.size || 'Size',
|
|
13271
|
-
material: texts.material || 'Material',
|
|
13272
|
-
style: texts.style || 'Style'
|
|
13273
|
-
};
|
|
13274
|
-
// 查询Shopify商品数据
|
|
13275
|
-
const fetchProductData = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
13276
|
-
var _m;
|
|
13277
|
-
if (!productId || !finalShopifyDomain || !finalStorefrontToken) {
|
|
13278
|
-
console.log('[AddToCartPopup] 缺少必要配置:', {
|
|
13279
|
-
productId,
|
|
13280
|
-
shopifyDomain: finalShopifyDomain,
|
|
13281
|
-
hasToken: !!finalStorefrontToken
|
|
13282
|
-
});
|
|
13283
|
-
setLoading(false);
|
|
13284
|
-
return;
|
|
13285
|
-
}
|
|
13286
|
-
console.log('[AddToCartPopup] 开始加载商品数据:', {
|
|
13287
|
-
productId,
|
|
13288
|
-
shopifyDomain: finalShopifyDomain
|
|
13289
|
-
});
|
|
13290
|
-
setLoading(true);
|
|
13291
|
-
setError(null);
|
|
13292
|
-
try {
|
|
13293
|
-
const query = `
|
|
13294
|
-
query getProduct($id: ID!) {
|
|
13295
|
-
product(id: $id) {
|
|
13296
|
-
id
|
|
13297
|
-
title
|
|
13298
|
-
images(first: 10) {
|
|
13299
|
-
edges {
|
|
13300
|
-
node {
|
|
13301
|
-
url
|
|
13302
|
-
}
|
|
13303
|
-
}
|
|
13304
|
-
}
|
|
13305
|
-
options {
|
|
13306
|
-
name
|
|
13307
|
-
values
|
|
13308
|
-
}
|
|
13309
|
-
variants(first: 100) {
|
|
13310
|
-
edges {
|
|
13311
|
-
node {
|
|
13312
|
-
id
|
|
13313
|
-
title
|
|
13314
|
-
availableForSale
|
|
13315
|
-
quantityAvailable
|
|
13316
|
-
price {
|
|
13317
|
-
amount
|
|
13318
|
-
currencyCode
|
|
13319
|
-
}
|
|
13320
|
-
image {
|
|
13321
|
-
url
|
|
13322
|
-
}
|
|
13323
|
-
selectedOptions {
|
|
13324
|
-
name
|
|
13325
|
-
value
|
|
13326
|
-
}
|
|
13327
|
-
}
|
|
13328
|
-
}
|
|
13329
|
-
}
|
|
13330
|
-
}
|
|
13331
|
-
}
|
|
13332
|
-
`;
|
|
13333
|
-
// 确保 Product ID 格式正确
|
|
13334
|
-
const formattedProductId = productId.startsWith('gid://')
|
|
13335
|
-
? productId
|
|
13336
|
-
: `gid://shopify/Product/${productId}`;
|
|
13337
|
-
console.log('[AddToCartPopup] 使用的 Product ID:', formattedProductId);
|
|
13338
|
-
const response = yield fetch(`https://${finalShopifyDomain}/api/2024-01/graphql.json`, {
|
|
13339
|
-
method: 'POST',
|
|
13340
|
-
headers: {
|
|
13341
|
-
'Content-Type': 'application/json',
|
|
13342
|
-
'X-Shopify-Storefront-Access-Token': finalStorefrontToken
|
|
13343
|
-
},
|
|
13344
|
-
body: JSON.stringify({
|
|
13345
|
-
query,
|
|
13346
|
-
variables: { id: formattedProductId }
|
|
13347
|
-
})
|
|
13348
|
-
});
|
|
13349
|
-
if (!response.ok) {
|
|
13350
|
-
throw new Error(`HTTP ${response.status}`);
|
|
13351
|
-
}
|
|
13352
|
-
const result = yield response.json();
|
|
13353
|
-
if (result.errors) {
|
|
13354
|
-
console.error('[AddToCartPopup] GraphQL 错误:', result.errors);
|
|
13355
|
-
throw new Error(result.errors[0].message);
|
|
13356
|
-
}
|
|
13357
|
-
if (!((_m = result.data) === null || _m === void 0 ? void 0 : _m.product)) {
|
|
13358
|
-
console.error('[AddToCartPopup] 未找到商品');
|
|
13359
|
-
throw new Error('Product not found');
|
|
13360
|
-
}
|
|
13361
|
-
console.log('[AddToCartPopup] 商品数据加载成功:', result.data.product.title);
|
|
13362
|
-
setProductData(result.data.product);
|
|
13363
|
-
}
|
|
13364
|
-
catch (err) {
|
|
13365
|
-
const errorMessage = err instanceof Error ? err.message : finalTexts.error;
|
|
13366
|
-
setError(errorMessage);
|
|
13367
|
-
console.error('[AddToCartPopup] 加载失败:', err);
|
|
13368
|
-
}
|
|
13369
|
-
finally {
|
|
13370
|
-
setLoading(false);
|
|
13371
|
-
}
|
|
13372
|
-
}), [productId, finalShopifyDomain, finalStorefrontToken, finalTexts.error]);
|
|
13373
|
-
React.useEffect(() => {
|
|
13374
|
-
if (isActive) {
|
|
13375
|
-
fetchProductData();
|
|
13376
|
-
}
|
|
13377
|
-
}, [isActive, fetchProductData]);
|
|
13378
|
-
// 根据选中的规格匹配variant
|
|
13379
|
-
React.useEffect(() => {
|
|
13380
|
-
if (!productData)
|
|
13381
|
-
return;
|
|
13382
|
-
const variants = productData.variants.edges.map(edge => edge.node);
|
|
13383
|
-
const optionsCount = productData.options.length;
|
|
13384
|
-
const selectedCount = Object.keys(selectedOptions).length;
|
|
13385
|
-
if (selectedCount === 0 || selectedCount < optionsCount) {
|
|
13386
|
-
setSelectedVariant(null);
|
|
13387
|
-
return;
|
|
13388
|
-
}
|
|
13389
|
-
const matchedVariant = variants.find(variant => {
|
|
13390
|
-
return variant.selectedOptions.every(option => selectedOptions[option.name] === option.value);
|
|
13391
|
-
});
|
|
13392
|
-
setSelectedVariant(matchedVariant || null);
|
|
13393
|
-
setQuantity(1);
|
|
13394
|
-
}, [selectedOptions, productData]);
|
|
13395
|
-
// 处理规格选择
|
|
13396
|
-
const handleOptionSelect = React.useCallback((optionName, value) => {
|
|
13397
|
-
setSelectedOptions(prev => {
|
|
13398
|
-
const newOptions = Object.assign({}, prev);
|
|
13399
|
-
if (newOptions[optionName] === value) {
|
|
13400
|
-
delete newOptions[optionName];
|
|
13401
|
-
}
|
|
13402
|
-
else {
|
|
13403
|
-
newOptions[optionName] = value;
|
|
13404
|
-
}
|
|
13405
|
-
return newOptions;
|
|
13406
|
-
});
|
|
13407
|
-
}, []);
|
|
13408
|
-
// 处理数量变化
|
|
13409
|
-
const handleQuantityChange = React.useCallback((delta) => {
|
|
13410
|
-
setQuantity(prev => {
|
|
13411
|
-
var _a;
|
|
13412
|
-
const newQuantity = prev + delta;
|
|
13413
|
-
const maxQuantity = (_a = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) !== null && _a !== void 0 ? _a : 999;
|
|
13414
|
-
return Math.max(1, Math.min(newQuantity, maxQuantity));
|
|
13415
|
-
});
|
|
13416
|
-
}, [selectedVariant]);
|
|
13417
|
-
// 检查某个规格值是否可用
|
|
13418
|
-
const isOptionValueAvailable = React.useCallback((optionName, value) => {
|
|
13419
|
-
if (!productData)
|
|
13420
|
-
return false;
|
|
13421
|
-
const variants = productData.variants.edges.map(edge => edge.node);
|
|
13422
|
-
const tempOptions = Object.assign(Object.assign({}, selectedOptions), { [optionName]: value });
|
|
13423
|
-
return variants.some(variant => {
|
|
13424
|
-
const matches = variant.selectedOptions.every(option => !tempOptions[option.name] || tempOptions[option.name] === option.value);
|
|
13425
|
-
const hasStock = variant.quantityAvailable === null || variant.quantityAvailable > 0;
|
|
13426
|
-
return matches && variant.availableForSale && hasStock;
|
|
13427
|
-
});
|
|
13428
|
-
}, [productData, selectedOptions]);
|
|
13429
|
-
// 处理加购
|
|
13430
|
-
const handleAddToCart = React.useCallback(() => {
|
|
13431
|
-
var _a;
|
|
13432
|
-
if (!selectedVariant || quantity === 0)
|
|
13433
|
-
return;
|
|
13434
|
-
const variantId = selectedVariant.id.split('/').pop();
|
|
13435
|
-
const cartUrl = `https://${finalShopifyDomain}/cart/add?id=${variantId}&quantity=${quantity}`;
|
|
13436
|
-
console.log('[AddToCartPopup] 加购:', {
|
|
13437
|
-
variantId,
|
|
13438
|
-
quantity,
|
|
13439
|
-
cartUrl
|
|
13440
|
-
});
|
|
13441
|
-
// 上报事件
|
|
13442
|
-
bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
|
|
13443
|
-
eventName: 'AddToCart',
|
|
13444
|
-
product: product ? [product] : undefined,
|
|
13445
|
-
contentType: 'product',
|
|
13446
|
-
data,
|
|
13447
|
-
position,
|
|
13448
|
-
content_id: (_a = product === null || product === void 0 ? void 0 : product.itemId) !== null && _a !== void 0 ? _a : '',
|
|
13449
|
-
value: parseFloat(selectedVariant.price.amount) * quantity,
|
|
13450
|
-
currency: selectedVariant.price.currencyCode,
|
|
13451
|
-
contents: [{
|
|
13452
|
-
id: variantId,
|
|
13453
|
-
quantity
|
|
13454
|
-
}]
|
|
13455
|
-
});
|
|
13456
|
-
// 跳转到Shopify购物车页面
|
|
13457
|
-
window.location.href = cartUrl;
|
|
13458
|
-
}, [selectedVariant, quantity, finalShopifyDomain, bffFbReport, product, data, position]);
|
|
13459
|
-
// 计算总价
|
|
13460
|
-
const totalPrice = React.useMemo(() => {
|
|
13461
|
-
if (!selectedVariant)
|
|
13462
|
-
return null;
|
|
13463
|
-
const price = parseFloat(selectedVariant.price.amount);
|
|
13464
|
-
const total = price * quantity;
|
|
13465
|
-
return total.toFixed(2);
|
|
13466
|
-
}, [selectedVariant, quantity]);
|
|
13467
|
-
// 初始化时间
|
|
13468
|
-
React.useEffect(() => {
|
|
13469
|
-
const initTime = () => {
|
|
13470
|
-
curTimeRef.current = new Date();
|
|
13471
|
-
};
|
|
13472
|
-
initTime();
|
|
13473
|
-
window.addEventListener('pageshow', initTime);
|
|
13474
|
-
return () => {
|
|
13475
|
-
window.removeEventListener('pageshow', initTime);
|
|
13476
|
-
};
|
|
13477
|
-
}, []);
|
|
13478
|
-
// 加载中
|
|
13479
|
-
if (loading) {
|
|
13480
|
-
return (React.createElement("div", { className: "add-to-cart-popup-loading", style: style },
|
|
13481
|
-
React.createElement("div", null, finalTexts.loading)));
|
|
13482
|
-
}
|
|
13483
|
-
// 错误状态
|
|
13484
|
-
if (error || !productData) {
|
|
13485
|
-
return (React.createElement("div", { className: "add-to-cart-popup-error", style: style },
|
|
13486
|
-
React.createElement("div", null,
|
|
13487
|
-
finalTexts.error,
|
|
13488
|
-
": ",
|
|
13489
|
-
error || 'Product not found')));
|
|
13490
|
-
}
|
|
13491
|
-
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]) || '';
|
|
13492
|
-
const hasAllOptionsSelected = productData.options.length === Object.keys(selectedOptions).length;
|
|
13493
|
-
const isAddToCartDisabled = !selectedVariant || quantity === 0;
|
|
13494
|
-
return (React.createElement("div", Object.assign({ className: "add-to-cart-popup-container", style: style }, props),
|
|
13495
|
-
React.createElement("div", { className: "variant-detail-section" },
|
|
13496
|
-
React.createElement("div", { className: "variant-image-wrapper" },
|
|
13497
|
-
React.createElement("img", { src: mainImage, alt: productData.title, className: "variant-image" })),
|
|
13498
|
-
React.createElement("div", { className: "variant-info-wrapper" },
|
|
13499
|
-
React.createElement("h2", { className: "product-title-text", style: variantStyles.title, dangerouslySetInnerHTML: {
|
|
13500
|
-
__html: setFontForText(productData.title, variantStyles.title)
|
|
13501
|
-
} }),
|
|
13502
|
-
selectedVariant && (React.createElement(React.Fragment, null,
|
|
13503
|
-
React.createElement("div", { className: "selected-options-tags" }, selectedVariant.selectedOptions.map(option => (React.createElement("span", { key: option.name, className: "option-tag", style: variantStyles.selectedOption },
|
|
13504
|
-
option.name,
|
|
13505
|
-
": ",
|
|
13506
|
-
option.value)))),
|
|
13507
|
-
React.createElement("div", { className: "price-display" },
|
|
13508
|
-
React.createElement("span", { className: "price-value", style: variantStyles.price, dangerouslySetInnerHTML: {
|
|
13509
|
-
__html: setFontForText(`${selectedVariant.price.currencyCode} $${totalPrice}`, variantStyles.price)
|
|
13510
|
-
} })),
|
|
13511
|
-
React.createElement("div", { className: "quantity-selector-wrapper", style: quantityStyle },
|
|
13512
|
-
React.createElement("button", { className: "quantity-btn quantity-decrease", onClick: () => handleQuantityChange(-1), disabled: quantity <= 1, "aria-label": "Decrease quantity" }, "-"),
|
|
13513
|
-
React.createElement("input", { type: "number", value: quantity, readOnly: true, className: "quantity-input-field", "aria-label": "Quantity" }),
|
|
13514
|
-
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" }, "+")))),
|
|
13515
|
-
!hasAllOptionsSelected && (React.createElement("div", { className: "no-selection-hint", style: variantStyles.option }, finalTexts.selectOptions)))),
|
|
13516
|
-
React.createElement("div", { className: "variant-options-section" }, productData.options.map(option => (React.createElement("div", { key: option.name, className: "option-group-wrapper" },
|
|
13517
|
-
React.createElement("h3", { className: "option-group-name", style: variantStyles.option, dangerouslySetInnerHTML: {
|
|
13518
|
-
__html: setFontForText(option.name, variantStyles.option)
|
|
13519
|
-
} }),
|
|
13520
|
-
React.createElement("div", { className: "option-values-grid" }, option.values.map(value => {
|
|
13521
|
-
const isSelected = selectedOptions[option.name] === value;
|
|
13522
|
-
const isAvailable = isOptionValueAvailable(option.name, value);
|
|
13523
|
-
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));
|
|
13524
|
-
})))))),
|
|
13525
|
-
React.createElement("button", { className: `add-to-cart-button ${isAddToCartDisabled ? 'disabled' : ''}`, style: buttonStyle, onClick: handleAddToCart, disabled: isAddToCartDisabled, "aria-label": finalTexts.addToCart },
|
|
13526
|
-
React.createElement("span", { dangerouslySetInnerHTML: {
|
|
13527
|
-
__html: setFontForText(finalTexts.addToCart, buttonStyle)
|
|
13528
|
-
} }))));
|
|
13529
|
-
};
|
|
13530
|
-
|
|
13531
13640
|
/*
|
|
13532
13641
|
* @Author: tao
|
|
13533
13642
|
* @Date: 2026-01-12
|
|
@@ -13543,60 +13652,7 @@ Made in Italy` })));
|
|
|
13543
13652
|
interactionRender: interactionRender$d
|
|
13544
13653
|
},
|
|
13545
13654
|
defaulSetting: {
|
|
13546
|
-
props: {
|
|
13547
|
-
shopifyDomain: '',
|
|
13548
|
-
storefrontAccessToken: '',
|
|
13549
|
-
variantStyles: {
|
|
13550
|
-
title: {
|
|
13551
|
-
color: '#000',
|
|
13552
|
-
fontSize: 20,
|
|
13553
|
-
fontWeight: 600,
|
|
13554
|
-
marginBottom: 12
|
|
13555
|
-
},
|
|
13556
|
-
price: {
|
|
13557
|
-
color: '#000',
|
|
13558
|
-
fontSize: 24,
|
|
13559
|
-
fontWeight: 700,
|
|
13560
|
-
marginBottom: 16
|
|
13561
|
-
},
|
|
13562
|
-
option: {
|
|
13563
|
-
color: '#111',
|
|
13564
|
-
fontSize: 16,
|
|
13565
|
-
fontWeight: 600,
|
|
13566
|
-
marginBottom: 12
|
|
13567
|
-
},
|
|
13568
|
-
selectedOption: {
|
|
13569
|
-
fontSize: 14,
|
|
13570
|
-
color: '#374151'
|
|
13571
|
-
}
|
|
13572
|
-
},
|
|
13573
|
-
buttonStyle: {
|
|
13574
|
-
backgroundColor: '#000',
|
|
13575
|
-
color: '#fff',
|
|
13576
|
-
fontSize: 16,
|
|
13577
|
-
height: 52,
|
|
13578
|
-
fontWeight: 600,
|
|
13579
|
-
textAlign: 'center',
|
|
13580
|
-
textTransform: 'uppercase'
|
|
13581
|
-
},
|
|
13582
|
-
quantityStyle: {
|
|
13583
|
-
gap: 12
|
|
13584
|
-
},
|
|
13585
|
-
texts: {
|
|
13586
|
-
addToCart: 'Add to Cart',
|
|
13587
|
-
selectOptions: 'Please select options',
|
|
13588
|
-
loading: 'Loading...',
|
|
13589
|
-
error: 'Failed to load product',
|
|
13590
|
-
color: 'Color',
|
|
13591
|
-
size: 'Size',
|
|
13592
|
-
material: 'Material',
|
|
13593
|
-
style: 'Style'
|
|
13594
|
-
},
|
|
13595
|
-
popupBg: {
|
|
13596
|
-
horizontalMargin: 0,
|
|
13597
|
-
bottomMargin: 0
|
|
13598
|
-
}
|
|
13599
|
-
},
|
|
13655
|
+
props: {},
|
|
13600
13656
|
style: {}
|
|
13601
13657
|
},
|
|
13602
13658
|
w: 100,
|
|
@@ -19692,7 +19748,7 @@ Made in Italy` })));
|
|
|
19692
19748
|
return res.json();
|
|
19693
19749
|
})
|
|
19694
19750
|
.then((result) => {
|
|
19695
|
-
var _a, _b, _c, _d;
|
|
19751
|
+
var _a, _b, _c, _d, _e;
|
|
19696
19752
|
if (result.code === '0' || result.code === '00000') {
|
|
19697
19753
|
// 判断数据结构:CMS 模式和普通模式可能不同
|
|
19698
19754
|
let multiCtaData = null;
|
|
@@ -19711,6 +19767,14 @@ Made in Italy` })));
|
|
|
19711
19767
|
console.error('[StructurePage] No multiCta data found in response:', result);
|
|
19712
19768
|
setError(result.message || 'No multiCta data found');
|
|
19713
19769
|
}
|
|
19770
|
+
// 存储 Shopify 配置信息到 window 对象,供 AddToCart 弹窗使用
|
|
19771
|
+
if ((_e = result.data) === null || _e === void 0 ? void 0 : _e.shopify) {
|
|
19772
|
+
window.__SHOPIFY_CONFIG__ = {
|
|
19773
|
+
domain: result.data.shopify.domain,
|
|
19774
|
+
storefrontAccessToken: result.data.shopify.storefrontAccessToken
|
|
19775
|
+
};
|
|
19776
|
+
console.log('[StructurePage] Shopify config stored:', window.__SHOPIFY_CONFIG__);
|
|
19777
|
+
}
|
|
19714
19778
|
}
|
|
19715
19779
|
else {
|
|
19716
19780
|
setError(result.message || 'Failed to load data');
|
|
@@ -19892,7 +19956,13 @@ Made in Italy` })));
|
|
|
19892
19956
|
var index$3 = /*#__PURE__*/Object.freeze({
|
|
19893
19957
|
__proto__: null,
|
|
19894
19958
|
EditorCore: EditorCore,
|
|
19895
|
-
|
|
19959
|
+
Pagebuilder: Pagebuilder,
|
|
19960
|
+
StructurePage: StructurePage,
|
|
19961
|
+
createMaterial: createMaterial,
|
|
19962
|
+
hooks: index$4,
|
|
19963
|
+
localStore: localStore,
|
|
19964
|
+
sessionStore: sessionStore,
|
|
19965
|
+
tool: tool
|
|
19896
19966
|
});
|
|
19897
19967
|
|
|
19898
19968
|
/*
|