@blocklet/payment-react 1.23.9 → 1.23.11
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/es/payment/product-item.js +48 -14
- package/lib/payment/product-item.js +48 -14
- package/package.json +3 -3
- package/src/payment/product-item.tsx +58 -18
|
@@ -95,42 +95,76 @@ export default function ProductItem({
|
|
|
95
95
|
refreshDeps: [isCreditProduct, userDid, creditCurrency?.id]
|
|
96
96
|
}
|
|
97
97
|
);
|
|
98
|
-
const
|
|
98
|
+
const canAdjustQuantity = adjustableQuantity.enabled && mode === "normal";
|
|
99
|
+
const minQuantity = Math.max(adjustableQuantity.minimum || 1, 1);
|
|
100
|
+
const quantityAvailable = Math.min(item.price.quantity_limit_per_checkout, item.price.quantity_available);
|
|
101
|
+
const maxQuantity = quantityAvailable ? Math.min(adjustableQuantity.maximum || Infinity, quantityAvailable) : adjustableQuantity.maximum || Infinity;
|
|
102
|
+
const getMinQuantityForPending = useMemo(() => {
|
|
103
|
+
if (!isCreditProduct || !pendingAmount) return null;
|
|
104
|
+
const pendingAmountBN = new BN(pendingAmount || "0");
|
|
105
|
+
if (!pendingAmountBN.gt(new BN(0))) return null;
|
|
106
|
+
const creditAmountBN = fromTokenToUnit(creditAmount, creditCurrency?.decimal || 2);
|
|
107
|
+
return Math.ceil(pendingAmountBN.mul(new BN(100)).div(creditAmountBN).toNumber() / 100);
|
|
108
|
+
}, [isCreditProduct, pendingAmount, creditAmount, creditCurrency?.decimal]);
|
|
109
|
+
const initialQuantity = useMemo(() => {
|
|
99
110
|
const urlQuantity = getRecommendedQuantityFromUrl(item.price.id);
|
|
100
111
|
if (urlQuantity && urlQuantity > 0) {
|
|
112
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
113
|
+
return Math.max(urlQuantity, getMinQuantityForPending, minQuantity);
|
|
114
|
+
}
|
|
101
115
|
return urlQuantity;
|
|
102
116
|
}
|
|
103
117
|
if (userDid) {
|
|
104
118
|
const preferredQuantity = getUserQuantityPreference(userDid, item.price.id);
|
|
105
119
|
if (preferredQuantity && preferredQuantity > 0) {
|
|
120
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
121
|
+
return Math.max(preferredQuantity, getMinQuantityForPending, minQuantity);
|
|
122
|
+
}
|
|
106
123
|
return preferredQuantity;
|
|
107
124
|
}
|
|
108
125
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
126
|
+
let baseQuantity = item.quantity;
|
|
127
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
128
|
+
baseQuantity = Math.max(baseQuantity, getMinQuantityForPending, minQuantity);
|
|
129
|
+
}
|
|
130
|
+
return baseQuantity;
|
|
131
|
+
}, [item.quantity, item.price.id, userDid, getMinQuantityForPending, canAdjustQuantity, minQuantity]);
|
|
132
|
+
const [localQuantity, setLocalQuantity] = useState(initialQuantity);
|
|
116
133
|
const localQuantityNum = localQuantity || 0;
|
|
117
134
|
useEffect(() => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
135
|
+
if (initialQuantity && initialQuantity > 0) {
|
|
136
|
+
if (initialQuantity !== localQuantity) {
|
|
137
|
+
setLocalQuantity(initialQuantity);
|
|
138
|
+
}
|
|
139
|
+
if (initialQuantity !== item.quantity) {
|
|
140
|
+
onQuantityChange(item.price_id, initialQuantity);
|
|
141
|
+
}
|
|
142
|
+
if (isCreditProduct && pendingAmount && getMinQuantityForPending) {
|
|
143
|
+
setPayable(initialQuantity >= getMinQuantityForPending);
|
|
144
|
+
} else {
|
|
145
|
+
setPayable(true);
|
|
146
|
+
}
|
|
121
147
|
}
|
|
122
|
-
}, []);
|
|
148
|
+
}, [initialQuantity, isCreditProduct, pendingAmount, getMinQuantityForPending]);
|
|
123
149
|
const handleQuantityChange = (newQuantity) => {
|
|
124
150
|
if (!newQuantity) {
|
|
125
151
|
setLocalQuantity(void 0);
|
|
126
152
|
setPayable(false);
|
|
127
153
|
return;
|
|
128
154
|
}
|
|
129
|
-
setPayable(true);
|
|
130
155
|
if (newQuantity >= minQuantity && newQuantity <= maxQuantity) {
|
|
131
156
|
if (formatQuantityInventory(item.price, newQuantity, locale)) {
|
|
132
157
|
return;
|
|
133
158
|
}
|
|
159
|
+
if (isCreditProduct && pendingAmount && getMinQuantityForPending) {
|
|
160
|
+
if (newQuantity < getMinQuantityForPending) {
|
|
161
|
+
setPayable(false);
|
|
162
|
+
setLocalQuantity(newQuantity);
|
|
163
|
+
onQuantityChange(item.price_id, newQuantity);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
setPayable(true);
|
|
134
168
|
setLocalQuantity(newQuantity);
|
|
135
169
|
onQuantityChange(item.price_id, newQuantity);
|
|
136
170
|
if (userDid && newQuantity > 0) {
|
|
@@ -204,7 +238,7 @@ export default function ProductItem({
|
|
|
204
238
|
}
|
|
205
239
|
const pendingAmountBN = new BN(pendingAmount || "0");
|
|
206
240
|
const creditAmountBN = fromTokenToUnit(creditAmount, creditCurrency?.decimal || 2);
|
|
207
|
-
const minQuantityNeeded =
|
|
241
|
+
const minQuantityNeeded = getMinQuantityForPending || 0;
|
|
208
242
|
const currentPurchaseCreditBN = creditAmountBN.mul(new BN(localQuantity || 0));
|
|
209
243
|
const actualAvailable = currentPurchaseCreditBN.sub(pendingAmountBN).toString();
|
|
210
244
|
if (!new BN(actualAvailable).gt(new BN(0))) {
|
|
@@ -103,42 +103,76 @@ function ProductItem({
|
|
|
103
103
|
}, {
|
|
104
104
|
refreshDeps: [isCreditProduct, userDid, creditCurrency?.id]
|
|
105
105
|
});
|
|
106
|
-
const
|
|
106
|
+
const canAdjustQuantity = adjustableQuantity.enabled && mode === "normal";
|
|
107
|
+
const minQuantity = Math.max(adjustableQuantity.minimum || 1, 1);
|
|
108
|
+
const quantityAvailable = Math.min(item.price.quantity_limit_per_checkout, item.price.quantity_available);
|
|
109
|
+
const maxQuantity = quantityAvailable ? Math.min(adjustableQuantity.maximum || Infinity, quantityAvailable) : adjustableQuantity.maximum || Infinity;
|
|
110
|
+
const getMinQuantityForPending = (0, _react.useMemo)(() => {
|
|
111
|
+
if (!isCreditProduct || !pendingAmount) return null;
|
|
112
|
+
const pendingAmountBN = new _util.BN(pendingAmount || "0");
|
|
113
|
+
if (!pendingAmountBN.gt(new _util.BN(0))) return null;
|
|
114
|
+
const creditAmountBN = (0, _util.fromTokenToUnit)(creditAmount, creditCurrency?.decimal || 2);
|
|
115
|
+
return Math.ceil(pendingAmountBN.mul(new _util.BN(100)).div(creditAmountBN).toNumber() / 100);
|
|
116
|
+
}, [isCreditProduct, pendingAmount, creditAmount, creditCurrency?.decimal]);
|
|
117
|
+
const initialQuantity = (0, _react.useMemo)(() => {
|
|
107
118
|
const urlQuantity = getRecommendedQuantityFromUrl(item.price.id);
|
|
108
119
|
if (urlQuantity && urlQuantity > 0) {
|
|
120
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
121
|
+
return Math.max(urlQuantity, getMinQuantityForPending, minQuantity);
|
|
122
|
+
}
|
|
109
123
|
return urlQuantity;
|
|
110
124
|
}
|
|
111
125
|
if (userDid) {
|
|
112
126
|
const preferredQuantity = getUserQuantityPreference(userDid, item.price.id);
|
|
113
127
|
if (preferredQuantity && preferredQuantity > 0) {
|
|
128
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
129
|
+
return Math.max(preferredQuantity, getMinQuantityForPending, minQuantity);
|
|
130
|
+
}
|
|
114
131
|
return preferredQuantity;
|
|
115
132
|
}
|
|
116
133
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
134
|
+
let baseQuantity = item.quantity;
|
|
135
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
136
|
+
baseQuantity = Math.max(baseQuantity, getMinQuantityForPending, minQuantity);
|
|
137
|
+
}
|
|
138
|
+
return baseQuantity;
|
|
139
|
+
}, [item.quantity, item.price.id, userDid, getMinQuantityForPending, canAdjustQuantity, minQuantity]);
|
|
140
|
+
const [localQuantity, setLocalQuantity] = (0, _react.useState)(initialQuantity);
|
|
124
141
|
const localQuantityNum = localQuantity || 0;
|
|
125
142
|
(0, _react.useEffect)(() => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
143
|
+
if (initialQuantity && initialQuantity > 0) {
|
|
144
|
+
if (initialQuantity !== localQuantity) {
|
|
145
|
+
setLocalQuantity(initialQuantity);
|
|
146
|
+
}
|
|
147
|
+
if (initialQuantity !== item.quantity) {
|
|
148
|
+
onQuantityChange(item.price_id, initialQuantity);
|
|
149
|
+
}
|
|
150
|
+
if (isCreditProduct && pendingAmount && getMinQuantityForPending) {
|
|
151
|
+
setPayable(initialQuantity >= getMinQuantityForPending);
|
|
152
|
+
} else {
|
|
153
|
+
setPayable(true);
|
|
154
|
+
}
|
|
129
155
|
}
|
|
130
|
-
}, []);
|
|
156
|
+
}, [initialQuantity, isCreditProduct, pendingAmount, getMinQuantityForPending]);
|
|
131
157
|
const handleQuantityChange = newQuantity => {
|
|
132
158
|
if (!newQuantity) {
|
|
133
159
|
setLocalQuantity(void 0);
|
|
134
160
|
setPayable(false);
|
|
135
161
|
return;
|
|
136
162
|
}
|
|
137
|
-
setPayable(true);
|
|
138
163
|
if (newQuantity >= minQuantity && newQuantity <= maxQuantity) {
|
|
139
164
|
if ((0, _util2.formatQuantityInventory)(item.price, newQuantity, locale)) {
|
|
140
165
|
return;
|
|
141
166
|
}
|
|
167
|
+
if (isCreditProduct && pendingAmount && getMinQuantityForPending) {
|
|
168
|
+
if (newQuantity < getMinQuantityForPending) {
|
|
169
|
+
setPayable(false);
|
|
170
|
+
setLocalQuantity(newQuantity);
|
|
171
|
+
onQuantityChange(item.price_id, newQuantity);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
setPayable(true);
|
|
142
176
|
setLocalQuantity(newQuantity);
|
|
143
177
|
onQuantityChange(item.price_id, newQuantity);
|
|
144
178
|
if (userDid && newQuantity > 0) {
|
|
@@ -204,7 +238,7 @@ function ProductItem({
|
|
|
204
238
|
}
|
|
205
239
|
const pendingAmountBN = new _util.BN(pendingAmount || "0");
|
|
206
240
|
const creditAmountBN = (0, _util.fromTokenToUnit)(creditAmount, creditCurrency?.decimal || 2);
|
|
207
|
-
const minQuantityNeeded =
|
|
241
|
+
const minQuantityNeeded = getMinQuantityForPending || 0;
|
|
208
242
|
const currentPurchaseCreditBN = creditAmountBN.mul(new _util.BN(localQuantity || 0));
|
|
209
243
|
const actualAvailable = currentPurchaseCreditBN.sub(pendingAmountBN).toString();
|
|
210
244
|
if (!new _util.BN(actualAvailable).gt(new _util.BN(0))) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.11",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"@babel/core": "^7.27.4",
|
|
97
97
|
"@babel/preset-env": "^7.27.2",
|
|
98
98
|
"@babel/preset-react": "^7.27.1",
|
|
99
|
-
"@blocklet/payment-types": "1.23.
|
|
99
|
+
"@blocklet/payment-types": "1.23.11",
|
|
100
100
|
"@storybook/addon-essentials": "^7.6.20",
|
|
101
101
|
"@storybook/addon-interactions": "^7.6.20",
|
|
102
102
|
"@storybook/addon-links": "^7.6.20",
|
|
@@ -127,5 +127,5 @@
|
|
|
127
127
|
"vite-plugin-babel": "^1.3.1",
|
|
128
128
|
"vite-plugin-node-polyfills": "^0.23.0"
|
|
129
129
|
},
|
|
130
|
-
"gitHead": "
|
|
130
|
+
"gitHead": "72af80fc6e91e88058665212985002966f55787c"
|
|
131
131
|
}
|
|
@@ -127,40 +127,69 @@ export default function ProductItem({
|
|
|
127
127
|
}
|
|
128
128
|
);
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
const
|
|
130
|
+
const canAdjustQuantity = adjustableQuantity.enabled && mode === 'normal';
|
|
131
|
+
const minQuantity = Math.max(adjustableQuantity.minimum || 1, 1);
|
|
132
|
+
const quantityAvailable = Math.min(item.price.quantity_limit_per_checkout, item.price.quantity_available);
|
|
133
|
+
const maxQuantity = quantityAvailable
|
|
134
|
+
? Math.min(adjustableQuantity.maximum || Infinity, quantityAvailable)
|
|
135
|
+
: adjustableQuantity.maximum || Infinity;
|
|
136
|
+
|
|
137
|
+
const getMinQuantityForPending = useMemo(() => {
|
|
138
|
+
if (!isCreditProduct || !pendingAmount) return null;
|
|
139
|
+
const pendingAmountBN = new BN(pendingAmount || '0');
|
|
140
|
+
if (!pendingAmountBN.gt(new BN(0))) return null;
|
|
141
|
+
const creditAmountBN = fromTokenToUnit(creditAmount, creditCurrency?.decimal || 2);
|
|
142
|
+
return Math.ceil(pendingAmountBN.mul(new BN(100)).div(creditAmountBN).toNumber() / 100);
|
|
143
|
+
}, [isCreditProduct, pendingAmount, creditAmount, creditCurrency?.decimal]);
|
|
144
|
+
|
|
145
|
+
const initialQuantity = useMemo(() => {
|
|
132
146
|
const urlQuantity = getRecommendedQuantityFromUrl(item.price.id);
|
|
133
147
|
if (urlQuantity && urlQuantity > 0) {
|
|
148
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
149
|
+
return Math.max(urlQuantity, getMinQuantityForPending, minQuantity);
|
|
150
|
+
}
|
|
134
151
|
return urlQuantity;
|
|
135
152
|
}
|
|
136
153
|
|
|
137
154
|
if (userDid) {
|
|
138
155
|
const preferredQuantity = getUserQuantityPreference(userDid, item.price.id);
|
|
139
156
|
if (preferredQuantity && preferredQuantity > 0) {
|
|
157
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
158
|
+
return Math.max(preferredQuantity, getMinQuantityForPending, minQuantity);
|
|
159
|
+
}
|
|
140
160
|
return preferredQuantity;
|
|
141
161
|
}
|
|
142
162
|
}
|
|
143
163
|
|
|
144
|
-
|
|
145
|
-
};
|
|
164
|
+
let baseQuantity = item.quantity;
|
|
146
165
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
166
|
+
if (canAdjustQuantity && getMinQuantityForPending) {
|
|
167
|
+
baseQuantity = Math.max(baseQuantity, getMinQuantityForPending, minQuantity);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return baseQuantity;
|
|
171
|
+
}, [item.quantity, item.price.id, userDid, getMinQuantityForPending, canAdjustQuantity, minQuantity]);
|
|
172
|
+
|
|
173
|
+
const [localQuantity, setLocalQuantity] = useState<number | undefined>(initialQuantity);
|
|
154
174
|
const localQuantityNum = localQuantity || 0;
|
|
155
175
|
|
|
156
176
|
useEffect(() => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
177
|
+
if (initialQuantity && initialQuantity > 0) {
|
|
178
|
+
if (initialQuantity !== localQuantity) {
|
|
179
|
+
setLocalQuantity(initialQuantity);
|
|
180
|
+
}
|
|
181
|
+
if (initialQuantity !== item.quantity) {
|
|
182
|
+
onQuantityChange(item.price_id, initialQuantity);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (isCreditProduct && pendingAmount && getMinQuantityForPending) {
|
|
186
|
+
setPayable(initialQuantity >= getMinQuantityForPending);
|
|
187
|
+
} else {
|
|
188
|
+
setPayable(true);
|
|
189
|
+
}
|
|
161
190
|
}
|
|
162
191
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
163
|
-
}, []);
|
|
192
|
+
}, [initialQuantity, isCreditProduct, pendingAmount, getMinQuantityForPending]);
|
|
164
193
|
|
|
165
194
|
const handleQuantityChange = (newQuantity: number) => {
|
|
166
195
|
if (!newQuantity) {
|
|
@@ -168,11 +197,22 @@ export default function ProductItem({
|
|
|
168
197
|
setPayable(false);
|
|
169
198
|
return;
|
|
170
199
|
}
|
|
171
|
-
|
|
200
|
+
|
|
172
201
|
if (newQuantity >= minQuantity && newQuantity <= maxQuantity) {
|
|
173
202
|
if (formatQuantityInventory(item.price, newQuantity, locale)) {
|
|
174
203
|
return;
|
|
175
204
|
}
|
|
205
|
+
|
|
206
|
+
if (isCreditProduct && pendingAmount && getMinQuantityForPending) {
|
|
207
|
+
if (newQuantity < getMinQuantityForPending) {
|
|
208
|
+
setPayable(false);
|
|
209
|
+
setLocalQuantity(newQuantity);
|
|
210
|
+
onQuantityChange(item.price_id, newQuantity);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
setPayable(true);
|
|
176
216
|
setLocalQuantity(newQuantity);
|
|
177
217
|
onQuantityChange(item.price_id, newQuantity);
|
|
178
218
|
|
|
@@ -259,7 +299,7 @@ export default function ProductItem({
|
|
|
259
299
|
|
|
260
300
|
const pendingAmountBN = new BN(pendingAmount || '0');
|
|
261
301
|
const creditAmountBN = fromTokenToUnit(creditAmount, creditCurrency?.decimal || 2);
|
|
262
|
-
const minQuantityNeeded =
|
|
302
|
+
const minQuantityNeeded = getMinQuantityForPending || 0;
|
|
263
303
|
const currentPurchaseCreditBN = creditAmountBN.mul(new BN(localQuantity || 0));
|
|
264
304
|
const actualAvailable = currentPurchaseCreditBN.sub(pendingAmountBN).toString();
|
|
265
305
|
|