@gem-sdk/components 2.1.13-staging.0 → 2.1.13-staging.2
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/cjs/article/components/ArticleList.liquid.js +6 -2
- package/dist/cjs/post-purchase/product/components/ProductDiscountTag.js +5 -2
- package/dist/cjs/post-purchase/product/components/ProductOffer.js +16 -3
- package/dist/cjs/post-purchase/product/components/ProductPrice.js +3 -1
- package/dist/cjs/post-purchase/product/components/ProductPriceBreakdown.js +9 -21
- package/dist/cjs/post-purchase/product/constants/ProductOfferPlaceholder.js +127 -0
- package/dist/cjs/post-purchase/product/hooks/useDynamicProduct.js +28 -0
- package/dist/cjs/post-purchase/product/settings/ProductOffer.js +26 -0
- package/dist/esm/article/components/ArticleList.liquid.js +6 -2
- package/dist/esm/post-purchase/product/components/ProductDiscountTag.js +5 -2
- package/dist/esm/post-purchase/product/components/ProductOffer.js +16 -3
- package/dist/esm/post-purchase/product/components/ProductPrice.js +3 -1
- package/dist/esm/post-purchase/product/components/ProductPriceBreakdown.js +9 -21
- package/dist/esm/post-purchase/product/constants/ProductOfferPlaceholder.js +125 -0
- package/dist/esm/post-purchase/product/hooks/useDynamicProduct.js +26 -0
- package/dist/esm/post-purchase/product/settings/ProductOffer.js +26 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -56,8 +56,12 @@ const ArticleList = ({ setting, styles, className, children, advanced, builderPr
|
|
|
56
56
|
assign all_articles = all_articles | concat: articleByHandle
|
|
57
57
|
endfor
|
|
58
58
|
else
|
|
59
|
-
assign
|
|
60
|
-
|
|
59
|
+
assign current_blog_handle = blogs['${blogHandle}']
|
|
60
|
+
if gp_enable_custom_dynamic_blog == true
|
|
61
|
+
assign current_blog_handle = blogs[blog.handle]
|
|
62
|
+
endif
|
|
63
|
+
assign all_articles = current_blog_handle.articles | limit: limit | sort: "${articleOrderBy.replace('_REVERSE', '').toLowerCase()}" ${articleOrderBy.includes('_REVERSE') ? '| reverse' : ''}
|
|
64
|
+
assign blogTitle = current_blog_handle.title
|
|
61
65
|
endif
|
|
62
66
|
|
|
63
67
|
%}
|
|
@@ -5,26 +5,29 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var core = require('@gem-sdk/core');
|
|
7
7
|
var Text = require('../../text/Text.js');
|
|
8
|
+
var useDynamicProduct = require('../hooks/useDynamicProduct.js');
|
|
8
9
|
|
|
9
10
|
const PostPurchaseProductDiscountTag = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
|
|
10
11
|
const currentProduct = core.useProduct();
|
|
11
12
|
const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
|
|
12
13
|
const currentOfferDiscount = core.useProductOfferDiscount();
|
|
14
|
+
const { isDynamicProduct, isEnableDynamicDiscount } = useDynamicProduct.useDynamicProduct();
|
|
13
15
|
const { typo } = styles;
|
|
14
16
|
const { message } = setting;
|
|
17
|
+
const hasDiscount = !!currentOfferDiscount || isDynamicProduct && isEnableDynamicDiscount;
|
|
15
18
|
return /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
16
19
|
...builderAttrs,
|
|
17
20
|
className: core.cls(builderProps?.uid, 'gp-flex gp-w-full'),
|
|
18
21
|
style: {
|
|
19
22
|
...style,
|
|
20
|
-
opacity:
|
|
23
|
+
opacity: hasDiscount ? 1 : 0.2
|
|
21
24
|
},
|
|
22
25
|
id: `shopify-text-element-${builderProps?.uid}`,
|
|
23
26
|
"data-product-id": currentProductId,
|
|
24
27
|
children: [
|
|
25
28
|
/*#__PURE__*/ jsxRuntime.jsx(Text.default, {
|
|
26
29
|
setting: {
|
|
27
|
-
text:
|
|
30
|
+
text: hasDiscount ? message : message?.replace(new RegExp(/\{\{Discount\}\}/, 'gi'), '0%')
|
|
28
31
|
},
|
|
29
32
|
styles: {
|
|
30
33
|
typo
|
|
@@ -11,14 +11,20 @@ var Loading = require('../../../common/components/Loading.js');
|
|
|
11
11
|
var ProductVariant = require('./ProductVariant.js');
|
|
12
12
|
var helper = require('../../utils/helper.js');
|
|
13
13
|
var index = require('../helpers/index.js');
|
|
14
|
+
var ProductOfferPlaceholder = require('../constants/ProductOfferPlaceholder.js');
|
|
15
|
+
var useDynamicProduct = require('../hooks/useDynamicProduct.js');
|
|
14
16
|
|
|
15
17
|
const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children, setting })=>{
|
|
16
18
|
const mode = core.useEditorMode();
|
|
17
|
-
const { productSetting, productOfferLayout, inlineAlignment, ...rowSetting } = setting || {};
|
|
19
|
+
const { productSetting, productOfferLayout, inlineAlignment, discountAndShippingFee, ...rowSetting } = setting || {};
|
|
18
20
|
const { productOfferColumnGap, productOfferVerticalGutter, productOfferWidth, ...rowStyles } = styles || {};
|
|
19
21
|
const productOffers = core.usePageStore((s)=>s.productOffers);
|
|
20
22
|
const publicStoreFrontData = core.usePageStore((s)=>s.publicStoreFrontData);
|
|
21
|
-
const
|
|
23
|
+
const { isDynamicProduct } = useDynamicProduct.useDynamicProduct();
|
|
24
|
+
const dynamicDiscountOffer = core.usePageStore((s)=>s.dynamicDiscountOffer);
|
|
25
|
+
const totalProduct = React.useMemo(()=>isDynamicProduct ? dynamicDiscountOffer?.appliedProductCount : productOffers?.length, [
|
|
26
|
+
dynamicDiscountOffer?.appliedProductCount,
|
|
27
|
+
isDynamicProduct,
|
|
22
28
|
productOffers?.length
|
|
23
29
|
]);
|
|
24
30
|
const sortedProductBaseIDs = React.useMemo(()=>{
|
|
@@ -44,7 +50,14 @@ const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children
|
|
|
44
50
|
const products = React.useMemo(()=>core.flattenConnection(productData.data?.products), [
|
|
45
51
|
productData.data?.products
|
|
46
52
|
]);
|
|
47
|
-
const productSortedById =
|
|
53
|
+
const productSortedById = React.useMemo(()=>{
|
|
54
|
+
return isDynamicProduct && dynamicDiscountOffer?.appliedProductCount ? Array(dynamicDiscountOffer.appliedProductCount).fill(ProductOfferPlaceholder.productOfferPlaceholder) : sortedProductBaseIDs?.map((id)=>products?.find((el)=>el?.baseID === id)).filter(Boolean);
|
|
55
|
+
}, [
|
|
56
|
+
isDynamicProduct,
|
|
57
|
+
dynamicDiscountOffer?.appliedProductCount,
|
|
58
|
+
sortedProductBaseIDs,
|
|
59
|
+
products
|
|
60
|
+
]);
|
|
48
61
|
const getStyles = ()=>{
|
|
49
62
|
return {
|
|
50
63
|
...core.makeStyleResponsive('cg', productOfferColumnGap),
|
|
@@ -6,6 +6,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
var core = require('@gem-sdk/core');
|
|
7
7
|
var React = require('react');
|
|
8
8
|
var Text = require('../../text/Text.js');
|
|
9
|
+
var useDynamicProduct = require('../hooks/useDynamicProduct.js');
|
|
9
10
|
|
|
10
11
|
const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, children })=>{
|
|
11
12
|
const currentVariant = core.useCurrentVariant();
|
|
@@ -13,6 +14,7 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
|
|
|
13
14
|
const price = currentVariant?.price ?? 0;
|
|
14
15
|
const salePrice = currentVariant?.salePrice ?? 0;
|
|
15
16
|
const discount = parseFloat(core.shopifyPriceRounding(core.useProductOfferDiscount(), 2));
|
|
17
|
+
const { isDynamicProduct } = useDynamicProduct.useDynamicProduct();
|
|
16
18
|
const priceShow = React.useMemo(()=>{
|
|
17
19
|
if (!discount) {
|
|
18
20
|
if (styles?.priceType === 'compare') {
|
|
@@ -53,7 +55,7 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
|
|
|
53
55
|
/*#__PURE__*/ jsxRuntime.jsx(Text.default, {
|
|
54
56
|
styles: styles,
|
|
55
57
|
setting: {
|
|
56
|
-
text: moneyFormatted
|
|
58
|
+
text: isDynamicProduct ? '$???' : moneyFormatted
|
|
57
59
|
},
|
|
58
60
|
className: core.cls({
|
|
59
61
|
'gp-money': styles?.priceType === 'regular',
|
|
@@ -7,6 +7,7 @@ var core = require('@gem-sdk/core');
|
|
|
7
7
|
var React = require('react');
|
|
8
8
|
var helper = require('../../utils/helper.js');
|
|
9
9
|
var MoneyLine = require('./priceBreakdown/MoneyLine.js');
|
|
10
|
+
var useDynamicProduct = require('../hooks/useDynamicProduct.js');
|
|
10
11
|
|
|
11
12
|
const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
|
|
12
13
|
const currentVariant = core.useCurrentVariant();
|
|
@@ -21,6 +22,7 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
21
22
|
const discountShopifyFormat = core.shopifyPriceRounding(discountWithQuantity, 2);
|
|
22
23
|
const totalMoneyFormatted = core.useFormatMoney(subTotal - parseFloat(discountShopifyFormat), false);
|
|
23
24
|
const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
|
|
25
|
+
const { isDynamicProduct, dynamicPrice, dynamicDiscount, isEnableDynamicDiscount } = useDynamicProduct.useDynamicProduct();
|
|
24
26
|
const { labelStyle, moneyStyle, spacing, width, align, isShowPrice } = styles;
|
|
25
27
|
const itemGap = React.useMemo(()=>{
|
|
26
28
|
return helper.postPurchaseSpacing[spacing || 'none'];
|
|
@@ -33,19 +35,19 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
33
35
|
}, [
|
|
34
36
|
isShowPrice
|
|
35
37
|
]);
|
|
36
|
-
const
|
|
38
|
+
const getMoneyLines = ()=>{
|
|
37
39
|
const data = [];
|
|
38
40
|
if (styles.isShowSubTotalLabel !== false) {
|
|
39
41
|
data.push({
|
|
40
42
|
title: setting.subTotalLabel,
|
|
41
|
-
money: subTotalMoneyFormatted,
|
|
43
|
+
money: isDynamicProduct ? dynamicPrice : subTotalMoneyFormatted,
|
|
42
44
|
uniqueId: 'subTotalLabel'
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
if (styles.isShowDiscountLabel !== false) {
|
|
46
48
|
data.push({
|
|
47
49
|
title: setting.discountLabel,
|
|
48
|
-
money: discount > 0 ? discountMoneyFormatted : 'No discount',
|
|
50
|
+
money: isDynamicProduct && dynamicDiscount && isEnableDynamicDiscount ? dynamicPrice : discount > 0 ? discountMoneyFormatted : 'No discount',
|
|
49
51
|
uniqueId: 'discountLabel'
|
|
50
52
|
});
|
|
51
53
|
}
|
|
@@ -71,25 +73,11 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
71
73
|
}
|
|
72
74
|
data.push({
|
|
73
75
|
title: setting.totalLabel,
|
|
74
|
-
money: totalMoneyFormatted,
|
|
76
|
+
money: isDynamicProduct ? dynamicPrice : totalMoneyFormatted,
|
|
75
77
|
uniqueId: 'totalLabel'
|
|
76
78
|
});
|
|
77
79
|
return data;
|
|
78
|
-
}
|
|
79
|
-
discount,
|
|
80
|
-
discountMoneyFormatted,
|
|
81
|
-
setting.discountLabel,
|
|
82
|
-
setting.shippingLabel,
|
|
83
|
-
setting.subTotalLabel,
|
|
84
|
-
setting.taxesLabel,
|
|
85
|
-
setting.totalLabel,
|
|
86
|
-
styles.isShowSubTotalLabel,
|
|
87
|
-
styles.isShowDiscountLabel,
|
|
88
|
-
styles.isShowShippingLabel,
|
|
89
|
-
styles.isShowTaxesLabel,
|
|
90
|
-
subTotalMoneyFormatted,
|
|
91
|
-
totalMoneyFormatted
|
|
92
|
-
]);
|
|
80
|
+
};
|
|
93
81
|
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
94
82
|
children: [
|
|
95
83
|
/*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
@@ -140,9 +128,9 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
140
128
|
...core.makeStyleResponsive('w', width),
|
|
141
129
|
gap: itemGap
|
|
142
130
|
},
|
|
143
|
-
children:
|
|
131
|
+
children: getMoneyLines().map((item)=>/*#__PURE__*/ jsxRuntime.jsxs(React.Fragment, {
|
|
144
132
|
children: [
|
|
145
|
-
item.uniqueId === 'totalLabel' &&
|
|
133
|
+
item.uniqueId === 'totalLabel' && getMoneyLines().length > 1 && /*#__PURE__*/ jsxRuntime.jsx("hr", {}),
|
|
146
134
|
/*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
147
135
|
children: /*#__PURE__*/ jsxRuntime.jsx(MoneyLine.default, {
|
|
148
136
|
uniqueId: item.uniqueId,
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const productOfferPlaceholder = {
|
|
4
|
+
id: '',
|
|
5
|
+
title: 'Dynamic product',
|
|
6
|
+
description: 'This is a dynamic product. The actual product will appear here based on your setup',
|
|
7
|
+
descriptionHtml: '<p class="QN2lPu">This is a dynamic product. The actual product will</p>\n<p class="QN2lPu">appear here based on your setup</p>',
|
|
8
|
+
createdAt: '2024-07-01T04:19:51.286753Z',
|
|
9
|
+
handle: 'dynamic-product',
|
|
10
|
+
averageRating: 0,
|
|
11
|
+
isStorefront: true,
|
|
12
|
+
isSample: false,
|
|
13
|
+
baseID: '',
|
|
14
|
+
sku: '',
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
id: '1',
|
|
18
|
+
name: 'Variant',
|
|
19
|
+
optionType: '',
|
|
20
|
+
values: [
|
|
21
|
+
{
|
|
22
|
+
id: '1',
|
|
23
|
+
label: 'Variant option',
|
|
24
|
+
isDefault: true,
|
|
25
|
+
baseID: '1'
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
vendor: '',
|
|
31
|
+
featuredImage: {
|
|
32
|
+
id: '542178560626918105',
|
|
33
|
+
contentType: 'IMAGE',
|
|
34
|
+
previewImage: '',
|
|
35
|
+
src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
|
|
36
|
+
width: 449,
|
|
37
|
+
height: 449,
|
|
38
|
+
alt: ''
|
|
39
|
+
},
|
|
40
|
+
collections: {
|
|
41
|
+
edges: [
|
|
42
|
+
{
|
|
43
|
+
node: {
|
|
44
|
+
id: '502321959132988135',
|
|
45
|
+
title: 'Home page'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
node: {
|
|
50
|
+
id: '539286505089204764',
|
|
51
|
+
title: 'b'
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
node: {
|
|
56
|
+
id: '539286505089401372',
|
|
57
|
+
title: 'e'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
tags: [],
|
|
63
|
+
medias: {
|
|
64
|
+
edges: [
|
|
65
|
+
{
|
|
66
|
+
cursor: 'gqFpzweGNIc/AALZoXYB',
|
|
67
|
+
node: {
|
|
68
|
+
id: '542178560626918105',
|
|
69
|
+
contentType: 'IMAGE',
|
|
70
|
+
previewImage: '',
|
|
71
|
+
src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
|
|
72
|
+
width: 449,
|
|
73
|
+
height: 449,
|
|
74
|
+
alt: ''
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
pageInfo: {
|
|
79
|
+
endCursor: 'gqFpzweGNIc/AALZoXYB',
|
|
80
|
+
hasNextPage: true
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
variants: {
|
|
84
|
+
edges: [
|
|
85
|
+
{
|
|
86
|
+
cursor: 'gqFpzwc5ZqRtDAMIoXYC',
|
|
87
|
+
node: {
|
|
88
|
+
id: '520560088328176392',
|
|
89
|
+
title: 'Default Title',
|
|
90
|
+
barcode: '',
|
|
91
|
+
baseID: 'gid://shopify/ProductVariant/49298248925463',
|
|
92
|
+
costPrice: 88,
|
|
93
|
+
height: 0,
|
|
94
|
+
inventoryPolicy: 'DENY',
|
|
95
|
+
inventoryQuantity: 211,
|
|
96
|
+
inventoryStatus: '',
|
|
97
|
+
isDigital: true,
|
|
98
|
+
length: 0,
|
|
99
|
+
lowInventoryAmount: 0,
|
|
100
|
+
manageInventory: false,
|
|
101
|
+
mediaId: '0',
|
|
102
|
+
platform: 'SHOPIFY',
|
|
103
|
+
price: 88,
|
|
104
|
+
salePrice: 88,
|
|
105
|
+
sku: '',
|
|
106
|
+
soldIndividually: false,
|
|
107
|
+
weight: 0,
|
|
108
|
+
width: 0,
|
|
109
|
+
selectedOptions: [
|
|
110
|
+
{
|
|
111
|
+
name: 'Variant',
|
|
112
|
+
value: 'Variant option',
|
|
113
|
+
optionType: ''
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
media: undefined
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
pageInfo: {
|
|
121
|
+
hasNextPage: false,
|
|
122
|
+
endCursor: 'gaFpzwc5ZqRtDAMI'
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
exports.productOfferPlaceholder = productOfferPlaceholder;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@gem-sdk/core');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
const useDynamicProduct = ()=>{
|
|
7
|
+
const dynamicDiscountOffer = core.usePageStore((s)=>s.dynamicDiscountOffer);
|
|
8
|
+
const isDynamicProduct = React.useMemo(()=>{
|
|
9
|
+
return !!dynamicDiscountOffer;
|
|
10
|
+
}, [
|
|
11
|
+
dynamicDiscountOffer
|
|
12
|
+
]);
|
|
13
|
+
// false = No discount
|
|
14
|
+
const isEnableDynamicDiscount = React.useMemo(()=>{
|
|
15
|
+
return dynamicDiscountOffer?.isEnabled;
|
|
16
|
+
}, [
|
|
17
|
+
dynamicDiscountOffer
|
|
18
|
+
]);
|
|
19
|
+
const dynamicPrice = '$???';
|
|
20
|
+
return {
|
|
21
|
+
isDynamicProduct,
|
|
22
|
+
dynamicPrice,
|
|
23
|
+
dynamicDiscount: dynamicDiscountOffer,
|
|
24
|
+
isEnableDynamicDiscount
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.useDynamicProduct = useDynamicProduct;
|
|
@@ -184,6 +184,14 @@ const config = {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
|
+
{
|
|
188
|
+
id: 'dynamicOfferQuantity',
|
|
189
|
+
type: 'dynamic-offer-quantity',
|
|
190
|
+
min: 1,
|
|
191
|
+
max: 4,
|
|
192
|
+
default: 2,
|
|
193
|
+
isOnlyAcceptInteger: true
|
|
194
|
+
},
|
|
187
195
|
{
|
|
188
196
|
id: 'discountAndShippingFee',
|
|
189
197
|
type: 'discount-and-shipping-fee-product-offer',
|
|
@@ -377,6 +385,24 @@ const config = {
|
|
|
377
385
|
},
|
|
378
386
|
layout: 'vertical'
|
|
379
387
|
},
|
|
388
|
+
{
|
|
389
|
+
type: 'group',
|
|
390
|
+
label: {
|
|
391
|
+
en: 'Product offers'
|
|
392
|
+
},
|
|
393
|
+
controls: [
|
|
394
|
+
{
|
|
395
|
+
type: 'control',
|
|
396
|
+
label: {
|
|
397
|
+
en: 'Quantity'
|
|
398
|
+
},
|
|
399
|
+
setting: {
|
|
400
|
+
id: 'dynamicOfferQuantity'
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
],
|
|
404
|
+
condition: 'false'
|
|
405
|
+
},
|
|
380
406
|
{
|
|
381
407
|
type: 'control',
|
|
382
408
|
label: {
|
|
@@ -52,8 +52,12 @@ const ArticleList = ({ setting, styles, className, children, advanced, builderPr
|
|
|
52
52
|
assign all_articles = all_articles | concat: articleByHandle
|
|
53
53
|
endfor
|
|
54
54
|
else
|
|
55
|
-
assign
|
|
56
|
-
|
|
55
|
+
assign current_blog_handle = blogs['${blogHandle}']
|
|
56
|
+
if gp_enable_custom_dynamic_blog == true
|
|
57
|
+
assign current_blog_handle = blogs[blog.handle]
|
|
58
|
+
endif
|
|
59
|
+
assign all_articles = current_blog_handle.articles | limit: limit | sort: "${articleOrderBy.replace('_REVERSE', '').toLowerCase()}" ${articleOrderBy.includes('_REVERSE') ? '| reverse' : ''}
|
|
60
|
+
assign blogTitle = current_blog_handle.title
|
|
57
61
|
endif
|
|
58
62
|
|
|
59
63
|
%}
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useProduct, useProductOfferDiscount, cls } from '@gem-sdk/core';
|
|
3
3
|
import Text from '../../text/Text.js';
|
|
4
|
+
import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
|
|
4
5
|
|
|
5
6
|
const PostPurchaseProductDiscountTag = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
|
|
6
7
|
const currentProduct = useProduct();
|
|
7
8
|
const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
|
|
8
9
|
const currentOfferDiscount = useProductOfferDiscount();
|
|
10
|
+
const { isDynamicProduct, isEnableDynamicDiscount } = useDynamicProduct();
|
|
9
11
|
const { typo } = styles;
|
|
10
12
|
const { message } = setting;
|
|
13
|
+
const hasDiscount = !!currentOfferDiscount || isDynamicProduct && isEnableDynamicDiscount;
|
|
11
14
|
return /*#__PURE__*/ jsxs("div", {
|
|
12
15
|
...builderAttrs,
|
|
13
16
|
className: cls(builderProps?.uid, 'gp-flex gp-w-full'),
|
|
14
17
|
style: {
|
|
15
18
|
...style,
|
|
16
|
-
opacity:
|
|
19
|
+
opacity: hasDiscount ? 1 : 0.2
|
|
17
20
|
},
|
|
18
21
|
id: `shopify-text-element-${builderProps?.uid}`,
|
|
19
22
|
"data-product-id": currentProductId,
|
|
20
23
|
children: [
|
|
21
24
|
/*#__PURE__*/ jsx(Text, {
|
|
22
25
|
setting: {
|
|
23
|
-
text:
|
|
26
|
+
text: hasDiscount ? message : message?.replace(new RegExp(/\{\{Discount\}\}/, 'gi'), '0%')
|
|
24
27
|
},
|
|
25
28
|
styles: {
|
|
26
29
|
typo
|
|
@@ -7,14 +7,20 @@ import Loading from '../../../common/components/Loading.js';
|
|
|
7
7
|
import { DEVICES } from './ProductVariant.js';
|
|
8
8
|
import { postPurchaseViewSpacing } from '../../utils/helper.js';
|
|
9
9
|
import { hasPublicStoreFrontData, createStoreFrontFetcher } from '../helpers/index.js';
|
|
10
|
+
import { productOfferPlaceholder } from '../constants/ProductOfferPlaceholder.js';
|
|
11
|
+
import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
|
|
10
12
|
|
|
11
13
|
const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children, setting })=>{
|
|
12
14
|
const mode = useEditorMode();
|
|
13
|
-
const { productSetting, productOfferLayout, inlineAlignment, ...rowSetting } = setting || {};
|
|
15
|
+
const { productSetting, productOfferLayout, inlineAlignment, discountAndShippingFee, ...rowSetting } = setting || {};
|
|
14
16
|
const { productOfferColumnGap, productOfferVerticalGutter, productOfferWidth, ...rowStyles } = styles || {};
|
|
15
17
|
const productOffers = usePageStore((s)=>s.productOffers);
|
|
16
18
|
const publicStoreFrontData = usePageStore((s)=>s.publicStoreFrontData);
|
|
17
|
-
const
|
|
19
|
+
const { isDynamicProduct } = useDynamicProduct();
|
|
20
|
+
const dynamicDiscountOffer = usePageStore((s)=>s.dynamicDiscountOffer);
|
|
21
|
+
const totalProduct = useMemo(()=>isDynamicProduct ? dynamicDiscountOffer?.appliedProductCount : productOffers?.length, [
|
|
22
|
+
dynamicDiscountOffer?.appliedProductCount,
|
|
23
|
+
isDynamicProduct,
|
|
18
24
|
productOffers?.length
|
|
19
25
|
]);
|
|
20
26
|
const sortedProductBaseIDs = useMemo(()=>{
|
|
@@ -40,7 +46,14 @@ const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children
|
|
|
40
46
|
const products = useMemo(()=>flattenConnection(productData.data?.products), [
|
|
41
47
|
productData.data?.products
|
|
42
48
|
]);
|
|
43
|
-
const productSortedById =
|
|
49
|
+
const productSortedById = useMemo(()=>{
|
|
50
|
+
return isDynamicProduct && dynamicDiscountOffer?.appliedProductCount ? Array(dynamicDiscountOffer.appliedProductCount).fill(productOfferPlaceholder) : sortedProductBaseIDs?.map((id)=>products?.find((el)=>el?.baseID === id)).filter(Boolean);
|
|
51
|
+
}, [
|
|
52
|
+
isDynamicProduct,
|
|
53
|
+
dynamicDiscountOffer?.appliedProductCount,
|
|
54
|
+
sortedProductBaseIDs,
|
|
55
|
+
products
|
|
56
|
+
]);
|
|
44
57
|
const getStyles = ()=>{
|
|
45
58
|
return {
|
|
46
59
|
...makeStyleResponsive('cg', productOfferColumnGap),
|
|
@@ -2,6 +2,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useCurrentVariant, useProduct, shopifyPriceRounding, useProductOfferDiscount, useFormatMoney, cls } from '@gem-sdk/core';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import Text from '../../text/Text.js';
|
|
5
|
+
import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
|
|
5
6
|
|
|
6
7
|
const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, children })=>{
|
|
7
8
|
const currentVariant = useCurrentVariant();
|
|
@@ -9,6 +10,7 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
|
|
|
9
10
|
const price = currentVariant?.price ?? 0;
|
|
10
11
|
const salePrice = currentVariant?.salePrice ?? 0;
|
|
11
12
|
const discount = parseFloat(shopifyPriceRounding(useProductOfferDiscount(), 2));
|
|
13
|
+
const { isDynamicProduct } = useDynamicProduct();
|
|
12
14
|
const priceShow = useMemo(()=>{
|
|
13
15
|
if (!discount) {
|
|
14
16
|
if (styles?.priceType === 'compare') {
|
|
@@ -49,7 +51,7 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
|
|
|
49
51
|
/*#__PURE__*/ jsx(Text, {
|
|
50
52
|
styles: styles,
|
|
51
53
|
setting: {
|
|
52
|
-
text: moneyFormatted
|
|
54
|
+
text: isDynamicProduct ? '$???' : moneyFormatted
|
|
53
55
|
},
|
|
54
56
|
className: cls({
|
|
55
57
|
'gp-money': styles?.priceType === 'regular',
|
|
@@ -3,6 +3,7 @@ import { useCurrentVariant, useProduct, useQuantity, useProductOfferDiscount, us
|
|
|
3
3
|
import { useMemo, useState, useEffect, Fragment as Fragment$1 } from 'react';
|
|
4
4
|
import { postPurchaseSpacing } from '../../utils/helper.js';
|
|
5
5
|
import MoneyLine from './priceBreakdown/MoneyLine.js';
|
|
6
|
+
import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
|
|
6
7
|
|
|
7
8
|
const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
|
|
8
9
|
const currentVariant = useCurrentVariant();
|
|
@@ -17,6 +18,7 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
17
18
|
const discountShopifyFormat = shopifyPriceRounding(discountWithQuantity, 2);
|
|
18
19
|
const totalMoneyFormatted = useFormatMoney(subTotal - parseFloat(discountShopifyFormat), false);
|
|
19
20
|
const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
|
|
21
|
+
const { isDynamicProduct, dynamicPrice, dynamicDiscount, isEnableDynamicDiscount } = useDynamicProduct();
|
|
20
22
|
const { labelStyle, moneyStyle, spacing, width, align, isShowPrice } = styles;
|
|
21
23
|
const itemGap = useMemo(()=>{
|
|
22
24
|
return postPurchaseSpacing[spacing || 'none'];
|
|
@@ -29,19 +31,19 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
29
31
|
}, [
|
|
30
32
|
isShowPrice
|
|
31
33
|
]);
|
|
32
|
-
const
|
|
34
|
+
const getMoneyLines = ()=>{
|
|
33
35
|
const data = [];
|
|
34
36
|
if (styles.isShowSubTotalLabel !== false) {
|
|
35
37
|
data.push({
|
|
36
38
|
title: setting.subTotalLabel,
|
|
37
|
-
money: subTotalMoneyFormatted,
|
|
39
|
+
money: isDynamicProduct ? dynamicPrice : subTotalMoneyFormatted,
|
|
38
40
|
uniqueId: 'subTotalLabel'
|
|
39
41
|
});
|
|
40
42
|
}
|
|
41
43
|
if (styles.isShowDiscountLabel !== false) {
|
|
42
44
|
data.push({
|
|
43
45
|
title: setting.discountLabel,
|
|
44
|
-
money: discount > 0 ? discountMoneyFormatted : 'No discount',
|
|
46
|
+
money: isDynamicProduct && dynamicDiscount && isEnableDynamicDiscount ? dynamicPrice : discount > 0 ? discountMoneyFormatted : 'No discount',
|
|
45
47
|
uniqueId: 'discountLabel'
|
|
46
48
|
});
|
|
47
49
|
}
|
|
@@ -67,25 +69,11 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
67
69
|
}
|
|
68
70
|
data.push({
|
|
69
71
|
title: setting.totalLabel,
|
|
70
|
-
money: totalMoneyFormatted,
|
|
72
|
+
money: isDynamicProduct ? dynamicPrice : totalMoneyFormatted,
|
|
71
73
|
uniqueId: 'totalLabel'
|
|
72
74
|
});
|
|
73
75
|
return data;
|
|
74
|
-
}
|
|
75
|
-
discount,
|
|
76
|
-
discountMoneyFormatted,
|
|
77
|
-
setting.discountLabel,
|
|
78
|
-
setting.shippingLabel,
|
|
79
|
-
setting.subTotalLabel,
|
|
80
|
-
setting.taxesLabel,
|
|
81
|
-
setting.totalLabel,
|
|
82
|
-
styles.isShowSubTotalLabel,
|
|
83
|
-
styles.isShowDiscountLabel,
|
|
84
|
-
styles.isShowShippingLabel,
|
|
85
|
-
styles.isShowTaxesLabel,
|
|
86
|
-
subTotalMoneyFormatted,
|
|
87
|
-
totalMoneyFormatted
|
|
88
|
-
]);
|
|
76
|
+
};
|
|
89
77
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
90
78
|
children: [
|
|
91
79
|
/*#__PURE__*/ jsxs("div", {
|
|
@@ -136,9 +124,9 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
|
|
|
136
124
|
...makeStyleResponsive('w', width),
|
|
137
125
|
gap: itemGap
|
|
138
126
|
},
|
|
139
|
-
children:
|
|
127
|
+
children: getMoneyLines().map((item)=>/*#__PURE__*/ jsxs(Fragment$1, {
|
|
140
128
|
children: [
|
|
141
|
-
item.uniqueId === 'totalLabel' &&
|
|
129
|
+
item.uniqueId === 'totalLabel' && getMoneyLines().length > 1 && /*#__PURE__*/ jsx("hr", {}),
|
|
142
130
|
/*#__PURE__*/ jsx("div", {
|
|
143
131
|
children: /*#__PURE__*/ jsx(MoneyLine, {
|
|
144
132
|
uniqueId: item.uniqueId,
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const productOfferPlaceholder = {
|
|
2
|
+
id: '',
|
|
3
|
+
title: 'Dynamic product',
|
|
4
|
+
description: 'This is a dynamic product. The actual product will appear here based on your setup',
|
|
5
|
+
descriptionHtml: '<p class="QN2lPu">This is a dynamic product. The actual product will</p>\n<p class="QN2lPu">appear here based on your setup</p>',
|
|
6
|
+
createdAt: '2024-07-01T04:19:51.286753Z',
|
|
7
|
+
handle: 'dynamic-product',
|
|
8
|
+
averageRating: 0,
|
|
9
|
+
isStorefront: true,
|
|
10
|
+
isSample: false,
|
|
11
|
+
baseID: '',
|
|
12
|
+
sku: '',
|
|
13
|
+
options: [
|
|
14
|
+
{
|
|
15
|
+
id: '1',
|
|
16
|
+
name: 'Variant',
|
|
17
|
+
optionType: '',
|
|
18
|
+
values: [
|
|
19
|
+
{
|
|
20
|
+
id: '1',
|
|
21
|
+
label: 'Variant option',
|
|
22
|
+
isDefault: true,
|
|
23
|
+
baseID: '1'
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
vendor: '',
|
|
29
|
+
featuredImage: {
|
|
30
|
+
id: '542178560626918105',
|
|
31
|
+
contentType: 'IMAGE',
|
|
32
|
+
previewImage: '',
|
|
33
|
+
src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
|
|
34
|
+
width: 449,
|
|
35
|
+
height: 449,
|
|
36
|
+
alt: ''
|
|
37
|
+
},
|
|
38
|
+
collections: {
|
|
39
|
+
edges: [
|
|
40
|
+
{
|
|
41
|
+
node: {
|
|
42
|
+
id: '502321959132988135',
|
|
43
|
+
title: 'Home page'
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
node: {
|
|
48
|
+
id: '539286505089204764',
|
|
49
|
+
title: 'b'
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
node: {
|
|
54
|
+
id: '539286505089401372',
|
|
55
|
+
title: 'e'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
tags: [],
|
|
61
|
+
medias: {
|
|
62
|
+
edges: [
|
|
63
|
+
{
|
|
64
|
+
cursor: 'gqFpzweGNIc/AALZoXYB',
|
|
65
|
+
node: {
|
|
66
|
+
id: '542178560626918105',
|
|
67
|
+
contentType: 'IMAGE',
|
|
68
|
+
previewImage: '',
|
|
69
|
+
src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
|
|
70
|
+
width: 449,
|
|
71
|
+
height: 449,
|
|
72
|
+
alt: ''
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
pageInfo: {
|
|
77
|
+
endCursor: 'gqFpzweGNIc/AALZoXYB',
|
|
78
|
+
hasNextPage: true
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
variants: {
|
|
82
|
+
edges: [
|
|
83
|
+
{
|
|
84
|
+
cursor: 'gqFpzwc5ZqRtDAMIoXYC',
|
|
85
|
+
node: {
|
|
86
|
+
id: '520560088328176392',
|
|
87
|
+
title: 'Default Title',
|
|
88
|
+
barcode: '',
|
|
89
|
+
baseID: 'gid://shopify/ProductVariant/49298248925463',
|
|
90
|
+
costPrice: 88,
|
|
91
|
+
height: 0,
|
|
92
|
+
inventoryPolicy: 'DENY',
|
|
93
|
+
inventoryQuantity: 211,
|
|
94
|
+
inventoryStatus: '',
|
|
95
|
+
isDigital: true,
|
|
96
|
+
length: 0,
|
|
97
|
+
lowInventoryAmount: 0,
|
|
98
|
+
manageInventory: false,
|
|
99
|
+
mediaId: '0',
|
|
100
|
+
platform: 'SHOPIFY',
|
|
101
|
+
price: 88,
|
|
102
|
+
salePrice: 88,
|
|
103
|
+
sku: '',
|
|
104
|
+
soldIndividually: false,
|
|
105
|
+
weight: 0,
|
|
106
|
+
width: 0,
|
|
107
|
+
selectedOptions: [
|
|
108
|
+
{
|
|
109
|
+
name: 'Variant',
|
|
110
|
+
value: 'Variant option',
|
|
111
|
+
optionType: ''
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
media: undefined
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
pageInfo: {
|
|
119
|
+
hasNextPage: false,
|
|
120
|
+
endCursor: 'gaFpzwc5ZqRtDAMI'
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export { productOfferPlaceholder };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { usePageStore } from '@gem-sdk/core';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
const useDynamicProduct = ()=>{
|
|
5
|
+
const dynamicDiscountOffer = usePageStore((s)=>s.dynamicDiscountOffer);
|
|
6
|
+
const isDynamicProduct = useMemo(()=>{
|
|
7
|
+
return !!dynamicDiscountOffer;
|
|
8
|
+
}, [
|
|
9
|
+
dynamicDiscountOffer
|
|
10
|
+
]);
|
|
11
|
+
// false = No discount
|
|
12
|
+
const isEnableDynamicDiscount = useMemo(()=>{
|
|
13
|
+
return dynamicDiscountOffer?.isEnabled;
|
|
14
|
+
}, [
|
|
15
|
+
dynamicDiscountOffer
|
|
16
|
+
]);
|
|
17
|
+
const dynamicPrice = '$???';
|
|
18
|
+
return {
|
|
19
|
+
isDynamicProduct,
|
|
20
|
+
dynamicPrice,
|
|
21
|
+
dynamicDiscount: dynamicDiscountOffer,
|
|
22
|
+
isEnableDynamicDiscount
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { useDynamicProduct };
|
|
@@ -180,6 +180,14 @@ const config = {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
},
|
|
183
|
+
{
|
|
184
|
+
id: 'dynamicOfferQuantity',
|
|
185
|
+
type: 'dynamic-offer-quantity',
|
|
186
|
+
min: 1,
|
|
187
|
+
max: 4,
|
|
188
|
+
default: 2,
|
|
189
|
+
isOnlyAcceptInteger: true
|
|
190
|
+
},
|
|
183
191
|
{
|
|
184
192
|
id: 'discountAndShippingFee',
|
|
185
193
|
type: 'discount-and-shipping-fee-product-offer',
|
|
@@ -373,6 +381,24 @@ const config = {
|
|
|
373
381
|
},
|
|
374
382
|
layout: 'vertical'
|
|
375
383
|
},
|
|
384
|
+
{
|
|
385
|
+
type: 'group',
|
|
386
|
+
label: {
|
|
387
|
+
en: 'Product offers'
|
|
388
|
+
},
|
|
389
|
+
controls: [
|
|
390
|
+
{
|
|
391
|
+
type: 'control',
|
|
392
|
+
label: {
|
|
393
|
+
en: 'Quantity'
|
|
394
|
+
},
|
|
395
|
+
setting: {
|
|
396
|
+
id: 'dynamicOfferQuantity'
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
],
|
|
400
|
+
condition: 'false'
|
|
401
|
+
},
|
|
376
402
|
{
|
|
377
403
|
type: 'control',
|
|
378
404
|
label: {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4475,6 +4475,7 @@ type ProductOfferSettings = Omit<ProductSetting, 'productSetting'> & {
|
|
|
4475
4475
|
productIds?: string[];
|
|
4476
4476
|
};
|
|
4477
4477
|
productOfferLayout: ObjectDevices<'1col' | '2col'>;
|
|
4478
|
+
dynamicOfferQuantity?: number;
|
|
4478
4479
|
discountAndShippingFee?: boolean;
|
|
4479
4480
|
};
|
|
4480
4481
|
type ProductOfferStyles = RowProps$1['styles'] & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gem-sdk/components",
|
|
3
|
-
"version": "2.1.13-staging.
|
|
3
|
+
"version": "2.1.13-staging.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"format": "prettier --write \"./src/**/*.{ts,tsx}\""
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@gem-sdk/core": "2.1.13-staging.
|
|
24
|
+
"@gem-sdk/core": "2.1.13-staging.1",
|
|
25
25
|
"@gem-sdk/styles": "2.1.0",
|
|
26
26
|
"@types/react-transition-group": "^4.4.5"
|
|
27
27
|
},
|