Skip to content

Commit

Permalink
Merge pull request #687 from appwrite/refactor-change-plan-to-map
Browse files Browse the repository at this point in the history
refactor: change plansInfo to a map
  • Loading branch information
eldadfux authored Dec 28, 2023
2 parents db0774d + f096271 commit bf29696
Show file tree
Hide file tree
Showing 39 changed files with 173 additions and 130 deletions.
7 changes: 5 additions & 2 deletions src/lib/components/support.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import { isSupportOnline, showSupportModal } from '../../routes/console/wizard/support/store';
import { isCloud } from '$lib/system';
import { organization } from '$lib/stores/organization';
import { BillingPlan } from '$lib/constants';
export let show = false;
$: isPaid = $organization?.billingPlan === 'tier-1' || $organization?.billingPlan === 'tier-2';
$: isPaid =
$organization?.billingPlan === BillingPlan.PRO ||
$organization?.billingPlan === BillingPlan.SCALE;
</script>

{#if isCloud}
Expand All @@ -39,7 +42,7 @@
</p>
{/if}
</div>
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<Button fullWidth href="https://appwrite.io/pricing" external>
<span class="text">Get Premium support</span>
</Button>
Expand Down
6 changes: 6 additions & 0 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,3 +616,9 @@ export const limitRates = {
}
]
};

