@bunnyapp/components 1.8.0-beta.3 → 1.8.0-beta.5
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/index.js +86 -46
- package/dist/cjs/types/src/components/Checkout/QuoteCheckout.d.ts +2 -2
- package/dist/cjs/types/src/components/Signup/{CheckoutSummary.d.ts → components/CheckoutSummary/CheckoutSummary.d.ts} +1 -1
- package/dist/cjs/types/src/components/Signup/components/CheckoutSummary/hooks/sortQuoteChangeCharges.d.ts +14 -0
- package/dist/cjs/types/src/components/Signup/fragments/Signup_QuoteFragment.d.ts +2 -0
- package/dist/cjs/types/src/components/Signup/hooks/useApplyDefaultCoupon.d.ts +21 -0
- package/dist/cjs/types/src/components/priceListPricing/PricingTooltip.d.ts +0 -2
- package/dist/cjs/types/src/utils/couponUtils.d.ts +5 -5
- package/dist/esm/index.js +86 -46
- package/dist/esm/types/src/components/Checkout/QuoteCheckout.d.ts +2 -2
- package/dist/esm/types/src/components/Signup/{CheckoutSummary.d.ts → components/CheckoutSummary/CheckoutSummary.d.ts} +1 -1
- package/dist/esm/types/src/components/Signup/components/CheckoutSummary/hooks/sortQuoteChangeCharges.d.ts +14 -0
- package/dist/esm/types/src/components/Signup/fragments/Signup_QuoteFragment.d.ts +2 -0
- package/dist/esm/types/src/components/Signup/hooks/useApplyDefaultCoupon.d.ts +21 -0
- package/dist/esm/types/src/components/priceListPricing/PricingTooltip.d.ts +0 -2
- package/dist/esm/types/src/utils/couponUtils.d.ts +5 -5
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -1283,7 +1283,7 @@ const DEFAULT_CONFIG = {
|
|
|
1283
1283
|
};
|
|
1284
1284
|
|
|
1285
1285
|
// This will be replaced at build time by rollup-plugin-replace
|
|
1286
|
-
const PACKAGE_VERSION = '1.8.0-beta.
|
|
1286
|
+
const PACKAGE_VERSION = '1.8.0-beta.4';
|
|
1287
1287
|
const createRequestHeaders = (token) => {
|
|
1288
1288
|
const headers = createClientDevHeaders({ token });
|
|
1289
1289
|
// Add the components version header
|
|
@@ -22955,15 +22955,15 @@ function QuotesWrapper() {
|
|
|
22955
22955
|
return (jsxRuntime.jsx(TransactionsDisplay, { transactions: quotesAsTransactions, onSearchValueChanged: setSearch, search: search }));
|
|
22956
22956
|
}
|
|
22957
22957
|
|
|
22958
|
-
const
|
|
22959
|
-
fragment
|
|
22958
|
+
const canApplyCoupons_QuoteFragment = t(`
|
|
22959
|
+
fragment canApplyCoupons_QuoteFragment on Quote {
|
|
22960
22960
|
id
|
|
22961
22961
|
kind
|
|
22962
22962
|
amountDue
|
|
22963
22963
|
}
|
|
22964
22964
|
`, []);
|
|
22965
|
-
const
|
|
22966
|
-
fragment
|
|
22965
|
+
const canApplyCoupons_SubscriptionFragment = t(`
|
|
22966
|
+
fragment canApplyCoupons_SubscriptionFragment on Subscription {
|
|
22967
22967
|
id
|
|
22968
22968
|
state
|
|
22969
22969
|
charges {
|
|
@@ -22971,10 +22971,10 @@ const shouldShowCouponEditor_SubscriptionFragment = t(`
|
|
|
22971
22971
|
}
|
|
22972
22972
|
}
|
|
22973
22973
|
`, []);
|
|
22974
|
-
function
|
|
22974
|
+
function canApplyCoupons(maskedQuote, activeCouponsExist, maskedUpgradingSubscription) {
|
|
22975
22975
|
var _a, _b;
|
|
22976
|
-
const quote = readFragment(
|
|
22977
|
-
const upgradingSubscription = readFragment(
|
|
22976
|
+
const quote = readFragment(canApplyCoupons_QuoteFragment, maskedQuote);
|
|
22977
|
+
const upgradingSubscription = readFragment(canApplyCoupons_SubscriptionFragment, maskedUpgradingSubscription);
|
|
22978
22978
|
const upgradingFromTrial = ((_a = upgradingSubscription === null || upgradingSubscription === void 0 ? void 0 : upgradingSubscription.state) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === t.scalar('SubscriptionState', 'TRIAL') ||
|
|
22979
22979
|
((_b = upgradingSubscription === null || upgradingSubscription === void 0 ? void 0 : upgradingSubscription.state) === null || _b === void 0 ? void 0 : _b.toUpperCase()) ===
|
|
22980
22980
|
t.scalar('SubscriptionState', 'TRIAL_EXPIRED');
|
|
@@ -22992,7 +22992,10 @@ function shouldShowCouponEditor(maskedQuote, activeCouponsExist, maskedUpgrading
|
|
|
22992
22992
|
return false;
|
|
22993
22993
|
}
|
|
22994
22994
|
if (quoteKindIsValid) {
|
|
22995
|
-
|
|
22995
|
+
const result = activeCouponsExist &&
|
|
22996
|
+
(upgradingFromTrial || upgradingFromFree() || signingUpForNewSubscription);
|
|
22997
|
+
console.log('returning result', result);
|
|
22998
|
+
return result;
|
|
22996
22999
|
}
|
|
22997
23000
|
return false;
|
|
22998
23001
|
}
|
|
@@ -23004,6 +23007,27 @@ function CouponEditor({ className, onAddCoupon, isAddingCoupon, couponCode, setC
|
|
|
23004
23007
|
return (jsxRuntime.jsx("div", { className: `bunny-flex bunny-flex-col bunny-gap-2 ${className}`, children: jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-row bunny-gap-2", children: [jsxRuntime.jsx(antd.Input, { value: couponCode, onChange: e => setCouponCode(e.target.value), placeholder: "Coupon code", disabled: isAddingCoupon, size: "small" }), jsxRuntime.jsx(antd.Button, { loading: isAddingCoupon, type: "primary", onClick: handleAddCoupon, disabled: couponCode.length === 0, children: "Apply" })] }) }));
|
|
23005
23008
|
}
|
|
23006
23009
|
|
|
23010
|
+
t(`
|
|
23011
|
+
fragment sortQuoteChangeCharges_QuoteChargeFragment on QuoteCharge {
|
|
23012
|
+
kind
|
|
23013
|
+
}
|
|
23014
|
+
`, []);
|
|
23015
|
+
/**
|
|
23016
|
+
* Sorts quote change charges so that coupon charges appear at the end of the list.
|
|
23017
|
+
* Uses a generic type so the full charge shape is preserved.
|
|
23018
|
+
*/
|
|
23019
|
+
function sortQuoteChangeCharges(charges) {
|
|
23020
|
+
return [...charges].sort((chargeA, chargeB) => {
|
|
23021
|
+
const aIsCoupon = chargeA.kind === 'COUPON';
|
|
23022
|
+
const bIsCoupon = chargeB.kind === 'COUPON';
|
|
23023
|
+
if (aIsCoupon && !bIsCoupon)
|
|
23024
|
+
return 1;
|
|
23025
|
+
if (!aIsCoupon && bIsCoupon)
|
|
23026
|
+
return -1;
|
|
23027
|
+
return 0;
|
|
23028
|
+
});
|
|
23029
|
+
}
|
|
23030
|
+
|
|
23007
23031
|
const { Text: Text$r } = antd.Typography;
|
|
23008
23032
|
const CheckoutSummary_PriceListFragment = t(`
|
|
23009
23033
|
fragment CheckoutSummary_PriceListFragment on PriceList {
|
|
@@ -23033,14 +23057,14 @@ const CheckoutSummary_QuoteFragment = t(`
|
|
|
23033
23057
|
currencyId
|
|
23034
23058
|
}
|
|
23035
23059
|
}
|
|
23036
|
-
...
|
|
23060
|
+
...canApplyCoupons_QuoteFragment
|
|
23037
23061
|
}
|
|
23038
|
-
`, [
|
|
23062
|
+
`, [canApplyCoupons_QuoteFragment]);
|
|
23039
23063
|
function CheckoutSummary({ quote: maskedQuote, className, onAddCoupon, onRemoveCoupon, isRemovingCoupon, priceList: maskedPriceList, isAddingCoupon, couponCode, setCouponCode, activeCouponsExist, }) {
|
|
23040
23064
|
var _a, _b;
|
|
23041
23065
|
const priceList = readFragment(CheckoutSummary_PriceListFragment, maskedPriceList);
|
|
23042
23066
|
const quote = readFragment(CheckoutSummary_QuoteFragment, maskedQuote);
|
|
23043
|
-
return (jsxRuntime.jsxs("div", { className: `${className} bunny-space-y-4`, children: [jsxRuntime.jsxs(Text$r, { children: [jsxRuntime.jsxs("div", { className: "bunny-text-lg bunny-font-medium bunny-mb-4", children: ["Checkout summary - ", (_a = priceList === null || priceList === void 0 ? void 0 : priceList.product) === null || _a === void 0 ? void 0 : _a.name, " ", priceList === null || priceList === void 0 ? void 0 : priceList.name] }), jsxRuntime.jsx("div", { className: "bunny-space-y-4", children: (_b = quote === null || quote === void 0 ? void 0 : quote.quoteChanges) === null || _b === void 0 ? void 0 : _b.map(quoteChange => quoteChange === null || quoteChange === void 0 ? void 0 : quoteChange.charges.map(charge => {
|
|
23067
|
+
return (jsxRuntime.jsxs("div", { className: `${className} bunny-space-y-4`, children: [jsxRuntime.jsxs(Text$r, { children: [jsxRuntime.jsxs("div", { className: "bunny-text-lg bunny-font-medium bunny-mb-4", children: ["Checkout summary - ", (_a = priceList === null || priceList === void 0 ? void 0 : priceList.product) === null || _a === void 0 ? void 0 : _a.name, " ", priceList === null || priceList === void 0 ? void 0 : priceList.name] }), jsxRuntime.jsx("div", { className: "bunny-space-y-4", children: (_b = quote === null || quote === void 0 ? void 0 : quote.quoteChanges) === null || _b === void 0 ? void 0 : _b.map(quoteChange => sortQuoteChangeCharges(quoteChange === null || quoteChange === void 0 ? void 0 : quoteChange.charges).map(charge => {
|
|
23044
23068
|
var _a;
|
|
23045
23069
|
const multiplier = charge.kind === 'COUPON' ? -1 : 1;
|
|
23046
23070
|
return (jsxRuntime.jsxs("div", { className: "bunny-grid bunny-grid-cols-3 bunny-gap-4 bunny-items-center", children: [jsxRuntime.jsx("div", { className: "bunny-col-span-1", children: charge.name }), jsxRuntime.jsx("div", { className: "bunny-col-span-1 bunny-text-center", children: ((_a = charge.coupon) === null || _a === void 0 ? void 0 : _a.couponCode) ? (jsxRuntime.jsx("button", { onClick: () => {
|
|
@@ -23053,7 +23077,7 @@ function CheckoutSummary({ quote: maskedQuote, className, onAddCoupon, onRemoveC
|
|
|
23053
23077
|
}
|
|
23054
23078
|
onRemoveCoupon((_b = charge.coupon) === null || _b === void 0 ? void 0 : _b.couponCode);
|
|
23055
23079
|
}, className: "bunny-text-orange-500 hover:bunny-text-orange-400 bunny-cursor-pointer bunny-bg-transparent bunny-border-none", children: "Remove" })) : (jsxRuntime.jsx("div", { children: charge.quantity })) }), jsxRuntime.jsx("div", { className: "bunny-col-span-1 bunny-text-right", children: formatCurrency(multiplier * (charge.subtotal || 0), charge.currencyId) })] }, charge.id));
|
|
23056
|
-
})) }), jsxRuntime.jsx(CheckoutSummaryDivider, {}), jsxRuntime.jsxs("div", { className: "bunny-space-y-4", children: [jsxRuntime.jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsxRuntime.jsx("div", { children: "Subtotal" }), jsxRuntime.jsx("div", { children: formatCurrency(quote.subtotal, quote.currencyId) })] }), jsxRuntime.jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsxRuntime.jsx("div", { children: "Taxes" }), jsxRuntime.jsx("div", { children: formatCurrency(quote.taxAmount, quote.currencyId) })] })] }), jsxRuntime.jsx(CheckoutSummaryDivider, {}), jsxRuntime.jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsxRuntime.jsx("div", { children: "Total" }), jsxRuntime.jsx("div", { children: formatCurrency(quote.amountDue, quote.currencyId) })] })] }),
|
|
23080
|
+
})) }), jsxRuntime.jsx(CheckoutSummaryDivider, {}), jsxRuntime.jsxs("div", { className: "bunny-space-y-4", children: [jsxRuntime.jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsxRuntime.jsx("div", { children: "Subtotal" }), jsxRuntime.jsx("div", { children: formatCurrency(quote.subtotal, quote.currencyId) })] }), jsxRuntime.jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsxRuntime.jsx("div", { children: "Taxes" }), jsxRuntime.jsx("div", { children: formatCurrency(quote.taxAmount, quote.currencyId) })] })] }), jsxRuntime.jsx(CheckoutSummaryDivider, {}), jsxRuntime.jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsxRuntime.jsx("div", { children: "Total" }), jsxRuntime.jsx("div", { children: formatCurrency(quote.amountDue, quote.currencyId) })] })] }), canApplyCoupons(quote, activeCouponsExist) && (jsxRuntime.jsx(CouponEditor, { className: "bunny-w-full", onAddCoupon: onAddCoupon, isAddingCoupon: isAddingCoupon, couponCode: couponCode, setCouponCode: setCouponCode }))] }));
|
|
23057
23081
|
}
|
|
23058
23082
|
const CheckoutSummaryDivider = () => {
|
|
23059
23083
|
return (jsxRuntime.jsx("div", { className: "bunny-my-2", children: jsxRuntime.jsx(antd.Divider, { className: "m-0" }) }));
|
|
@@ -23104,10 +23128,36 @@ function InitialSignupForm({ className, onSubmit, submitting, defaultValues, })
|
|
|
23104
23128
|
} }) }) }) }), jsxRuntime.jsx(antd.Form.Item, { children: jsxRuntime.jsx(antd.Button, { type: "primary", onClick: handleSubmit, loading: submitting, className: "bunny-w-full", children: "Proceed to payment" }) })] }) }));
|
|
23105
23129
|
}
|
|
23106
23130
|
|
|
23131
|
+
const useApplyDefaultCoupon_QuoteFragment = t(`
|
|
23132
|
+
fragment useApplyDefaultCoupon_QuoteFragment on Quote {
|
|
23133
|
+
...canApplyCoupons_QuoteFragment
|
|
23134
|
+
}
|
|
23135
|
+
`, [canApplyCoupons_QuoteFragment]);
|
|
23136
|
+
/**
|
|
23137
|
+
* Applies a default coupon code once when quoteChangeId is available.
|
|
23138
|
+
* Uses a ref to ensure coupon code is only applied once.
|
|
23139
|
+
*/
|
|
23140
|
+
function useApplyDefaultCoupon({ couponCode, quoteChangeId, quote: maskedQuote, activeCouponsExist, addCoupon, }) {
|
|
23141
|
+
const defaultCouponAppliedRef = react.useRef(undefined);
|
|
23142
|
+
// Derived state
|
|
23143
|
+
const quote = readFragment(useApplyDefaultCoupon_QuoteFragment, maskedQuote);
|
|
23144
|
+
const canApplyCouponsResult = canApplyCoupons(quote, activeCouponsExist);
|
|
23145
|
+
react.useEffect(() => {
|
|
23146
|
+
if (couponCode &&
|
|
23147
|
+
quoteChangeId &&
|
|
23148
|
+
defaultCouponAppliedRef.current !== couponCode &&
|
|
23149
|
+
canApplyCouponsResult) {
|
|
23150
|
+
addCoupon(couponCode);
|
|
23151
|
+
defaultCouponAppliedRef.current = couponCode;
|
|
23152
|
+
}
|
|
23153
|
+
}, [couponCode, quoteChangeId, addCoupon, canApplyCouponsResult]);
|
|
23154
|
+
}
|
|
23155
|
+
|
|
23107
23156
|
const Signup_QuoteFragment = t(`
|
|
23108
23157
|
fragment Signup_QuoteFragment on Quote {
|
|
23109
23158
|
...CheckoutSummary_QuoteFragment
|
|
23110
23159
|
...PaymentForms_QuoteFragment
|
|
23160
|
+
...useApplyDefaultCoupon_QuoteFragment
|
|
23111
23161
|
id
|
|
23112
23162
|
currencyId
|
|
23113
23163
|
amountDue
|
|
@@ -23115,7 +23165,7 @@ const Signup_QuoteFragment = t(`
|
|
|
23115
23165
|
id
|
|
23116
23166
|
}
|
|
23117
23167
|
}
|
|
23118
|
-
`, [CheckoutSummary_QuoteFragment, PaymentForms_QuoteFragment]);
|
|
23168
|
+
`, [CheckoutSummary_QuoteFragment, PaymentForms_QuoteFragment, useApplyDefaultCoupon_QuoteFragment]);
|
|
23119
23169
|
|
|
23120
23170
|
const query$6 = t(`
|
|
23121
23171
|
query quote($id: ID) {
|
|
@@ -23571,7 +23621,6 @@ function Signup({ companyName, priceListCode, returnUrl, couponCode, className,
|
|
|
23571
23621
|
const [portalSessionToken, setPortalSessionToken] = react.useState(undefined);
|
|
23572
23622
|
const token = portalSessionToken || tokenFromContexts;
|
|
23573
23623
|
const [purchaseSucceeded, setPurchaseSucceeded] = react.useState(false);
|
|
23574
|
-
const defaultCouponAppliedRef = react.useRef(undefined);
|
|
23575
23624
|
const [couponEditorCouponCode, setCouponEditorCouponCode] = react.useState('');
|
|
23576
23625
|
// Read fragment
|
|
23577
23626
|
const initialQuoteId = (_a = readFragment(Signup_QuoteFragment, initialQuote)) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -23688,13 +23737,7 @@ function Signup({ companyName, priceListCode, returnUrl, couponCode, className,
|
|
|
23688
23737
|
handleRecalculateTaxes(quote === null || quote === void 0 ? void 0 : quote.id);
|
|
23689
23738
|
},
|
|
23690
23739
|
});
|
|
23691
|
-
|
|
23692
|
-
react.useEffect(() => {
|
|
23693
|
-
if (couponCode && quoteChangeId && defaultCouponAppliedRef.current !== couponCode) {
|
|
23694
|
-
addCoupon(couponCode);
|
|
23695
|
-
defaultCouponAppliedRef.current = couponCode;
|
|
23696
|
-
}
|
|
23697
|
-
}, [couponCode, quoteChangeId]);
|
|
23740
|
+
useApplyDefaultCoupon({ couponCode, quoteChangeId, addCoupon, activeCouponsExist, quote });
|
|
23698
23741
|
async function handleSubmit(formData) {
|
|
23699
23742
|
if (selfServiceBuyEnabled === false) {
|
|
23700
23743
|
handleShowSelfServiceBuyWarning();
|
|
@@ -23924,22 +23967,22 @@ const QuoteCheckout_QuoteFragment = t(`
|
|
|
23924
23967
|
}
|
|
23925
23968
|
}
|
|
23926
23969
|
...QuoteFields_QuoteFragment
|
|
23927
|
-
...
|
|
23970
|
+
...canApplyCoupons_QuoteFragment
|
|
23928
23971
|
...PaymentForm_QuoteFragment
|
|
23929
23972
|
...getQuoteAmountDue_QuoteFragment
|
|
23930
23973
|
}
|
|
23931
23974
|
`, [
|
|
23932
23975
|
QuoteFields_QuoteFragment,
|
|
23933
|
-
|
|
23976
|
+
canApplyCoupons_QuoteFragment,
|
|
23934
23977
|
PaymentForm_QuoteFragment,
|
|
23935
23978
|
getQuoteAmountDue_QuoteFragment,
|
|
23936
23979
|
]);
|
|
23937
23980
|
const QuoteCheckout_SubscriptionFragment = t(`
|
|
23938
23981
|
fragment QuoteCheckout_SubscriptionFragment on Subscription {
|
|
23939
23982
|
id
|
|
23940
|
-
...
|
|
23983
|
+
...canApplyCoupons_SubscriptionFragment
|
|
23941
23984
|
}
|
|
23942
|
-
`, [
|
|
23985
|
+
`, [canApplyCoupons_SubscriptionFragment]);
|
|
23943
23986
|
const showSuccessNotification = useSuccessNotification();
|
|
23944
23987
|
const QuoteCheckout = ({ account, onSuccess, onFail, quote: maskedQuote, taxationRequiredAccountFields, isUpdatingQuote, onRecalculateTaxes, isRecalculatingTaxes, }) => {
|
|
23945
23988
|
var _a, _b, _c, _d, _e;
|
|
@@ -24025,7 +24068,7 @@ const QuoteCheckout = ({ account, onSuccess, onFail, quote: maskedQuote, taxatio
|
|
|
24025
24068
|
if (taxationRequiredAccountFields)
|
|
24026
24069
|
return (jsxRuntime.jsx(PaymentFormWrapper, { setMaxHeight: false, children: jsxRuntime.jsx(TaxationForm, { account: account, accountId: quote.accountId }) }));
|
|
24027
24070
|
return (jsxRuntime.jsx(PaymentFormWrapper, { setMaxHeight: false, children: paymentRequired ? (jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-2 bunny-w-full", children: [jsxRuntime.jsx(PaymentForm, { onPaymentSuccess: onSuccess, quote: quote, onSavePaymentMethod: (paymentMethod) => onPaymentMethodSaved === null || onPaymentMethodSaved === void 0 ? void 0 : onPaymentMethodSaved(paymentMethod.savedPaymentMethodResponse.paymentMethodId), onPaymentMethodRemoved: (paymentMethod) => onPaymentMethodRemoved === null || onPaymentMethodRemoved === void 0 ? void 0 : onPaymentMethodRemoved(paymentMethod.id), disablePayButton: isFinalizingQuote }), isFinalizingQuote && jsxRuntime.jsx(QuoteLoadingIndicator, {}), (couponsOnQuote === null || couponsOnQuote === void 0 ? void 0 : couponsOnQuote.length) === 0 ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: upgradingSubscription &&
|
|
24028
|
-
|
|
24071
|
+
canApplyCoupons(quote, activeCouponsExist, upgradingSubscription) && (jsxRuntime.jsx(CouponEditor, { className: "bunny-px-4 bunny-pt-1", onAddCoupon: addCoupon, isAddingCoupon: isAddingCoupon, couponCode: couponCode, setCouponCode: setCouponCode })) })) : (jsxRuntime.jsx(antd.Button, { type: "link", loading: isRemovingCoupon, onClick: () => {
|
|
24029
24072
|
couponsOnQuote === null || couponsOnQuote === void 0 ? void 0 : couponsOnQuote.forEach(couponCharge => {
|
|
24030
24073
|
var _a;
|
|
24031
24074
|
const couponCode = (_a = couponCharge === null || couponCharge === void 0 ? void 0 : couponCharge.coupon) === null || _a === void 0 ? void 0 : _a.couponCode;
|
|
@@ -26561,20 +26604,6 @@ function priceListChargePriceDescription(maskedPriceListCharge) {
|
|
|
26561
26604
|
return `Per ${unitName ? `${unitName} / ` : ''}${priceListCharge.showPriceAsMonthly ? 'month' : periodLabel}`;
|
|
26562
26605
|
}
|
|
26563
26606
|
|
|
26564
|
-
const GetActiveCharges_PriceListChargeFragment = t(`
|
|
26565
|
-
fragment GetActiveCharges_PriceListChargeFragment on PriceListCharge {
|
|
26566
|
-
deprecated
|
|
26567
|
-
featureAddon
|
|
26568
|
-
}
|
|
26569
|
-
`);
|
|
26570
|
-
// Active charges: any charge that is not deprecated and not a feature addon
|
|
26571
|
-
function getActiveCharges(charges) {
|
|
26572
|
-
return charges.filter(maskedCharge => {
|
|
26573
|
-
const charge = readFragment(GetActiveCharges_PriceListChargeFragment, maskedCharge);
|
|
26574
|
-
return !charge.deprecated && !charge.featureAddon;
|
|
26575
|
-
});
|
|
26576
|
-
}
|
|
26577
|
-
|
|
26578
26607
|
const getPriceListUnitName_PriceListFragment = t(`
|
|
26579
26608
|
fragment getPriceListUnitName_PriceListFragment on PriceList {
|
|
26580
26609
|
charges {
|
|
@@ -26717,12 +26746,10 @@ const PricingTooltip_PriceListChargeFragment = t(`
|
|
|
26717
26746
|
...priceListChargePriceDescription_PriceListChargeFragment
|
|
26718
26747
|
...ChargeHasPriceTiers_PriceListChargeFragment
|
|
26719
26748
|
...ChargePriceTiers_PriceListChargeFragment
|
|
26720
|
-
...GetActiveCharges_PriceListChargeFragment
|
|
26721
26749
|
}
|
|
26722
26750
|
`, [
|
|
26723
26751
|
ChargeHasPriceTiers_PriceListChargeFragment,
|
|
26724
26752
|
ChargePriceTiers_PriceListChargeFragment,
|
|
26725
|
-
GetActiveCharges_PriceListChargeFragment,
|
|
26726
26753
|
priceListChargePriceDescription_PriceListChargeFragment
|
|
26727
26754
|
]);
|
|
26728
26755
|
const PricingTooltip_PriceListFragment = t(`
|
|
@@ -26736,16 +26763,15 @@ const PricingTooltip_PriceListFragment = t(`
|
|
|
26736
26763
|
const PricingTooltip = ({ className, priceListCharges: maskedPriceListCharges, currencyId, }) => {
|
|
26737
26764
|
// Read fragments
|
|
26738
26765
|
const priceListCharges = maskedPriceListCharges.map(charge => readFragment(PricingTooltip_PriceListChargeFragment, charge));
|
|
26739
|
-
const activeCharges = getActiveCharges(priceListCharges);
|
|
26740
26766
|
const content = react.useMemo(() => {
|
|
26741
|
-
return (jsxRuntime.jsx("div", { className: "bunny-flex bunny-flex-col bunny-gap-3", children:
|
|
26767
|
+
return (jsxRuntime.jsx("div", { className: "bunny-flex bunny-flex-col bunny-gap-3", children: priceListCharges === null || priceListCharges === void 0 ? void 0 : priceListCharges.map((charge, index) => {
|
|
26742
26768
|
const hasPriceTiers = chargeHasPriceTiers(charge);
|
|
26743
26769
|
if (hasPriceTiers) {
|
|
26744
26770
|
return jsxRuntime.jsx(ChargePriceTiers, { charge: charge, currencyId: currencyId }, index);
|
|
26745
26771
|
}
|
|
26746
26772
|
return (jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-1", children: [jsxRuntime.jsx("div", { className: "bunny-text-white bunny-font-bold", children: charge.name }), jsxRuntime.jsxs("div", { className: "bunny-text-gray-400 bunny-text-xs/3", children: [getChargeBasePrice(charge, currencyId), ' ', priceListChargePriceDescription(charge)] })] }, index));
|
|
26747
26773
|
}) }));
|
|
26748
|
-
}, [
|
|
26774
|
+
}, [priceListCharges, currencyId]);
|
|
26749
26775
|
return (jsxRuntime.jsx(Tooltip, { className: `bunny-text-gray-400 bunny-text-sm ${className}`, title: content, children: jsxRuntime.jsx(icons.InfoCircleOutlined, { className: "bunny-text-gray-400 ", size: 15 }) }));
|
|
26750
26776
|
};
|
|
26751
26777
|
|
|
@@ -26759,6 +26785,20 @@ function isEmptyHTML(html) {
|
|
|
26759
26785
|
return /^<[^>]*>(\s*)<\/[^>]*>$/.test(html);
|
|
26760
26786
|
}
|
|
26761
26787
|
|
|
26788
|
+
const GetActiveCharges_PriceListChargeFragment = t(`
|
|
26789
|
+
fragment GetActiveCharges_PriceListChargeFragment on PriceListCharge {
|
|
26790
|
+
deprecated
|
|
26791
|
+
featureAddon
|
|
26792
|
+
}
|
|
26793
|
+
`);
|
|
26794
|
+
// Active charges: any charge that is not deprecated and not a feature addon
|
|
26795
|
+
function getActiveCharges(charges) {
|
|
26796
|
+
return charges.filter(maskedCharge => {
|
|
26797
|
+
const charge = readFragment(GetActiveCharges_PriceListChargeFragment, maskedCharge);
|
|
26798
|
+
return !charge.deprecated && !charge.featureAddon;
|
|
26799
|
+
});
|
|
26800
|
+
}
|
|
26801
|
+
|
|
26762
26802
|
const BillingPeriodDescription_PriceListFragment = t(`
|
|
26763
26803
|
fragment BillingPeriodDescription_PriceListFragment on PriceList {
|
|
26764
26804
|
periodMonths
|
|
@@ -72,7 +72,7 @@ export declare const QuoteCheckout_QuoteFragment: import("gql.tada").TadaDocumen
|
|
|
72
72
|
}[];
|
|
73
73
|
kind: "SUBSCRIBE" | "UPDATE" | "RENEW" | "REINSTATE" | "UNSUBSCRIBE" | "ADJUSTMENT" | "COUPON" | "DISCOUNT" | "CREDIT" | "PRICE_UPDATE" | "QUANTITY_UPDATE" | "FREE_PERIOD_DISCOUNT" | "ACTIVATE";
|
|
74
74
|
[$tada.fragmentRefs]: {
|
|
75
|
-
|
|
75
|
+
canApplyCoupons_QuoteFragment: "Quote";
|
|
76
76
|
} & {
|
|
77
77
|
PaymentForm_QuoteFragment: "Quote";
|
|
78
78
|
} & {
|
|
@@ -86,7 +86,7 @@ export declare const QuoteCheckout_QuoteFragment: import("gql.tada").TadaDocumen
|
|
|
86
86
|
export declare const QuoteCheckout_SubscriptionFragment: import("gql.tada").TadaDocumentNode<{
|
|
87
87
|
id: string;
|
|
88
88
|
[$tada.fragmentRefs]: {
|
|
89
|
-
|
|
89
|
+
canApplyCoupons_SubscriptionFragment: "Subscription";
|
|
90
90
|
};
|
|
91
91
|
}, {}, {
|
|
92
92
|
fragment: "QuoteCheckout_SubscriptionFragment";
|
|
@@ -29,7 +29,7 @@ export declare const CheckoutSummary_QuoteFragment: import("gql.tada").TadaDocum
|
|
|
29
29
|
}[];
|
|
30
30
|
}[] | null;
|
|
31
31
|
[$tada.fragmentRefs]: {
|
|
32
|
-
|
|
32
|
+
canApplyCoupons_QuoteFragment: "Quote";
|
|
33
33
|
};
|
|
34
34
|
}, {}, {
|
|
35
35
|
fragment: "CheckoutSummary_QuoteFragment";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ResultOf } from 'gql.tada';
|
|
2
|
+
declare const sortQuoteChangeCharges_QuoteChargeFragment: import("gql.tada").TadaDocumentNode<{
|
|
3
|
+
kind: "SUBSCRIBE" | "UPDATE" | "RENEW" | "REINSTATE" | "UNSUBSCRIBE" | "ADJUSTMENT" | "COUPON" | "DISCOUNT" | "CREDIT" | "PRICE_UPDATE" | "QUANTITY_UPDATE" | "FREE_PERIOD_DISCOUNT" | "ACTIVATE" | null;
|
|
4
|
+
}, {}, {
|
|
5
|
+
fragment: "sortQuoteChangeCharges_QuoteChargeFragment";
|
|
6
|
+
on: "QuoteCharge";
|
|
7
|
+
masked: true;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Sorts quote change charges so that coupon charges appear at the end of the list.
|
|
11
|
+
* Uses a generic type so the full charge shape is preserved.
|
|
12
|
+
*/
|
|
13
|
+
export declare function sortQuoteChangeCharges<T extends ResultOf<typeof sortQuoteChangeCharges_QuoteChargeFragment>>(charges: T[]): T[];
|
|
14
|
+
export {};
|
|
@@ -3,6 +3,8 @@ export declare const Signup_QuoteFragment: import("gql.tada").TadaDocumentNode<{
|
|
|
3
3
|
CheckoutSummary_QuoteFragment: "Quote";
|
|
4
4
|
} & {
|
|
5
5
|
PaymentForms_QuoteFragment: "Quote";
|
|
6
|
+
} & {
|
|
7
|
+
useApplyDefaultCoupon_QuoteFragment: "Quote";
|
|
6
8
|
};
|
|
7
9
|
id: string | null;
|
|
8
10
|
currencyId: string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FragmentOf } from 'gql.tada';
|
|
2
|
+
export declare const useApplyDefaultCoupon_QuoteFragment: import("gql.tada").TadaDocumentNode<{
|
|
3
|
+
[$tada.fragmentRefs]: {
|
|
4
|
+
canApplyCoupons_QuoteFragment: "Quote";
|
|
5
|
+
};
|
|
6
|
+
}, {}, {
|
|
7
|
+
fragment: "useApplyDefaultCoupon_QuoteFragment";
|
|
8
|
+
on: "Quote";
|
|
9
|
+
masked: true;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Applies a default coupon code once when quoteChangeId is available.
|
|
13
|
+
* Uses a ref to ensure coupon code is only applied once.
|
|
14
|
+
*/
|
|
15
|
+
export default function useApplyDefaultCoupon({ couponCode, quoteChangeId, quote: maskedQuote, activeCouponsExist, addCoupon, }: {
|
|
16
|
+
couponCode: string | undefined;
|
|
17
|
+
quoteChangeId: string | undefined;
|
|
18
|
+
quote: FragmentOf<typeof useApplyDefaultCoupon_QuoteFragment> | undefined | null;
|
|
19
|
+
activeCouponsExist: boolean;
|
|
20
|
+
addCoupon: (code: string) => void;
|
|
21
|
+
}): void;
|
|
@@ -17,8 +17,6 @@ export declare const PricingTooltip_PriceListChargeFragment: import("gql.tada").
|
|
|
17
17
|
ChargeHasPriceTiers_PriceListChargeFragment: "PriceListCharge";
|
|
18
18
|
} & {
|
|
19
19
|
ChargePriceTiers_PriceListChargeFragment: "PriceListCharge";
|
|
20
|
-
} & {
|
|
21
|
-
GetActiveCharges_PriceListChargeFragment: "PriceListCharge";
|
|
22
20
|
};
|
|
23
21
|
}, {}, {
|
|
24
22
|
fragment: "PricingTooltip_PriceListChargeFragment";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { FragmentOf } from 'gql.tada';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const canApplyCoupons_QuoteFragment: import("gql.tada").TadaDocumentNode<{
|
|
3
3
|
id: string | null;
|
|
4
4
|
kind: "SUBSCRIBE" | "UPDATE" | "RENEW" | "REINSTATE" | "UNSUBSCRIBE" | "ADJUSTMENT" | "COUPON" | "DISCOUNT" | "CREDIT" | "PRICE_UPDATE" | "QUANTITY_UPDATE" | "FREE_PERIOD_DISCOUNT" | "ACTIVATE";
|
|
5
5
|
amountDue: number | null;
|
|
6
6
|
}, {}, {
|
|
7
|
-
fragment: "
|
|
7
|
+
fragment: "canApplyCoupons_QuoteFragment";
|
|
8
8
|
on: "Quote";
|
|
9
9
|
masked: true;
|
|
10
10
|
}>;
|
|
11
|
-
export declare const
|
|
11
|
+
export declare const canApplyCoupons_SubscriptionFragment: import("gql.tada").TadaDocumentNode<{
|
|
12
12
|
id: string;
|
|
13
13
|
state: "ACTIVE" | "TRIAL" | "CANCELED" | "EXPIRED" | "TRIAL_EXPIRED" | "PENDING";
|
|
14
14
|
charges: {
|
|
15
15
|
discountedPrice: string | null;
|
|
16
16
|
}[] | null;
|
|
17
17
|
}, {}, {
|
|
18
|
-
fragment: "
|
|
18
|
+
fragment: "canApplyCoupons_SubscriptionFragment";
|
|
19
19
|
on: "Subscription";
|
|
20
20
|
masked: true;
|
|
21
21
|
}>;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function canApplyCoupons(maskedQuote: FragmentOf<typeof canApplyCoupons_QuoteFragment> | undefined | null, activeCouponsExist: boolean, maskedUpgradingSubscription?: FragmentOf<typeof canApplyCoupons_SubscriptionFragment>): boolean;
|
package/dist/esm/index.js
CHANGED
|
@@ -1281,7 +1281,7 @@ const DEFAULT_CONFIG = {
|
|
|
1281
1281
|
};
|
|
1282
1282
|
|
|
1283
1283
|
// This will be replaced at build time by rollup-plugin-replace
|
|
1284
|
-
const PACKAGE_VERSION = '1.8.0-beta.
|
|
1284
|
+
const PACKAGE_VERSION = '1.8.0-beta.4';
|
|
1285
1285
|
const createRequestHeaders = (token) => {
|
|
1286
1286
|
const headers = createClientDevHeaders({ token });
|
|
1287
1287
|
// Add the components version header
|
|
@@ -22953,15 +22953,15 @@ function QuotesWrapper() {
|
|
|
22953
22953
|
return (jsx(TransactionsDisplay, { transactions: quotesAsTransactions, onSearchValueChanged: setSearch, search: search }));
|
|
22954
22954
|
}
|
|
22955
22955
|
|
|
22956
|
-
const
|
|
22957
|
-
fragment
|
|
22956
|
+
const canApplyCoupons_QuoteFragment = t(`
|
|
22957
|
+
fragment canApplyCoupons_QuoteFragment on Quote {
|
|
22958
22958
|
id
|
|
22959
22959
|
kind
|
|
22960
22960
|
amountDue
|
|
22961
22961
|
}
|
|
22962
22962
|
`, []);
|
|
22963
|
-
const
|
|
22964
|
-
fragment
|
|
22963
|
+
const canApplyCoupons_SubscriptionFragment = t(`
|
|
22964
|
+
fragment canApplyCoupons_SubscriptionFragment on Subscription {
|
|
22965
22965
|
id
|
|
22966
22966
|
state
|
|
22967
22967
|
charges {
|
|
@@ -22969,10 +22969,10 @@ const shouldShowCouponEditor_SubscriptionFragment = t(`
|
|
|
22969
22969
|
}
|
|
22970
22970
|
}
|
|
22971
22971
|
`, []);
|
|
22972
|
-
function
|
|
22972
|
+
function canApplyCoupons(maskedQuote, activeCouponsExist, maskedUpgradingSubscription) {
|
|
22973
22973
|
var _a, _b;
|
|
22974
|
-
const quote = readFragment(
|
|
22975
|
-
const upgradingSubscription = readFragment(
|
|
22974
|
+
const quote = readFragment(canApplyCoupons_QuoteFragment, maskedQuote);
|
|
22975
|
+
const upgradingSubscription = readFragment(canApplyCoupons_SubscriptionFragment, maskedUpgradingSubscription);
|
|
22976
22976
|
const upgradingFromTrial = ((_a = upgradingSubscription === null || upgradingSubscription === void 0 ? void 0 : upgradingSubscription.state) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === t.scalar('SubscriptionState', 'TRIAL') ||
|
|
22977
22977
|
((_b = upgradingSubscription === null || upgradingSubscription === void 0 ? void 0 : upgradingSubscription.state) === null || _b === void 0 ? void 0 : _b.toUpperCase()) ===
|
|
22978
22978
|
t.scalar('SubscriptionState', 'TRIAL_EXPIRED');
|
|
@@ -22990,7 +22990,10 @@ function shouldShowCouponEditor(maskedQuote, activeCouponsExist, maskedUpgrading
|
|
|
22990
22990
|
return false;
|
|
22991
22991
|
}
|
|
22992
22992
|
if (quoteKindIsValid) {
|
|
22993
|
-
|
|
22993
|
+
const result = activeCouponsExist &&
|
|
22994
|
+
(upgradingFromTrial || upgradingFromFree() || signingUpForNewSubscription);
|
|
22995
|
+
console.log('returning result', result);
|
|
22996
|
+
return result;
|
|
22994
22997
|
}
|
|
22995
22998
|
return false;
|
|
22996
22999
|
}
|
|
@@ -23002,6 +23005,27 @@ function CouponEditor({ className, onAddCoupon, isAddingCoupon, couponCode, setC
|
|
|
23002
23005
|
return (jsx("div", { className: `bunny-flex bunny-flex-col bunny-gap-2 ${className}`, children: jsxs("div", { className: "bunny-flex bunny-flex-row bunny-gap-2", children: [jsx(Input, { value: couponCode, onChange: e => setCouponCode(e.target.value), placeholder: "Coupon code", disabled: isAddingCoupon, size: "small" }), jsx(Button, { loading: isAddingCoupon, type: "primary", onClick: handleAddCoupon, disabled: couponCode.length === 0, children: "Apply" })] }) }));
|
|
23003
23006
|
}
|
|
23004
23007
|
|
|
23008
|
+
t(`
|
|
23009
|
+
fragment sortQuoteChangeCharges_QuoteChargeFragment on QuoteCharge {
|
|
23010
|
+
kind
|
|
23011
|
+
}
|
|
23012
|
+
`, []);
|
|
23013
|
+
/**
|
|
23014
|
+
* Sorts quote change charges so that coupon charges appear at the end of the list.
|
|
23015
|
+
* Uses a generic type so the full charge shape is preserved.
|
|
23016
|
+
*/
|
|
23017
|
+
function sortQuoteChangeCharges(charges) {
|
|
23018
|
+
return [...charges].sort((chargeA, chargeB) => {
|
|
23019
|
+
const aIsCoupon = chargeA.kind === 'COUPON';
|
|
23020
|
+
const bIsCoupon = chargeB.kind === 'COUPON';
|
|
23021
|
+
if (aIsCoupon && !bIsCoupon)
|
|
23022
|
+
return 1;
|
|
23023
|
+
if (!aIsCoupon && bIsCoupon)
|
|
23024
|
+
return -1;
|
|
23025
|
+
return 0;
|
|
23026
|
+
});
|
|
23027
|
+
}
|
|
23028
|
+
|
|
23005
23029
|
const { Text: Text$r } = Typography;
|
|
23006
23030
|
const CheckoutSummary_PriceListFragment = t(`
|
|
23007
23031
|
fragment CheckoutSummary_PriceListFragment on PriceList {
|
|
@@ -23031,14 +23055,14 @@ const CheckoutSummary_QuoteFragment = t(`
|
|
|
23031
23055
|
currencyId
|
|
23032
23056
|
}
|
|
23033
23057
|
}
|
|
23034
|
-
...
|
|
23058
|
+
...canApplyCoupons_QuoteFragment
|
|
23035
23059
|
}
|
|
23036
|
-
`, [
|
|
23060
|
+
`, [canApplyCoupons_QuoteFragment]);
|
|
23037
23061
|
function CheckoutSummary({ quote: maskedQuote, className, onAddCoupon, onRemoveCoupon, isRemovingCoupon, priceList: maskedPriceList, isAddingCoupon, couponCode, setCouponCode, activeCouponsExist, }) {
|
|
23038
23062
|
var _a, _b;
|
|
23039
23063
|
const priceList = readFragment(CheckoutSummary_PriceListFragment, maskedPriceList);
|
|
23040
23064
|
const quote = readFragment(CheckoutSummary_QuoteFragment, maskedQuote);
|
|
23041
|
-
return (jsxs("div", { className: `${className} bunny-space-y-4`, children: [jsxs(Text$r, { children: [jsxs("div", { className: "bunny-text-lg bunny-font-medium bunny-mb-4", children: ["Checkout summary - ", (_a = priceList === null || priceList === void 0 ? void 0 : priceList.product) === null || _a === void 0 ? void 0 : _a.name, " ", priceList === null || priceList === void 0 ? void 0 : priceList.name] }), jsx("div", { className: "bunny-space-y-4", children: (_b = quote === null || quote === void 0 ? void 0 : quote.quoteChanges) === null || _b === void 0 ? void 0 : _b.map(quoteChange => quoteChange === null || quoteChange === void 0 ? void 0 : quoteChange.charges.map(charge => {
|
|
23065
|
+
return (jsxs("div", { className: `${className} bunny-space-y-4`, children: [jsxs(Text$r, { children: [jsxs("div", { className: "bunny-text-lg bunny-font-medium bunny-mb-4", children: ["Checkout summary - ", (_a = priceList === null || priceList === void 0 ? void 0 : priceList.product) === null || _a === void 0 ? void 0 : _a.name, " ", priceList === null || priceList === void 0 ? void 0 : priceList.name] }), jsx("div", { className: "bunny-space-y-4", children: (_b = quote === null || quote === void 0 ? void 0 : quote.quoteChanges) === null || _b === void 0 ? void 0 : _b.map(quoteChange => sortQuoteChangeCharges(quoteChange === null || quoteChange === void 0 ? void 0 : quoteChange.charges).map(charge => {
|
|
23042
23066
|
var _a;
|
|
23043
23067
|
const multiplier = charge.kind === 'COUPON' ? -1 : 1;
|
|
23044
23068
|
return (jsxs("div", { className: "bunny-grid bunny-grid-cols-3 bunny-gap-4 bunny-items-center", children: [jsx("div", { className: "bunny-col-span-1", children: charge.name }), jsx("div", { className: "bunny-col-span-1 bunny-text-center", children: ((_a = charge.coupon) === null || _a === void 0 ? void 0 : _a.couponCode) ? (jsx("button", { onClick: () => {
|
|
@@ -23051,7 +23075,7 @@ function CheckoutSummary({ quote: maskedQuote, className, onAddCoupon, onRemoveC
|
|
|
23051
23075
|
}
|
|
23052
23076
|
onRemoveCoupon((_b = charge.coupon) === null || _b === void 0 ? void 0 : _b.couponCode);
|
|
23053
23077
|
}, className: "bunny-text-orange-500 hover:bunny-text-orange-400 bunny-cursor-pointer bunny-bg-transparent bunny-border-none", children: "Remove" })) : (jsx("div", { children: charge.quantity })) }), jsx("div", { className: "bunny-col-span-1 bunny-text-right", children: formatCurrency(multiplier * (charge.subtotal || 0), charge.currencyId) })] }, charge.id));
|
|
23054
|
-
})) }), jsx(CheckoutSummaryDivider, {}), jsxs("div", { className: "bunny-space-y-4", children: [jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsx("div", { children: "Subtotal" }), jsx("div", { children: formatCurrency(quote.subtotal, quote.currencyId) })] }), jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsx("div", { children: "Taxes" }), jsx("div", { children: formatCurrency(quote.taxAmount, quote.currencyId) })] })] }), jsx(CheckoutSummaryDivider, {}), jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsx("div", { children: "Total" }), jsx("div", { children: formatCurrency(quote.amountDue, quote.currencyId) })] })] }),
|
|
23078
|
+
})) }), jsx(CheckoutSummaryDivider, {}), jsxs("div", { className: "bunny-space-y-4", children: [jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsx("div", { children: "Subtotal" }), jsx("div", { children: formatCurrency(quote.subtotal, quote.currencyId) })] }), jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsx("div", { children: "Taxes" }), jsx("div", { children: formatCurrency(quote.taxAmount, quote.currencyId) })] })] }), jsx(CheckoutSummaryDivider, {}), jsxs("div", { className: "bunny-flex bunny-justify-between", children: [jsx("div", { children: "Total" }), jsx("div", { children: formatCurrency(quote.amountDue, quote.currencyId) })] })] }), canApplyCoupons(quote, activeCouponsExist) && (jsx(CouponEditor, { className: "bunny-w-full", onAddCoupon: onAddCoupon, isAddingCoupon: isAddingCoupon, couponCode: couponCode, setCouponCode: setCouponCode }))] }));
|
|
23055
23079
|
}
|
|
23056
23080
|
const CheckoutSummaryDivider = () => {
|
|
23057
23081
|
return (jsx("div", { className: "bunny-my-2", children: jsx(Divider, { className: "m-0" }) }));
|
|
@@ -23102,10 +23126,36 @@ function InitialSignupForm({ className, onSubmit, submitting, defaultValues, })
|
|
|
23102
23126
|
} }) }) }) }), jsx(Form.Item, { children: jsx(Button, { type: "primary", onClick: handleSubmit, loading: submitting, className: "bunny-w-full", children: "Proceed to payment" }) })] }) }));
|
|
23103
23127
|
}
|
|
23104
23128
|
|
|
23129
|
+
const useApplyDefaultCoupon_QuoteFragment = t(`
|
|
23130
|
+
fragment useApplyDefaultCoupon_QuoteFragment on Quote {
|
|
23131
|
+
...canApplyCoupons_QuoteFragment
|
|
23132
|
+
}
|
|
23133
|
+
`, [canApplyCoupons_QuoteFragment]);
|
|
23134
|
+
/**
|
|
23135
|
+
* Applies a default coupon code once when quoteChangeId is available.
|
|
23136
|
+
* Uses a ref to ensure coupon code is only applied once.
|
|
23137
|
+
*/
|
|
23138
|
+
function useApplyDefaultCoupon({ couponCode, quoteChangeId, quote: maskedQuote, activeCouponsExist, addCoupon, }) {
|
|
23139
|
+
const defaultCouponAppliedRef = useRef(undefined);
|
|
23140
|
+
// Derived state
|
|
23141
|
+
const quote = readFragment(useApplyDefaultCoupon_QuoteFragment, maskedQuote);
|
|
23142
|
+
const canApplyCouponsResult = canApplyCoupons(quote, activeCouponsExist);
|
|
23143
|
+
useEffect(() => {
|
|
23144
|
+
if (couponCode &&
|
|
23145
|
+
quoteChangeId &&
|
|
23146
|
+
defaultCouponAppliedRef.current !== couponCode &&
|
|
23147
|
+
canApplyCouponsResult) {
|
|
23148
|
+
addCoupon(couponCode);
|
|
23149
|
+
defaultCouponAppliedRef.current = couponCode;
|
|
23150
|
+
}
|
|
23151
|
+
}, [couponCode, quoteChangeId, addCoupon, canApplyCouponsResult]);
|
|
23152
|
+
}
|
|
23153
|
+
|
|
23105
23154
|
const Signup_QuoteFragment = t(`
|
|
23106
23155
|
fragment Signup_QuoteFragment on Quote {
|
|
23107
23156
|
...CheckoutSummary_QuoteFragment
|
|
23108
23157
|
...PaymentForms_QuoteFragment
|
|
23158
|
+
...useApplyDefaultCoupon_QuoteFragment
|
|
23109
23159
|
id
|
|
23110
23160
|
currencyId
|
|
23111
23161
|
amountDue
|
|
@@ -23113,7 +23163,7 @@ const Signup_QuoteFragment = t(`
|
|
|
23113
23163
|
id
|
|
23114
23164
|
}
|
|
23115
23165
|
}
|
|
23116
|
-
`, [CheckoutSummary_QuoteFragment, PaymentForms_QuoteFragment]);
|
|
23166
|
+
`, [CheckoutSummary_QuoteFragment, PaymentForms_QuoteFragment, useApplyDefaultCoupon_QuoteFragment]);
|
|
23117
23167
|
|
|
23118
23168
|
const query$6 = t(`
|
|
23119
23169
|
query quote($id: ID) {
|
|
@@ -23569,7 +23619,6 @@ function Signup({ companyName, priceListCode, returnUrl, couponCode, className,
|
|
|
23569
23619
|
const [portalSessionToken, setPortalSessionToken] = useState(undefined);
|
|
23570
23620
|
const token = portalSessionToken || tokenFromContexts;
|
|
23571
23621
|
const [purchaseSucceeded, setPurchaseSucceeded] = useState(false);
|
|
23572
|
-
const defaultCouponAppliedRef = useRef(undefined);
|
|
23573
23622
|
const [couponEditorCouponCode, setCouponEditorCouponCode] = useState('');
|
|
23574
23623
|
// Read fragment
|
|
23575
23624
|
const initialQuoteId = (_a = readFragment(Signup_QuoteFragment, initialQuote)) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -23686,13 +23735,7 @@ function Signup({ companyName, priceListCode, returnUrl, couponCode, className,
|
|
|
23686
23735
|
handleRecalculateTaxes(quote === null || quote === void 0 ? void 0 : quote.id);
|
|
23687
23736
|
},
|
|
23688
23737
|
});
|
|
23689
|
-
|
|
23690
|
-
useEffect(() => {
|
|
23691
|
-
if (couponCode && quoteChangeId && defaultCouponAppliedRef.current !== couponCode) {
|
|
23692
|
-
addCoupon(couponCode);
|
|
23693
|
-
defaultCouponAppliedRef.current = couponCode;
|
|
23694
|
-
}
|
|
23695
|
-
}, [couponCode, quoteChangeId]);
|
|
23738
|
+
useApplyDefaultCoupon({ couponCode, quoteChangeId, addCoupon, activeCouponsExist, quote });
|
|
23696
23739
|
async function handleSubmit(formData) {
|
|
23697
23740
|
if (selfServiceBuyEnabled === false) {
|
|
23698
23741
|
handleShowSelfServiceBuyWarning();
|
|
@@ -23922,22 +23965,22 @@ const QuoteCheckout_QuoteFragment = t(`
|
|
|
23922
23965
|
}
|
|
23923
23966
|
}
|
|
23924
23967
|
...QuoteFields_QuoteFragment
|
|
23925
|
-
...
|
|
23968
|
+
...canApplyCoupons_QuoteFragment
|
|
23926
23969
|
...PaymentForm_QuoteFragment
|
|
23927
23970
|
...getQuoteAmountDue_QuoteFragment
|
|
23928
23971
|
}
|
|
23929
23972
|
`, [
|
|
23930
23973
|
QuoteFields_QuoteFragment,
|
|
23931
|
-
|
|
23974
|
+
canApplyCoupons_QuoteFragment,
|
|
23932
23975
|
PaymentForm_QuoteFragment,
|
|
23933
23976
|
getQuoteAmountDue_QuoteFragment,
|
|
23934
23977
|
]);
|
|
23935
23978
|
const QuoteCheckout_SubscriptionFragment = t(`
|
|
23936
23979
|
fragment QuoteCheckout_SubscriptionFragment on Subscription {
|
|
23937
23980
|
id
|
|
23938
|
-
...
|
|
23981
|
+
...canApplyCoupons_SubscriptionFragment
|
|
23939
23982
|
}
|
|
23940
|
-
`, [
|
|
23983
|
+
`, [canApplyCoupons_SubscriptionFragment]);
|
|
23941
23984
|
const showSuccessNotification = useSuccessNotification();
|
|
23942
23985
|
const QuoteCheckout = ({ account, onSuccess, onFail, quote: maskedQuote, taxationRequiredAccountFields, isUpdatingQuote, onRecalculateTaxes, isRecalculatingTaxes, }) => {
|
|
23943
23986
|
var _a, _b, _c, _d, _e;
|
|
@@ -24023,7 +24066,7 @@ const QuoteCheckout = ({ account, onSuccess, onFail, quote: maskedQuote, taxatio
|
|
|
24023
24066
|
if (taxationRequiredAccountFields)
|
|
24024
24067
|
return (jsx(PaymentFormWrapper, { setMaxHeight: false, children: jsx(TaxationForm, { account: account, accountId: quote.accountId }) }));
|
|
24025
24068
|
return (jsx(PaymentFormWrapper, { setMaxHeight: false, children: paymentRequired ? (jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-2 bunny-w-full", children: [jsx(PaymentForm, { onPaymentSuccess: onSuccess, quote: quote, onSavePaymentMethod: (paymentMethod) => onPaymentMethodSaved === null || onPaymentMethodSaved === void 0 ? void 0 : onPaymentMethodSaved(paymentMethod.savedPaymentMethodResponse.paymentMethodId), onPaymentMethodRemoved: (paymentMethod) => onPaymentMethodRemoved === null || onPaymentMethodRemoved === void 0 ? void 0 : onPaymentMethodRemoved(paymentMethod.id), disablePayButton: isFinalizingQuote }), isFinalizingQuote && jsx(QuoteLoadingIndicator, {}), (couponsOnQuote === null || couponsOnQuote === void 0 ? void 0 : couponsOnQuote.length) === 0 ? (jsx(Fragment, { children: upgradingSubscription &&
|
|
24026
|
-
|
|
24069
|
+
canApplyCoupons(quote, activeCouponsExist, upgradingSubscription) && (jsx(CouponEditor, { className: "bunny-px-4 bunny-pt-1", onAddCoupon: addCoupon, isAddingCoupon: isAddingCoupon, couponCode: couponCode, setCouponCode: setCouponCode })) })) : (jsx(Button, { type: "link", loading: isRemovingCoupon, onClick: () => {
|
|
24027
24070
|
couponsOnQuote === null || couponsOnQuote === void 0 ? void 0 : couponsOnQuote.forEach(couponCharge => {
|
|
24028
24071
|
var _a;
|
|
24029
24072
|
const couponCode = (_a = couponCharge === null || couponCharge === void 0 ? void 0 : couponCharge.coupon) === null || _a === void 0 ? void 0 : _a.couponCode;
|
|
@@ -26559,20 +26602,6 @@ function priceListChargePriceDescription(maskedPriceListCharge) {
|
|
|
26559
26602
|
return `Per ${unitName ? `${unitName} / ` : ''}${priceListCharge.showPriceAsMonthly ? 'month' : periodLabel}`;
|
|
26560
26603
|
}
|
|
26561
26604
|
|
|
26562
|
-
const GetActiveCharges_PriceListChargeFragment = t(`
|
|
26563
|
-
fragment GetActiveCharges_PriceListChargeFragment on PriceListCharge {
|
|
26564
|
-
deprecated
|
|
26565
|
-
featureAddon
|
|
26566
|
-
}
|
|
26567
|
-
`);
|
|
26568
|
-
// Active charges: any charge that is not deprecated and not a feature addon
|
|
26569
|
-
function getActiveCharges(charges) {
|
|
26570
|
-
return charges.filter(maskedCharge => {
|
|
26571
|
-
const charge = readFragment(GetActiveCharges_PriceListChargeFragment, maskedCharge);
|
|
26572
|
-
return !charge.deprecated && !charge.featureAddon;
|
|
26573
|
-
});
|
|
26574
|
-
}
|
|
26575
|
-
|
|
26576
26605
|
const getPriceListUnitName_PriceListFragment = t(`
|
|
26577
26606
|
fragment getPriceListUnitName_PriceListFragment on PriceList {
|
|
26578
26607
|
charges {
|
|
@@ -26715,12 +26744,10 @@ const PricingTooltip_PriceListChargeFragment = t(`
|
|
|
26715
26744
|
...priceListChargePriceDescription_PriceListChargeFragment
|
|
26716
26745
|
...ChargeHasPriceTiers_PriceListChargeFragment
|
|
26717
26746
|
...ChargePriceTiers_PriceListChargeFragment
|
|
26718
|
-
...GetActiveCharges_PriceListChargeFragment
|
|
26719
26747
|
}
|
|
26720
26748
|
`, [
|
|
26721
26749
|
ChargeHasPriceTiers_PriceListChargeFragment,
|
|
26722
26750
|
ChargePriceTiers_PriceListChargeFragment,
|
|
26723
|
-
GetActiveCharges_PriceListChargeFragment,
|
|
26724
26751
|
priceListChargePriceDescription_PriceListChargeFragment
|
|
26725
26752
|
]);
|
|
26726
26753
|
const PricingTooltip_PriceListFragment = t(`
|
|
@@ -26734,16 +26761,15 @@ const PricingTooltip_PriceListFragment = t(`
|
|
|
26734
26761
|
const PricingTooltip = ({ className, priceListCharges: maskedPriceListCharges, currencyId, }) => {
|
|
26735
26762
|
// Read fragments
|
|
26736
26763
|
const priceListCharges = maskedPriceListCharges.map(charge => readFragment(PricingTooltip_PriceListChargeFragment, charge));
|
|
26737
|
-
const activeCharges = getActiveCharges(priceListCharges);
|
|
26738
26764
|
const content = useMemo(() => {
|
|
26739
|
-
return (jsx("div", { className: "bunny-flex bunny-flex-col bunny-gap-3", children:
|
|
26765
|
+
return (jsx("div", { className: "bunny-flex bunny-flex-col bunny-gap-3", children: priceListCharges === null || priceListCharges === void 0 ? void 0 : priceListCharges.map((charge, index) => {
|
|
26740
26766
|
const hasPriceTiers = chargeHasPriceTiers(charge);
|
|
26741
26767
|
if (hasPriceTiers) {
|
|
26742
26768
|
return jsx(ChargePriceTiers, { charge: charge, currencyId: currencyId }, index);
|
|
26743
26769
|
}
|
|
26744
26770
|
return (jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-1", children: [jsx("div", { className: "bunny-text-white bunny-font-bold", children: charge.name }), jsxs("div", { className: "bunny-text-gray-400 bunny-text-xs/3", children: [getChargeBasePrice(charge, currencyId), ' ', priceListChargePriceDescription(charge)] })] }, index));
|
|
26745
26771
|
}) }));
|
|
26746
|
-
}, [
|
|
26772
|
+
}, [priceListCharges, currencyId]);
|
|
26747
26773
|
return (jsx(Tooltip, { className: `bunny-text-gray-400 bunny-text-sm ${className}`, title: content, children: jsx(InfoCircleOutlined, { className: "bunny-text-gray-400 ", size: 15 }) }));
|
|
26748
26774
|
};
|
|
26749
26775
|
|
|
@@ -26757,6 +26783,20 @@ function isEmptyHTML(html) {
|
|
|
26757
26783
|
return /^<[^>]*>(\s*)<\/[^>]*>$/.test(html);
|
|
26758
26784
|
}
|
|
26759
26785
|
|
|
26786
|
+
const GetActiveCharges_PriceListChargeFragment = t(`
|
|
26787
|
+
fragment GetActiveCharges_PriceListChargeFragment on PriceListCharge {
|
|
26788
|
+
deprecated
|
|
26789
|
+
featureAddon
|
|
26790
|
+
}
|
|
26791
|
+
`);
|
|
26792
|
+
// Active charges: any charge that is not deprecated and not a feature addon
|
|
26793
|
+
function getActiveCharges(charges) {
|
|
26794
|
+
return charges.filter(maskedCharge => {
|
|
26795
|
+
const charge = readFragment(GetActiveCharges_PriceListChargeFragment, maskedCharge);
|
|
26796
|
+
return !charge.deprecated && !charge.featureAddon;
|
|
26797
|
+
});
|
|
26798
|
+
}
|
|
26799
|
+
|
|
26760
26800
|
const BillingPeriodDescription_PriceListFragment = t(`
|
|
26761
26801
|
fragment BillingPeriodDescription_PriceListFragment on PriceList {
|
|
26762
26802
|
periodMonths
|
|
@@ -72,7 +72,7 @@ export declare const QuoteCheckout_QuoteFragment: import("gql.tada").TadaDocumen
|
|
|
72
72
|
}[];
|
|
73
73
|
kind: "SUBSCRIBE" | "UPDATE" | "RENEW" | "REINSTATE" | "UNSUBSCRIBE" | "ADJUSTMENT" | "COUPON" | "DISCOUNT" | "CREDIT" | "PRICE_UPDATE" | "QUANTITY_UPDATE" | "FREE_PERIOD_DISCOUNT" | "ACTIVATE";
|
|
74
74
|
[$tada.fragmentRefs]: {
|
|
75
|
-
|
|
75
|
+
canApplyCoupons_QuoteFragment: "Quote";
|
|
76
76
|
} & {
|
|
77
77
|
PaymentForm_QuoteFragment: "Quote";
|
|
78
78
|
} & {
|
|
@@ -86,7 +86,7 @@ export declare const QuoteCheckout_QuoteFragment: import("gql.tada").TadaDocumen
|
|
|
86
86
|
export declare const QuoteCheckout_SubscriptionFragment: import("gql.tada").TadaDocumentNode<{
|
|
87
87
|
id: string;
|
|
88
88
|
[$tada.fragmentRefs]: {
|
|
89
|
-
|
|
89
|
+
canApplyCoupons_SubscriptionFragment: "Subscription";
|
|
90
90
|
};
|
|
91
91
|
}, {}, {
|
|
92
92
|
fragment: "QuoteCheckout_SubscriptionFragment";
|
|
@@ -29,7 +29,7 @@ export declare const CheckoutSummary_QuoteFragment: import("gql.tada").TadaDocum
|
|
|
29
29
|
}[];
|
|
30
30
|
}[] | null;
|
|
31
31
|
[$tada.fragmentRefs]: {
|
|
32
|
-
|
|
32
|
+
canApplyCoupons_QuoteFragment: "Quote";
|
|
33
33
|
};
|
|
34
34
|
}, {}, {
|
|
35
35
|
fragment: "CheckoutSummary_QuoteFragment";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ResultOf } from 'gql.tada';
|
|
2
|
+
declare const sortQuoteChangeCharges_QuoteChargeFragment: import("gql.tada").TadaDocumentNode<{
|
|
3
|
+
kind: "SUBSCRIBE" | "UPDATE" | "RENEW" | "REINSTATE" | "UNSUBSCRIBE" | "ADJUSTMENT" | "COUPON" | "DISCOUNT" | "CREDIT" | "PRICE_UPDATE" | "QUANTITY_UPDATE" | "FREE_PERIOD_DISCOUNT" | "ACTIVATE" | null;
|
|
4
|
+
}, {}, {
|
|
5
|
+
fragment: "sortQuoteChangeCharges_QuoteChargeFragment";
|
|
6
|
+
on: "QuoteCharge";
|
|
7
|
+
masked: true;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Sorts quote change charges so that coupon charges appear at the end of the list.
|
|
11
|
+
* Uses a generic type so the full charge shape is preserved.
|
|
12
|
+
*/
|
|
13
|
+
export declare function sortQuoteChangeCharges<T extends ResultOf<typeof sortQuoteChangeCharges_QuoteChargeFragment>>(charges: T[]): T[];
|
|
14
|
+
export {};
|
|
@@ -3,6 +3,8 @@ export declare const Signup_QuoteFragment: import("gql.tada").TadaDocumentNode<{
|
|
|
3
3
|
CheckoutSummary_QuoteFragment: "Quote";
|
|
4
4
|
} & {
|
|
5
5
|
PaymentForms_QuoteFragment: "Quote";
|
|
6
|
+
} & {
|
|
7
|
+
useApplyDefaultCoupon_QuoteFragment: "Quote";
|
|
6
8
|
};
|
|
7
9
|
id: string | null;
|
|
8
10
|
currencyId: string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FragmentOf } from 'gql.tada';
|
|
2
|
+
export declare const useApplyDefaultCoupon_QuoteFragment: import("gql.tada").TadaDocumentNode<{
|
|
3
|
+
[$tada.fragmentRefs]: {
|
|
4
|
+
canApplyCoupons_QuoteFragment: "Quote";
|
|
5
|
+
};
|
|
6
|
+
}, {}, {
|
|
7
|
+
fragment: "useApplyDefaultCoupon_QuoteFragment";
|
|
8
|
+
on: "Quote";
|
|
9
|
+
masked: true;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Applies a default coupon code once when quoteChangeId is available.
|
|
13
|
+
* Uses a ref to ensure coupon code is only applied once.
|
|
14
|
+
*/
|
|
15
|
+
export default function useApplyDefaultCoupon({ couponCode, quoteChangeId, quote: maskedQuote, activeCouponsExist, addCoupon, }: {
|
|
16
|
+
couponCode: string | undefined;
|
|
17
|
+
quoteChangeId: string | undefined;
|
|
18
|
+
quote: FragmentOf<typeof useApplyDefaultCoupon_QuoteFragment> | undefined | null;
|
|
19
|
+
activeCouponsExist: boolean;
|
|
20
|
+
addCoupon: (code: string) => void;
|
|
21
|
+
}): void;
|
|
@@ -17,8 +17,6 @@ export declare const PricingTooltip_PriceListChargeFragment: import("gql.tada").
|
|
|
17
17
|
ChargeHasPriceTiers_PriceListChargeFragment: "PriceListCharge";
|
|
18
18
|
} & {
|
|
19
19
|
ChargePriceTiers_PriceListChargeFragment: "PriceListCharge";
|
|
20
|
-
} & {
|
|
21
|
-
GetActiveCharges_PriceListChargeFragment: "PriceListCharge";
|
|
22
20
|
};
|
|
23
21
|
}, {}, {
|
|
24
22
|
fragment: "PricingTooltip_PriceListChargeFragment";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { FragmentOf } from 'gql.tada';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const canApplyCoupons_QuoteFragment: import("gql.tada").TadaDocumentNode<{
|
|
3
3
|
id: string | null;
|
|
4
4
|
kind: "SUBSCRIBE" | "UPDATE" | "RENEW" | "REINSTATE" | "UNSUBSCRIBE" | "ADJUSTMENT" | "COUPON" | "DISCOUNT" | "CREDIT" | "PRICE_UPDATE" | "QUANTITY_UPDATE" | "FREE_PERIOD_DISCOUNT" | "ACTIVATE";
|
|
5
5
|
amountDue: number | null;
|
|
6
6
|
}, {}, {
|
|
7
|
-
fragment: "
|
|
7
|
+
fragment: "canApplyCoupons_QuoteFragment";
|
|
8
8
|
on: "Quote";
|
|
9
9
|
masked: true;
|
|
10
10
|
}>;
|
|
11
|
-
export declare const
|
|
11
|
+
export declare const canApplyCoupons_SubscriptionFragment: import("gql.tada").TadaDocumentNode<{
|
|
12
12
|
id: string;
|
|
13
13
|
state: "ACTIVE" | "TRIAL" | "CANCELED" | "EXPIRED" | "TRIAL_EXPIRED" | "PENDING";
|
|
14
14
|
charges: {
|
|
15
15
|
discountedPrice: string | null;
|
|
16
16
|
}[] | null;
|
|
17
17
|
}, {}, {
|
|
18
|
-
fragment: "
|
|
18
|
+
fragment: "canApplyCoupons_SubscriptionFragment";
|
|
19
19
|
on: "Subscription";
|
|
20
20
|
masked: true;
|
|
21
21
|
}>;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function canApplyCoupons(maskedQuote: FragmentOf<typeof canApplyCoupons_QuoteFragment> | undefined | null, activeCouponsExist: boolean, maskedUpgradingSubscription?: FragmentOf<typeof canApplyCoupons_SubscriptionFragment>): boolean;
|
package/package.json
CHANGED