@alma/widgets 2.2.10 → 2.3.0
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/CHANGELOG.md +7 -0
- package/dist/raw/widgets.css +21 -14
- package/dist/raw/widgets.js +107 -54
- package/dist/raw/widgets.js.map +1 -1
- package/dist/raw/widgets.m.js +107 -54
- package/dist/raw/widgets.m.js.map +1 -1
- package/dist/raw/widgets.modern.js +97 -45
- package/dist/raw/widgets.modern.js.map +1 -1
- package/dist/raw/widgets.umd.js +107 -54
- package/dist/raw/widgets.umd.js.map +1 -1
- package/dist/types/Widgets/PaymentPlans/index.d.ts +3 -2
- package/dist/types/Widgets/PaymentPlans/tests/SuggestedPaymentPlan.d.ts +1 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types/utils/merchantOrderPreferences.d.ts +14 -0
- package/dist/widgets.css +6 -6
- package/dist/widgets.js +1 -1
- package/dist/widgets.js.map +1 -1
- package/dist/widgets.m.js +1 -1
- package/dist/widgets.m.js.map +1 -1
- package/dist/widgets.modern.js +1 -1
- package/dist/widgets.modern.js.map +1 -1
- package/dist/widgets.umd.js +1 -1
- package/dist/widgets.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1506,7 +1506,7 @@ var messagesDE = {
|
|
|
1506
1506
|
"payment-plan-strings.deferred": "{totalAmount} zu zahlen am {dueDate}",
|
|
1507
1507
|
"payment-plan-strings.ineligible-greater-than-max": "Bis zu {maxAmount}",
|
|
1508
1508
|
"payment-plan-strings.ineligible-lower-than-min": "Ab {minAmount}",
|
|
1509
|
-
"payment-plan-strings.multiple-installments": "{firstInstallmentAmount} dann {numberOfRemainingInstallments} x {othersInstallmentAmount}",
|
|
1509
|
+
"payment-plan-strings.multiple-installments": "{numberOfRemainingInstallments, plural, one {{firstInstallmentAmount} dann {numberOfRemainingInstallments} x {othersInstallmentAmount}} other {{firstInstallmentAmount} dann {numberOfRemainingInstallments} x {othersInstallmentAmount}}}",
|
|
1510
1510
|
"payment-plan-strings.multiple-installments-same-amount": "{installmentsCount} x {totalAmount}",
|
|
1511
1511
|
"payment-plan-strings.no-fee": "(gebührenfrei)"
|
|
1512
1512
|
};
|
|
@@ -1528,7 +1528,7 @@ var messagesEN = {
|
|
|
1528
1528
|
"payment-plan-strings.deferred": "{totalAmount} to be paid on {dueDate}",
|
|
1529
1529
|
"payment-plan-strings.ineligible-greater-than-max": "Until {maxAmount}",
|
|
1530
1530
|
"payment-plan-strings.ineligible-lower-than-min": "From {minAmount}",
|
|
1531
|
-
"payment-plan-strings.multiple-installments": "{firstInstallmentAmount} then {numberOfRemainingInstallments} x {othersInstallmentAmount}",
|
|
1531
|
+
"payment-plan-strings.multiple-installments": "{numberOfRemainingInstallments, plural, one {{firstInstallmentAmount} then {numberOfRemainingInstallments} x {othersInstallmentAmount}} other {{firstInstallmentAmount} then {numberOfRemainingInstallments} x {othersInstallmentAmount}}}",
|
|
1532
1532
|
"payment-plan-strings.multiple-installments-same-amount": "{installmentsCount} x {totalAmount}",
|
|
1533
1533
|
"payment-plan-strings.no-fee": "(free of charge)"
|
|
1534
1534
|
};
|
|
@@ -1550,7 +1550,7 @@ var messagesES = {
|
|
|
1550
1550
|
"payment-plan-strings.deferred": "{totalAmount} a pagar el {dueDate}",
|
|
1551
1551
|
"payment-plan-strings.ineligible-greater-than-max": "Hasta {maxAmount}",
|
|
1552
1552
|
"payment-plan-strings.ineligible-lower-than-min": "Desde {minAmount}",
|
|
1553
|
-
"payment-plan-strings.multiple-installments": "{firstInstallmentAmount} hoy, después {numberOfRemainingInstallments
|
|
1553
|
+
"payment-plan-strings.multiple-installments": "{numberOfRemainingInstallments, plural, one {{firstInstallmentAmount} hoy, después {numberOfRemainingInstallments} mensualidad de {othersInstallmentAmount}} other {{firstInstallmentAmount} hoy, después {numberOfRemainingInstallments} de {othersInstallmentAmount} mensualidades }}",
|
|
1554
1554
|
"payment-plan-strings.multiple-installments-same-amount": "{installmentsCount} plazos de {totalAmount}",
|
|
1555
1555
|
"payment-plan-strings.no-fee": "(sin intereses)"
|
|
1556
1556
|
};
|
|
@@ -1572,7 +1572,7 @@ var messagesFR = {
|
|
|
1572
1572
|
"payment-plan-strings.deferred": "{totalAmount} à payer le {dueDate}",
|
|
1573
1573
|
"payment-plan-strings.ineligible-greater-than-max": "Jusqu'à {maxAmount}",
|
|
1574
1574
|
"payment-plan-strings.ineligible-lower-than-min": "À partir de {minAmount}",
|
|
1575
|
-
"payment-plan-strings.multiple-installments": "{firstInstallmentAmount} puis {numberOfRemainingInstallments} x {othersInstallmentAmount}",
|
|
1575
|
+
"payment-plan-strings.multiple-installments": "{numberOfRemainingInstallments, plural, one {{firstInstallmentAmount} puis {numberOfRemainingInstallments} x {othersInstallmentAmount}} other {{firstInstallmentAmount} puis {numberOfRemainingInstallments} x {othersInstallmentAmount}}}",
|
|
1576
1576
|
"payment-plan-strings.multiple-installments-same-amount": "{installmentsCount} x {totalAmount}",
|
|
1577
1577
|
"payment-plan-strings.no-fee": "(sans frais)"
|
|
1578
1578
|
};
|
|
@@ -1594,7 +1594,7 @@ var messagesIT = {
|
|
|
1594
1594
|
"payment-plan-strings.deferred": "{totalAmount} da pagare il {dueDate}",
|
|
1595
1595
|
"payment-plan-strings.ineligible-greater-than-max": "Disponibile fino a {maxAmount}",
|
|
1596
1596
|
"payment-plan-strings.ineligible-lower-than-min": "Pagamento rateale disponibile a partire da {minAmount}",
|
|
1597
|
-
"payment-plan-strings.multiple-installments": "Oggi paghi {firstInstallmentAmount} poi {numberOfRemainingInstallments} rate mensili di {othersInstallmentAmount}",
|
|
1597
|
+
"payment-plan-strings.multiple-installments": "{numberOfRemainingInstallments, plural, one {Oggi paghi {firstInstallmentAmount} poi {numberOfRemainingInstallments} rata mensile di {othersInstallmentAmount}} other {Oggi paghi {firstInstallmentAmount} poi {numberOfRemainingInstallments} rate mensili di {othersInstallmentAmount}}}",
|
|
1598
1598
|
"payment-plan-strings.multiple-installments-same-amount": "In {installmentsCount} rate mensili di {totalAmount}",
|
|
1599
1599
|
"payment-plan-strings.no-fee": "(senza interessi)"
|
|
1600
1600
|
};
|
|
@@ -1616,7 +1616,7 @@ var messagesNL = {
|
|
|
1616
1616
|
"payment-plan-strings.deferred": "{totalAmount} te betalen op {dueDate}",
|
|
1617
1617
|
"payment-plan-strings.ineligible-greater-than-max": "Tot {maxAmount}",
|
|
1618
1618
|
"payment-plan-strings.ineligible-lower-than-min": "Van {minAmount}",
|
|
1619
|
-
"payment-plan-strings.multiple-installments": "{firstInstallmentAmount} dan {numberOfRemainingInstallments} x {othersInstallmentAmount}",
|
|
1619
|
+
"payment-plan-strings.multiple-installments": "{numberOfRemainingInstallments, plural, one {{firstInstallmentAmount} dan {numberOfRemainingInstallments} x {othersInstallmentAmount}} other {{firstInstallmentAmount} dan {numberOfRemainingInstallments} x {othersInstallmentAmount}}}",
|
|
1620
1620
|
"payment-plan-strings.multiple-installments-same-amount": "{installmentsCount} x {totalAmount}",
|
|
1621
1621
|
"payment-plan-strings.no-fee": "(gratis)"
|
|
1622
1622
|
};
|
|
@@ -1744,8 +1744,8 @@ const useFetchEligibility = (purchaseAmount, {
|
|
|
1744
1744
|
}, {
|
|
1745
1745
|
Authorization: `Alma-Merchant-Auth ${merchantId}`
|
|
1746
1746
|
}).then(res => {
|
|
1747
|
-
setStatus(apiStatus.SUCCESS);
|
|
1748
1747
|
setEligibility(res);
|
|
1748
|
+
setStatus(apiStatus.SUCCESS);
|
|
1749
1749
|
}).catch(() => {
|
|
1750
1750
|
setStatus(apiStatus.FAILED);
|
|
1751
1751
|
});
|
|
@@ -1927,7 +1927,7 @@ const paymentPlanInfoText = payment => {
|
|
|
1927
1927
|
|
|
1928
1928
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
1929
1929
|
id: "payment-plan-strings.multiple-installments",
|
|
1930
|
-
defaultMessage: "{firstInstallmentAmount} puis {numberOfRemainingInstallments} x {othersInstallmentAmount}",
|
|
1930
|
+
defaultMessage: "{numberOfRemainingInstallments, plural, one {{firstInstallmentAmount} puis {numberOfRemainingInstallments} x {othersInstallmentAmount}} other {{firstInstallmentAmount} puis {numberOfRemainingInstallments} x {othersInstallmentAmount}}}",
|
|
1931
1931
|
values: {
|
|
1932
1932
|
firstInstallmentAmount: /*#__PURE__*/React.createElement(FormattedNumber, {
|
|
1933
1933
|
value: priceFromCents(payment.payment_plan[0].total_amount),
|
|
@@ -2257,37 +2257,106 @@ const useButtonAnimation = (iterateValues, transitionDelay) => {
|
|
|
2257
2257
|
};
|
|
2258
2258
|
};
|
|
2259
2259
|
|
|
2260
|
-
|
|
2260
|
+
/**
|
|
2261
|
+
* It returns the **index** of the **first eligible plan** that matches the default installments count
|
|
2262
|
+
*
|
|
2263
|
+
* @param {number | number[]} suggestedPaymentPlan
|
|
2264
|
+
* @param {EligibilityPlan[]} eligibilityPlans
|
|
2265
|
+
* @returns number (index of the first eligible plan that matches the default installments count)
|
|
2266
|
+
*/
|
|
2267
|
+
const getIndexOfActivePlan = ({
|
|
2268
|
+
suggestedPaymentPlan,
|
|
2269
|
+
eligibilityPlans
|
|
2270
|
+
}) => {
|
|
2271
|
+
const suggestedPaymentPlanArray = Array.isArray(suggestedPaymentPlan) ? suggestedPaymentPlan : [suggestedPaymentPlan];
|
|
2272
|
+
|
|
2273
|
+
for (const index in suggestedPaymentPlanArray) {
|
|
2274
|
+
const installmentsCount = suggestedPaymentPlanArray[index];
|
|
2275
|
+
const planFound = eligibilityPlans.findIndex(plan => {
|
|
2276
|
+
return plan.installments_count === installmentsCount && plan.eligible;
|
|
2277
|
+
});
|
|
2278
|
+
|
|
2279
|
+
if (planFound !== -1) {
|
|
2280
|
+
return planFound;
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
return 0;
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2287
|
+
var s$b = {"widgetButton":"_TSkFv","logo":"_LJ4nZ","primaryContainer":"_bMClc","paymentPlans":"_17c_S","plan":"_2Kqjn","active":"_3dG_J","notEligible":"_3O1bg","info":"_25GrF","loader":"_30j1O","error":"_R0YlN","errorText":"_2kGhu","errorButton":"_73d_Y","pending":"_1ZDMS","clickable":"_UksZa","unClickable":"_1lr-q"};
|
|
2288
|
+
|
|
2289
|
+
const VERY_LONG_TIME_IN_MS = 1000 * 3600 * 24 * 365;
|
|
2290
|
+
const DEFAULT_TRANSITION_TIME = 5500;
|
|
2261
2291
|
|
|
2262
2292
|
const PaymentPlanWidget = ({
|
|
2263
2293
|
purchaseAmount,
|
|
2264
2294
|
apiData,
|
|
2265
2295
|
configPlans,
|
|
2266
2296
|
transitionDelay,
|
|
2267
|
-
hideIfNotEligible
|
|
2297
|
+
hideIfNotEligible,
|
|
2298
|
+
suggestedPaymentPlan
|
|
2268
2299
|
}) => {
|
|
2269
2300
|
const [eligibilityPlans, status] = useFetchEligibility(purchaseAmount, apiData, configPlans);
|
|
2270
2301
|
const eligiblePlans = eligibilityPlans.filter(plan => plan.eligible);
|
|
2302
|
+
const activePlanIndex = getIndexOfActivePlan({
|
|
2303
|
+
eligibilityPlans,
|
|
2304
|
+
suggestedPaymentPlan: suggestedPaymentPlan != null ? suggestedPaymentPlan : 0
|
|
2305
|
+
});
|
|
2306
|
+
const isSuggestedPaymentPlanSpecified = suggestedPaymentPlan !== undefined; // 👈 The merchant decided to focus a tab and remove animated transition.
|
|
2307
|
+
|
|
2308
|
+
const isTransitionSpecified = transitionDelay !== undefined; // 👈 The merchant has specified a transition time
|
|
2309
|
+
|
|
2271
2310
|
const [isOpen, setIsOpen] = useState(false);
|
|
2272
|
-
const [initialPlanIndex, setInitialPlanIndex] = useState(0);
|
|
2273
2311
|
|
|
2274
2312
|
const openModal = () => setIsOpen(true);
|
|
2275
2313
|
|
|
2276
2314
|
const closeModal = () => setIsOpen(false);
|
|
2277
2315
|
|
|
2278
2316
|
const eligiblePlanKeys = eligibilityPlans.reduce((acc, plan, index) => plan.eligible ? [...acc, index] : acc, []);
|
|
2317
|
+
/**
|
|
2318
|
+
* If merchand specify a suggestedPaymentPlan and no transition, we set a very long transition delay.
|
|
2319
|
+
* Otherwise, we set the transition delay specified by the merchant.
|
|
2320
|
+
* If none of those properties are specified, we set a default transition delay.
|
|
2321
|
+
* @returns
|
|
2322
|
+
*/
|
|
2323
|
+
|
|
2324
|
+
const realTransitionTime = () => {
|
|
2325
|
+
if (isTransitionSpecified) {
|
|
2326
|
+
return transitionDelay != null ? transitionDelay : DEFAULT_TRANSITION_TIME;
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
if (isSuggestedPaymentPlanSpecified) {
|
|
2330
|
+
return VERY_LONG_TIME_IN_MS;
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
return DEFAULT_TRANSITION_TIME;
|
|
2334
|
+
};
|
|
2335
|
+
|
|
2279
2336
|
const {
|
|
2280
2337
|
current,
|
|
2281
2338
|
onHover,
|
|
2282
2339
|
onLeave
|
|
2283
|
-
} = useButtonAnimation(eligiblePlanKeys,
|
|
2284
|
-
// updates the `current` value (i.e. without any hover / click callback).
|
|
2285
|
-
|
|
2340
|
+
} = useButtonAnimation(eligiblePlanKeys, realTransitionTime());
|
|
2286
2341
|
useEffect(() => {
|
|
2287
|
-
|
|
2288
|
-
|
|
2342
|
+
// When API has given a response AND the marchand set an active plan by default.
|
|
2343
|
+
if (status === apiStatus.SUCCESS && isSuggestedPaymentPlanSpecified) {
|
|
2344
|
+
onHover(activePlanIndex); // We select the first active plan possible
|
|
2345
|
+
|
|
2346
|
+
onLeave(); // We need to call onLeave to reset the animation
|
|
2289
2347
|
}
|
|
2290
|
-
}, [
|
|
2348
|
+
}, [status]);
|
|
2349
|
+
/**
|
|
2350
|
+
* It takes a plan index and returns the index of that plan within the eligible plans
|
|
2351
|
+
*
|
|
2352
|
+
* @param {number} planIndex - The index of the plan that the user has selected.
|
|
2353
|
+
* @returns The index of the planKey in the eligiblePlanKeys array.
|
|
2354
|
+
*/
|
|
2355
|
+
|
|
2356
|
+
const getIndexWithinEligiblePlans = planIndex => {
|
|
2357
|
+
const index = eligiblePlanKeys.findIndex(planKey => planKey === planIndex);
|
|
2358
|
+
return index === -1 ? 0 : index;
|
|
2359
|
+
};
|
|
2291
2360
|
|
|
2292
2361
|
if (status === apiStatus.PENDING) {
|
|
2293
2362
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -2295,11 +2364,7 @@ const PaymentPlanWidget = ({
|
|
|
2295
2364
|
}, /*#__PURE__*/React.createElement(Loader, null));
|
|
2296
2365
|
}
|
|
2297
2366
|
|
|
2298
|
-
if (hideIfNotEligible && eligiblePlans.length
|
|
2299
|
-
return null;
|
|
2300
|
-
}
|
|
2301
|
-
|
|
2302
|
-
if (status === apiStatus.FAILED) {
|
|
2367
|
+
if (hideIfNotEligible && eligiblePlans.length === 0 || eligibilityPlans.length === 0 || status === apiStatus.FAILED) {
|
|
2303
2368
|
return null;
|
|
2304
2369
|
}
|
|
2305
2370
|
|
|
@@ -2311,19 +2376,12 @@ const PaymentPlanWidget = ({
|
|
|
2311
2376
|
}
|
|
2312
2377
|
};
|
|
2313
2378
|
|
|
2314
|
-
const handleHoverAndClick = (key, newInitialPlanIndex) => {
|
|
2315
|
-
// This is needed to update the initial plan index and button style when hovering (desktop) or clicking (mobile).
|
|
2316
|
-
// The actual modal opening is triggered by a click on the highest parent div in `handleOpenModal`.
|
|
2317
|
-
onHover(key);
|
|
2318
|
-
setInitialPlanIndex(newInitialPlanIndex);
|
|
2319
|
-
};
|
|
2320
|
-
|
|
2321
2379
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
2322
2380
|
onClick: handleOpenModal,
|
|
2323
|
-
className: s$b.widgetButton,
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
},
|
|
2381
|
+
className: cx(s$b.widgetButton, {
|
|
2382
|
+
[s$b.clickable]: eligiblePlans.length > 0,
|
|
2383
|
+
[s$b.unClickable]: eligiblePlans.length === 0
|
|
2384
|
+
}),
|
|
2327
2385
|
"data-testid": "widget-button"
|
|
2328
2386
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2329
2387
|
className: s$b.primaryContainer
|
|
@@ -2332,18 +2390,10 @@ const PaymentPlanWidget = ({
|
|
|
2332
2390
|
}), /*#__PURE__*/React.createElement("div", {
|
|
2333
2391
|
className: s$b.paymentPlans
|
|
2334
2392
|
}, eligibilityPlans.map((eligibilityPlan, key) => {
|
|
2335
|
-
const newInitialPlanIndex = eligiblePlanKeys.includes(key) ? eligiblePlanKeys.findIndex(planKey => planKey === key) : 0;
|
|
2336
2393
|
return /*#__PURE__*/React.createElement("div", {
|
|
2337
|
-
onMouseEnter: () => {
|
|
2338
|
-
handleHoverAndClick(key, newInitialPlanIndex);
|
|
2339
|
-
},
|
|
2340
|
-
onMouseOut: () => {
|
|
2341
|
-
onLeave();
|
|
2342
|
-
},
|
|
2343
|
-
onClick: () => {
|
|
2344
|
-
handleHoverAndClick(key, newInitialPlanIndex);
|
|
2345
|
-
},
|
|
2346
2394
|
key: key,
|
|
2395
|
+
onMouseEnter: () => onHover(key),
|
|
2396
|
+
onMouseOut: onLeave,
|
|
2347
2397
|
className: cx(s$b.plan, {
|
|
2348
2398
|
[s$b.active]: current === key,
|
|
2349
2399
|
[s$b.notEligible]: !eligibilityPlan.eligible
|
|
@@ -2354,7 +2404,7 @@ const PaymentPlanWidget = ({
|
|
|
2354
2404
|
[s$b.notEligible]: eligibilityPlans[current] && !eligibilityPlans[current].eligible
|
|
2355
2405
|
})
|
|
2356
2406
|
}, eligibilityPlans.length !== 0 && paymentPlanInfoText(eligibilityPlans[current]))), isOpen && /*#__PURE__*/React.createElement(EligibilityModal, {
|
|
2357
|
-
initialPlanIndex:
|
|
2407
|
+
initialPlanIndex: getIndexWithinEligiblePlans(current),
|
|
2358
2408
|
onClose: closeModal,
|
|
2359
2409
|
eligibilityPlans: eligiblePlans,
|
|
2360
2410
|
status: status
|
|
@@ -2380,6 +2430,7 @@ class WidgetsController {
|
|
|
2380
2430
|
plans,
|
|
2381
2431
|
transitionDelay,
|
|
2382
2432
|
hideIfNotEligible,
|
|
2433
|
+
suggestedPaymentPlan,
|
|
2383
2434
|
locale = Locale.en
|
|
2384
2435
|
} = options;
|
|
2385
2436
|
|
|
@@ -2391,7 +2442,8 @@ class WidgetsController {
|
|
|
2391
2442
|
apiData: this.apiData,
|
|
2392
2443
|
configPlans: plans,
|
|
2393
2444
|
transitionDelay: transitionDelay,
|
|
2394
|
-
hideIfNotEligible: hideIfNotEligible
|
|
2445
|
+
hideIfNotEligible: hideIfNotEligible,
|
|
2446
|
+
suggestedPaymentPlan: suggestedPaymentPlan
|
|
2395
2447
|
})), document.querySelector(container));
|
|
2396
2448
|
}
|
|
2397
2449
|
}
|