refactor: tiers into enum

This commit is contained in:
Arman
2023-12-22 17:47:49 +01:00
parent d7c8eaa1d7
commit f851e61124
37 changed files with 146 additions and 109 deletions
+5 -2
View File
@@ -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}
@@ -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>
+6
View File
@@ -616,3 +616,9 @@ export const limitRates = {
}
]
};
export enum BillingPlan {
STARTER = 'tier-0',
PRO = 'tier-1',
SCALE = 'tier-2'
}
+2 -1
View File
@@ -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;
@@ -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}
+2 -1
View File
@@ -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
+5 -4
View File
@@ -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;
@@ -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;
@@ -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.
@@ -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()}.
@@ -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}
+2 -1
View File
@@ -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;
@@ -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}
secondary
+2 -1
View File
@@ -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';
@@ -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={() =>
+2 -1
View File
@@ -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';
@@ -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"
+7 -6
View File
@@ -15,6 +15,7 @@ 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';
@@ -26,11 +27,11 @@ 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;
@@ -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':
@@ -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);
@@ -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')
+2 -2
View File
@@ -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';
@@ -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);
@@ -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;
@@ -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={{
@@ -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';
@@ -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,
@@ -162,7 +162,7 @@
onDestroy(() => {
$changeOrganizationTier = {
billingPlan: 'tier-1',
billingPlan: BillingPlan.PRO,
paymentMethodId: null,
collaborators: [],
billingAddressId: null,
@@ -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';
@@ -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) {
@@ -93,7 +93,7 @@
$createOrganization = {
id: null,
name: null,
billingPlan: 'tier-1',
billingPlan: BillingPlan.PRO,
paymentMethodId: null,
collaborators: [],
billingAddressId: null,
+2 -2
View File
@@ -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';
@@ -61,7 +61,7 @@
return await sdk.forConsole.billing.createOrganization(
ID.unique(),
'Personal Projects',
'tier-0',
BillingPlan.STARTER,
null,
null
);
@@ -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
@@ -95,7 +96,7 @@
<BillingAddress />
<TaxId />
<BudgetCap />
{#if $organization?.billingPlan !== 'tier-0' && !!$organization?.billingBudget}
{#if $organization?.billingPlan !== BillingPlan.STARTER && !!$organization?.billingBudget}
<BudgetAlert />
{/if}
<AvailableCredit />
@@ -2,7 +2,7 @@
import { invalidate } from '$app/navigation';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Alert, CardGrid, Heading } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Button, Form, FormList, InputNumber, InputSwitch } from '$lib/elements/forms';
import { showUsageRatesModal } from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
@@ -59,7 +59,7 @@
class="link">Learn more about usage rates.</button>
</p>
<svelte:fragment slot="aside">
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<Alert type="info">
<svelte:fragment slot="title">
Budget caps are a Pro plan feature
@@ -14,6 +14,7 @@
import { Query } from '@appwrite.io/console';
import { abbreviateNumber, formatNumberWithCommas } from '$lib/helpers/numbers';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import { BillingPlan } from '$lib/constants';
let currentInvoice: Invoice;
const today = new Date();
@@ -51,7 +52,7 @@
<h6 class="body-text-1 u-bold u-trim-1">
{tierToPlan($organization?.billingPlan)?.name} plan
</h6>
{#if $organization?.billingPlan !== 'tier-0' && isTrial}
{#if $organization?.billingPlan !== BillingPlan.STARTER && isTrial}
<Pill>TRIAL</Pill>
{/if}
</div>
@@ -65,7 +66,7 @@
</span>
</p>
</div>
{#if currentInvoice?.usage?.length && $organization?.billingPlan !== 'tier-0' && !isTrial}
{#if currentInvoice?.usage?.length && $organization?.billingPlan !== BillingPlan.STARTER && !isTrial}
{@const extraMembers = currentInvoice.usage.find((u) => u.name === 'members')}
{#if extraMembers}
<div class="u-margin-block-start-24">
@@ -128,7 +129,7 @@
</div>
</svelte:fragment>
<svelte:fragment slot="actions">
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<div class="u-flex u-gap-16 u-flex-wrap">
<Button text href={`${base}/console/organization-${$organization?.$id}/usage`}>
View estimated usage
@@ -7,7 +7,7 @@
import { createEventDispatcher } from 'svelte';
import { organization } from '$lib/stores/organization';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
import { isCloud } from '$lib/system';
import { plansInfo } from '$lib/stores/billing';
@@ -57,9 +57,9 @@
<Modal title="Invite Member" {error} size="big" bind:show={showCreate} onSubmit={create}>
{#if isCloud}
<Alert type="info">
{#if $organization?.billingPlan === 'tier-2'}
{#if $organization?.billingPlan === BillingPlan.SCALE}
You can add unlimited organization members on the {plan.name} plan at no cost.
{:else if $organization?.billingPlan === 'tier-1'}
{:else if $organization?.billingPlan === BillingPlan.PRO}
You can add unlimited organization members on the {plan.name} plan for
<b>${plan.addons.member.price} each per billing period</b>.
{/if}
@@ -13,6 +13,7 @@
import ChangeOrganizationTierCloud from '../changeOrganizationTierCloud.svelte';
import { goto } from '$app/navigation';
import { last } from '$lib/helpers/array';
import { BillingPlan } from '$lib/constants';
export let show = false;
const plan = $plansInfo.plans.find((plan) => plan.$id === $organization.billingPlan);
@@ -64,7 +65,7 @@
will maintain its current state of unlimited resource usage. This extension will be in effect
until January 31st, 2024.
{#if $organization.billingPlan === 'tier-0'}
{#if $organization.billingPlan === BillingPlan.STARTER}
<p class="text">
Usage for <b>{$organization.name}</b> organization has reached the limits of the {tierToPlan(
$organization.billingPlan
@@ -3,6 +3,7 @@
import { page } from '$app/stores';
import { tooltip } from '$lib/actions/tooltip';
import { AvatarGroup, DropList, DropListItem, DropListLink, Tab, Tabs } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import { toLocaleDate } from '$lib/helpers/date';
@@ -90,7 +91,7 @@
<h1 class="heading-level-4 u-flex u-cross-center u-gap-8">
<span class="u-flex u-cross-center u-gap-8">
{$organization.name}
{#if isCloud && $organization?.billingPlan === 'tier-0'}
{#if isCloud && $organization?.billingPlan === BillingPlan.STARTER}
<Pill>FREE</Pill>
{/if}
{#if isCloud && $organization?.billingTrialStartDate && $daysLeftInTrial > 0}
@@ -136,7 +137,7 @@
<div
use:tooltip={{
content:
$organization?.billingPlan === 'tier-0'
$organization?.billingPlan === BillingPlan.STARTER
? `Upgrade to add more members`
: `You've reached the members limit for the ${
tierToPlan($organization?.billingPlan)?.name
@@ -12,6 +12,7 @@
import { formatNum } from '$lib/helpers/string';
import { accumulateFromEndingTotal, total } from '$lib/layout/usage.svelte';
import type { OrganizationUsage } from '$lib/sdk/billing';
import { BillingPlan } from '$lib/constants';
export let data;
@@ -40,14 +41,14 @@
<div class="u-flex u-cross-center u-main-space-between">
<Heading tag="h2" size="5">Usage</Heading>
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<Button on:click={() => wizard.start(ChangeOrganizationTierCloud)}>
<span class="text">Upgrade</span>
</Button>
{/if}
</div>
<div class="u-flex u-main-space-between common-section u-cross-center">
{#if $organization.billingPlan === 'tier-2'}
{#if $organization.billingPlan === BillingPlan.SCALE}
<p class="text">
On the Scale plan, you'll be charged only for any usage that exceeds the thresholds
per resource listed below. <button
@@ -55,7 +56,7 @@
class="link"
type="button">Learn more about plan usage limits.</button>
</p>
{:else if $organization.billingPlan === 'tier-1'}
{:else if $organization.billingPlan === BillingPlan.PRO}
<p class="text">
On the Pro plan, you'll be charged only for any usage that exceeds the thresholds
per resource listed below. <button
@@ -63,7 +64,7 @@
class="link"
type="button">Learn more about plan usage limits.</button>
</p>
{:else if $organization.billingPlan === 'tier-0'}
{:else if $organization.billingPlan === BillingPlan.STARTER}
<p class="text">
If you exceed the limits of the {plan} plan, services for your organization's projects
may be disrupted.
@@ -43,6 +43,7 @@
import { organization } from '$lib/stores/organization';
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
import { wizard } from '$lib/stores/wizard';
import { BillingPlan } from '$lib/constants';
const projectId = $page.params.project;
@@ -117,7 +118,7 @@
</p>
<svelte:fragment slot="aside">
{#if $organization.billingPlan === 'tier-0'}
{#if $organization.billingPlan === BillingPlan.STARTER}
<Alert
buttons={[
{
@@ -1,7 +1,7 @@
<script lang="ts">
import { invalidate } from '$app/navigation';
import { Alert, EmptySearch, Id, PaginationWithLimit } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import {
@@ -65,7 +65,7 @@
{logs} hour of logs
</li>
</ul>
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<p class="text">
<button class="link" type="button" on:click|preventDefault={upgradeMethod}
>Upgrade</button>
@@ -13,7 +13,7 @@
import InputPassword from '$lib/elements/forms/inputPassword.svelte';
import { sdk } from '$lib/stores/sdk';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { BillingPlan, Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import InputNumber from '$lib/elements/forms/inputNumber.svelte';
@@ -124,7 +124,7 @@
class="link">here</a>
</p>
<svelte:fragment slot="aside">
{#if $organization.billingPlan === 'tier-0'}
{#if $organization.billingPlan === BillingPlan.STARTER}
<Alert type="info">
Custom SMTP is a Pro plan feature. Upgrade to enable custom SMTP sever.
<svelte:fragment slot="action">
@@ -202,7 +202,8 @@
<svelte:fragment slot="actions">
<Button
submit
disabled={isButtonDisabled || $organization.billingPlan === 'tier-0'}>
disabled={isButtonDisabled ||
$organization.billingPlan === BillingPlan.STARTER}>
Update
</Button>
</svelte:fragment>
@@ -19,6 +19,7 @@
import { formatNum } from '$lib/helpers/string';
import { total } from '$lib/layout/usage.svelte';
import ChangeOrganizationTierCloud from '$routes/console/changeOrganizationTierCloud.svelte';
import { BillingPlan } from '$lib/constants.js';
export let data;
@@ -51,28 +52,28 @@
<div class="u-flex u-cross-center u-main-space-between">
<Heading tag="h2" size="5">Usage</Heading>
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<Button on:click={() => wizard.start(ChangeOrganizationTierCloud)}>
<span class="text">Upgrade</span>
</Button>
{/if}
</div>
<div class="u-flex u-main-space-between common-section u-cross-center">
{#if $organization.billingPlan === 'tier-2'}
{#if $organization.billingPlan === BillingPlan.SCALE}
<p class="text">
On the Scale plan, you'll be charged only for any usage that exceeds the thresholds
per resource listed below. <Button
on:click={() => ($showUsageRatesModal = true)}
link>Learn more about plan usage limits.</Button>
</p>
{:else if $organization.billingPlan === 'tier-1'}
{:else if $organization.billingPlan === BillingPlan.PRO}
<p class="text">
On the Pro plan, you'll be charged only for any usage that exceeds the thresholds
per resource listed below. <Button
on:click={() => ($showUsageRatesModal = true)}
link>Learn more about plan usage limits.</Button>
</p>
{:else if $organization.billingPlan === 'tier-0'}
{:else if $organization.billingPlan === BillingPlan.STARTER}
<p class="text">
If you exceed the limits of the {plan} plan, services for your projects may be disrupted.
<button
@@ -1,5 +1,6 @@
<script lang="ts">
import { Alert, CustomId } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Pill } from '$lib/elements';
import { Button, FormList, InputFile } from '$lib/elements/forms';
import { humanFileSize, sizeToBytes } from '$lib/helpers/sizeConvertion';
@@ -28,12 +29,12 @@
The {plan.name} plan has a maximum upload file size limit of {Math.floor(
parseInt(size.value)
)}{size.unit}.
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
Upgrade to allow files of a larger size.
{/if}
</p>
<svelte:fragment slot="action">
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<div class="alert-buttons u-flex">
<Button text on:click={() => wizard.start(ChangeOrganizationTierCloud)}>
Upgrade plan
@@ -1,6 +1,7 @@
<script lang="ts">
import { Submit } from '$lib/actions/analytics';
import { Alert, CardGrid, Heading } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Button, Form, FormItem, InputNumber, InputSelect } from '$lib/elements/forms';
import { humanFileSize, sizeToBytes } from '$lib/helpers/sizeConvertion';
import { createByteUnitPair } from '$lib/helpers/unit';
@@ -42,12 +43,12 @@
The {plan.name} plan has a maximum upload file size limit of {Math.floor(
parseInt(size.value)
)}{size.unit}.
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
Upgrade to allow files of a larger size.
{/if}
</p>
<svelte:fragment slot="action">
{#if $organization?.billingPlan === 'tier-0'}
{#if $organization?.billingPlan === BillingPlan.STARTER}
<div class="alert-buttons u-flex">
<Button
text
@@ -1,5 +1,6 @@
<script lang="ts">
import { Box, CreditCardBrandImage } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Pill } from '$lib/elements';
import { toLocaleDate } from '$lib/helpers/date';
import { WizardStep } from '$lib/layout';
@@ -29,12 +30,12 @@
if (!$createOrganization.billingPlan) {
throw new Error('Please select a plan.');
}
if ($createOrganization.billingPlan === 'tier-0') {
if ($createOrganization.billingPlan === BillingPlan.STARTER) {
$createOrganization.collaborators = [];
}
}
$: if ($createOrganization.billingPlan === 'tier-0') {
$: if ($createOrganization.billingPlan === BillingPlan.STARTER) {
$createOrganizationFinalAction = 'Create organization';
}
</script>
@@ -53,7 +54,7 @@
{/if}
</div>
{#if $createOrganization.billingPlan !== 'tier-0'}
{#if $createOrganization.billingPlan !== BillingPlan.STARTER}
<div class="u-margin-block-start-32">
<p class="body-text-1 u-bold">Additional members</p>
<p class="text u-margin-block-start-8">{collaboratorsNumber} members</p>
@@ -75,7 +76,7 @@
</div>
{/if}
<Box class="u-margin-block-start-32 u-flex u-flex-vertical u-gap-16" radius="small">
{#if $createOrganization.billingPlan !== 'tier-0'}
{#if $createOrganization.billingPlan !== BillingPlan.STARTER}
<span class="u-flex u-main-space-between">
<p class="text">{plan.name} plan</p>
<p class="text">${plan.price}</p>
@@ -91,7 +92,7 @@
<p class="text">${totalExpences}</p>
</span>
{#if $createOrganization.billingPlan !== 'tier-0'}
{#if $createOrganization.billingPlan !== BillingPlan.STARTER}
<p class="text u-margin-block-start-16">
This amount, and any additional usage fees, will be charged on a recurring 30-day
billing cycle after your trial period ends on <b
@@ -1,5 +1,6 @@
<script lang="ts">
import { Alert } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Button, Form, FormList, InputEmail } from '$lib/elements/forms';
import {
Table,
@@ -41,10 +42,10 @@
</svelte:fragment>
<Alert type="info">
{#if $createOrganization.billingPlan === 'tier-2'}
{#if $createOrganization.billingPlan === BillingPlan.SCALE}
You can add unlimited organization members on the {plan.name} plan at no cost. Each member
added will receive an email invite to your organization on completion.
{:else if $createOrganization.billingPlan === 'tier-1'}
{:else if $createOrganization.billingPlan === BillingPlan.PRO}
You can add unlimited organization members on the {plan.name} plan for
<b>${plan.addons.member.price} each per month</b>. Each member added will receive an
email invite to your organization on completion.
@@ -70,7 +71,7 @@
<Table noStyles noMargin>
<TableHeader>
<TableCellHead>Collaborator</TableCellHead>
{#if $createOrganization.billingPlan === 'tier-1'}
{#if $createOrganization.billingPlan === BillingPlan.PRO}
<TableCellHead width={80}>Cost</TableCellHead>
{/if}
<TableCellHead width={40} />
@@ -79,7 +80,7 @@
{#each $createOrganization.collaborators as collaborator}
<TableRow>
<TableCellText title="collaborator">{collaborator}</TableCellText>
{#if $createOrganization.billingPlan === 'tier-1'}
{#if $createOrganization.billingPlan === BillingPlan.PRO}
<TableCellText title="cost">15$</TableCellText>
{/if}
<TableCell>
@@ -1,5 +1,6 @@
<script lang="ts">
import { CustomId, LabelCard } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Pill } from '$lib/elements';
import { InputText, FormList } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
@@ -11,27 +12,27 @@
let showCustomId = false;
$: anyOrgFree = $organizationList.teams?.find(
(org) => (org as Organization)?.billingPlan === 'tier-0'
(org) => (org as Organization)?.billingPlan === BillingPlan.STARTER
);
$: if ($createOrganization.billingPlan === 'tier-0' && $createOrgSteps) {
$: if ($createOrganization.billingPlan === BillingPlan.STARTER && $createOrgSteps) {
$createOrgSteps = updateStepStatus($createOrgSteps, 2, true);
$createOrgSteps = updateStepStatus($createOrgSteps, 3, true);
$createOrgSteps = updateStepStatus($createOrgSteps, 4, true);
}
$: if (
$createOrganization.billingPlan === 'tier-2' ||
$createOrganization.billingPlan === 'tier-1'
$createOrganization.billingPlan === BillingPlan.SCALE ||
$createOrganization.billingPlan === BillingPlan.PRO
) {
$createOrgSteps = updateStepStatus($createOrgSteps, 2, false);
$createOrgSteps = updateStepStatus($createOrgSteps, 3, false);
$createOrgSteps = updateStepStatus($createOrgSteps, 4, false);
}
$: freePlan = $plansInfo.plans.find((p) => p.$id === 'tier-0');
$: proPlan = $plansInfo.plans.find((p) => p.$id === 'tier-1');
$: scalePlan = $plansInfo.plans.find((p) => p.$id === 'tier-2');
$: freePlan = $plansInfo.plans.find((p) => p.$id === BillingPlan.STARTER);
$: proPlan = $plansInfo.plans.find((p) => p.$id === BillingPlan.PRO);
$: scalePlan = $plansInfo.plans.find((p) => p.$id === BillingPlan.SCALE);
</script>
<WizardStep>
@@ -1,3 +1,4 @@
import { BillingPlan } from '$lib/constants';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import type { Tier } from '$lib/stores/billing';
import { writable } from 'svelte/store';
@@ -17,7 +18,7 @@ export const createOrganization = writable<{
}>({
id: null,
name: null,
billingPlan: 'tier-1',
billingPlan: BillingPlan.PRO,
paymentMethodId: null,
collaborators: [],
billingAddressId: null,
@@ -14,6 +14,7 @@
import { createOrganization } from './store';
import { plansInfo } from '$lib/stores/billing';
import { abbreviateNumber } from '$lib/helpers/numbers';
import { BillingPlan } from '$lib/constants';
export let show = false;
export let tier: string;
@@ -49,7 +50,7 @@
}
];
$: isFree = tier === 'tier-0';
$: isFree = tier === BillingPlan.STARTER;
</script>
<Modal bind:show size="big" headerDivider={false} title="Usage rates">
@@ -57,12 +58,12 @@
Usage on the Starter plan is limited for the following resources. Next billing period: {toLocaleDate(
nextDate
)}.
{:else if tier === 'tier-1'}
{:else if tier === BillingPlan.PRO}
<p>
Usage on the Pro plan will be charged at the end of each billing period at the following
rates. Next billing period: {toLocaleDate(nextDate)}.
</p>
{:else if tier === 'tier-2'}
{:else if tier === BillingPlan.SCALE}
<p>
Usage on the Scale plan will be charged at the end of each billing period at the
following rates. Next billing period: {toLocaleDate(nextDate)}.
@@ -11,19 +11,20 @@
import type { Models } from '@appwrite.io/console';
import { sizeToBytes } from '$lib/helpers/sizeConvertion';
import { Pill } from '$lib/elements';
import { BillingPlan } from '$lib/constants';
let usage: OrganizationUsage = null;
let members: Models.MembershipList = null;
$: if ($changeOrganizationTier.billingPlan === 'tier-0' && $changeTierSteps) {
$: if ($changeOrganizationTier.billingPlan === BillingPlan.STARTER && $changeTierSteps) {
$changeTierSteps = updateStepStatus($changeTierSteps, 2, true);
$changeTierSteps = updateStepStatus($changeTierSteps, 3, true);
$changeTierSteps = updateStepStatus($changeTierSteps, 4, true);
}
$: if (
$changeOrganizationTier.billingPlan === 'tier-2' ||
$changeOrganizationTier.billingPlan === 'tier-1'
$changeOrganizationTier.billingPlan === BillingPlan.SCALE ||
$changeOrganizationTier.billingPlan === BillingPlan.PRO
) {
$changeTierSteps = updateStepStatus($changeTierSteps, 2, false);
$changeTierSteps = updateStepStatus($changeTierSteps, 3, false);
@@ -62,7 +63,7 @@
$changeOrganizationTier.limitOverflow.users > 0 ||
$changeOrganizationTier.limitOverflow.executions > 0 ||
$changeOrganizationTier.limitOverflow.members > 0) &&
$changeOrganizationTier.billingPlan === 'tier-0'
$changeOrganizationTier.billingPlan === BillingPlan.STARTER
) {
$changeOrganizationTier.isOverLimit = true;
$changeTierSteps = updateStepStatus($changeTierSteps, 5, false);
@@ -77,14 +78,14 @@
members = await sdk.forConsole.teams.listMemberships($organization.$id);
//Select closest tier from starting one
// if ($organization.billingPlan === 'tier-2') {
// $changeOrganizationTier.billingPlan = 'tier-1';
// if ($organization.billingPlan === BillingPlan.SCALE) {
// $changeOrganizationTier.billingPlan = BillingPlan.PRO;
// }
// else
if ($organization.billingPlan === 'tier-1') {
$changeOrganizationTier.billingPlan = 'tier-0';
} else if ($organization.billingPlan === 'tier-0') {
$changeOrganizationTier.billingPlan = 'tier-1';
if ($organization.billingPlan === BillingPlan.PRO) {
$changeOrganizationTier.billingPlan = BillingPlan.STARTER;
} else if ($organization.billingPlan === BillingPlan.STARTER) {
$changeOrganizationTier.billingPlan = BillingPlan.PRO;
}
});
@@ -92,14 +93,14 @@
if (!$changeOrganizationTier.billingPlan) {
throw new Error('Please select a plan.');
}
if ($changeOrganizationTier.billingPlan === 'tier-0') {
if ($changeOrganizationTier.billingPlan === BillingPlan.STARTER) {
$changeOrganizationTier.collaborators = [];
}
}
$: freePlan = $plansInfo.plans.find((p) => p.$id === 'tier-0');
$: proPlan = $plansInfo.plans.find((p) => p.$id === 'tier-1');
$: scalePlan = $plansInfo.plans.find((p) => p.$id === 'tier-2');
$: freePlan = $plansInfo.plans.find((p) => p.$id === BillingPlan.STARTER);
$: proPlan = $plansInfo.plans.find((p) => p.$id === BillingPlan.PRO);
$: scalePlan = $plansInfo.plans.find((p) => p.$id === BillingPlan.SCALE);
</script>
<WizardStep beforeSubmit={handleBefore}>
@@ -122,7 +123,7 @@
name="plan"
bind:group={$changeOrganizationTier.billingPlan}
value="tier-0"
disabled={$organization.billingPlan === 'tier-0'}>
disabled={$organization.billingPlan === BillingPlan.STARTER}>
<svelte:fragment slot="custom" let:disabled>
<div
class="u-flex u-flex-vertical u-gap-4 u-width-full-line"
@@ -133,7 +134,7 @@
<p class="u-color-text-gray u-small">{tierFree.description}</p>
</div>
<div class:u-opacity-50={disabled}>
{#if $organization.billingPlan === 'tier-0'}
{#if $organization.billingPlan === BillingPlan.STARTER}
<Pill disabled>CURRENT PLAN</Pill>
{/if}
</div>
@@ -145,7 +146,7 @@
name="plan"
bind:group={$changeOrganizationTier.billingPlan}
value="tier-1"
disabled={$organization.billingPlan === 'tier-1'}>
disabled={$organization.billingPlan === BillingPlan.PRO}>
<svelte:fragment slot="custom" let:disabled>
<div
class="u-flex u-flex-vertical u-gap-4 u-width-full-line"
@@ -159,7 +160,7 @@
</p>
</div>
<div class:u-opacity-50={disabled}>
{#if $organization.billingPlan === 'tier-1'}
{#if $organization.billingPlan === BillingPlan.PRO}
<Pill disabled>CURRENT PLAN</Pill>
{:else}
<Pill>14 DAY FREE TRIAL</Pill>
@@ -1,6 +1,7 @@
<script lang="ts">
import { Box, CreditCardBrandImage } from '$lib/components';
import { CouponInput } from '$lib/components/billing';
import { BillingPlan } from '$lib/constants';
import { FormList, InputTextarea } from '$lib/elements/forms';
import { toLocaleDate } from '$lib/helpers/date';
import { WizardStep } from '$lib/layout';
@@ -39,7 +40,7 @@
}
}
$: downgradeToStarter = $changeOrganizationTier.billingPlan === 'tier-0';
$: downgradeToStarter = $changeOrganizationTier.billingPlan === BillingPlan.STARTER;
$: if (!$isUpgrade) {
$changeOrganizationFinalAction = 'Confirm plan change';
}
@@ -73,7 +74,7 @@
<p class="text">{$organization.name}</p>
</div>
{#if $changeOrganizationTier.billingPlan !== 'tier-0'}
{#if $changeOrganizationTier.billingPlan !== BillingPlan.STARTER}
<div class="u-margin-block-start-32">
<p class="body-text-1 u-bold">Additional members</p>
<p class="text u-margin-block-start-8">{collaboratorsNumber} members</p>
@@ -100,7 +101,7 @@
bind:coupon
bind:couponData
on:validation={(e) => ($changeOrganizationTier.couponCode = e.detail.code)} />
{#if $changeOrganizationTier.billingPlan !== 'tier-0'}
{#if $changeOrganizationTier.billingPlan !== BillingPlan.STARTER}
<span class="u-flex u-main-space-between">
<p class="text">{plan.name} plan</p>
<p class="text">${plan.price}</p>
@@ -17,6 +17,7 @@
import { sdk } from '$lib/stores/sdk';
import { user } from '$lib/stores/user';
import { organization } from '$lib/stores/organization';
import { BillingPlan } from '$lib/constants';
const plan = $plansInfo.plans.find((p) => p.$id === $changeOrganizationTier.billingPlan);
@@ -57,10 +58,10 @@
</svelte:fragment>
<Alert type="info">
{#if $changeOrganizationTier.billingPlan === 'tier-2'}
{#if $changeOrganizationTier.billingPlan === BillingPlan.SCALE}
You can add unlimited organization members on the {plan.name} plan at no cost. Each member
added will receive an email invite to your organization on completion.
{:else if $changeOrganizationTier.billingPlan === 'tier-1'}
{:else if $changeOrganizationTier.billingPlan === BillingPlan.PRO}
You can add unlimited organization members on the {plan.name} plan for
<b>${plan.addons.member.price} each per month</b>. Each member added will receive an
email invite to your organization on completion.
@@ -86,7 +87,7 @@
<Table noStyles noMargin>
<TableHeader>
<TableCellHead>Collaborator</TableCellHead>
{#if $changeOrganizationTier.billingPlan === 'tier-1'}
{#if $changeOrganizationTier.billingPlan === BillingPlan.PRO}
<TableCellHead width={80}>Cost</TableCellHead>
{/if}
<TableCellHead width={40} />
@@ -95,7 +96,7 @@
{#each $changeOrganizationTier.collaborators as collaborator}
<TableRow>
<TableCellText title="collaborator">{collaborator}</TableCellText>
{#if $changeOrganizationTier.billingPlan === 'tier-1'}
{#if $changeOrganizationTier.billingPlan === BillingPlan.PRO}
<TableCellText title="cost">15$</TableCellText>
{/if}
<TableCell>
@@ -16,6 +16,7 @@
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import { abbreviateNumber } from '$lib/helpers/numbers';
import { formatNum } from '$lib/helpers/string';
import { BillingPlan } from '$lib/constants';
export let excess: {
bandwidth?: number;
@@ -32,7 +33,7 @@
<Alert type="error">
<svelte:fragment slot="title">
{#if currentTier === 'tier-0'}
{#if currentTier === BillingPlan.STARTER}
Your usage exceeds the {plan.name} plan limits
{:else}
Changing your plan now will result in removal of organization members and more
@@ -40,10 +41,10 @@
</svelte:fragment>
{#if excess?.members > 0}
{#if currentTier === 'tier-0'}
{#if currentTier === BillingPlan.STARTER}
The Starter plan has a limit of one organization member. By proceeding, all but the
creator of the organization admin will be removed.
{:else if currentTier === 'tier-1'}
{:else if currentTier === BillingPlan.PRO}
Additional organization members on the Pro plan cost {collaboratorPrice} per member per billing
period. By proceeding, you acknowledge your fees may increase in your next billing period.
{/if}
@@ -56,14 +57,14 @@
{/if}
<svelte:fragment slot="buttons">
{#if currentTier === 'tier-0'}
{#if currentTier === BillingPlan.STARTER}
<Button
text
external
href="https://appwrite.io/docs/advanced/platform/starter#reaching-resource-limits">
Learn more
</Button>
{:else if currentTier === 'tier-1'}
{:else if currentTier === BillingPlan.PRO}
<Button
text
external
@@ -1,3 +1,4 @@
import { BillingPlan } from '$lib/constants';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import type { Tier } from '$lib/stores/billing';
import { writable } from 'svelte/store';
@@ -24,7 +25,7 @@ export const changeOrganizationTier = writable<{
feedbackMessage?: string;
couponCode?: string;
}>({
billingPlan: 'tier-1',
billingPlan: BillingPlan.PRO,
paymentMethodId: null,
collaborators: [],
isOverLimit: false,