@zuplo/zudoku-plugin-monetization 0.0.25 → 0.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -5
- package/dist/index.mjs +112 -55
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import * as zudoku from "zudoku";
|
|
2
|
+
import "react";
|
|
2
3
|
|
|
3
|
-
//#region src/
|
|
4
|
-
|
|
4
|
+
//#region src/MonetizationContext.d.ts
|
|
5
|
+
interface MonetizationConfig {
|
|
5
6
|
pricing?: {
|
|
6
7
|
subtitle?: string;
|
|
7
8
|
title?: string;
|
|
8
|
-
units?: Record<string, string>;
|
|
9
9
|
showYearlyPrice?: boolean;
|
|
10
|
+
units?: Record<string, string>;
|
|
10
11
|
};
|
|
11
|
-
}
|
|
12
|
-
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/ZuploMonetizationPlugin.d.ts
|
|
15
|
+
declare const zuploMonetizationPlugin: (options?: MonetizationConfig | undefined) => zudoku.ZudokuPlugin;
|
|
13
16
|
//#endregion
|
|
14
17
|
export { zuploMonetizationPlugin };
|
package/dist/index.mjs
CHANGED
|
@@ -8,9 +8,9 @@ import { Alert, AlertAction, AlertDescription, AlertTitle } from "zudoku/ui/Aler
|
|
|
8
8
|
import { Card, CardContent, CardHeader, CardTitle } from "zudoku/ui/Card";
|
|
9
9
|
import { Separator } from "zudoku/ui/Separator";
|
|
10
10
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { createContext, use, useEffect, useMemo, useState } from "react";
|
|
11
12
|
import { parse } from "tinyduration";
|
|
12
13
|
import { Button as Button$1 } from "zudoku/ui/Button";
|
|
13
|
-
import { useEffect, useMemo, useState } from "react";
|
|
14
14
|
import { DismissibleAlert, DismissibleAlertAction } from "zudoku/ui/DismissibleAlert";
|
|
15
15
|
import { ActionButton } from "zudoku/ui/ActionButton";
|
|
16
16
|
import { Item, ItemContent, ItemDescription, ItemMedia, ItemTitle } from "zudoku/ui/Item";
|
|
@@ -90,6 +90,11 @@ const usePlans = () => {
|
|
|
90
90
|
});
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/MonetizationContext.tsx
|
|
95
|
+
const MonetizationContext = createContext({});
|
|
96
|
+
const useMonetizationConfig = () => use(MonetizationContext);
|
|
97
|
+
|
|
93
98
|
//#endregion
|
|
94
99
|
//#region src/utils/formatDuration.ts
|
|
95
100
|
const formatDuration = (iso) => {
|
|
@@ -124,6 +129,24 @@ const formatDurationInterval = (iso) => {
|
|
|
124
129
|
return iso;
|
|
125
130
|
}
|
|
126
131
|
};
|
|
132
|
+
/**
|
|
133
|
+
* Returns an adjective form suitable for possessive context
|
|
134
|
+
* e.g. "your monthly quota", "your weekly limit".
|
|
135
|
+
* Falls back to "billing period" for multi-unit cadences
|
|
136
|
+
* where "every 3 months" would be grammatically awkward.
|
|
137
|
+
*/
|
|
138
|
+
const formatDurationAdjective = (iso) => {
|
|
139
|
+
try {
|
|
140
|
+
const d = parse(iso);
|
|
141
|
+
if (d.years === 1) return "yearly";
|
|
142
|
+
if (d.months === 1) return "monthly";
|
|
143
|
+
if (d.weeks === 1) return "weekly";
|
|
144
|
+
if (d.days === 1) return "daily";
|
|
145
|
+
return "billing period";
|
|
146
|
+
} catch {
|
|
147
|
+
return "billing period";
|
|
148
|
+
}
|
|
149
|
+
};
|
|
127
150
|
|
|
128
151
|
//#endregion
|
|
129
152
|
//#region src/utils/formatPrice.ts
|
|
@@ -137,7 +160,8 @@ const formatPrice = (amount, currency) => new Intl.NumberFormat("en-US", {
|
|
|
137
160
|
|
|
138
161
|
//#endregion
|
|
139
162
|
//#region src/utils/categorizeRateCards.ts
|
|
140
|
-
const categorizeRateCards = (rateCards,
|
|
163
|
+
const categorizeRateCards = (rateCards, options) => {
|
|
164
|
+
const { currency, units, planBillingCadence } = options ?? {};
|
|
141
165
|
const quotas = [];
|
|
142
166
|
const features = [];
|
|
143
167
|
for (const rc of rateCards) {
|
|
@@ -157,7 +181,7 @@ const categorizeRateCards = (rateCards, currency, units) => {
|
|
|
157
181
|
key: rc.featureKey ?? rc.key,
|
|
158
182
|
name: rc.name,
|
|
159
183
|
limit: et.issueAfterReset,
|
|
160
|
-
period:
|
|
184
|
+
period: rc.billingCadence ? formatDuration(rc.billingCadence) : planBillingCadence ? formatDuration(planBillingCadence) : "month",
|
|
161
185
|
overagePrice
|
|
162
186
|
});
|
|
163
187
|
} else if (et.type === "boolean") features.push({
|
|
@@ -267,12 +291,13 @@ const queryClient = new QueryClient({ defaultOptions: {
|
|
|
267
291
|
}
|
|
268
292
|
}
|
|
269
293
|
} });
|
|
270
|
-
const ZuploMonetizationWrapper = () => {
|
|
271
|
-
|
|
272
|
-
|
|
294
|
+
const ZuploMonetizationWrapper = ({ options = {} }) => /* @__PURE__ */ jsx(QueryClientProvider, {
|
|
295
|
+
client: queryClient,
|
|
296
|
+
children: /* @__PURE__ */ jsx(MonetizationContext, {
|
|
297
|
+
value: options,
|
|
273
298
|
children: /* @__PURE__ */ jsx(ClientOnly, { children: /* @__PURE__ */ jsx(Outlet, {}) })
|
|
274
|
-
})
|
|
275
|
-
};
|
|
299
|
+
})
|
|
300
|
+
});
|
|
276
301
|
|
|
277
302
|
//#endregion
|
|
278
303
|
//#region src/pages/CheckoutConfirmPage.tsx
|
|
@@ -283,10 +308,15 @@ const CheckoutConfirmPage = () => {
|
|
|
283
308
|
const deploymentName = useDeploymentName();
|
|
284
309
|
const navigate = useNavigate();
|
|
285
310
|
const { data: plans } = usePlans();
|
|
311
|
+
const { pricing } = useMonetizationConfig();
|
|
286
312
|
const selectedPlan = plans?.items?.find((plan) => plan.id === planId);
|
|
287
313
|
if (!planId) throw new Error("Parameter `planId` missing");
|
|
288
314
|
const rateCards = selectedPlan?.phases.at(-1)?.rateCards;
|
|
289
|
-
const { quotas, features } = categorizeRateCards(rateCards ?? [],
|
|
315
|
+
const { quotas, features } = categorizeRateCards(rateCards ?? [], {
|
|
316
|
+
currency: selectedPlan?.currency,
|
|
317
|
+
units: pricing?.units,
|
|
318
|
+
planBillingCadence: selectedPlan?.billingCadence
|
|
319
|
+
});
|
|
290
320
|
const price = selectedPlan ? getPriceFromPlan(selectedPlan) : null;
|
|
291
321
|
const billingCycle = selectedPlan?.billingCadence ? formatDuration(selectedPlan.billingCadence) : null;
|
|
292
322
|
const createSubscriptionMutation = useMutation({
|
|
@@ -578,11 +608,14 @@ const ManagePaymentPage = () => {
|
|
|
578
608
|
|
|
579
609
|
//#endregion
|
|
580
610
|
//#region src/pages/pricing/PricingCard.tsx
|
|
581
|
-
const PhaseSection = ({ phase, currency, showName,
|
|
582
|
-
const {
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
611
|
+
const PhaseSection = ({ phase, currency, showName, billingCadence }) => {
|
|
612
|
+
const { pricing } = useMonetizationConfig();
|
|
613
|
+
const { quotas, features } = categorizeRateCards(phase.rateCards, {
|
|
614
|
+
currency,
|
|
615
|
+
units: pricing?.units,
|
|
616
|
+
planBillingCadence: billingCadence
|
|
617
|
+
});
|
|
618
|
+
if (quotas.length === 0 && features.length === 0) return null;
|
|
586
619
|
return /* @__PURE__ */ jsxs("div", {
|
|
587
620
|
className: "space-y-2",
|
|
588
621
|
children: [
|
|
@@ -597,17 +630,19 @@ const PhaseSection = ({ phase, currency, showName, excludeKeys, units }) => {
|
|
|
597
630
|
]
|
|
598
631
|
})]
|
|
599
632
|
}),
|
|
600
|
-
|
|
601
|
-
|
|
633
|
+
quotas.map((quota) => /* @__PURE__ */ jsx(QuotaItem, { quota }, quota.key)),
|
|
634
|
+
features.map((feature) => /* @__PURE__ */ jsx(FeatureItem, { feature }, feature.key))
|
|
602
635
|
]
|
|
603
636
|
});
|
|
604
637
|
};
|
|
605
|
-
const PricingCard = ({ plan, isPopular = false, isSubscribed = false
|
|
638
|
+
const PricingCard = ({ plan, isPopular = false, isSubscribed = false }) => {
|
|
639
|
+
const { pricing } = useMonetizationConfig();
|
|
606
640
|
if (plan.phases.length === 0) return null;
|
|
607
641
|
const price = getPriceFromPlan(plan);
|
|
608
642
|
const isFree = price.monthly === 0;
|
|
609
643
|
const isCustom = plan.metadata?.isCustom === true;
|
|
610
644
|
const hasMultiplePhases = plan.phases.length > 1;
|
|
645
|
+
const billingInterval = formatDuration(plan.billingCadence);
|
|
611
646
|
return /* @__PURE__ */ jsxs("div", {
|
|
612
647
|
className: cn("relative rounded-lg border p-6 flex flex-col", isPopular && "border-primary border-2"),
|
|
613
648
|
children: [
|
|
@@ -636,10 +671,10 @@ const PricingCard = ({ plan, isPopular = false, isSubscribed = false, showYearly
|
|
|
636
671
|
})] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
637
672
|
className: "text-3xl font-bold text-card-foreground",
|
|
638
673
|
children: isFree ? "Free" : formatPrice(price.monthly, plan.currency)
|
|
639
|
-
}), !isFree && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */
|
|
674
|
+
}), !isFree && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
|
|
640
675
|
className: "text-muted-foreground text-sm",
|
|
641
|
-
children: "/
|
|
642
|
-
}), showYearlyPrice && /* @__PURE__ */ jsxs("div", {
|
|
676
|
+
children: ["/", billingInterval]
|
|
677
|
+
}), pricing?.showYearlyPrice !== false && price.yearly > 0 && /* @__PURE__ */ jsxs("div", {
|
|
643
678
|
className: "w-full text-sm text-muted-foreground mt-1",
|
|
644
679
|
children: [formatPrice(price.yearly, plan.currency), "/year"]
|
|
645
680
|
})] })] })
|
|
@@ -652,16 +687,12 @@ const PricingCard = ({ plan, isPopular = false, isSubscribed = false, showYearly
|
|
|
652
687
|
}),
|
|
653
688
|
/* @__PURE__ */ jsx("div", {
|
|
654
689
|
className: "space-y-4 mb-6 grow",
|
|
655
|
-
children: plan.phases.map((phase
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
excludeKeys: laterKeys,
|
|
662
|
-
units
|
|
663
|
-
}, phase.key);
|
|
664
|
-
})
|
|
690
|
+
children: plan.phases.map((phase) => /* @__PURE__ */ jsx(PhaseSection, {
|
|
691
|
+
phase,
|
|
692
|
+
currency: plan.currency,
|
|
693
|
+
showName: hasMultiplePhases,
|
|
694
|
+
billingCadence: plan.billingCadence
|
|
695
|
+
}, phase.key))
|
|
665
696
|
}),
|
|
666
697
|
isSubscribed ? /* @__PURE__ */ jsx(Button, {
|
|
667
698
|
variant: isPopular ? "default" : "secondary",
|
|
@@ -684,7 +715,8 @@ const PricingCard = ({ plan, isPopular = false, isSubscribed = false, showYearly
|
|
|
684
715
|
|
|
685
716
|
//#endregion
|
|
686
717
|
//#region src/pages/PricingPage.tsx
|
|
687
|
-
const PricingPage = (
|
|
718
|
+
const PricingPage = () => {
|
|
719
|
+
const { pricing } = useMonetizationConfig();
|
|
688
720
|
const zudoku = useZudoku();
|
|
689
721
|
const deploymentName = useDeploymentName();
|
|
690
722
|
const auth = useAuth();
|
|
@@ -697,28 +729,26 @@ const PricingPage = ({ subtitle = "See our pricing options and choose the one th
|
|
|
697
729
|
return /* @__PURE__ */ jsxs("div", {
|
|
698
730
|
className: "w-full px-4 pt-(--padding-content-top) pb-(--padding-content-bottom)",
|
|
699
731
|
children: [
|
|
700
|
-
/* @__PURE__ */ jsxs(Head, { children: [/* @__PURE__ */ jsx("title", { children: title }), /* @__PURE__ */ jsx("meta", {
|
|
732
|
+
/* @__PURE__ */ jsxs(Head, { children: [/* @__PURE__ */ jsx("title", { children: pricing?.title ?? "Pricing" }), /* @__PURE__ */ jsx("meta", {
|
|
701
733
|
name: "description",
|
|
702
|
-
content: subtitle
|
|
734
|
+
content: pricing?.subtitle ?? "See our pricing options and choose the one that best suits your needs."
|
|
703
735
|
})] }),
|
|
704
736
|
/* @__PURE__ */ jsxs("div", {
|
|
705
737
|
className: "text-center space-y-4 mb-12",
|
|
706
738
|
children: [/* @__PURE__ */ jsx(Heading, {
|
|
707
739
|
level: 1,
|
|
708
740
|
"data-testid": "title",
|
|
709
|
-
children: title
|
|
741
|
+
children: pricing?.title ?? "Pricing"
|
|
710
742
|
}), /* @__PURE__ */ jsx("p", {
|
|
711
743
|
className: "text-muted-foreground",
|
|
712
744
|
"data-testid": "subtitle",
|
|
713
|
-
children: subtitle
|
|
745
|
+
children: pricing?.subtitle ?? "See our pricing options and choose the one that best suits your needs."
|
|
714
746
|
})]
|
|
715
747
|
}),
|
|
716
748
|
/* @__PURE__ */ jsx("div", {
|
|
717
749
|
className: "w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(300px,max-content))] justify-center gap-6",
|
|
718
750
|
children: pricingTable.items.map((plan) => /* @__PURE__ */ jsx(PricingCard, {
|
|
719
751
|
plan,
|
|
720
|
-
units,
|
|
721
|
-
showYearlyPrice,
|
|
722
752
|
isPopular: plan.metadata?.zuplo_most_popular === "true",
|
|
723
753
|
isSubscribed: subscriptions.items.some((subscription) => ["active", "canceled"].includes(subscription.status))
|
|
724
754
|
}, plan.id))
|
|
@@ -738,11 +768,16 @@ const SubscriptionChangeConfirmPage = () => {
|
|
|
738
768
|
const deploymentName = useDeploymentName();
|
|
739
769
|
const navigate = useNavigate();
|
|
740
770
|
const { data: plans } = usePlans();
|
|
771
|
+
const { pricing } = useMonetizationConfig();
|
|
741
772
|
const selectedPlan = plans?.items?.find((plan) => plan.id === planId);
|
|
742
773
|
if (!planId) throw new Error("Parameter `planId` missing");
|
|
743
774
|
if (!subscriptionId) throw new Error("Parameter `subscriptionId` missing");
|
|
744
775
|
const rateCards = selectedPlan?.phases.at(-1)?.rateCards;
|
|
745
|
-
const { quotas, features } = categorizeRateCards(rateCards ?? [],
|
|
776
|
+
const { quotas, features } = categorizeRateCards(rateCards ?? [], {
|
|
777
|
+
currency: selectedPlan?.currency,
|
|
778
|
+
units: pricing?.units,
|
|
779
|
+
planBillingCadence: selectedPlan?.billingCadence
|
|
780
|
+
});
|
|
746
781
|
const price = selectedPlan ? getPriceFromPlan(selectedPlan) : null;
|
|
747
782
|
const billingCycle = selectedPlan?.billingCadence ? formatDuration(selectedPlan.billingCadence) : null;
|
|
748
783
|
const changeMutation = useMutation({
|
|
@@ -1279,15 +1314,23 @@ const CancelSubscriptionDialog = ({ open, onOpenChange, planName, subscriptionId
|
|
|
1279
1314
|
|
|
1280
1315
|
//#endregion
|
|
1281
1316
|
//#region src/pages/subscriptions/SwitchPlanModal.tsx
|
|
1282
|
-
const comparePlans = (currentPlan, targetPlan, currentIndex, targetIndex) => {
|
|
1317
|
+
const comparePlans = (currentPlan, targetPlan, currentIndex, targetIndex, units) => {
|
|
1283
1318
|
const isUpgrade = targetIndex > currentIndex;
|
|
1284
1319
|
const currentPhase = currentPlan?.phases.at(-1);
|
|
1285
1320
|
const targetPhase = targetPlan.phases.at(-1);
|
|
1286
|
-
const { quotas: currentQuotas, features: currentFeatures } = currentPhase ? categorizeRateCards(currentPhase.rateCards,
|
|
1321
|
+
const { quotas: currentQuotas, features: currentFeatures } = currentPhase ? categorizeRateCards(currentPhase.rateCards, {
|
|
1322
|
+
currency: currentPlan?.currency,
|
|
1323
|
+
units,
|
|
1324
|
+
planBillingCadence: currentPlan?.billingCadence
|
|
1325
|
+
}) : {
|
|
1287
1326
|
quotas: [],
|
|
1288
1327
|
features: []
|
|
1289
1328
|
};
|
|
1290
|
-
const { quotas: targetQuotas, features: targetFeatures } = targetPhase ? categorizeRateCards(targetPhase.rateCards,
|
|
1329
|
+
const { quotas: targetQuotas, features: targetFeatures } = targetPhase ? categorizeRateCards(targetPhase.rateCards, {
|
|
1330
|
+
currency: targetPlan.currency,
|
|
1331
|
+
units,
|
|
1332
|
+
planBillingCadence: targetPlan.billingCadence
|
|
1333
|
+
}) : {
|
|
1291
1334
|
quotas: [],
|
|
1292
1335
|
features: []
|
|
1293
1336
|
};
|
|
@@ -1394,7 +1437,11 @@ const PlanComparisonItem = ({ comparison, subscriptionId, mode, onRequestChange
|
|
|
1394
1437
|
children: "Free"
|
|
1395
1438
|
}) : /* @__PURE__ */ jsxs("span", {
|
|
1396
1439
|
className: "text-primary font-medium text-lg",
|
|
1397
|
-
children: [
|
|
1440
|
+
children: [
|
|
1441
|
+
formatPrice(displayPrice, comparison.plan.currency),
|
|
1442
|
+
"/",
|
|
1443
|
+
formatDuration(comparison.plan.billingCadence)
|
|
1444
|
+
]
|
|
1398
1445
|
})]
|
|
1399
1446
|
}), isCustom ? /* @__PURE__ */ jsx(Button$1, {
|
|
1400
1447
|
variant: "default",
|
|
@@ -1558,6 +1605,7 @@ const SwitchPlanModal = ({ subscription, children }) => {
|
|
|
1558
1605
|
const [open, setOpen] = useState(false);
|
|
1559
1606
|
const { data: plansData } = usePlans();
|
|
1560
1607
|
const [switchTo, setSwitchTo] = useState(null);
|
|
1608
|
+
const { pricing } = useMonetizationConfig();
|
|
1561
1609
|
const currentPlan = plansData?.items.find((p) => p.id === subscription.plan.id);
|
|
1562
1610
|
const { upgrades, downgrades, privatePlans } = useMemo(() => {
|
|
1563
1611
|
if (!plansData?.items || !currentPlan) return {
|
|
@@ -1568,14 +1616,18 @@ const SwitchPlanModal = ({ subscription, children }) => {
|
|
|
1568
1616
|
const isPrivatePlan = (plan) => plan.metadata?.zuplo_private_plan === "true";
|
|
1569
1617
|
const currentIndex = plansData.items.findIndex((p) => p.id === currentPlan.id);
|
|
1570
1618
|
const allComparisons = plansData.items.filter((p) => p.id !== currentPlan.id).map((plan) => {
|
|
1571
|
-
return comparePlans(currentPlan, plan, currentIndex, plansData.items.indexOf(plan));
|
|
1619
|
+
return comparePlans(currentPlan, plan, currentIndex, plansData.items.indexOf(plan), pricing?.units);
|
|
1572
1620
|
});
|
|
1573
1621
|
return {
|
|
1574
1622
|
upgrades: allComparisons.filter((c) => c.isUpgrade && !isPrivatePlan(c.plan)),
|
|
1575
1623
|
downgrades: allComparisons.filter((c) => !c.isUpgrade && !isPrivatePlan(c.plan)),
|
|
1576
1624
|
privatePlans: allComparisons.filter((c) => isPrivatePlan(c.plan))
|
|
1577
1625
|
};
|
|
1578
|
-
}, [
|
|
1626
|
+
}, [
|
|
1627
|
+
plansData?.items,
|
|
1628
|
+
currentPlan,
|
|
1629
|
+
pricing?.units
|
|
1630
|
+
]);
|
|
1579
1631
|
return /* @__PURE__ */ jsxs(Fragment, { children: [switchTo !== null && /* @__PURE__ */ jsx(ConfirmSwitchAlert, {
|
|
1580
1632
|
switchTo,
|
|
1581
1633
|
onRequestClose: () => setSwitchTo(null)
|
|
@@ -1763,6 +1815,8 @@ const isMeteredEntitlement = (entitlement) => {
|
|
|
1763
1815
|
return "balance" in entitlement;
|
|
1764
1816
|
};
|
|
1765
1817
|
const UsageItem = ({ meter, item, subscription }) => {
|
|
1818
|
+
const cadence = item?.billingCadence ?? subscription?.billingCadence;
|
|
1819
|
+
const billingPeriod = cadence ? formatDurationAdjective(cadence) : "monthly";
|
|
1766
1820
|
const isSoftLimit = item?.included?.entitlement?.isSoftLimit ?? true;
|
|
1767
1821
|
const rate = (item?.price?.tiers?.find((t) => !t.upToAmount) ?? item?.price?.tiers?.at(-1))?.unitPrice?.amount;
|
|
1768
1822
|
const hasOverage = meter.overage > 0;
|
|
@@ -1777,7 +1831,11 @@ const UsageItem = ({ meter, item, subscription }) => {
|
|
|
1777
1831
|
className: "mb-4",
|
|
1778
1832
|
children: [
|
|
1779
1833
|
/* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4 text-red-600 shrink-0" }),
|
|
1780
|
-
/* @__PURE__ */
|
|
1834
|
+
/* @__PURE__ */ jsxs(AlertTitle, { children: [
|
|
1835
|
+
"You've exceeded your ",
|
|
1836
|
+
billingPeriod,
|
|
1837
|
+
" quota"
|
|
1838
|
+
] }),
|
|
1781
1839
|
/* @__PURE__ */ jsxs(AlertDescription, { children: [
|
|
1782
1840
|
"Additional usage is being charged at the overage rate",
|
|
1783
1841
|
rate ? ` ($${Number(rate).toFixed(2)}/call)` : "",
|
|
@@ -1798,7 +1856,11 @@ const UsageItem = ({ meter, item, subscription }) => {
|
|
|
1798
1856
|
className: "mb-4",
|
|
1799
1857
|
children: [
|
|
1800
1858
|
/* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4 text-red-600 shrink-0" }),
|
|
1801
|
-
/* @__PURE__ */
|
|
1859
|
+
/* @__PURE__ */ jsxs(AlertTitle, { children: [
|
|
1860
|
+
"You've reached your ",
|
|
1861
|
+
billingPeriod,
|
|
1862
|
+
" limit"
|
|
1863
|
+
] }),
|
|
1802
1864
|
/* @__PURE__ */ jsx(AlertDescription, { children: "Requests beyond your quota are blocked. Upgrade to a higher plan for more usage." }),
|
|
1803
1865
|
subscription && /* @__PURE__ */ jsx(AlertAction, { children: /* @__PURE__ */ jsx(SwitchPlanModal, {
|
|
1804
1866
|
subscription,
|
|
@@ -1848,7 +1910,7 @@ const UsageItem = ({ meter, item, subscription }) => {
|
|
|
1848
1910
|
}),
|
|
1849
1911
|
/* @__PURE__ */ jsxs("p", {
|
|
1850
1912
|
className: "text-xs text-muted-foreground",
|
|
1851
|
-
children: [meter.balance.toLocaleString(), " remaining this
|
|
1913
|
+
children: [meter.balance.toLocaleString(), " remaining this billing period"]
|
|
1852
1914
|
})
|
|
1853
1915
|
]
|
|
1854
1916
|
})]
|
|
@@ -2071,7 +2133,7 @@ const SubscriptionsPage = () => {
|
|
|
2071
2133
|
//#endregion
|
|
2072
2134
|
//#region src/ZuploMonetizationPlugin.tsx
|
|
2073
2135
|
const PRICING_PATH = "/pricing";
|
|
2074
|
-
const zuploMonetizationPlugin = createPlugin((options) => ({
|
|
2136
|
+
const zuploMonetizationPlugin = createPlugin((options = {}) => ({
|
|
2075
2137
|
transformConfig: ({ config, merge }) => merge({
|
|
2076
2138
|
apiKeys: { enabled: false },
|
|
2077
2139
|
header: { navigation: [...config.header?.navigation ?? [], {
|
|
@@ -2107,7 +2169,7 @@ const zuploMonetizationPlugin = createPlugin((options) => ({
|
|
|
2107
2169
|
}],
|
|
2108
2170
|
getRoutes: () => {
|
|
2109
2171
|
return [{
|
|
2110
|
-
|
|
2172
|
+
element: /* @__PURE__ */ jsx(ZuploMonetizationWrapper, { options }),
|
|
2111
2173
|
handle: { layout: "none" },
|
|
2112
2174
|
children: [
|
|
2113
2175
|
{
|
|
@@ -2129,12 +2191,7 @@ const zuploMonetizationPlugin = createPlugin((options) => ({
|
|
|
2129
2191
|
{
|
|
2130
2192
|
path: PRICING_PATH,
|
|
2131
2193
|
handle: { layout: "default" },
|
|
2132
|
-
element: /* @__PURE__ */ jsx(PricingPage, {
|
|
2133
|
-
subtitle: options?.pricing?.subtitle,
|
|
2134
|
-
title: options?.pricing?.title,
|
|
2135
|
-
units: options?.pricing?.units,
|
|
2136
|
-
showYearlyPrice: options?.pricing?.showYearlyPrice
|
|
2137
|
-
})
|
|
2194
|
+
element: /* @__PURE__ */ jsx(PricingPage, {})
|
|
2138
2195
|
},
|
|
2139
2196
|
{
|
|
2140
2197
|
handle: { layout: "default" },
|