diff --git a/Assets/WebsiteAssets/css/site.css b/Assets/WebsiteAssets/css/site.css index 67742b1618..ad54a6ffff 100644 --- a/Assets/WebsiteAssets/css/site.css +++ b/Assets/WebsiteAssets/css/site.css @@ -1212,6 +1212,13 @@ footer .bottom-links-row p { margin-top: 2em; } +.price-container p.pricing-table-billed-annually { + font-size: 14px; + font-style: italic; + opacity: 0.7; + margin-top: 0.5em; +} + .price-row { display: flex; flex-direction: row; diff --git a/Assets/WebsiteAssets/templates/partials/plan.mustache b/Assets/WebsiteAssets/templates/partials/plan.mustache index 2145a78ae3..b784ff4a42 100644 --- a/Assets/WebsiteAssets/templates/partials/plan.mustache +++ b/Assets/WebsiteAssets/templates/partials/plan.mustache @@ -40,12 +40,16 @@ {{#pricingTable}} Pricing
| Users | Price |
|---|---|
| {{condition}} | {{priceYearly}} |
| {{condition}} | {{priceMonthly}} |
{{billedAnnually}}
{{/pricingTable}}
diff --git a/packages/lib/utils/joplinCloud/index.ts b/packages/lib/utils/joplinCloud/index.ts
index 3b0d61432d..120aded0df 100644
--- a/packages/lib/utils/joplinCloud/index.ts
+++ b/packages/lib/utils/joplinCloud/index.ts
@@ -40,7 +40,7 @@ enum PlanHostingType {
export interface PlanTieredPricingTableRow {
condition: string;
- priceYearly: string;
+ priceMonthly: string;
}
export interface Plan {
@@ -48,7 +48,7 @@ export interface Plan {
title: string;
priceMonthly?: StripePublicConfigPrice;
priceYearly?: StripePublicConfigPrice;
- pricingTable?: { rows: PlanTieredPricingTableRow[] };
+ pricingTable?: { rows: PlanTieredPricingTableRow[]; billedAnnually: string };
featured: boolean;
iconName: string;
featuresOn: FeatureId[];
@@ -578,24 +578,32 @@ export const createFeatureTableMd = () => {
const getTieredPricingTable = (price: StripePublicConfigPrice) => {
if (!isTieredPrice(price)) throw new Error(`Not a tiered price: ${price.id}`);
+ const formatUserCount = (count: number) => {
+ if (count === Number.POSITIVE_INFINITY) {
+ return '∞';
+ }
+ return String(count);
+ };
+
const rows: PlanTieredPricingTableRow[] = [];
for (const amount of price.amounts) {
- const formatUserCount = (count: number) => {
- if (count === Number.POSITIVE_INFINITY) {
- return '∞';
- }
- return String(count);
- };
+ // The tiered amounts are yearly per-user prices, so derive the monthly
+ // price shown in the table by dividing by 12.
+ const monthlyAmount = formatPrice(Math.round(Number(amount.amount) / 12 * 100) / 100, price.currency);
rows.push({
condition: `${
formatUserCount(amount.userRange.min)
}—${
formatUserCount(amount.userRange.max)
} users`,
- priceYearly: `${amount.formattedAmount} / user / year`,
+ priceMonthly: `${monthlyAmount} / user / month`,
});
}
- return rows;
+
+ const yearlyAmounts = price.amounts.map(amount => amount.formattedAmount).join(' / ');
+ const billedAnnually = _('Billed annually (%s per user per year respectively).', yearlyAmounts);
+
+ return { rows, billedAnnually };
};
export function getPlans(stripeConfig: StripePublicConfig): Record