@zuplo/zudoku-plugin-monetization 0.0.36-pre.2 → 0.0.37
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.
|
@@ -295,11 +295,86 @@ const PlanEntitlements = ({ phases, currency, billingCadence, units, itemClassNa
|
|
|
295
295
|
};
|
|
296
296
|
//#endregion
|
|
297
297
|
//#region src/utils/getPriceFromPlan.ts
|
|
298
|
-
const
|
|
298
|
+
const sumFlatFeeAmounts = (rateCards) => {
|
|
299
|
+
let total = 0;
|
|
300
|
+
for (const rc of rateCards) if (rc.type === "flat_fee" && rc.price) {
|
|
301
|
+
const amount = Number(rc.price.amount);
|
|
302
|
+
if (Number.isFinite(amount)) total += amount;
|
|
303
|
+
}
|
|
304
|
+
return total;
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* Convert an ISO 8601 duration to an approximate number of months.
|
|
308
|
+
* Years and months contribute exactly; weeks use 12/52 months/week and
|
|
309
|
+
* days use 1/30 months/day. Sub-day units (hours, minutes, seconds) do
|
|
310
|
+
* not contribute and a duration consisting only of those returns
|
|
311
|
+
* `undefined` because there is no sensible monthly equivalent.
|
|
312
|
+
*/
|
|
313
|
+
const cadenceToMonths = (iso) => {
|
|
314
|
+
try {
|
|
315
|
+
const d = parse(iso);
|
|
316
|
+
let months = 0;
|
|
317
|
+
if (d.years) months += d.years * 12;
|
|
318
|
+
if (d.months) months += d.months;
|
|
319
|
+
if (d.weeks) months += d.weeks * (12 / 52);
|
|
320
|
+
if (d.days) months += d.days * (1 / 30);
|
|
321
|
+
return months > 0 ? months : void 0;
|
|
322
|
+
} catch {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* Derive a (monthly, yearly) headline price from a plan's last phase by
|
|
328
|
+
* summing all `flat_fee` rate-card amounts and converting from the plan's
|
|
329
|
+
* `billingCadence` to a monthly equivalent.
|
|
330
|
+
*
|
|
331
|
+
* Returns `null` for either field when no value can be derived (no
|
|
332
|
+
* phases, or an unparseable / sub-day cadence). A flat-fee sum of 0
|
|
333
|
+
* returns `{ monthly: 0, yearly: 0 }` (Free).
|
|
334
|
+
*
|
|
335
|
+
* Useful for consumers whose source data doesn't already include
|
|
336
|
+
* pre-computed `monthlyPrice` / `yearlyPrice` — pass the result through
|
|
337
|
+
* (or rely on `getPriceFromPlan`'s built-in fallback).
|
|
338
|
+
*/
|
|
339
|
+
const derivePriceFromPlan = (plan) => {
|
|
340
|
+
const lastPhase = plan.phases?.at(-1);
|
|
341
|
+
if (!lastPhase) return {
|
|
342
|
+
monthly: null,
|
|
343
|
+
yearly: null
|
|
344
|
+
};
|
|
345
|
+
const flatPrice = sumFlatFeeAmounts(lastPhase.rateCards ?? []);
|
|
346
|
+
if (flatPrice === 0) return {
|
|
347
|
+
monthly: 0,
|
|
348
|
+
yearly: 0
|
|
349
|
+
};
|
|
350
|
+
const months = cadenceToMonths(plan.billingCadence);
|
|
351
|
+
if (months == null) return {
|
|
352
|
+
monthly: null,
|
|
353
|
+
yearly: null
|
|
354
|
+
};
|
|
355
|
+
const monthly = flatPrice / months;
|
|
299
356
|
return {
|
|
357
|
+
monthly,
|
|
358
|
+
yearly: monthly * 12
|
|
359
|
+
};
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Returns the monthly and yearly headline price for a plan. Prefers the
|
|
363
|
+
* server-provided `monthlyPrice` / `yearlyPrice` strings when present;
|
|
364
|
+
* otherwise falls back to {@link derivePriceFromPlan}. Values that can't
|
|
365
|
+
* be resolved are reported as `0`, which the pricing card renders as
|
|
366
|
+
* "Free".
|
|
367
|
+
*/
|
|
368
|
+
const getPriceFromPlan = (plan) => {
|
|
369
|
+
if (plan.monthlyPrice != null || plan.yearlyPrice != null) return {
|
|
300
370
|
monthly: plan.monthlyPrice != null ? parseFloat(plan.monthlyPrice) : 0,
|
|
301
371
|
yearly: plan.yearlyPrice != null ? parseFloat(plan.yearlyPrice) : 0
|
|
302
372
|
};
|
|
373
|
+
const derived = derivePriceFromPlan(plan);
|
|
374
|
+
return {
|
|
375
|
+
monthly: derived.monthly ?? 0,
|
|
376
|
+
yearly: derived.yearly ?? 0
|
|
377
|
+
};
|
|
303
378
|
};
|
|
304
379
|
//#endregion
|
|
305
380
|
//#region src/utils/pricingTaxLegend.ts
|
|
@@ -411,7 +486,7 @@ const PricingTable = ({ plans, showYearlyPrice = true, units, renderAction, rend
|
|
|
411
486
|
const firstPlan = plans[0];
|
|
412
487
|
const taxLegendSentence = showTaxLegend && firstPlan ? taxBehaviorLegendSentence(collectDefaultTaxBehaviors(firstPlan)) : void 0;
|
|
413
488
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
414
|
-
className: cn("w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(
|
|
489
|
+
className: cn("w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(200px,1fr))] justify-center gap-2", className),
|
|
415
490
|
children: plans.map((plan) => {
|
|
416
491
|
const popular = isPopular(plan);
|
|
417
492
|
const defaultCard = /* @__PURE__ */ jsx(PricingCard, {
|
|
@@ -440,4 +515,4 @@ const PricingTable = ({ plans, showYearlyPrice = true, units, renderAction, rend
|
|
|
440
515
|
})] });
|
|
441
516
|
};
|
|
442
517
|
//#endregion
|
|
443
|
-
export {
|
|
518
|
+
export { formatDuration as _, subscriptionTaxLegendSentence as a, getPriceFromPlan as c, FeatureItem as d, categorizeRateCards as f, formatPrice as g, formatMinorCurrencyAmount as h, planHasDefaultTaxBehavior as i, PlanEntitlements as l, formatStaticEntitlementConfig as m, PricingCard as n, taxBehaviorLegendSentence as o, formatTieredPriceBreakdown as p, collectDefaultTaxBehaviors as r, derivePriceFromPlan as s, PricingTable as t, QuotaItem as u, formatDurationAdjective as v, formatDurationInterval as y };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as formatDuration, a as subscriptionTaxLegendSentence, c as getPriceFromPlan, f as categorizeRateCards, g as formatPrice, h as formatMinorCurrencyAmount, i as planHasDefaultTaxBehavior, l as PlanEntitlements, m as formatStaticEntitlementConfig, p as formatTieredPriceBreakdown, t as PricingTable, v as formatDurationAdjective, y as formatDurationInterval } from "./PricingTable-Dsbd3E2Q.mjs";
|
|
2
2
|
import { Suspense, createContext, use, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { cn, createPlugin, joinUrl, throwIfProblemJson } from "zudoku";
|
|
4
4
|
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";
|
|
@@ -517,26 +517,23 @@ const PricingPageSkeleton = () => /* @__PURE__ */ jsxs("div", {
|
|
|
517
517
|
className: "text-center space-y-4 mb-12",
|
|
518
518
|
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-48 mx-auto" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-96 mx-auto" })]
|
|
519
519
|
}), /* @__PURE__ */ jsx("div", {
|
|
520
|
-
className: "w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(
|
|
520
|
+
className: "w-full grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(200px,1fr))] justify-center gap-2",
|
|
521
521
|
children: [
|
|
522
522
|
1,
|
|
523
523
|
2,
|
|
524
524
|
3
|
|
525
|
-
].map((i) => /* @__PURE__ */ jsxs(Card, {
|
|
526
|
-
className: "
|
|
527
|
-
children: [/* @__PURE__ */
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
className: "
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
]
|
|
538
|
-
})]
|
|
539
|
-
}, i))
|
|
525
|
+
].map((i) => /* @__PURE__ */ jsxs(Card, { children: [/* @__PURE__ */ jsxs(CardHeader, {
|
|
526
|
+
className: "space-y-3",
|
|
527
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-24" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-32" })]
|
|
528
|
+
}), /* @__PURE__ */ jsxs(CardContent, {
|
|
529
|
+
className: "space-y-3",
|
|
530
|
+
children: [
|
|
531
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
|
|
532
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
|
|
533
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
534
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full mt-4" })
|
|
535
|
+
]
|
|
536
|
+
})] }, i))
|
|
540
537
|
})]
|
|
541
538
|
});
|
|
542
539
|
//#endregion
|
package/dist/pricing-ui.d.mts
CHANGED
|
@@ -281,6 +281,30 @@ declare const formatTieredPriceBreakdown: (opts: {
|
|
|
281
281
|
}) => string[] | undefined;
|
|
282
282
|
//#endregion
|
|
283
283
|
//#region src/utils/getPriceFromPlan.d.ts
|
|
284
|
+
/**
|
|
285
|
+
* Derive a (monthly, yearly) headline price from a plan's last phase by
|
|
286
|
+
* summing all `flat_fee` rate-card amounts and converting from the plan's
|
|
287
|
+
* `billingCadence` to a monthly equivalent.
|
|
288
|
+
*
|
|
289
|
+
* Returns `null` for either field when no value can be derived (no
|
|
290
|
+
* phases, or an unparseable / sub-day cadence). A flat-fee sum of 0
|
|
291
|
+
* returns `{ monthly: 0, yearly: 0 }` (Free).
|
|
292
|
+
*
|
|
293
|
+
* Useful for consumers whose source data doesn't already include
|
|
294
|
+
* pre-computed `monthlyPrice` / `yearlyPrice` — pass the result through
|
|
295
|
+
* (or rely on `getPriceFromPlan`'s built-in fallback).
|
|
296
|
+
*/
|
|
297
|
+
declare const derivePriceFromPlan: (plan: Plan) => {
|
|
298
|
+
monthly: number | null;
|
|
299
|
+
yearly: number | null;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Returns the monthly and yearly headline price for a plan. Prefers the
|
|
303
|
+
* server-provided `monthlyPrice` / `yearlyPrice` strings when present;
|
|
304
|
+
* otherwise falls back to {@link derivePriceFromPlan}. Values that can't
|
|
305
|
+
* be resolved are reported as `0`, which the pricing card renders as
|
|
306
|
+
* "Free".
|
|
307
|
+
*/
|
|
284
308
|
declare const getPriceFromPlan: (plan: Plan) => {
|
|
285
309
|
monthly: number;
|
|
286
310
|
yearly: number;
|
|
@@ -293,4 +317,4 @@ declare const collectDefaultTaxBehaviors: (plan: Plan) => CanonicalTaxBehavior;
|
|
|
293
317
|
declare const taxBehaviorLegendSentence: (behavior: string) => string | undefined;
|
|
294
318
|
declare const subscriptionTaxLegendSentence: (behavior: string) => string | undefined;
|
|
295
319
|
//#endregion
|
|
296
|
-
export { type Alignment, type BooleanEntitlementTemplate, type DynamicPrice, type EntitlementTemplate, type Feature, FeatureItem, type FlatFeeRateCard, type FlatPrice, type MeteredEntitlementTemplate, type PackagePrice, type Plan, type PlanDefaultTaxConfig, PlanEntitlements, type PlanPhase, type Price, type PriceTier, PricingCard, type PricingCardProps, PricingTable, type PricingTableProps, type ProRatingConfig, type Quota, QuotaItem, type RateCard, type StaticEntitlementTemplate, type TieredPrice, type TieredPriceBreakdownTier, type UnitPrice, type UsageBasedRateCard, type ValidationError, categorizeRateCards, collectDefaultTaxBehaviors, formatDuration, formatDurationAdjective, formatDurationInterval, formatMinorCurrencyAmount, formatPrice, formatStaticEntitlementConfig, formatTieredPriceBreakdown, getPriceFromPlan, planHasDefaultTaxBehavior, subscriptionTaxLegendSentence, taxBehaviorLegendSentence };
|
|
320
|
+
export { type Alignment, type BooleanEntitlementTemplate, type DynamicPrice, type EntitlementTemplate, type Feature, FeatureItem, type FlatFeeRateCard, type FlatPrice, type MeteredEntitlementTemplate, type PackagePrice, type Plan, type PlanDefaultTaxConfig, PlanEntitlements, type PlanPhase, type Price, type PriceTier, PricingCard, type PricingCardProps, PricingTable, type PricingTableProps, type ProRatingConfig, type Quota, QuotaItem, type RateCard, type StaticEntitlementTemplate, type TieredPrice, type TieredPriceBreakdownTier, type UnitPrice, type UsageBasedRateCard, type ValidationError, categorizeRateCards, collectDefaultTaxBehaviors, derivePriceFromPlan, formatDuration, formatDurationAdjective, formatDurationInterval, formatMinorCurrencyAmount, formatPrice, formatStaticEntitlementConfig, formatTieredPriceBreakdown, getPriceFromPlan, planHasDefaultTaxBehavior, subscriptionTaxLegendSentence, taxBehaviorLegendSentence };
|
package/dist/pricing-ui.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
export { FeatureItem, PlanEntitlements, PricingCard, PricingTable, QuotaItem, categorizeRateCards, collectDefaultTaxBehaviors, formatDuration, formatDurationAdjective, formatDurationInterval, formatMinorCurrencyAmount, formatPrice, formatStaticEntitlementConfig, formatTieredPriceBreakdown, getPriceFromPlan, planHasDefaultTaxBehavior, subscriptionTaxLegendSentence, taxBehaviorLegendSentence };
|
|
1
|
+
import { _ as formatDuration, a as subscriptionTaxLegendSentence, c as getPriceFromPlan, d as FeatureItem, f as categorizeRateCards, g as formatPrice, h as formatMinorCurrencyAmount, i as planHasDefaultTaxBehavior, l as PlanEntitlements, m as formatStaticEntitlementConfig, n as PricingCard, o as taxBehaviorLegendSentence, p as formatTieredPriceBreakdown, r as collectDefaultTaxBehaviors, s as derivePriceFromPlan, t as PricingTable, u as QuotaItem, v as formatDurationAdjective, y as formatDurationInterval } from "./PricingTable-Dsbd3E2Q.mjs";
|
|
2
|
+
export { FeatureItem, PlanEntitlements, PricingCard, PricingTable, QuotaItem, categorizeRateCards, collectDefaultTaxBehaviors, derivePriceFromPlan, formatDuration, formatDurationAdjective, formatDurationInterval, formatMinorCurrencyAmount, formatPrice, formatStaticEntitlementConfig, formatTieredPriceBreakdown, getPriceFromPlan, planHasDefaultTaxBehavior, subscriptionTaxLegendSentence, taxBehaviorLegendSentence };
|
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.37",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/zuplo/zudoku",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"clsx": "2.1.1",
|
|
27
|
-
"tailwind-merge": "3.
|
|
27
|
+
"tailwind-merge": "3.6.0",
|
|
28
28
|
"tinyduration": "3.4.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|