Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/stores/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export function tierToPlan(tier: Tier) {
case BillingPlan.ENTERPRISE:
return tierEnterprise;
default:
return tierFree;
return tierCustom;
}
}

Expand Down
59 changes: 43 additions & 16 deletions src/routes/(console)/account/organizations/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { Badge } from '@appwrite.io/pink-svelte';
import type { Models } from '@appwrite.io/console';
import type { Organization } from '$lib/stores/organization';
import { daysLeftInTrial, plansInfo, tierToPlan } from '$lib/stores/billing';
import { daysLeftInTrial, plansInfo, tierToPlan, type Tier } from '$lib/stores/billing';
import { toLocaleDate } from '$lib/helpers/date';
import { BillingPlan } from '$lib/constants';
import { goto } from '$app/navigation';
Expand All @@ -36,6 +36,27 @@
return memberships.memberships.map((team) => team.userName || team.userEmail);
}
async function getPlanName(billingPlan: string | undefined): Promise<string> {
if (!billingPlan) return 'Unknown';
// For known plans, use tierToPlan
const tierData = tierToPlan(billingPlan as Tier);
// If it's not a custom plan or we got a non-custom result, return the name
if (tierData.name !== 'Custom') {
return tierData.name;
}
// For custom plans, fetch from API
try {
const plan = await sdk.forConsole.billing.getPlan(billingPlan);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can do a quick cached data lookup first to avoid a network call, there should be a plansInfo available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ItzNotABug tierToPlan essentially has the same data as plansInfo, right?

return plan.name;
} catch (error) {
// Fallback to 'Custom' if fetch fails
return 'Custom';
}
}
function isOrganizationOnTrial(organization: Organization): boolean {
if (!organization?.billingTrialStartDate) return false;
if ($daysLeftInTrial <= 0) return false;
Expand Down Expand Up @@ -92,6 +113,9 @@
{#each data.organizations.teams as organization}
{@const avatarList = getMemberships(organization.$id)}
{@const payingOrg = isPayingOrganization(organization)}
{@const planName = isCloudOrg(organization)
? getPlanName(organization.billingPlan)
: null}

<GridItem1 href={`${base}/organization-${organization.$id}`}>
<svelte:fragment slot="eyebrow">
Expand All @@ -104,16 +128,17 @@
<svelte:fragment slot="status">
{#if isCloudOrg(organization)}
{#if isNonPayingOrganization(organization)}
<Tooltip>
<Badge
size="xs"
variant="secondary"
content={tierToPlan(organization?.billingPlan)?.name} />

<span slot="tooltip">
You are limited to 1 free organization per account
</span>
</Tooltip>
{#if planName}
{#await planName then name}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't there be a slight content/layout shift until this loads and if the api call was made?

<Tooltip>
<Badge size="xs" variant="secondary" content={name} />

<span slot="tooltip">
You are limited to 1 free organization per account
</span>
</Tooltip>
{/await}
{/if}
{/if}

{#if isOrganizationOnTrial(organization)}
Expand All @@ -132,11 +157,13 @@
{/if}

{#if payingOrg}
<Badge
size="xs"
type="success"
variant="secondary"
content={tierToPlan(payingOrg?.billingPlan)?.name} />
{#await getPlanName(payingOrg.billingPlan) then name}
<Badge
size="xs"
type="success"
variant="secondary"
content={name} />
{/await}
Comment on lines +160 to +166
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ItzNotABug do we want some sort of skeleton loader here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah as I mentioned above for shifts, we could use a skeleton. Please run by design once 👍

{/if}
{/if}
</svelte:fragment>
Expand Down