@zuplo/zudoku-plugin-monetization 0.0.28 → 0.0.30
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 +1 -1
- package/dist/index.mjs +213 -60
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Suspense, createContext, use, useEffect, useMemo, useState } from "react";
|
|
1
2
|
import { cn, createPlugin, joinUrl, throwIfProblemJson } from "zudoku";
|
|
2
3
|
import { AlertTriangleIcon, ArrowDownIcon, ArrowLeftRightIcon, ArrowUpIcon, CalendarIcon, CheckCheckIcon, CheckIcon, CircleSlashIcon, ClockIcon, CreditCardIcon, Grid2x2XIcon, InfoIcon, Loader2Icon, LockIcon, MoreVerticalIcon, RefreshCcw, RefreshCwIcon, Settings, ShieldIcon, StarsIcon, Trash2Icon, XIcon } from "zudoku/icons";
|
|
3
4
|
import { Button, ClientOnly, Head, Heading, Link, Slot } from "zudoku/components";
|
|
@@ -8,9 +9,9 @@ import { Alert, AlertAction, AlertDescription, AlertTitle } from "zudoku/ui/Aler
|
|
|
8
9
|
import { Card, CardContent, CardHeader, CardTitle } from "zudoku/ui/Card";
|
|
9
10
|
import { Separator } from "zudoku/ui/Separator";
|
|
10
11
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { createContext, use, useEffect, useMemo, useState } from "react";
|
|
12
12
|
import { parse } from "tinyduration";
|
|
13
13
|
import { Button as Button$1 } from "zudoku/ui/Button";
|
|
14
|
+
import { Skeleton } from "zudoku/ui/Skeleton";
|
|
14
15
|
import { DismissibleAlert, DismissibleAlertAction } from "zudoku/ui/DismissibleAlert";
|
|
15
16
|
import { ActionButton } from "zudoku/ui/ActionButton";
|
|
16
17
|
import { Item, ItemContent, ItemDescription, ItemMedia, ItemTitle } from "zudoku/ui/Item";
|
|
@@ -155,6 +156,12 @@ const formatPrice = (amount, currency) => new Intl.NumberFormat("en-US", {
|
|
|
155
156
|
maximumFractionDigits: 6,
|
|
156
157
|
trailingZeroDisplay: "stripIfInteger"
|
|
157
158
|
}).format(amount);
|
|
159
|
+
const formatPriceTwoDecimals = (amount, currency) => new Intl.NumberFormat("en-US", {
|
|
160
|
+
style: "currency",
|
|
161
|
+
currency: currency ?? "USD",
|
|
162
|
+
minimumFractionDigits: 2,
|
|
163
|
+
maximumFractionDigits: 2
|
|
164
|
+
}).format(amount);
|
|
158
165
|
|
|
159
166
|
//#endregion
|
|
160
167
|
//#region src/utils/categorizeRateCards.ts
|
|
@@ -231,7 +238,7 @@ const getPlanFromPurchaseDetails = (response) => {
|
|
|
231
238
|
return response;
|
|
232
239
|
};
|
|
233
240
|
const getTaxAmountFromPurchaseDetails = (response) => {
|
|
234
|
-
const taxAmount = response?.tax?.taxAmount;
|
|
241
|
+
const taxAmount = response?.tax?.items[0]?.taxAmount;
|
|
235
242
|
const numericAmount = typeof taxAmount === "number" ? taxAmount : Number.parseFloat(taxAmount ?? "");
|
|
236
243
|
if (!Number.isFinite(numericAmount)) return;
|
|
237
244
|
return numericAmount;
|
|
@@ -410,13 +417,13 @@ const CheckoutConfirmPage = () => {
|
|
|
410
417
|
className: "text-2xl font-bold",
|
|
411
418
|
children: formatPrice(price.monthly, selectedPlan?.currency)
|
|
412
419
|
}),
|
|
420
|
+
taxAmount != null && /* @__PURE__ */ jsx("div", {
|
|
421
|
+
className: "text-xs font-normal mt-1",
|
|
422
|
+
children: taxInclusive ? `${formatPriceTwoDecimals(taxAmount, selectedPlan?.currency)} ${taxLabel} included` : `+ ${formatPriceTwoDecimals(taxAmount, selectedPlan?.currency)} ${taxLabel}`
|
|
423
|
+
}),
|
|
413
424
|
billingCycle && /* @__PURE__ */ jsxs("div", {
|
|
414
425
|
className: "text-sm text-muted-foreground font-normal",
|
|
415
426
|
children: ["Billed ", formatBillingCycle(billingCycle)]
|
|
416
|
-
}),
|
|
417
|
-
taxAmount != null && /* @__PURE__ */ jsx("div", {
|
|
418
|
-
className: "text-xs text-muted-foreground font-normal mt-1",
|
|
419
|
-
children: taxInclusive ? `${formatPrice(taxAmount, selectedPlan?.currency)} ${taxLabel} included` : `+ ${formatPrice(taxAmount, selectedPlan?.currency)} ${taxLabel}`
|
|
420
427
|
})
|
|
421
428
|
]
|
|
422
429
|
}),
|
|
@@ -782,7 +789,13 @@ const PricingPage = () => {
|
|
|
782
789
|
children: pricing?.subtitle ?? "See our pricing options and choose the one that best suits your needs."
|
|
783
790
|
})]
|
|
784
791
|
}),
|
|
785
|
-
/* @__PURE__ */
|
|
792
|
+
pricingTable.items.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
793
|
+
className: "text-center py-12 text-muted-foreground",
|
|
794
|
+
children: [/* @__PURE__ */ jsx("p", { children: "No plans are currently available." }), /* @__PURE__ */ jsx("p", {
|
|
795
|
+
className: "text-sm mt-2",
|
|
796
|
+
children: "Make sure your plans are set up and published."
|
|
797
|
+
})]
|
|
798
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
786
799
|
className: "w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(300px,max-content))] justify-center gap-6",
|
|
787
800
|
children: pricingTable.items.map((plan) => /* @__PURE__ */ jsx(PricingCard, {
|
|
788
801
|
plan,
|
|
@@ -795,6 +808,37 @@ const PricingPage = () => {
|
|
|
795
808
|
});
|
|
796
809
|
};
|
|
797
810
|
|
|
811
|
+
//#endregion
|
|
812
|
+
//#region src/pages/PricingPageSkeleton.tsx
|
|
813
|
+
const PricingPageSkeleton = () => /* @__PURE__ */ jsxs("div", {
|
|
814
|
+
className: "w-full px-4 pt-(--padding-content-top) pb-(--padding-content-bottom)",
|
|
815
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
816
|
+
className: "text-center space-y-4 mb-12",
|
|
817
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-48 mx-auto" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-96 mx-auto" })]
|
|
818
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
819
|
+
className: "w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(300px,max-content))] justify-center gap-6",
|
|
820
|
+
children: [
|
|
821
|
+
1,
|
|
822
|
+
2,
|
|
823
|
+
3
|
|
824
|
+
].map((i) => /* @__PURE__ */ jsxs(Card, {
|
|
825
|
+
className: "w-[300px]",
|
|
826
|
+
children: [/* @__PURE__ */ jsxs(CardHeader, {
|
|
827
|
+
className: "space-y-3",
|
|
828
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-24" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-32" })]
|
|
829
|
+
}), /* @__PURE__ */ jsxs(CardContent, {
|
|
830
|
+
className: "space-y-3",
|
|
831
|
+
children: [
|
|
832
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
|
|
833
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
|
|
834
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
835
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full mt-4" })
|
|
836
|
+
]
|
|
837
|
+
})]
|
|
838
|
+
}, i))
|
|
839
|
+
})]
|
|
840
|
+
});
|
|
841
|
+
|
|
798
842
|
//#endregion
|
|
799
843
|
//#region src/pages/SubscriptionChangeConfirmPage.tsx
|
|
800
844
|
const SubscriptionChangeConfirmPage = () => {
|
|
@@ -899,13 +943,13 @@ const SubscriptionChangeConfirmPage = () => {
|
|
|
899
943
|
className: "text-2xl font-bold",
|
|
900
944
|
children: formatPrice(price.monthly, selectedPlan?.currency)
|
|
901
945
|
}),
|
|
946
|
+
taxAmount != null && /* @__PURE__ */ jsx("div", {
|
|
947
|
+
className: "text-xs font-normal mt-1",
|
|
948
|
+
children: taxInclusive ? `${formatPriceTwoDecimals(taxAmount, selectedPlan?.currency)} ${taxLabel} included` : `+ ${formatPriceTwoDecimals(taxAmount, selectedPlan?.currency)} ${taxLabel}`
|
|
949
|
+
}),
|
|
902
950
|
billingCycle && /* @__PURE__ */ jsxs("div", {
|
|
903
951
|
className: "text-sm text-muted-foreground font-normal",
|
|
904
952
|
children: ["Billed ", formatBillingCycle(billingCycle)]
|
|
905
|
-
}),
|
|
906
|
-
taxAmount != null && /* @__PURE__ */ jsx("div", {
|
|
907
|
-
className: "text-xs text-muted-foreground font-normal mt-1",
|
|
908
|
-
children: taxInclusive ? `${formatPrice(taxAmount, selectedPlan?.currency)} ${taxLabel} included` : `+ ${formatPrice(taxAmount, selectedPlan?.currency)} ${taxLabel}`
|
|
909
953
|
})
|
|
910
954
|
]
|
|
911
955
|
}),
|
|
@@ -969,7 +1013,15 @@ const useSubscriptions = (environmentName) => {
|
|
|
969
1013
|
const zudoku = useZudoku();
|
|
970
1014
|
return useSuspenseQuery({
|
|
971
1015
|
queryKey: [`/v3/zudoku-metering/${environmentName}/subscriptions`],
|
|
972
|
-
meta: { context: zudoku }
|
|
1016
|
+
meta: { context: zudoku },
|
|
1017
|
+
select: (data) => ({
|
|
1018
|
+
...data,
|
|
1019
|
+
items: [...data.items].sort((a, b) => {
|
|
1020
|
+
if (a.status === "active" && b.status !== "active") return -1;
|
|
1021
|
+
if (a.status !== "active" && b.status === "active") return 1;
|
|
1022
|
+
return 0;
|
|
1023
|
+
})
|
|
1024
|
+
})
|
|
973
1025
|
});
|
|
974
1026
|
};
|
|
975
1027
|
|
|
@@ -1461,6 +1513,23 @@ const RestoreSubscriptionDialog = ({ open, onOpenChange, planName, subscriptionI
|
|
|
1461
1513
|
|
|
1462
1514
|
//#endregion
|
|
1463
1515
|
//#region src/pages/subscriptions/SwitchPlanModal.tsx
|
|
1516
|
+
const getAllKeysAcrossPhases = (plan, units) => {
|
|
1517
|
+
const quotaKeys = /* @__PURE__ */ new Set();
|
|
1518
|
+
const featureKeys = /* @__PURE__ */ new Set();
|
|
1519
|
+
for (const phase of plan.phases) {
|
|
1520
|
+
const { quotas, features } = categorizeRateCards(phase.rateCards, {
|
|
1521
|
+
currency: plan.currency,
|
|
1522
|
+
units,
|
|
1523
|
+
planBillingCadence: plan.billingCadence
|
|
1524
|
+
});
|
|
1525
|
+
for (const q of quotas) quotaKeys.add(q.key);
|
|
1526
|
+
for (const f of features) featureKeys.add(f.key);
|
|
1527
|
+
}
|
|
1528
|
+
return {
|
|
1529
|
+
quotaKeys,
|
|
1530
|
+
featureKeys
|
|
1531
|
+
};
|
|
1532
|
+
};
|
|
1464
1533
|
const comparePlans = (currentPlan, targetPlan, currentIndex, targetIndex, units) => {
|
|
1465
1534
|
const isUpgrade = targetIndex > currentIndex;
|
|
1466
1535
|
const currentPhase = currentPlan?.phases.at(-1);
|
|
@@ -1481,6 +1550,11 @@ const comparePlans = (currentPlan, targetPlan, currentIndex, targetIndex, units)
|
|
|
1481
1550
|
quotas: [],
|
|
1482
1551
|
features: []
|
|
1483
1552
|
};
|
|
1553
|
+
const currentAllKeys = currentPlan ? getAllKeysAcrossPhases(currentPlan, units) : {
|
|
1554
|
+
quotaKeys: /* @__PURE__ */ new Set(),
|
|
1555
|
+
featureKeys: /* @__PURE__ */ new Set()
|
|
1556
|
+
};
|
|
1557
|
+
const targetAllKeys = getAllKeysAcrossPhases(targetPlan, units);
|
|
1484
1558
|
const quotaChanges = [];
|
|
1485
1559
|
const allQuotaKeys = new Set([...currentQuotas.map((q) => q.key), ...targetQuotas.map((q) => q.key)]);
|
|
1486
1560
|
for (const key of allQuotaKeys) {
|
|
@@ -1498,22 +1572,37 @@ const comparePlans = (currentPlan, targetPlan, currentIndex, targetIndex, units)
|
|
|
1498
1572
|
period: target.period,
|
|
1499
1573
|
change
|
|
1500
1574
|
});
|
|
1501
|
-
} else if (target && !current)
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1575
|
+
} else if (target && !current) {
|
|
1576
|
+
if (currentAllKeys.featureKeys.has(key)) {
|
|
1577
|
+
quotaChanges.push({
|
|
1578
|
+
key: key ?? "",
|
|
1579
|
+
name: target.name,
|
|
1580
|
+
currentValue: null,
|
|
1581
|
+
newValue: target.limit,
|
|
1582
|
+
period: target.period,
|
|
1583
|
+
change: "same"
|
|
1584
|
+
});
|
|
1585
|
+
continue;
|
|
1586
|
+
}
|
|
1587
|
+
quotaChanges.push({
|
|
1588
|
+
key: key ?? "",
|
|
1589
|
+
name: target.name,
|
|
1590
|
+
currentValue: null,
|
|
1591
|
+
newValue: target.limit,
|
|
1592
|
+
period: target.period,
|
|
1593
|
+
change: "added"
|
|
1594
|
+
});
|
|
1595
|
+
} else if (current && !target) {
|
|
1596
|
+
if (targetAllKeys.featureKeys.has(key)) continue;
|
|
1597
|
+
quotaChanges.push({
|
|
1598
|
+
key: key ?? "",
|
|
1599
|
+
name: current.name,
|
|
1600
|
+
currentValue: current.limit,
|
|
1601
|
+
newValue: null,
|
|
1602
|
+
period: current.period,
|
|
1603
|
+
change: "removed"
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1517
1606
|
}
|
|
1518
1607
|
const featureChanges = [];
|
|
1519
1608
|
const allFeatureKeys = new Set([...currentFeatures.map((f) => f.key), ...targetFeatures.map((f) => f.key)]);
|
|
@@ -1530,20 +1619,34 @@ const comparePlans = (currentPlan, targetPlan, currentIndex, targetIndex, units)
|
|
|
1530
1619
|
newValue: target.value ?? true,
|
|
1531
1620
|
change
|
|
1532
1621
|
});
|
|
1533
|
-
} else if (target && !current)
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1622
|
+
} else if (target && !current) {
|
|
1623
|
+
if (currentAllKeys.quotaKeys.has(key)) {
|
|
1624
|
+
featureChanges.push({
|
|
1625
|
+
key: key ?? "",
|
|
1626
|
+
name: target.name,
|
|
1627
|
+
currentValue: true,
|
|
1628
|
+
newValue: target.value ?? true,
|
|
1629
|
+
change: "same"
|
|
1630
|
+
});
|
|
1631
|
+
continue;
|
|
1632
|
+
}
|
|
1633
|
+
featureChanges.push({
|
|
1634
|
+
key: key ?? "",
|
|
1635
|
+
name: target.name,
|
|
1636
|
+
currentValue: null,
|
|
1637
|
+
newValue: target.value ?? true,
|
|
1638
|
+
change: "added"
|
|
1639
|
+
});
|
|
1640
|
+
} else if (current && !target) {
|
|
1641
|
+
if (targetAllKeys.quotaKeys.has(key)) continue;
|
|
1642
|
+
featureChanges.push({
|
|
1643
|
+
key: key ?? "",
|
|
1644
|
+
name: current.name,
|
|
1645
|
+
currentValue: current.value ?? true,
|
|
1646
|
+
newValue: null,
|
|
1647
|
+
change: "removed"
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1547
1650
|
}
|
|
1548
1651
|
return {
|
|
1549
1652
|
plan: targetPlan,
|
|
@@ -1571,7 +1674,7 @@ const PlanComparisonItem = ({ comparison, subscriptionId, mode, onRequestChange,
|
|
|
1571
1674
|
const price = getPriceFromPlan(comparison.plan);
|
|
1572
1675
|
const isCustom = comparison.plan.key === "enterprise";
|
|
1573
1676
|
const displayPrice = price.monthly;
|
|
1574
|
-
const hasChanges = comparison.quotaChanges.
|
|
1677
|
+
const hasChanges = comparison.quotaChanges.length > 0 || comparison.featureChanges.length > 0;
|
|
1575
1678
|
return /* @__PURE__ */ jsxs("div", {
|
|
1576
1679
|
className: "border rounded-lg p-4",
|
|
1577
1680
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -1612,7 +1715,7 @@ const PlanComparisonItem = ({ comparison, subscriptionId, mode, onRequestChange,
|
|
|
1612
1715
|
})]
|
|
1613
1716
|
}), hasChanges && /* @__PURE__ */ jsxs("div", {
|
|
1614
1717
|
className: "space-y-1.5",
|
|
1615
|
-
children: [comparison.quotaChanges.
|
|
1718
|
+
children: [comparison.quotaChanges.map((quota) => /* @__PURE__ */ jsxs("div", {
|
|
1616
1719
|
className: "flex items-center gap-2 text-sm",
|
|
1617
1720
|
children: [
|
|
1618
1721
|
/* @__PURE__ */ jsx(ChangeIndicator, { change: quota.change }),
|
|
@@ -1620,7 +1723,14 @@ const PlanComparisonItem = ({ comparison, subscriptionId, mode, onRequestChange,
|
|
|
1620
1723
|
className: "font-medium",
|
|
1621
1724
|
children: [quota.name, ":"]
|
|
1622
1725
|
}),
|
|
1623
|
-
quota.change === "
|
|
1726
|
+
quota.change === "same" ? /* @__PURE__ */ jsxs("span", {
|
|
1727
|
+
className: "text-muted-foreground",
|
|
1728
|
+
children: [
|
|
1729
|
+
(quota.newValue ?? quota.currentValue)?.toLocaleString(),
|
|
1730
|
+
"/",
|
|
1731
|
+
quota.period
|
|
1732
|
+
]
|
|
1733
|
+
}) : quota.change === "added" ? /* @__PURE__ */ jsx("span", {
|
|
1624
1734
|
className: "text-green-600",
|
|
1625
1735
|
children: "Now included"
|
|
1626
1736
|
}) : quota.change === "removed" ? /* @__PURE__ */ jsx("span", {
|
|
@@ -1649,9 +1759,12 @@ const PlanComparisonItem = ({ comparison, subscriptionId, mode, onRequestChange,
|
|
|
1649
1759
|
})
|
|
1650
1760
|
] })
|
|
1651
1761
|
]
|
|
1652
|
-
}, quota.key)), comparison.featureChanges.
|
|
1762
|
+
}, quota.key)), comparison.featureChanges.map((feature) => /* @__PURE__ */ jsx("div", {
|
|
1653
1763
|
className: "flex items-center gap-2 text-sm",
|
|
1654
|
-
children: feature.change === "
|
|
1764
|
+
children: feature.change === "same" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CheckIcon, { className: "w-4 h-4 text-green-600 shrink-0" }), /* @__PURE__ */ jsxs("span", {
|
|
1765
|
+
className: "text-muted-foreground",
|
|
1766
|
+
children: [feature.name, typeof feature.newValue === "string" ? `: ${feature.newValue}` : typeof feature.currentValue === "string" ? `: ${feature.currentValue}` : ""]
|
|
1767
|
+
})] }) : feature.change === "added" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1655
1768
|
/* @__PURE__ */ jsx(CheckIcon, { className: "w-4 h-4 text-green-600 shrink-0" }),
|
|
1656
1769
|
/* @__PURE__ */ jsx("span", {
|
|
1657
1770
|
className: "text-muted-foreground font-medium",
|
|
@@ -1735,7 +1848,7 @@ const SwitchPlanModal = ({ subscription, children }) => {
|
|
|
1735
1848
|
window.location.href = data.url;
|
|
1736
1849
|
}
|
|
1737
1850
|
});
|
|
1738
|
-
const currentPlan = plansData?.items.find((p) => p.
|
|
1851
|
+
const currentPlan = plansData?.items.find((p) => p.key === subscription.plan.key);
|
|
1739
1852
|
const { upgrades, downgrades, privatePlans } = useMemo(() => {
|
|
1740
1853
|
if (!plansData?.items || !currentPlan) return {
|
|
1741
1854
|
upgrades: [],
|
|
@@ -1961,7 +2074,7 @@ const ManageSubscription = ({ subscription, planName }) => {
|
|
|
1961
2074
|
const isMeteredEntitlement = (entitlement) => {
|
|
1962
2075
|
return "balance" in entitlement;
|
|
1963
2076
|
};
|
|
1964
|
-
const UsageItem = ({ meter, item, subscription }) => {
|
|
2077
|
+
const UsageItem = ({ meter, item, subscription, featureKey }) => {
|
|
1965
2078
|
const cadence = item?.billingCadence ?? subscription?.billingCadence;
|
|
1966
2079
|
const billingPeriod = cadence ? formatDurationAdjective(cadence) : "monthly";
|
|
1967
2080
|
const isSoftLimit = item?.included?.entitlement?.isSoftLimit ?? true;
|
|
@@ -2020,7 +2133,7 @@ const UsageItem = ({ meter, item, subscription }) => {
|
|
|
2020
2133
|
]
|
|
2021
2134
|
}),
|
|
2022
2135
|
/* @__PURE__ */ jsxs(CardTitle, { children: [
|
|
2023
|
-
item?.name ??
|
|
2136
|
+
item?.name ?? featureKey,
|
|
2024
2137
|
" ",
|
|
2025
2138
|
item?.price?.amount
|
|
2026
2139
|
] })
|
|
@@ -2100,6 +2213,7 @@ const Usage = ({ usage, isFetching, currentItems, subscription, isPendingFirstPa
|
|
|
2100
2213
|
]
|
|
2101
2214
|
}),
|
|
2102
2215
|
hasUsage ? Object.entries(usage.entitlements).flatMap(([key, value]) => isMeteredEntitlement(value) ? /* @__PURE__ */ jsx(UsageItem, {
|
|
2216
|
+
featureKey: key,
|
|
2103
2217
|
meter: { ...value },
|
|
2104
2218
|
subscription,
|
|
2105
2219
|
item: currentItems?.find((item) => item.featureKey === key)
|
|
@@ -2277,6 +2391,40 @@ const SubscriptionsPage = () => {
|
|
|
2277
2391
|
});
|
|
2278
2392
|
};
|
|
2279
2393
|
|
|
2394
|
+
//#endregion
|
|
2395
|
+
//#region src/pages/SubscriptionsPageSkeleton.tsx
|
|
2396
|
+
const SubscriptionsPageSkeleton = () => /* @__PURE__ */ jsx("div", {
|
|
2397
|
+
className: "w-full pt-(--padding-content-top) pb-(--padding-content-bottom)",
|
|
2398
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2399
|
+
className: "max-w-4xl space-y-8",
|
|
2400
|
+
children: [
|
|
2401
|
+
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-56 mb-2" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-80" })] }),
|
|
2402
|
+
/* @__PURE__ */ jsx("div", {
|
|
2403
|
+
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3",
|
|
2404
|
+
children: [1, 2].map((i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-20 rounded-lg" }, i))
|
|
2405
|
+
}),
|
|
2406
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2407
|
+
className: "space-y-4",
|
|
2408
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-16" }), /* @__PURE__ */ jsxs(Card, { children: [/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-32" }) }), /* @__PURE__ */ jsxs(CardContent, {
|
|
2409
|
+
className: "space-y-2",
|
|
2410
|
+
children: [
|
|
2411
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2412
|
+
className: "flex justify-between",
|
|
2413
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-20" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })]
|
|
2414
|
+
}),
|
|
2415
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-2 w-full" }),
|
|
2416
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-48" })
|
|
2417
|
+
]
|
|
2418
|
+
})] })]
|
|
2419
|
+
}),
|
|
2420
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2421
|
+
className: "space-y-4",
|
|
2422
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-20" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-12 rounded-lg" })]
|
|
2423
|
+
})
|
|
2424
|
+
]
|
|
2425
|
+
})
|
|
2426
|
+
});
|
|
2427
|
+
|
|
2280
2428
|
//#endregion
|
|
2281
2429
|
//#region src/ZuploMonetizationPlugin.tsx
|
|
2282
2430
|
const PRICING_PATH = "/pricing";
|
|
@@ -2334,18 +2482,23 @@ const zuploMonetizationPlugin = createPlugin((options = {}) => ({
|
|
|
2334
2482
|
{
|
|
2335
2483
|
path: "/manage-payment",
|
|
2336
2484
|
element: /* @__PURE__ */ jsx(ManagePaymentPage, {})
|
|
2337
|
-
},
|
|
2338
|
-
{
|
|
2339
|
-
path: PRICING_PATH,
|
|
2340
|
-
handle: { layout: "default" },
|
|
2341
|
-
element: /* @__PURE__ */ jsx(PricingPage, {})
|
|
2342
|
-
},
|
|
2343
|
-
{
|
|
2344
|
-
handle: { layout: "default" },
|
|
2345
|
-
path: "/subscriptions",
|
|
2346
|
-
element: /* @__PURE__ */ jsx(SubscriptionsPage, {})
|
|
2347
2485
|
}
|
|
2348
2486
|
]
|
|
2487
|
+
}, {
|
|
2488
|
+
element: /* @__PURE__ */ jsx(ZuploMonetizationWrapper, { options }),
|
|
2489
|
+
children: [{
|
|
2490
|
+
path: PRICING_PATH,
|
|
2491
|
+
element: /* @__PURE__ */ jsx(Suspense, {
|
|
2492
|
+
fallback: /* @__PURE__ */ jsx(PricingPageSkeleton, {}),
|
|
2493
|
+
children: /* @__PURE__ */ jsx(PricingPage, {})
|
|
2494
|
+
})
|
|
2495
|
+
}, {
|
|
2496
|
+
path: "/subscriptions",
|
|
2497
|
+
element: /* @__PURE__ */ jsx(Suspense, {
|
|
2498
|
+
fallback: /* @__PURE__ */ jsx(SubscriptionsPageSkeleton, {}),
|
|
2499
|
+
children: /* @__PURE__ */ jsx(SubscriptionsPage, {})
|
|
2500
|
+
})
|
|
2501
|
+
}]
|
|
2349
2502
|
}];
|
|
2350
2503
|
},
|
|
2351
2504
|
getProtectedRoutes: () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuplo/zudoku-plugin-monetization",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/zuplo/zudoku",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"@testing-library/react": "16.3.2",
|
|
28
28
|
"@types/react": "19.2.14",
|
|
29
29
|
"@types/react-dom": "19.2.3",
|
|
30
|
-
"happy-dom": "20.8.
|
|
30
|
+
"happy-dom": "20.8.9",
|
|
31
31
|
"react": "19.2.4",
|
|
32
32
|
"react-dom": "19.2.4",
|
|
33
33
|
"tsdown": "0.20.3",
|
|
34
|
-
"zudoku": "0.
|
|
34
|
+
"zudoku": "0.75.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"react": ">=19.2.0",
|