Skip to content

Commit b3b19df

Browse files
authored
Merge pull request #2662 from appwrite/disable-free-when-applicable
2 parents f6b29f2 + fe7fdeb commit b3b19df

3 files changed

Lines changed: 57 additions & 40 deletions

File tree

src/lib/components/billing/planSelection.svelte

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { BillingPlan } from '$lib/constants';
33
import { formatCurrency } from '$lib/helpers/numbers';
44
import { currentPlan, organization } from '$lib/stores/organization';
5-
import { Badge, Layout, Typography } from '@appwrite.io/pink-svelte';
5+
import { Badge, Layout, Tooltip, Typography } from '@appwrite.io/pink-svelte';
66
import { LabelCard } from '..';
77
import type { Plan } from '$lib/sdk/billing';
88
import { page } from '$app/state';
@@ -17,31 +17,42 @@
1717
1818
// experiment to remove scale plan temporarily
1919
$: plansWithoutScale = plans.filter((plan) => plan.$id != BillingPlan.SCALE);
20+
21+
function shouldShowTooltip(plan: Plan) {
22+
if (plan.$id !== BillingPlan.FREE) return true;
23+
else return !anyOrgFree;
24+
}
2025
</script>
2126

2227
<Layout.Stack>
2328
{#each plansWithoutScale as plan}
24-
<LabelCard
25-
name="plan"
26-
bind:group={billingPlan}
27-
disabled={!selfService || (plan.$id === BillingPlan.FREE && anyOrgFree)}
28-
tooltipShow={plan.$id === BillingPlan.FREE && anyOrgFree}
29-
value={plan.$id}
30-
title={plan.name}>
31-
<svelte:fragment slot="action">
32-
{#if $organization?.billingPlan === plan.$id && !isNewOrg}
33-
<Badge variant="secondary" size="xs" content="Current plan" />
34-
{/if}
29+
<Tooltip disabled={shouldShowTooltip(plan)} maxWidth="fit-content">
30+
<LabelCard
31+
name="plan"
32+
bind:group={billingPlan}
33+
disabled={!selfService || (plan.$id === BillingPlan.FREE && anyOrgFree)}
34+
tooltipShow={plan.$id === BillingPlan.FREE && anyOrgFree}
35+
value={plan.$id}
36+
title={plan.name}>
37+
<svelte:fragment slot="action">
38+
{#if $organization?.billingPlan === plan.$id && !isNewOrg}
39+
<Badge variant="secondary" size="xs" content="Current plan" />
40+
{/if}
41+
</svelte:fragment>
42+
<Typography.Caption variant="400">
43+
{plan.desc}
44+
</Typography.Caption>
45+
<Typography.Text>
46+
{@const isZeroPrice = (plan.price ?? 0) <= 0}
47+
{@const price = formatCurrency(plan.price ?? 0)}
48+
{isZeroPrice ? price : `${price} per month + usage`}
49+
</Typography.Text>
50+
</LabelCard>
51+
52+
<svelte:fragment slot="tooltip">
53+
Only 1 free organization is allowed per account.
3554
</svelte:fragment>
36-
<Typography.Caption variant="400">
37-
{plan.desc}
38-
</Typography.Caption>
39-
<Typography.Text>
40-
{@const isZeroPrice = (plan.price ?? 0) <= 0}
41-
{@const price = formatCurrency(plan.price ?? 0)}
42-
{isZeroPrice ? price : `${price} per month + usage`}
43-
</Typography.Text>
44-
</LabelCard>
55+
</Tooltip>
4556
{/each}
4657
{#if $currentPlan && !currentPlanInList}
4758
<LabelCard

src/routes/(console)/create-organization/+page.svelte

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import { afterNavigate, goto, invalidate, preloadData } from '$app/navigation';
3-
import { base } from '$app/paths';
3+
import { base, resolve } from '$app/paths';
44
import { page } from '$app/state';
55
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
66
import { PlanComparisonBox, PlanSelection, SelectPaymentMethod } from '$lib/components/billing';
@@ -20,25 +20,26 @@
2020
import { writable } from 'svelte/store';
2121
import EstimatedTotalBox from '$lib/components/billing/estimatedTotalBox.svelte';
2222
import { onMount } from 'svelte';
23+
import type { PageProps } from './$types';
2324
24-
export let data;
25+
const { data }: PageProps = $props();
2526
26-
let selectedPlan: BillingPlan = data.plan as BillingPlan;
27-
let selectedCoupon: Partial<Coupon> | null = data.coupon;
28-
let previousPage: string = base;
29-
let showExitModal = false;
27+
let showExitModal = $state(false);
28+
let previousPage: string = $state(resolve('/(console)'));
29+
let selectedPlan: BillingPlan = $state(data.plan as BillingPlan);
30+
let selectedCoupon: Partial<Coupon> | null = $state(data.coupon);
3031
31-
let formComponent: Form;
32-
let isSubmitting = writable(false);
32+
let isSubmitting = $state(writable(false));
33+
let formComponent: Form | null = $state(null);
3334
34-
let name: string;
35-
let billingPlan: BillingPlan = BillingPlan.FREE;
36-
let paymentMethodId: string;
37-
let collaborators: string[] = [];
38-
let taxId: string;
35+
let name: string | null = $state(null);
36+
let taxId: string | null = $state(null);
37+
let collaborators: string[] = $state([]);
38+
let paymentMethodId: string | null = $state(null);
39+
let billingPlan: BillingPlan = $state(BillingPlan.FREE);
3940
40-
let billingBudget: number;
41-
let showCreditModal = false;
41+
let showCreditModal = $state(false);
42+
let billingBudget: number | undefined = $state(undefined);
4243
4344
afterNavigate(({ from }) => {
4445
previousPage = from?.url?.pathname || previousPage;
@@ -48,8 +49,7 @@
4849
if (page.url.searchParams.has('coupon')) {
4950
const coupon = page.url.searchParams.get('coupon');
5051
try {
51-
const response = await sdk.forConsole.billing.getCouponAccount(coupon);
52-
selectedCoupon = response;
52+
selectedCoupon = await sdk.forConsole.billing.getCouponAccount(coupon);
5353
} catch (e) {
5454
selectedCoupon = {
5555
code: null,
@@ -200,7 +200,10 @@
200200
>.
201201
</Typography.Text>
202202

203-
<PlanSelection bind:billingPlan={selectedPlan} isNewOrg />
203+
<PlanSelection
204+
isNewOrg
205+
bind:billingPlan={selectedPlan}
206+
anyOrgFree={data.hasFreeOrganizations} />
204207
</Layout.Stack>
205208
</Fieldset>
206209
{#if selectedPlan !== BillingPlan.FREE}

src/routes/(console)/organization-[organization]/change-plan/+page.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,10 @@
324324
</Alert.Inline>
325325
{/if}
326326

327-
<PlanSelection bind:billingPlan={selectedPlan} selfService={data.selfService} />
327+
<PlanSelection
328+
anyOrgFree={data.hasFreeOrgs}
329+
selfService={data.selfService}
330+
bind:billingPlan={selectedPlan} />
328331

329332
{#if isDowngrade && selectedPlan === BillingPlan.FREE && data.hasFreeOrgs}
330333
<Alert.Inline

0 commit comments

Comments
 (0)