fix: disable free plan in selection if one already exists.

This commit is contained in:
Darshan
2025-12-02 14:20:51 +05:30
parent f6b29f2ac6
commit fe7fdeb5fd
3 changed files with 57 additions and 40 deletions
+32 -21
View File
@@ -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;
}
</script>
<Layout.Stack>
{#each plansWithoutScale as plan}
<LabelCard
name="plan"
bind:group={billingPlan}
disabled={!selfService || (plan.$id === BillingPlan.FREE && anyOrgFree)}
tooltipShow={plan.$id === BillingPlan.FREE && anyOrgFree}
value={plan.$id}
title={plan.name}>
<svelte:fragment slot="action">
{#if $organization?.billingPlan === plan.$id && !isNewOrg}
<Badge variant="secondary" size="xs" content="Current plan" />
{/if}
<Tooltip disabled={shouldShowTooltip(plan)} maxWidth="fit-content">
<LabelCard
name="plan"
bind:group={billingPlan}
disabled={!selfService || (plan.$id === BillingPlan.FREE && anyOrgFree)}
tooltipShow={plan.$id === BillingPlan.FREE && anyOrgFree}
value={plan.$id}
title={plan.name}>
<svelte:fragment slot="action">
{#if $organization?.billingPlan === plan.$id && !isNewOrg}
<Badge variant="secondary" size="xs" content="Current plan" />
{/if}
</svelte:fragment>
<Typography.Caption variant="400">
{plan.desc}
</Typography.Caption>
<Typography.Text>
{@const isZeroPrice = (plan.price ?? 0) <= 0}
{@const price = formatCurrency(plan.price ?? 0)}
{isZeroPrice ? price : `${price} per month + usage`}
</Typography.Text>
</LabelCard>
<svelte:fragment slot="tooltip">
Only 1 free organization is allowed per account.
</svelte:fragment>
<Typography.Caption variant="400">
{plan.desc}
</Typography.Caption>
<Typography.Text>
{@const isZeroPrice = (plan.price ?? 0) <= 0}
{@const price = formatCurrency(plan.price ?? 0)}
{isZeroPrice ? price : `${price} per month + usage`}
</Typography.Text>
</LabelCard>
</Tooltip>
{/each}
{#if $currentPlan && !currentPlanInList}
<LabelCard
@@ -1,6 +1,6 @@
<script lang="ts">
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<Coupon> | 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<Coupon> | 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 @@
>.
</Typography.Text>
<PlanSelection bind:billingPlan={selectedPlan} isNewOrg />
<PlanSelection
isNewOrg
bind:billingPlan={selectedPlan}
anyOrgFree={data.hasFreeOrganizations} />
</Layout.Stack>
</Fieldset>
{#if selectedPlan !== BillingPlan.FREE}
@@ -324,7 +324,10 @@
</Alert.Inline>
{/if}
<PlanSelection bind:billingPlan={selectedPlan} selfService={data.selfService} />
<PlanSelection
anyOrgFree={data.hasFreeOrgs}
selfService={data.selfService}
bind:billingPlan={selectedPlan} />
{#if isDowngrade && selectedPlan === BillingPlan.FREE && data.hasFreeOrgs}
<Alert.Inline