From 66d2c76a756f5ac19b9628ceb974a5d29f94074f Mon Sep 17 00:00:00 2001
From: Arman
Date: Mon, 15 Jul 2024 15:13:01 +0200
Subject: [PATCH 01/19] refactor plan selection + add scale plan + fix copy and
edge cases
---
src/lib/components/billing/index.ts | 1 +
.../components/billing/planSelection.svelte | 91 +++++++++++++++++++
src/lib/stores/billing.ts | 2 +-
.../console/create-organization/+page.svelte | 59 ++----------
.../change-plan/+page.svelte | 75 ++++-----------
.../usage/[[invoice]]/totalMembers.svelte | 2 +-
6 files changed, 116 insertions(+), 114 deletions(-)
create mode 100644 src/lib/components/billing/planSelection.svelte
diff --git a/src/lib/components/billing/index.ts b/src/lib/components/billing/index.ts
index b8aac8ada..266d217d8 100644
--- a/src/lib/components/billing/index.ts
+++ b/src/lib/components/billing/index.ts
@@ -6,3 +6,4 @@ export { default as EstimatedTotalBox } from './estimatedTotalBox.svelte';
export { default as PlanComparisonBox } from './planComparisonBox.svelte';
export { default as EmptyCardCloud } from './emptyCardCloud.svelte';
export { default as CreditsApplied } from './creditsApplied.svelte';
+export { default as PlanSelection } from './planSelection.svelte';
diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte
new file mode 100644
index 000000000..cc35079dd
--- /dev/null
+++ b/src/lib/components/billing/planSelection.svelte
@@ -0,0 +1,91 @@
+
+
+{#if billingPlan}
+
+ -
+
+
+
+
+ {tierFree.name}
+ {#if $organization?.billingPlan === BillingPlan.FREE && !isNewOrg}
+ Current plan
+ {/if}
+
+
+ {tierFree.description}
+
+
+ {formatCurrency(freePlan?.price ?? 0)}
+
+
+
+
+
+
+ -
+
+
+
+
+ {tierPro.name}
+ {#if $organization?.billingPlan === BillingPlan.PRO && !isNewOrg}
+ Current plan
+ {/if}
+
+
+ {tierPro.description}
+
+
+ {formatCurrency(proPlan?.price ?? 0)} per member/month + usage
+
+
+
+
+
+ -
+
+
+
+
+ {tierScale.name}
+ {#if $organization?.billingPlan === BillingPlan.SCALE && !isNewOrg}
+ Current plan
+ {/if}
+
+
+ {tierScale.description}
+
+
+ {formatCurrency(scalePlan?.price ?? 0)} per organization/month + usage
+
+
+
+
+
+
+{/if}
diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts
index 5e54db955..0273dd5d0 100644
--- a/src/lib/stores/billing.ts
+++ b/src/lib/stores/billing.ts
@@ -150,7 +150,7 @@ export const tierPro: TierData = {
};
export const tierScale: TierData = {
name: 'Scale',
- description: 'For scaling teams that need dedicated support.'
+ description: 'For scaling teams and agencies that need dedicated support.'
};
export const showUsageRatesModal = writable(false);
diff --git a/src/routes/console/create-organization/+page.svelte b/src/routes/console/create-organization/+page.svelte
index e7ac26659..b83d5590a 100644
--- a/src/routes/console/create-organization/+page.svelte
+++ b/src/routes/console/create-organization/+page.svelte
@@ -3,16 +3,15 @@
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
- import { LabelCard } from '$lib/components';
import {
EstimatedTotalBox,
PlanComparisonBox,
+ PlanSelection,
SelectPaymentMethod
} from '$lib/components/billing';
import ValidateCreditModal from '$lib/components/billing/validateCreditModal.svelte';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Button, Form, FormList, InputTags, InputText, Label } from '$lib/elements/forms';
- import { formatCurrency } from '$lib/helpers/numbers';
import {
WizardSecondaryContainer,
WizardSecondaryContent,
@@ -20,7 +19,7 @@
WizardSecondaryHeader
} from '$lib/layout';
import type { Coupon, PaymentList } from '$lib/sdk/billing';
- import { plansInfo, tierFree, tierPro, tierToPlan } from '$lib/stores/billing';
+ import { tierToPlan } from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import { organizationList, type Organization } from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
@@ -80,7 +79,7 @@
billingPlan = plan as BillingPlan;
}
}
- if (anyOrgFree) {
+ if (!!anyOrgFree) {
billingPlan = BillingPlan.PRO;
}
});
@@ -175,8 +174,6 @@
}
}
- $: freePlan = $plansInfo.get(BillingPlan.FREE);
- $: proPlan = $plansInfo.get(BillingPlan.PRO);
$: if (billingPlan === BillingPlan.PRO) {
loadPaymentMethods();
}
@@ -205,53 +202,9 @@
For more details on our plans, visit our
.
-
- -
-
-
-
-
- {tierFree.name}
-
-
{tierFree.description}
-
- {formatCurrency(freePlan?.price ?? 0)}
-
-
-
-
-
-
- -
-
-
-
-
- {tierPro.name}
-
-
- {tierPro.description}
-
-
- {formatCurrency(proPlan?.price ?? 0)} per member/month + usage
-
-
-
-
-
-
- {#if billingPlan === BillingPlan.PRO}
-
+
+ {#if billingPlan !== BillingPlan.FREE}
+
$organization.billingPlan;
$: isDowngrade = billingPlan < $organization.billingPlan;
- $: freePlan = $plansInfo.get(BillingPlan.FREE);
- $: proPlan = $plansInfo.get(BillingPlan.PRO);
$: if (billingPlan === BillingPlan.PRO) {
loadPaymentMethods();
}
@@ -261,7 +263,7 @@
For more details on our plans, visit our
.
- {#if anyOrgFree && billingPlan === BillingPlan.PRO}
+ {#if anyOrgFree && billingPlan !== BillingPlan.FREE}
You are limited to one {tierToPlan(BillingPlan.FREE).name} organization per account.
Consider upgrading or deleting
{/if}
-
- -
-
-
-
-
- {tierFree.name}
- {#if $organization.billingPlan === BillingPlan.FREE}
- Current plan
- {/if}
-
-
{tierFree.description}
-
- {formatCurrency(freePlan?.price ?? 0)}
-
-
-
-
-
+
- -
-
-
-
-
- {tierPro.name}
- {#if $organization.billingPlan === BillingPlan.PRO}
- Current plan
- {/if}
-
-
- {tierPro.description}
-
-
- {formatCurrency(proPlan?.price ?? 0)} per member/month + usage
-
-
-
-
-
-
{#if isDowngrade}
{/if}
- {#if billingPlan === BillingPlan.PRO && $organization.billingPlan !== BillingPlan.PRO}
+ {#if billingPlan !== BillingPlan.FREE && $organization.billingPlan === BillingPlan.FREE}
From e1132df1ae4bee896f85bd0b2b552ebe6cf5fcad Mon Sep 17 00:00:00 2001
From: Arman
Date: Mon, 15 Jul 2024 15:30:37 +0200
Subject: [PATCH 02/19] fix: add-ons displaying when they shouldn't
---
.../organization-[organization]/billing/planSummary.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/routes/console/organization-[organization]/billing/planSummary.svelte b/src/routes/console/organization-[organization]/billing/planSummary.svelte
index 81edb295e..04d1aa258 100644
--- a/src/routes/console/organization-[organization]/billing/planSummary.svelte
+++ b/src/routes/console/organization-[organization]/billing/planSummary.svelte
@@ -58,7 +58,7 @@
{isTrial ? formatCurrency(0) : formatCurrency(currentPlan?.price)}
- {#if $organization?.billingPlan !== BillingPlan.FREE && extraUsage}
+ {#if $organization?.billingPlan !== BillingPlan.FREE && extraUsage > 0}
Add-ons
Date: Mon, 15 Jul 2024 17:21:40 +0200
Subject: [PATCH 03/19] feat: edgecases
---
.../billing/planComparisonBox.svelte | 36 +++++++++++++------
src/lib/components/billing/planExcess.svelte | 3 +-
src/routes/console/apply-credit/+page.svelte | 2 +-
.../console/create-organization/+page.svelte | 2 +-
.../change-plan/+page.svelte | 22 +++++++++---
.../createMember.svelte | 2 +-
6 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/src/lib/components/billing/planComparisonBox.svelte b/src/lib/components/billing/planComparisonBox.svelte
index ce1abe329..5db0ded16 100644
--- a/src/lib/components/billing/planComparisonBox.svelte
+++ b/src/lib/components/billing/planComparisonBox.svelte
@@ -1,9 +1,10 @@
diff --git a/src/routes/console/organization-[organization]/change-plan/+page.svelte b/src/routes/console/organization-[organization]/change-plan/+page.svelte
index 49dd83e23..fc7ba9d41 100644
--- a/src/routes/console/organization-[organization]/change-plan/+page.svelte
+++ b/src/routes/console/organization-[organization]/change-plan/+page.svelte
@@ -22,6 +22,7 @@
InputTextarea,
Label
} from '$lib/elements/forms';
+ import { formatCurrency } from '$lib/helpers/numbers.js';
import {
WizardSecondaryContainer,
WizardSecondaryContent,
@@ -29,7 +30,7 @@
WizardSecondaryHeader
} from '$lib/layout';
import { type Coupon, type PaymentList } from '$lib/sdk/billing';
- import { tierToPlan, type Tier } from '$lib/stores/billing';
+ import { plansInfo, tierToPlan, type Tier } from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import { organization, organizationList, type Organization } from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
@@ -242,7 +243,7 @@
$: isUpgrade = billingPlan > $organization.billingPlan;
$: isDowngrade = billingPlan < $organization.billingPlan;
- $: if (billingPlan === BillingPlan.PRO) {
+ $: if (billingPlan !== BillingPlan.FREE) {
loadPaymentMethods();
}
$: isButtonDisabled = $organization.billingPlan === billingPlan;
@@ -281,8 +282,21 @@
: ''} />
{#if isDowngrade}
-
+ {#if billingPlan === BillingPlan.FREE}
+
+ {:else if billingPlan === BillingPlan.PRO && $organization.billingPlan === BillingPlan.SCALE}
+ {@const members = collaborators?.length ?? 0}
+
+
+ Monthly payments are required for organization members on the Pro plan
+
+ On successful switching of your plan, you will be charged {formatCurrency(
+ members * ($plansInfo?.get(billingPlan)?.addons?.member?.price ?? 0)
+ )} monthly for {members} team members.
+
+ {/if}
{/if}
+
{#if billingPlan !== BillingPlan.FREE && $organization.billingPlan === BillingPlan.FREE}
{/if}
{/if}
- {#if !isUpgrade && billingPlan === BillingPlan.FREE && $organization.billingPlan !== BillingPlan.FREE}
+ {#if isDowngrade}
{#if $organization?.billingPlan === BillingPlan.SCALE}
- You can add unlimited organization members on the {plan.name} plan at no cost.
+ You can add unlimited organization members on the {plan.name} plan.
{:else if $organization?.billingPlan === BillingPlan.PRO}
You can add unlimited organization members on the {plan.name} plan for
{formatCurrency(plan.addons.member.price)} each per billing period.
From 19020636063cee9d031bc837dae57d0e7c3ad2af Mon Sep 17 00:00:00 2001
From: Arman
Date: Tue, 16 Jul 2024 11:31:05 +0200
Subject: [PATCH 04/19] fix: copy
---
.../organization-[organization]/change-plan/+page.svelte | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/routes/console/organization-[organization]/change-plan/+page.svelte b/src/routes/console/organization-[organization]/change-plan/+page.svelte
index fc7ba9d41..809c3dafb 100644
--- a/src/routes/console/organization-[organization]/change-plan/+page.svelte
+++ b/src/routes/console/organization-[organization]/change-plan/+page.svelte
@@ -288,11 +288,11 @@
{@const members = collaborators?.length ?? 0}
- Monthly payments are required for organization members on the Pro plan
+ Your monthly payments will be adjusted for the Pro plan
- On successful switching of your plan, you will be charged {formatCurrency(
+ After switching plans, you will be charged {formatCurrency(
members * ($plansInfo?.get(billingPlan)?.addons?.member?.price ?? 0)
- )} monthly for {members} team members.
+ )} monthly for {members} team members. This will be reflected in your next invoice.
{/if}
{/if}
From 43a957cd4c21ba0b530552a66e38eb4989014d20 Mon Sep 17 00:00:00 2001
From: Arman
Date: Tue, 16 Jul 2024 13:07:26 +0200
Subject: [PATCH 05/19] design fixes
---
src/lib/components/billing/planComparisonBox.svelte | 2 +-
src/lib/components/billing/planSelection.svelte | 11 ++++++-----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/lib/components/billing/planComparisonBox.svelte b/src/lib/components/billing/planComparisonBox.svelte
index 5db0ded16..1b223ebba 100644
--- a/src/lib/components/billing/planComparisonBox.svelte
+++ b/src/lib/components/billing/planComparisonBox.svelte
@@ -4,7 +4,7 @@
import { plansInfo, tierFree, tierPro, tierScale, type Tier } from '$lib/stores/billing';
import { Card, SecondaryTabs, SecondaryTabsItem } from '..';
- let selectedTab: Tier = 'tier-0';
+ let selectedTab: Tier = BillingPlan.FREE;
export let downgrade = false;
$: plan = $plansInfo.get(selectedTab);
diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte
index cc35079dd..c2af34653 100644
--- a/src/lib/components/billing/planSelection.svelte
+++ b/src/lib/components/billing/planSelection.svelte
@@ -23,9 +23,10 @@
name="plan"
bind:group={billingPlan}
disabled={anyOrgFree}
- value="tier-0"
+ value={BillingPlan.FREE}
tooltipShow={anyOrgFree}
- tooltipText="You are limited to 1 Free organization per account.">
+ tooltipText="You are limited to 1 Free organization per account."
+ padding={1.5}>
-
+
@@ -68,7 +69,7 @@
-
+
@@ -81,7 +82,7 @@
{tierScale.description}
- {formatCurrency(scalePlan?.price ?? 0)} per organization/month + usage
+ {formatCurrency(scalePlan?.price ?? 0)} per month + usage
From 73a72001e97be2f8bbd0a5535f43e00ca0ec1479 Mon Sep 17 00:00:00 2001
From: Arman
Date: Thu, 18 Jul 2024 18:01:16 +0200
Subject: [PATCH 06/19] fix: design review
---
.../billing/estimatedTotalBox.svelte | 5 +-
.../billing/planComparisonBox.svelte | 55 +++++++++++++------
.../change-plan/+page.svelte | 14 +++--
.../createMember.svelte | 10 ++--
4 files changed, 54 insertions(+), 30 deletions(-)
diff --git a/src/lib/components/billing/estimatedTotalBox.svelte b/src/lib/components/billing/estimatedTotalBox.svelte
index 3ff31041c..303e8de23 100644
--- a/src/lib/components/billing/estimatedTotalBox.svelte
+++ b/src/lib/components/billing/estimatedTotalBox.svelte
@@ -11,6 +11,7 @@
export let couponData: Partial;
export let billingBudget: number;
export let fixedCoupon = false; // If true, the coupon cannot be removed
+ export let isDowngrade = false;
const today = new Date();
const billingPayDate = new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000);
@@ -41,8 +42,8 @@
{formatCurrency(currentPlan.price)}
- Additional seats ({collaborators?.length})
-
+
Additional seats ({collaborators?.length})
+
{formatCurrency(extraSeatsCost)}
diff --git a/src/lib/components/billing/planComparisonBox.svelte b/src/lib/components/billing/planComparisonBox.svelte
index 1b223ebba..98f473ed4 100644
--- a/src/lib/components/billing/planComparisonBox.svelte
+++ b/src/lib/components/billing/planComparisonBox.svelte
@@ -11,23 +11,25 @@
-
- (selectedTab = BillingPlan.FREE)}>
- {tierFree.name}
-
- (selectedTab = BillingPlan.PRO)}>
- {tierPro.name}
-
- (selectedTab = BillingPlan.SCALE)}>
- {tierScale.name}
-
-
+
+
+ (selectedTab = BillingPlan.FREE)}>
+ {tierFree.name}
+
+ (selectedTab = BillingPlan.PRO)}>
+ {tierPro.name}
+
+ (selectedTab = BillingPlan.SCALE)}>
+ {tierScale.name}
+
+
+
{#if selectedTab === BillingPlan.FREE}
@@ -115,3 +117,22 @@
{/if}
+
+
diff --git a/src/routes/console/organization-[organization]/change-plan/+page.svelte b/src/routes/console/organization-[organization]/change-plan/+page.svelte
index 809c3dafb..ea2a6b9a5 100644
--- a/src/routes/console/organization-[organization]/change-plan/+page.svelte
+++ b/src/routes/console/organization-[organization]/change-plan/+page.svelte
@@ -290,9 +290,12 @@
Your monthly payments will be adjusted for the Pro plan
- After switching plans, you will be charged {formatCurrency(
- members * ($plansInfo?.get(billingPlan)?.addons?.member?.price ?? 0)
- )} monthly for {members} team members. This will be reflected in your next invoice.
+ After switching plans,
+ you will be charged {formatCurrency(
+ members * ($plansInfo?.get(billingPlan)?.addons?.member?.price ?? 0)
+ )} monthly for {members} team members. This will be reflected in your
+ next invoice.
{/if}
{/if}
@@ -337,12 +340,13 @@
{/if}
- {#if billingPlan !== BillingPlan.FREE && $organization.billingPlan !== BillingPlan.PRO}
+ {#if billingPlan !== BillingPlan.FREE && $organization.billingPlan !== billingPlan}
+ bind:billingBudget
+ {isDowngrade} />
{:else}
{/if}
diff --git a/src/routes/console/organization-[organization]/createMember.svelte b/src/routes/console/organization-[organization]/createMember.svelte
index 6e27e03ff..c3195a1f2 100644
--- a/src/routes/console/organization-[organization]/createMember.svelte
+++ b/src/routes/console/organization-[organization]/createMember.svelte
@@ -59,14 +59,12 @@
{#if isCloud}
-
- {#if $organization?.billingPlan === BillingPlan.SCALE}
- You can add unlimited organization members on the {plan.name} plan.
- {:else if $organization?.billingPlan === BillingPlan.PRO}
+ {#if $organization?.billingPlan === BillingPlan.PRO}
+
You can add unlimited organization members on the {plan.name} plan for
{formatCurrency(plan.addons.member.price)} each per billing period.
- {/if}
-
+
+ {/if}
{/if}
Date: Thu, 18 Jul 2024 18:08:25 +0200
Subject: [PATCH 07/19] fix: copy
---
src/lib/components/billing/planComparisonBox.svelte | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/lib/components/billing/planComparisonBox.svelte b/src/lib/components/billing/planComparisonBox.svelte
index 98f473ed4..6af1231f8 100644
--- a/src/lib/components/billing/planComparisonBox.svelte
+++ b/src/lib/components/billing/planComparisonBox.svelte
@@ -96,8 +96,8 @@
{/if}
{:else if selectedTab === BillingPlan.PRO}
{plan.name} plan
-
- - Everything in the Free plan, plus:
+ Everything in the Free plan, plus:
+
- Unlimited databases, buckets, functions
- {plan.bandwidth}GB bandwidth
- {plan.storage}GB storage
@@ -106,8 +106,8 @@
{:else if selectedTab === BillingPlan.SCALE}
{plan.name} plan
-
- - Everything in the Pro plan, plus:
+ Everything in the Pro plan, plus:
+