export enum BillingPlan {
STARTER = 'tier-0',
PRO = 'tier-1',
SCALE = 'tier-2'
}
3 changes: 2 additions & 1 deletion src/lib/layout/activity.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import { isCloud } from '$lib/system';
import { organization } from '$lib/stores/organization';
import { Button } from '$lib/elements/forms';
import { BillingPlan } from '$lib/constants';
export let logs: Models.LogList;
export let offset = 0;
Expand Down Expand Up @@ -51,7 +52,7 @@
Logs are retained in rolling {hoursToDays(limit)} intervals with the
{tierToPlan($organization.billingPlan).name}
plan.
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<Button link on:click={upgradeMethod}>Upgrade</Button> to increase your log
retention for a longer period.
{/if}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/layout/containerButton.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script lang="ts">
import { tooltip } from '$lib/actions/tooltip';
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { tierToPlan } from '$lib/stores/billing';
import { organization } from '$lib/stores/organization';
export let title: string;
export let tooltipContent =
$organization.billingPlan === 'tier-0'
$organization.billingPlan === BillingPlan.STARTER
? `Upgrade to add more ${title.toLocaleLowerCase()}`
: `You've reached the ${title.toLocaleLowerCase()} limit for the ${
tierToPlan($organization.billingPlan).name
Expand Down
9 changes: 5 additions & 4 deletions src/lib/layout/containerHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
import { ContainerButton } from '.';
import { Button } from '$lib/elements/forms';
import { BillingPlan } from '$lib/constants';
export let isFlex = true;
export let title: string;
Expand Down Expand Up @@ -52,7 +53,7 @@
$: tier = tierToPlan($organization?.billingPlan)?.name;
$: hasProjectLimitation =
checkForProjectLimitation(serviceId) && $organization?.billingPlan === 'tier-0';
checkForProjectLimitation(serviceId) && $organization?.billingPlan === BillingPlan.STARTER;
$: hasUsageFees = hasProjectLimitation
? checkForUsageFees($organization?.billingPlan, serviceId)
: false;
Expand All @@ -77,7 +78,7 @@
})
.join(', ')}
<slot name="alert" {limit} {tier} {title} {upgradeMethod} {hasUsageFees} {services}>
{#if $organization?.billingPlan !== 'tier-0' && hasUsageFees}
{#if $organization?.billingPlan !== BillingPlan.STARTER && hasUsageFees}
<Alert type="info" isStandalone>
<span class="text">
You've reached the {services} limit for the {tier} plan.
Expand Down Expand Up @@ -121,7 +122,7 @@
<p class="text">
Your are limited to {limit}
{title.toLocaleLowerCase()} per project on the {tier} plan.
{#if $organization?.billingPlan === 'tier-0'}<Button
{#if $organization?.billingPlan === BillingPlan.STARTER}<Button
link
on:click={upgradeMethod}>Upgrade</Button>
for addtional {title.toLocaleLowerCase()}.
Expand All @@ -139,7 +140,7 @@
<p class="text">
You are limited to {limit}
{title.toLocaleLowerCase()} per organization on the {tier} plan.
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<Button link on:click={upgradeMethod}>Upgrade</Button>
for additional {title.toLocaleLowerCase()}.
{/if}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/layout/header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import { Pill } from '$lib/elements';
import { showExcess } from '$routes/console/organization-[organization]/store';
import { readOnly } from '$lib/stores/billing';
import { BillingPlan } from '$lib/constants';
let showDropdown = false;
let showSupport = false;
Expand Down Expand Up @@ -117,7 +118,7 @@

<div class="main-header-end">
<nav class="u-flex is-only-desktop u-cross-center">
{#if isCloud && $organization?.billingPlan === 'tier-0' && !$page.url.pathname.startsWith('/console/account')}
{#if isCloud && $organization?.billingPlan === BillingPlan.STARTER && !$page.url.pathname.startsWith('/console/account')}
<Button
disabled={$organization?.markedForDeletion}
on:click={() => wizard.start(ChangeOrganizationTierCloud)}>
Expand Down
3 changes: 2 additions & 1 deletion src/lib/layout/logs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { organization } from '$lib/stores/organization';
import { app } from '$lib/stores/app';
import { Button } from '$lib/elements/forms';
import { BillingPlan } from '$lib/constants';
let selectedRequest = 'parameters';
let selectedResponse = 'logs';
Expand Down Expand Up @@ -311,7 +312,7 @@
<Alert>
Logs are retained in rolling {hoursToDays(limit)} intervals
with the {tier} plan.
{#if $organization.billingPlan === 'tier-0'}
{#if $organization.billingPlan === BillingPlan.STARTER}
<Button
link
on:click={() =>
Expand Down
3 changes: 2 additions & 1 deletion src/lib/layout/navigation.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { tooltip } from '$lib/actions/tooltip';
import { BillingPlan } from '$lib/constants';
import { isMac } from '$lib/helpers/platform';
import { slide } from '$lib/helpers/transition';
import { organization } from '$lib/stores/organization';
Expand Down Expand Up @@ -180,7 +181,7 @@
</a>

<ul class="drop-list is-only-mobile">
{#if isCloud && $organization?.billingPlan !== 'tier-2'}
{#if isCloud && $organization?.billingPlan !== BillingPlan.SCALE}
<li class="drop-list-item">
<button
class="drop-button"
Expand Down
2 changes: 2 additions & 0 deletions src/lib/sdk/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ export type PlansInfo = {
total: number;
};

export type PlansMap = Map<Tier, Plan>;

export class Billing {
client: Client;

Expand Down
23 changes: 12 additions & 11 deletions src/lib/stores/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { page } from '$app/stores';
import { derived, get, writable } from 'svelte/store';
import { sdk } from './sdk';
import { organization, type Organization } from './organization';
import type { InvoiceList, AddressesList, Invoice, PaymentList, PlansInfo } from '$lib/sdk/billing';
import type { InvoiceList, AddressesList, Invoice, PaymentList, PlansMap } from '$lib/sdk/billing';
import { isCloud } from '$lib/system';
import { cachedStore } from '$lib/helpers/cache';
import { Query, type Models } from '@appwrite.io/console';
Expand All @@ -15,22 +15,23 @@ import { base } from '$app/paths';
import TooManyFreOrgs from '$lib/components/billing/alerts/tooManyFreeOrgs.svelte';
import { activeHeaderAlert, showPostReleaseModal } from '$routes/console/store';
import MarkedForDeletion from '$lib/components/billing/alerts/markedForDeletion.svelte';
import { BillingPlan } from '$lib/constants';

export type Tier = 'tier-0' | 'tier-1' | 'tier-2';

export const paymentMethods = derived(page, ($page) => $page.data.paymentMethods as PaymentList);
export const addressList = derived(page, ($page) => $page.data.addressList as AddressesList);
export const plansInfo = derived(page, ($page) => $page.data.plansInfo as PlansInfo);
export const plansInfo = derived(page, ($page) => $page.data.plansInfo as PlansMap);
export const daysLeftInTrial = writable<number>(0);
export const readOnly = writable<boolean>(false);

export function tierToPlan(tier: Tier) {
switch (tier) {
case 'tier-0':
case BillingPlan.STARTER:
return tierFree;
case 'tier-1':
case BillingPlan.PRO:
return tierPro;
case 'tier-2':
case BillingPlan.SCALE:
return tierScale;
default:
return tierFree;
Expand Down Expand Up @@ -63,8 +64,8 @@ export function getServiceLimit(serviceId: PlanServices, tier: Tier = null): num
if (!isCloud) return 0;
if (!serviceId) return 0;
const info = get(plansInfo);
if (!info?.plans) return 0;
const plan = info.plans.find((p) => p.$id === (tier ?? get(organization)?.billingPlan));
if (!info) return 0;
const plan = info.get(tier ?? get(organization)?.billingPlan);
return plan?.[serviceId];
}

Expand Down Expand Up @@ -117,7 +118,7 @@ export const tierScale: TierData = {
export const showUsageRatesModal = writable<boolean>(false);

export function checkForUsageFees(plan: Tier, id: PlanServices) {
if (plan === 'tier-1' || plan === 'tier-2') {
if (plan === BillingPlan.PRO || plan === BillingPlan.SCALE) {
switch (id) {
case 'bandwidth':
case 'storage':
Expand Down Expand Up @@ -157,7 +158,7 @@ export function isServiceLimited(serviceId: PlanServices, plan: Tier, total: num
}

export function calculateTrialDay(org: Organization) {
if (org?.billingPlan === 'tier-0') return false;
if (org?.billingPlan === BillingPlan.STARTER) return false;
const endDate = new Date(org?.billingStartDate);
const today = new Date();
const days = diffDays(today, endDate);
Expand Down Expand Up @@ -190,7 +191,7 @@ export async function checkForUsageLimit(org: Organization) {
}
const { bandwidth, documents, executions, storage, users } = org?.billingLimits ?? {};
const members = await sdk.forConsole.teams.listMemberships(org.$id);
const plan = get(plansInfo).plans.find((plan) => plan.$id === org.billingPlan);
const plan = get(plansInfo)?.get(org.billingPlan);
const membersOverflow =
members?.total > plan.members ? members.total - (plan.members || members.total) : 0;

Expand All @@ -207,7 +208,7 @@ export async function checkForUsageLimit(org: Organization) {
}

export async function checkPaymentAuthorizationRequired(org: Organization) {
if (org.billingPlan === 'tier-0') return;
if (org.billingPlan === BillingPlan.STARTER) return;

const invoices = await sdk.forConsole.billing.listInvoices(org.$id, [
Query.equal('status', 'requires_authentication')
Expand Down
4 changes: 2 additions & 2 deletions src/routes/console/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';
import { INTERVAL } from '$lib/constants';
import { BillingPlan, INTERVAL } from '$lib/constants';
import { Logs } from '$lib/layout';
import Footer from '$lib/layout/footer.svelte';
import Header from '$lib/layout/header.svelte';
Expand Down Expand Up @@ -248,7 +248,7 @@
if (isCloud) {
if (!$page.url.pathname.includes('/console/onboarding')) {
const orgs = await sdk.forConsole.teams.list([
Query.equal('billingPlan', 'tier-0')
Query.equal('billingPlan', BillingPlan.STARTER)
]);
checkForPostReleaseProModal(orgs);
Expand Down
10 changes: 8 additions & 2 deletions src/routes/console/+layout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Dependencies } from '$lib/constants';
import type { Plan } from '$lib/sdk/billing';
import type { Tier } from '$lib/stores/billing';
import { sdk } from '$lib/stores/sdk';
import { isCloud } from '$lib/system';
import type { LayoutLoad } from './$types';
Expand All @@ -18,9 +20,13 @@ export const load: LayoutLoad = async ({ fetch, depends }) => {

const [data, variables] = await Promise.all([versionPromise, variablesPromise]);

let plansInfo = null;
let plansInfo = new Map<Tier, Plan>();
if (isCloud) {
plansInfo = await sdk.forConsole.billing.getPlansInfo();
const plansArray = await sdk.forConsole.billing.getPlansInfo();
plansInfo = plansArray.plans.reduce((map, plan) => {
map.set(plan.$id as Tier, plan);
return map;
}, new Map<Tier, Plan>());
}

return {
Expand Down
3 changes: 2 additions & 1 deletion src/routes/console/account/organizations/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import { toLocaleDate } from '$lib/helpers/date';
import { wizard } from '$lib/stores/wizard';
import CreateOrganizationCloud from '$routes/console/createOrganizationCloud.svelte';
import { BillingPlan } from '$lib/constants';
export let data: PageData;
let addOrganization = false;
Expand Down Expand Up @@ -71,7 +72,7 @@
</svelte:fragment>
<svelte:fragment slot="status">
{#if isCloudOrg(organization)}
{#if organization?.billingPlan === 'tier-0'}
{#if organization?.billingPlan === BillingPlan.STARTER}
<div
class="u-flex u-cross-center"
use:tooltip={{
Expand Down
6 changes: 3 additions & 3 deletions src/routes/console/changeOrganizationTierCloud.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
isUpgrade
} from './wizard/cloudOrganizationChangeTier/store';
import { goto, invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { page } from '$app/stores';
import { organization } from '$lib/stores/organization';
Expand All @@ -35,7 +35,7 @@
async function changeTier() {
//Downgrade
if ($changeOrganizationTier.billingPlan === 'tier-0') {
if ($changeOrganizationTier.billingPlan === BillingPlan.STARTER) {
try {
await sdk.forConsole.billing.updatePlan(
$organization.$id,
Expand Down Expand Up @@ -162,7 +162,7 @@
onDestroy(() => {
$changeOrganizationTier = {
billingPlan: 'tier-1',
billingPlan: BillingPlan.PRO,
paymentMethodId: null,
collaborators: [],
billingAddressId: null,
Expand Down
6 changes: 3 additions & 3 deletions src/routes/console/createOrganizationCloud.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
createOrgSteps
} from './wizard/cloudOrganization/store';
import { goto, invalidate, preloadData } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { ID } from '@appwrite.io/console';
import { page } from '$app/stores';
Expand Down Expand Up @@ -78,7 +78,7 @@
members_invited: $createOrganization?.collaborators?.length
});
wizard.hide();
if (org.billingPlan === 'tier-1') {
if (org.billingPlan === BillingPlan.PRO) {
wizard.showCover(HoodieCover);
}
} catch (e) {
Expand All @@ -93,7 +93,7 @@
$createOrganization = {
id: null,
name: null,
billingPlan: 'tier-1',
billingPlan: BillingPlan.PRO,
paymentMethodId: null,
collaborators: [],
billingAddressId: null,
Expand Down
4 changes: 2 additions & 2 deletions src/routes/console/onboarding/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { Card } from '$lib/components';
import CustomId from '$lib/components/customId.svelte';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Pill } from '$lib/elements';
import { Button, Form, InputText } from '$lib/elements/forms';
import FormList from '$lib/elements/forms/formList.svelte';
Expand Down Expand Up @@ -61,7 +61,7 @@
return await sdk.forConsole.billing.createOrganization(
ID.unique(),
'Personal Projects',
'tier-0',
BillingPlan.STARTER,
null,
null
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import { toLocaleDate } from '$lib/helpers/date';
import { wizard } from '$lib/stores/wizard';
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
import { BillingPlan } from '$lib/constants';
$: defaultPaymentMethod = $paymentMethods?.paymentMethods?.find(
(method: PaymentMethodData) => method.$id === $organization?.paymentMethodId
Expand Down Expand Up @@ -95,7 +96,7 @@
<BillingAddress />
<TaxId />
<BudgetCap />
{#if $organization?.billingPlan !== 'tier-0' && !!$organization?.billingBudget}
{#if $organization?.billingPlan !== BillingPlan.STARTER && !!$organization?.billingBudget}
<BudgetAlert />
{/if}
<AvailableCredit />
Expand Down
Loading

3 comments on commit bf29696

@vercel
Copy link

@vercel vercel bot commented on bf29696 Dec 28, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

console-cloud – ./

console-cloud.vercel.app
console-cloud-git-main-appwrite.vercel.app
console-cloud-appwrite.vercel.app

@vercel
Copy link

@vercel vercel bot commented on bf29696 Dec 28, 2023

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on bf29696 Dec 28, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

console-preview – ./

console-preview-appwrite.vercel.app
console-preview-git-main-appwrite.vercel.app
console-next.vercel.app

Please sign in to comment.