Skip to content

Commit 4d440b2

Browse files
authored
Fix custom plan names displaying as "Free" on account organizations page (#2545)
Ensure the custom plan name is used by: - Changing default return value from tierFree to tierCustom for unknown tiers - Fetching plan name for custom plans
1 parent 0cbd9ef commit 4d440b2

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

src/lib/stores/billing.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function tierToPlan(tier: Tier) {
100100
case BillingPlan.ENTERPRISE:
101101
return tierEnterprise;
102102
default:
103-
return tierFree;
103+
return tierCustom;
104104
}
105105
}
106106

src/routes/(console)/account/organizations/+page.svelte

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
import { sdk } from '$lib/stores/sdk';
1414
import type { PageData } from './$types';
1515
import { isCloud } from '$lib/system';
16-
import { Badge } from '@appwrite.io/pink-svelte';
16+
import { Badge, Skeleton } from '@appwrite.io/pink-svelte';
1717
import type { Models } from '@appwrite.io/console';
1818
import type { Organization } from '$lib/stores/organization';
19-
import { daysLeftInTrial, plansInfo, tierToPlan } from '$lib/stores/billing';
19+
import { daysLeftInTrial, plansInfo, tierToPlan, type Tier } from '$lib/stores/billing';
2020
import { toLocaleDate } from '$lib/helpers/date';
2121
import { BillingPlan } from '$lib/constants';
2222
import { goto } from '$app/navigation';
@@ -36,6 +36,27 @@
3636
return memberships.memberships.map((team) => team.userName || team.userEmail);
3737
}
3838
39+
async function getPlanName(billingPlan: string | undefined): Promise<string> {
40+
if (!billingPlan) return 'Unknown';
41+
42+
// For known plans, use tierToPlan
43+
const tierData = tierToPlan(billingPlan as Tier);
44+
45+
// If it's not a custom plan or we got a non-custom result, return the name
46+
if (tierData.name !== 'Custom') {
47+
return tierData.name;
48+
}
49+
50+
// For custom plans, fetch from API
51+
try {
52+
const plan = await sdk.forConsole.billing.getPlan(billingPlan);
53+
return plan.name;
54+
} catch (error) {
55+
// Fallback to 'Custom' if fetch fails
56+
return 'Custom';
57+
}
58+
}
59+
3960
function isOrganizationOnTrial(organization: Organization): boolean {
4061
if (!organization?.billingTrialStartDate) return false;
4162
if ($daysLeftInTrial <= 0) return false;
@@ -92,6 +113,9 @@
92113
{#each data.organizations.teams as organization}
93114
{@const avatarList = getMemberships(organization.$id)}
94115
{@const payingOrg = isPayingOrganization(organization)}
116+
{@const planName = isCloudOrg(organization)
117+
? getPlanName(organization.billingPlan)
118+
: null}
95119

96120
<GridItem1 href={`${base}/organization-${organization.$id}`}>
97121
<svelte:fragment slot="eyebrow">
@@ -104,16 +128,19 @@
104128
<svelte:fragment slot="status">
105129
{#if isCloudOrg(organization)}
106130
{#if isNonPayingOrganization(organization)}
107-
<Tooltip>
108-
<Badge
109-
size="xs"
110-
variant="secondary"
111-
content={tierToPlan(organization?.billingPlan)?.name} />
112-
113-
<span slot="tooltip">
114-
You are limited to 1 free organization per account
115-
</span>
116-
</Tooltip>
131+
{#if planName}
132+
{#await planName}
133+
<Skeleton width={30} height={20} variant="line" />
134+
{:then name}
135+
<Tooltip>
136+
<Badge size="xs" variant="secondary" content={name} />
137+
138+
<span slot="tooltip">
139+
You are limited to 1 free organization per account
140+
</span>
141+
</Tooltip>
142+
{/await}
143+
{/if}
117144
{/if}
118145

119146
{#if isOrganizationOnTrial(organization)}
@@ -132,16 +159,20 @@
132159
{/if}
133160

134161
{#if payingOrg}
135-
<Badge
136-
size="xs"
137-
type="success"
138-
variant="secondary"
139-
content={tierToPlan(payingOrg?.billingPlan)?.name} />
162+
{#await planName}
163+
<Skeleton width={30} height={20} variant="line" />
164+
{:then name}
165+
<Badge
166+
size="xs"
167+
type="success"
168+
variant="secondary"
169+
content={name} />
170+
{/await}
140171
{/if}
141172
{/if}
142173
</svelte:fragment>
143174
{#await avatarList}
144-
<span class="avatar is-color-empty"></span>
175+
<Skeleton width={40} height={40} variant="circle" />
145176
{:then avatars}
146177
<AvatarGroup {avatars} />
147178
{/await}

0 commit comments

Comments
 (0)