From fe7fdeb5fd39f680a76c88defd727ff681b4ade6 Mon Sep 17 00:00:00 2001 From: Darshan Date: Tue, 2 Dec 2025 14:20:51 +0530 Subject: [PATCH] fix: disable free plan in selection if one already exists. --- .../components/billing/planSelection.svelte | 53 +++++++++++-------- .../create-organization/+page.svelte | 39 +++++++------- .../change-plan/+page.svelte | 5 +- 3 files changed, 57 insertions(+), 40 deletions(-) diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte index 0e194f9b6..6499a47c0 100644 --- a/src/lib/components/billing/planSelection.svelte +++ b/src/lib/components/billing/planSelection.svelte @@ -2,7 +2,7 @@ import { BillingPlan } from '$lib/constants'; import { formatCurrency } from '$lib/helpers/numbers'; import { currentPlan, organization } from '$lib/stores/organization'; - import { Badge, Layout, Typography } from '@appwrite.io/pink-svelte'; + import { Badge, Layout, Tooltip, Typography } from '@appwrite.io/pink-svelte'; import { LabelCard } from '..'; import type { Plan } from '$lib/sdk/billing'; import { page } from '$app/state'; @@ -17,31 +17,42 @@ // experiment to remove scale plan temporarily $: plansWithoutScale = plans.filter((plan) => plan.$id != BillingPlan.SCALE); + + function shouldShowTooltip(plan: Plan) { + if (plan.$id !== BillingPlan.FREE) return true; + else return !anyOrgFree; + } {#each plansWithoutScale as plan} - - - {#if $organization?.billingPlan === plan.$id && !isNewOrg} - - {/if} + + + + {#if $organization?.billingPlan === plan.$id && !isNewOrg} + + {/if} + + + {plan.desc} + + + {@const isZeroPrice = (plan.price ?? 0) <= 0} + {@const price = formatCurrency(plan.price ?? 0)} + {isZeroPrice ? price : `${price} per month + usage`} + + + + + Only 1 free organization is allowed per account. - - {plan.desc} - - - {@const isZeroPrice = (plan.price ?? 0) <= 0} - {@const price = formatCurrency(plan.price ?? 0)} - {isZeroPrice ? price : `${price} per month + usage`} - - + {/each} {#if $currentPlan && !currentPlanInList} import { afterNavigate, goto, invalidate, preloadData } from '$app/navigation'; - import { base } from '$app/paths'; + import { base, resolve } from '$app/paths'; import { page } from '$app/state'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { PlanComparisonBox, PlanSelection, SelectPaymentMethod } from '$lib/components/billing'; @@ -20,25 +20,26 @@ import { writable } from 'svelte/store'; import EstimatedTotalBox from '$lib/components/billing/estimatedTotalBox.svelte'; import { onMount } from 'svelte'; + import type { PageProps } from './$types'; - export let data; + const { data }: PageProps = $props(); - let selectedPlan: BillingPlan = data.plan as BillingPlan; - let selectedCoupon: Partial | null = data.coupon; - let previousPage: string = base; - let showExitModal = false; + let showExitModal = $state(false); + let previousPage: string = $state(resolve('/(console)')); + let selectedPlan: BillingPlan = $state(data.plan as BillingPlan); + let selectedCoupon: Partial | null = $state(data.coupon); - let formComponent: Form; - let isSubmitting = writable(false); + let isSubmitting = $state(writable(false)); + let formComponent: Form | null = $state(null); - let name: string; - let billingPlan: BillingPlan = BillingPlan.FREE; - let paymentMethodId: string; - let collaborators: string[] = []; - let taxId: string; + let name: string | null = $state(null); + let taxId: string | null = $state(null); + let collaborators: string[] = $state([]); + let paymentMethodId: string | null = $state(null); + let billingPlan: BillingPlan = $state(BillingPlan.FREE); - let billingBudget: number; - let showCreditModal = false; + let showCreditModal = $state(false); + let billingBudget: number | undefined = $state(undefined); afterNavigate(({ from }) => { previousPage = from?.url?.pathname || previousPage; @@ -48,8 +49,7 @@ if (page.url.searchParams.has('coupon')) { const coupon = page.url.searchParams.get('coupon'); try { - const response = await sdk.forConsole.billing.getCouponAccount(coupon); - selectedCoupon = response; + selectedCoupon = await sdk.forConsole.billing.getCouponAccount(coupon); } catch (e) { selectedCoupon = { code: null, @@ -200,7 +200,10 @@ >. - + {#if selectedPlan !== BillingPlan.FREE} diff --git a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte index ac5d47b75..8d4e7110a 100644 --- a/src/routes/(console)/organization-[organization]/change-plan/+page.svelte +++ b/src/routes/(console)/organization-[organization]/change-plan/+page.svelte @@ -324,7 +324,10 @@ {/if} - + {#if isDowngrade && selectedPlan === BillingPlan.FREE && data.hasFreeOrgs}