From ef1435cdb4402b14cca805219d2efd4934337662 Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 18 Dec 2025 13:05:32 +0530 Subject: [PATCH 01/27] remove: hardcoded `Plan` type and use billing models from sdk. --- package.json | 2 +- pnpm-lock.yaml | 10 +- src/lib/components/archiveProject.svelte | 3 +- .../components/billing/planSelection.svelte | 6 +- src/lib/sdk/billing.ts | 94 +------------------ src/lib/stores/billing.ts | 15 +-- src/lib/stores/organization.ts | 3 +- src/routes/(console)/+layout.svelte | 3 +- src/routes/(console)/+layout.ts | 7 +- .../account/organizations/+page.svelte | 4 +- .../(console)/apply-credit/+page.svelte | 6 +- .../organization-[organization]/+layout.ts | 5 +- .../billing/budgetAlert.svelte | 9 +- .../billing/budgetCap.svelte | 7 +- .../billing/planSummary.svelte | 9 +- .../billing/planSummaryOld.svelte | 10 +- .../organization-[organization]/header.svelte | 10 +- .../databases/+page.ts | 3 +- .../settings/updateMaxFileSize.svelte | 3 +- 19 files changed, 60 insertions(+), 149 deletions(-) diff --git a/package.json b/package.json index 15cb88fa7f..971f912a30 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@49ffd53", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@865e2fc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7492f49f0..d38362e774 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107 - version: https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107 + specifier: https://pkg.vc/-/@appwrite/@appwrite.io/console@49ffd53 + version: https://pkg.vc/-/@appwrite/@appwrite.io/console@49ffd53 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -272,8 +272,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107': - resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@49ffd53': + resolution: {tarball: https://pkg.vc/-/@appwrite/@appwrite.io/console@49ffd53} version: 1.10.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': @@ -3823,7 +3823,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@9b32107': {} + '@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@49ffd53': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/components/archiveProject.svelte b/src/lib/components/archiveProject.svelte index 8a9797ca09..9fa20fc5b0 100644 --- a/src/lib/components/archiveProject.svelte +++ b/src/lib/components/archiveProject.svelte @@ -38,13 +38,12 @@ import { isCloud } from '$lib/system'; import { regions as regionsStore } from '$lib/stores/organization'; import type { Organization } from '$lib/stores/organization'; - import type { Plan } from '$lib/sdk/billing'; // props interface Props { projectsToArchive: Models.Project[]; organization: Organization; - currentPlan: Plan; + currentPlan: Models.BillingPlan; } let { projectsToArchive, organization, currentPlan }: Props = $props(); diff --git a/src/lib/components/billing/planSelection.svelte b/src/lib/components/billing/planSelection.svelte index 6499a47c0b..6d8d4a562b 100644 --- a/src/lib/components/billing/planSelection.svelte +++ b/src/lib/components/billing/planSelection.svelte @@ -4,21 +4,21 @@ import { currentPlan, organization } from '$lib/stores/organization'; 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'; + import type { Models } from '@appwrite.io/console'; export let billingPlan: BillingPlan; export let isNewOrg = false; export let selfService = true; export let anyOrgFree = false; - $: plans = Object.values(page.data.plans.plans) as Plan[]; + $: plans = Object.values(page.data.plans.plans) as Models.BillingPlan[]; $: currentPlanInList = plans.some((plan) => plan.$id === $currentPlan?.$id); // experiment to remove scale plan temporarily $: plansWithoutScale = plans.filter((plan) => plan.$id != BillingPlan.SCALE); - function shouldShowTooltip(plan: Plan) { + function shouldShowTooltip(plan: Models.BillingPlan) { if (plan.$id !== BillingPlan.FREE) return true; else return !anyOrgFree; } diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index f728ca5e84..2cf540d92e 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -354,91 +354,7 @@ export type AddressesList = { total: number; }; -export type AdditionalResource = { - name: string; - currency: string; - invoiceDesc: string; - price: number; - unit: string; - value: number; - multiplier?: number; -}; - -export type PlanAddon = { - supported: boolean; - currency: string; - invoiceDesc: string; - price: number; - limit: number; - value: number; - type: string; - planIncluded: number; -}; - -export type Plan = { - $id: string; - name: string; - desc: string; - price: number; - order: number; - bandwidth: number; - storage: number; - imageTransformations: number; - webhooks: number; - users: number; - teams: number; - projects: number; - databases: number; - databasesAllowEncrypt: boolean; - databasesReads: number; - databasesWrites: number; - buckets: number; - fileSize: number; - functions: number; - executions: number; - GBHours: number; - realtime: number; - logs: number; - authPhone: number; - usage: { - bandwidth: AdditionalResource; - executions: AdditionalResource; - member: AdditionalResource; - realtime: AdditionalResource; - storage: AdditionalResource; - users: AdditionalResource; - databasesReads: AdditionalResource; - databasesWrites: AdditionalResource; - GBHours: AdditionalResource; - imageTransformations: AdditionalResource; - }; - addons: { - seats: PlanAddon; - projects: PlanAddon; - }; - trialDays: number; - budgetCapEnabled: boolean; - isAvailable: boolean; - selfService: boolean; - premiumSupport: boolean; - budgeting: boolean; - supportsMockNumbers: boolean; - backupsEnabled: boolean; - backupPolicies: number; - emailBranding: boolean; - supportsCredits: boolean; - supportsOrganizationRoles: boolean; - buildSize: number; // in MB - deploymentSize: number; // in MB - usagePerProject: boolean; -}; - -export type PlanList = { - plans: Plan[]; - total: number; -}; - -export type PlansMap = Map; +export type BillingPlansMap = Map; export type Roles = { scopes: string[]; @@ -567,7 +483,7 @@ export class Billing { }); } - async getOrganizationPlan(organizationId: string): Promise { + async getOrganizationPlan(organizationId: string): Promise { const path = `/organizations/${organizationId}/plan`; const uri = new URL(this.client.config.endpoint + path); return await this.client.call('get', uri, { @@ -575,7 +491,7 @@ export class Billing { }); } - async listPlans(queries: string[] = []): Promise { + async listPlans(queries: string[] = []): Promise { const path = `/console/plans`; const uri = new URL(this.client.config.endpoint + path); const params = { @@ -591,7 +507,7 @@ export class Billing { ); } - async getPlan(planId: string): Promise { + async getPlan(planId: string): Promise { const path = `/console/plans/${planId}`; const uri = new URL(this.client.config.endpoint + path); return await this.client.call('get', uri, { @@ -1440,7 +1356,7 @@ export class Billing { ); } - async getPlansInfo(): Promise { + async getPlansInfo(): Promise { const path = `/console/plans`; const params = {}; const uri = new URL(this.client.config.endpoint + path); diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 695ef874c7..5c7305125f 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -19,12 +19,11 @@ import type { InvoiceList, PaymentList, PaymentMethodData, - Plan, - PlansMap + BillingPlansMap } from '$lib/sdk/billing'; import { isCloud } from '$lib/system'; import { activeHeaderAlert, orgMissingPaymentMethod } from '$routes/(console)/store'; -import { AppwriteException, Query, Platform } from '@appwrite.io/console'; +import { AppwriteException, Query, Platform, type Models } from '@appwrite.io/console'; import { derived, get, writable } from 'svelte/store'; import { headerAlert } from './headerAlert'; import { addNotification, notifications } from './notifications'; @@ -72,7 +71,7 @@ export const billingLimitOutstandingInvoice = 'outstanding_invoice'; 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 PlansMap); +export const plansInfo = derived(page, ($page) => $page.data.plansInfo as BillingPlansMap); export const daysLeftInTrial = writable(0); export const readOnly = writable(false); @@ -152,7 +151,11 @@ export type PlanServices = | 'authPhone' | 'imageTransformations'; -export function getServiceLimit(serviceId: PlanServices, tier: Tier = null, plan?: Plan): number { +export function getServiceLimit( + serviceId: PlanServices, + tier: Tier = null, + plan?: Models.BillingPlan +): number { if (!isCloud) return 0; if (!serviceId) return 0; @@ -626,7 +629,7 @@ export const billingURL = derived( export const hideBillingHeaderRoutes = [base + '/create-organization', base + '/account']; -export function calculateExcess(addon: AggregationTeam, plan: Plan) { +export function calculateExcess(addon: AggregationTeam, plan: Models.BillingPlan) { return { bandwidth: calculateResourceSurplus(addon.usageBandwidth, plan.bandwidth), storage: calculateResourceSurplus(addon.usageStorage, plan.storage, 'GB'), diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index 7393c6ed65..43b6074880 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -1,6 +1,5 @@ import { page } from '$app/stores'; import type { Tier } from './billing'; -import type { Plan } from '$lib/sdk/billing'; import { derived, writable } from 'svelte/store'; import { type Models, Platform } from '@appwrite.io/console'; @@ -61,6 +60,6 @@ export const organizationList = derived( ); export const organization = derived(page, ($page) => $page.data?.organization as Organization); -export const currentPlan = derived(page, ($page) => $page.data?.currentPlan as Plan); +export const currentPlan = derived(page, ($page) => $page.data?.currentPlan as Models.BillingPlan); export const members = derived(page, ($page) => $page.data.members as Models.MembershipList); export const regions = writable({ total: 0, regions: [] }); diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte index 109bdabb3a..be3539bf44 100644 --- a/src/routes/(console)/+layout.svelte +++ b/src/routes/(console)/+layout.svelte @@ -23,7 +23,6 @@ checkForUsageLimit, checkPaymentAuthorizationRequired, paymentExpired, - plansInfo, showUsageRatesModal } from '$lib/stores/billing'; import { goto } from '$app/navigation'; @@ -310,7 +309,7 @@ await checkPaymentAuthorizationRequired(org); await checkForMandate(org); - if ($plansInfo.get(org.billingPlan)?.trialDays) { + if (org?.billingTrialDays) { calculateTrialDay(org); } } diff --git a/src/routes/(console)/+layout.ts b/src/routes/(console)/+layout.ts index 3cf1478a3a..5ad9ebcbd1 100644 --- a/src/routes/(console)/+layout.ts +++ b/src/routes/(console)/+layout.ts @@ -3,8 +3,7 @@ import { sdk } from '$lib/stores/sdk'; import { isCloud } from '$lib/system'; import type { LayoutLoad } from './$types'; import type { Tier } from '$lib/stores/billing'; -import type { Plan, PlanList } from '$lib/sdk/billing'; -import { Query } from '@appwrite.io/console'; +import { type Models, Query } from '@appwrite.io/console'; export const load: LayoutLoad = async ({ depends, parent }) => { const { organizations } = await parent(); @@ -56,8 +55,8 @@ export const load: LayoutLoad = async ({ depends, parent }) => { }; }; -function toPlanMap(plansArray: PlanList | null): Map { - const map = new Map(); +function toPlanMap(plansArray: Models.BillingPlanList | null): Map { + const map = new Map(); if (!plansArray?.plans.length) return map; const plans = plansArray.plans; diff --git a/src/routes/(console)/account/organizations/+page.svelte b/src/routes/(console)/account/organizations/+page.svelte index 2d16680439..22396b6dd6 100644 --- a/src/routes/(console)/account/organizations/+page.svelte +++ b/src/routes/(console)/account/organizations/+page.svelte @@ -16,7 +16,7 @@ import { Badge, Skeleton } from '@appwrite.io/pink-svelte'; import type { Models } from '@appwrite.io/console'; import type { Organization } from '$lib/stores/organization'; - import { daysLeftInTrial, plansInfo, tierToPlan, type Tier } from '$lib/stores/billing'; + import { daysLeftInTrial, tierToPlan, type Tier } from '$lib/stores/billing'; import { toLocaleDate } from '$lib/helpers/date'; import { BillingPlan } from '$lib/constants'; import { goto } from '$app/navigation'; @@ -62,7 +62,7 @@ if ($daysLeftInTrial <= 0) return false; if (organization.billingPlan === BillingPlan.FREE) return false; - return !!$plansInfo.get(organization.billingPlan)?.trialDays; + return !!organization?.billingTrialDays; } function isNonPayingOrganization(organization: Organization): boolean { diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index db9dbc0387..b7226b3e77 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -8,7 +8,7 @@ import { Button, Form, InputSelect, InputTags, InputText } from '$lib/elements/forms'; import { toLocaleDate } from '$lib/helpers/date'; import { Wizard } from '$lib/layout'; - import type { PaymentList, Plan } from '$lib/sdk/billing'; + import type { PaymentList } from '$lib/sdk/billing'; import { addNotification } from '$lib/stores/notifications'; import { organizationList, @@ -17,7 +17,7 @@ } from '$lib/stores/organization'; import { sdk } from '$lib/stores/sdk'; import { confirmPayment } from '$lib/stores/stripe.js'; - import { ID } from '@appwrite.io/console'; + import { ID, type Models } from '@appwrite.io/console'; import { onMount } from 'svelte'; import { writable } from 'svelte/store'; import { isOrganization, plansInfo, type Tier } from '$lib/stores/billing'; @@ -70,7 +70,7 @@ let campaign = data?.campaign; let billingPlan: Tier = BillingPlan.PRO; let tempOrgId = null; - let currentPlan: Plan; + let currentPlan: Models.BillingPlan; $: onlyNewOrgs = campaign?.onlyNewOrgs || couponData?.onlyNewOrgs; diff --git a/src/routes/(console)/organization-[organization]/+layout.ts b/src/routes/(console)/organization-[organization]/+layout.ts index ef77274e81..39893dbd45 100644 --- a/src/routes/(console)/organization-[organization]/+layout.ts +++ b/src/routes/(console)/organization-[organization]/+layout.ts @@ -11,10 +11,9 @@ import ProjectsAtRisk from '$lib/components/billing/alerts/projectsAtRisk.svelte import { get } from 'svelte/store'; import { preferences } from '$lib/stores/preferences'; import { defaultRoles, defaultScopes } from '$lib/constants'; -import type { Plan } from '$lib/sdk/billing'; import { loadAvailableRegions } from '$routes/(console)/regions'; import type { Organization } from '$lib/stores/organization'; -import { Platform } from '@appwrite.io/console'; +import { type Models, Platform } from '@appwrite.io/console'; import { resolve } from '$app/paths'; export const load: LayoutLoad = async ({ params, depends, parent }) => { @@ -28,7 +27,7 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { let roles = isCloud ? [] : defaultRoles; let scopes = isCloud ? [] : defaultScopes; - let currentPlan: Plan = null; + let currentPlan: Models.BillingPlan | null = null; try { if (isCloud) { diff --git a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte index 5743273b94..ad5b178684 100644 --- a/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte +++ b/src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte @@ -12,11 +12,11 @@ import { Alert, Icon, Table } from '@appwrite.io/pink-svelte'; import { IconTrash } from '@appwrite.io/pink-icons-svelte'; import InputSelect from '$lib/elements/forms/inputSelect.svelte'; - import type { Plan } from '$lib/sdk/billing'; + import type { Models } from '@appwrite.io/console'; - export let organization: Organization; - export let currentPlan: Plan; export let alertsEnabled = false; + export let organization: Organization; + export let currentPlan: Models.BillingPlan; let search: string; let selectedAlert: number; @@ -53,13 +53,14 @@ alerts ); - invalidate(Dependencies.ORGANIZATION); + await invalidate(Dependencies.ORGANIZATION); addNotification({ type: 'success', isHtml: true, message: ` ${alerts.length === 0 ? 'Budget alerts removed from' : alerts.length > 1 ? `Budget alerts added to` : 'A budget alert has been added to'} ${organization.name} ` }); + trackEvent(Submit.BudgetAlertsUpdate, { alerts }); diff --git a/src/routes/(console)/organization-[organization]/billing/budgetCap.svelte b/src/routes/(console)/organization-[organization]/billing/budgetCap.svelte index bd08a88ca7..65062307b6 100644 --- a/src/routes/(console)/organization-[organization]/billing/budgetCap.svelte +++ b/src/routes/(console)/organization-[organization]/billing/budgetCap.svelte @@ -10,12 +10,13 @@ import { sdk } from '$lib/stores/sdk'; import { Alert, Link } from '@appwrite.io/pink-svelte'; import BudgetAlert from './budgetAlert.svelte'; - import type { Plan } from '$lib/sdk/billing'; + import type { Models } from '@appwrite.io/console'; - export let currentPlan: Plan; export let organization: Organization; - let capActive = organization?.billingBudget !== null; + export let currentPlan: Models.BillingPlan; + let budget = organization.billingBudget; + let capActive = organization?.billingBudget !== null; async function updateBudget() { try { diff --git a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte index fb3df8a608..fe6b28b852 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte @@ -5,7 +5,7 @@ import { toLocaleDate } from '$lib/helpers/date'; import { upgradeURL } from '$lib/stores/billing'; import { organization } from '$lib/stores/organization'; - import type { AggregationTeam, InvoiceUsage, Plan } from '$lib/sdk/billing'; + import type { AggregationTeam, InvoiceUsage } from '$lib/sdk/billing'; import { formatCurrency } from '$lib/helpers/numbers'; import { BillingPlan, DEFAULT_BILLING_PROJECTS_LIMIT } from '$lib/constants'; import { Click, trackEvent } from '$lib/actions/analytics'; @@ -25,6 +25,7 @@ import { IconTag } from '@appwrite.io/pink-icons-svelte'; import { page } from '$app/state'; import type { RowFactoryOptions } from '$routes/(console)/organization-[organization]/billing/store'; + import type { Models } from '@appwrite.io/console'; let { currentPlan, @@ -34,8 +35,8 @@ limit = undefined, offset = undefined }: { - currentPlan: Plan; - nextPlan?: Plan | null; + currentPlan: Models.BillingPlan; + nextPlan?: Models.BillingPlan | null; availableCredit?: number | undefined; currentAggregation?: AggregationTeam | undefined; limit?: number | undefined; @@ -229,7 +230,7 @@ } function getBillingData( - currentPlan: Plan, + currentPlan: Models.BillingPlan, currentAggregation: AggregationTeam | undefined, isSmallViewport: boolean ) { diff --git a/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte b/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte index 083aff4445..301792d33a 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummaryOld.svelte @@ -3,9 +3,9 @@ import { CardGrid } from '$lib/components'; import { Button } from '$lib/elements/forms'; import { toLocaleDate } from '$lib/helpers/date'; - import { plansInfo, upgradeURL } from '$lib/stores/billing'; + import { upgradeURL } from '$lib/stores/billing'; import { organization } from '$lib/stores/organization'; - import type { Aggregation, Invoice, Plan } from '$lib/sdk/billing'; + import type { Aggregation, Invoice } from '$lib/sdk/billing'; import { abbreviateNumber, formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers'; import { BillingPlan } from '$lib/constants'; import { Click, trackEvent } from '$lib/actions/analytics'; @@ -20,8 +20,9 @@ } from '@appwrite.io/pink-svelte'; import { IconInfo, IconTag } from '@appwrite.io/pink-icons-svelte'; import CancelDowngradeModel from './cancelDowngradeModal.svelte'; + import type { Models } from '@appwrite.io/console'; - export let currentPlan: Plan; + export let currentPlan: Models.BillingPlan; export let currentInvoice: Invoice | undefined = undefined; export let availableCredit: number | undefined = undefined; export let currentAggregation: Aggregation | undefined = undefined; @@ -31,7 +32,8 @@ const today = new Date(); const isTrial = new Date($organization?.billingStartDate).getTime() - today.getTime() > 0 && - $plansInfo.get($organization.billingPlan)?.trialDays; + $organization?.billingTrialDays; /* number of trial days. */ + const extraUsage = currentInvoice ? currentInvoice.amount - currentPlan?.price : 0; diff --git a/src/routes/(console)/organization-[organization]/header.svelte b/src/routes/(console)/organization-[organization]/header.svelte index 191131ae49..f35b360dcd 100644 --- a/src/routes/(console)/organization-[organization]/header.svelte +++ b/src/routes/(console)/organization-[organization]/header.svelte @@ -8,13 +8,7 @@ import { toLocaleDate } from '$lib/helpers/date'; import { isTabSelected } from '$lib/helpers/load'; import { Cover } from '$lib/layout'; - import { - daysLeftInTrial, - getServiceLimit, - plansInfo, - readOnly, - tierToPlan - } from '$lib/stores/billing'; + import { daysLeftInTrial, getServiceLimit, readOnly, tierToPlan } from '$lib/stores/billing'; import { members, newMemberModal, @@ -110,7 +104,7 @@ {:else if isCloud && organization?.billingPlan === BillingPlan.FREE} {/if} - {#if isCloud && organization?.billingTrialStartDate && $daysLeftInTrial > 0 && organization.billingPlan !== BillingPlan.FREE && $plansInfo.get(organization.billingPlan)?.trialDays} + {#if isCloud && organization?.billingTrialStartDate && $daysLeftInTrial > 0 && organization.billingPlan !== BillingPlan.FREE && organization?.billingTrialDays} diff --git a/src/routes/(console)/project-[region]-[project]/databases/+page.ts b/src/routes/(console)/project-[region]-[project]/databases/+page.ts index fcb828ff80..6c3719f61e 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/+page.ts @@ -7,7 +7,6 @@ import type { PageLoad, RouteParams } from './$types'; import type { BackupPolicy } from '$lib/sdk/backups'; import { isSelfHosted } from '$lib/system'; import { isCloud } from '$lib/system'; -import type { Plan } from '$lib/sdk/billing'; export const load: PageLoad = async ({ url, route, depends, params, parent }) => { depends(Dependencies.DATABASES); @@ -46,7 +45,7 @@ async function fetchDatabasesAndBackups( offset: number, params: RouteParams, search?: string | undefined, - currentPlan?: Plan + currentPlan?: Models.BillingPlan ) { const backupsEnabled = currentPlan?.backupsEnabled ?? true; diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte index 6e8b681dce..a58dbc1743 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/settings/updateMaxFileSize.svelte @@ -10,11 +10,10 @@ import { organization } from '$lib/stores/organization'; import { GRACE_PERIOD_OVERRIDE, isCloud } from '$lib/system'; import { updateBucket } from './+page.svelte'; - import type { Plan } from '$lib/sdk/billing'; import type { Models } from '@appwrite.io/console'; export let bucket: Models.Bucket; - export let currentPlan: Plan | null; + export let currentPlan: Models.BillingPlan | null; const service = currentPlan ? currentPlan['fileSize'] : null; const { value, unit, baseValue, units } = createByteUnitPair(bucket.maximumFileSize, 1000); From c462360681ec2e902bd503a70e6fdce30c7352b2 Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 18 Dec 2025 13:09:25 +0530 Subject: [PATCH 02/27] remove: credits manual type. --- src/lib/sdk/billing.ts | 55 +------------------ .../billing/availableCredit.svelte | 15 ++--- 2 files changed, 11 insertions(+), 59 deletions(-) diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 2cf540d92e..d195898758 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -102,55 +102,6 @@ export type Coupon = { onlyNewOrgs?: boolean; }; -export type Credit = { - /** - * Credit ID. - */ - $id: string; - /** - * Credit creation time in ISO 8601 format. - */ - $createdAt: string; - /** - * Credit update date in ISO 8601 format. - */ - $updatedAt: string; - /** - * coupon ID - */ - couponId: string; - /** - * ID of the User. - */ - userId: string; - /** - * ID of the Team. - */ - teamId: string; - /** - * Provided credit amount - */ - total: number; - /** - * Remaining credit amount - */ - credits: number; - /** - * Credit expiration time in ISO 8601 format. - */ - expiration: string; - /** - * Status of the credit. Can be one of `disabled`, `active` or `expired`. - */ - status: string; -}; - -export type CreditList = { - available: number; - credits: Credit[]; - total: number; -}; - export type AggregationTeam = { $id: string; /** @@ -880,7 +831,7 @@ export class Billing { ); } - async addCredit(organizationId: string, couponId: string): Promise { + async addCredit(organizationId: string, couponId: string): Promise { const path = `/organizations/${organizationId}/credits`; const params = { couponId @@ -895,7 +846,7 @@ export class Billing { params ); } - async listCredits(organizationId: string, queries = []): Promise { + async listCredits(organizationId: string, queries = []): Promise { const path = `/organizations/${organizationId}/credits`; const params = { queries @@ -925,7 +876,7 @@ export class Billing { ); } - async getCredit(organizationId: string, creditId: string): Promise { + async getCredit(organizationId: string, creditId: string): Promise { const path = `/organizations/${organizationId}/credits/${creditId}`; const params = { creditId diff --git a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte index 52bc768599..0744f5e653 100644 --- a/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte +++ b/src/routes/(console)/organization-[organization]/billing/availableCredit.svelte @@ -1,11 +1,10 @@ diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index d195898758..c52e2ed18a 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -4,31 +4,6 @@ import type { Client, Models } from '@appwrite.io/console'; import type { PaymentMethod } from '@stripe/stripe-js'; import type { Organization, OrganizationError, OrganizationList } from '../stores/organization'; -export type PaymentMethodData = { - $id: string; - $createdAt: string; - $updatedAt: string; - providerMethodId: string; - providerUserId: string; - userId: string; - expiryMonth: number; - expiryYear: number; - expired: boolean; - last4: string; - country: string; - brand: string; - clientSecret: string; - failed: boolean; - name: string; - mandateId?: string; - lastError?: string; -}; - -export type PaymentList = { - paymentMethods: PaymentMethodData[]; - total: number; -}; - export type Invoice = { $id: string; $createdAt: Date; @@ -1002,7 +977,7 @@ export class Billing { async getOrganizationPaymentMethod( organizationId: string, paymentMethodId: string - ): Promise { + ): Promise { const path = `/organizations/${organizationId}/payment-methods/${paymentMethodId}`; const params = { organizationId, @@ -1041,7 +1016,7 @@ export class Billing { //ACCOUNT - async listPaymentMethods(queries: [] = []): Promise { + async listPaymentMethods(queries: [] = []): Promise { const path = `/account/payment-methods`; const params = { queries @@ -1057,7 +1032,7 @@ export class Billing { ); } - async getPaymentMethod(paymentMethodId: string): Promise { + async getPaymentMethod(paymentMethodId: string): Promise { const path = `/account/payment-methods/${paymentMethodId}`; const params = { paymentMethodId @@ -1073,7 +1048,7 @@ export class Billing { ); } - async createPaymentMethod(): Promise { + async createPaymentMethod(): Promise { const path = `/account/payment-methods`; const params = {}; const uri = new URL(this.client.config.endpoint + path); @@ -1092,7 +1067,7 @@ export class Billing { providerMethodId: string | PaymentMethod, name: string, state: string | undefined = undefined - ): Promise { + ): Promise { const path = `/account/payment-methods/${paymentMethodId}/provider`; const params = { paymentMethodId, @@ -1118,7 +1093,7 @@ export class Billing { paymentMethodId: string, expiryMonth: string, expiryYear: string - ): Promise { + ): Promise { const path = `/account/payment-methods/${paymentMethodId}`; const params = { paymentMethodId, @@ -1136,7 +1111,7 @@ export class Billing { ); } - async deletePaymentMethod(paymentMethodId: string): Promise { + async deletePaymentMethod(paymentMethodId: string): Promise { const path = `/account/payment-methods/${paymentMethodId}`; const params = { paymentMethodId @@ -1151,7 +1126,7 @@ export class Billing { params ); } - async setDefaultPaymentMethod(paymentMethodId: string): Promise { + async setDefaultPaymentMethod(paymentMethodId: string): Promise { const path = `/account/payment-methods/${paymentMethodId}/default`; const params = { paymentMethodId @@ -1170,7 +1145,7 @@ export class Billing { async setupPaymentMandate( organizationId: string, paymentMethodId: string - ): Promise { + ): Promise { const path = `/account/payment-methods/${paymentMethodId}/setup`; const params = { organizationId, diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 5c7305125f..60746241d8 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -17,8 +17,6 @@ import type { AggregationTeam, Invoice, InvoiceList, - PaymentList, - PaymentMethodData, BillingPlansMap } from '$lib/sdk/billing'; import { isCloud } from '$lib/system'; @@ -69,7 +67,10 @@ export const roles = [ export const teamStatusReadonly = 'readonly'; export const billingLimitOutstandingInvoice = 'outstanding_invoice'; -export const paymentMethods = derived(page, ($page) => $page.data.paymentMethods as PaymentList); +export const paymentMethods = derived( + page, + ($page) => $page.data.paymentMethods as Models.PaymentMethodList +); export const addressList = derived(page, ($page) => $page.data.addressList as AddressesList); export const plansInfo = derived(page, ($page) => $page.data.plansInfo as BillingPlansMap); export const daysLeftInTrial = writable(0); @@ -538,7 +539,7 @@ export function checkForMarkedForDeletion(org: Organization) { } } -export const paymentMissingMandate = writable(null); +export const paymentMissingMandate = writable(null); export async function checkForMandate(org: Organization) { const paymentId = org.paymentMethodId ?? org.backupPaymentMethodId; diff --git a/src/lib/stores/stripe.ts b/src/lib/stores/stripe.ts index 9f4bc727bc..cda0bf776c 100644 --- a/src/lib/stores/stripe.ts +++ b/src/lib/stores/stripe.ts @@ -1,6 +1,6 @@ import type { Appearance, - PaymentMethod, + PaymentMethod as StripePaymentMethod, Stripe, StripeElement, StripeElements @@ -8,21 +8,21 @@ import type { import { sdk } from './sdk'; import { app } from './app'; import { get, writable } from 'svelte/store'; -import type { PaymentMethodData } from '$lib/sdk/billing'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from './notifications'; import { organization } from './organization'; import { base } from '$app/paths'; import { ThemeDarkCloud, ThemeLightCloud } from '$themes'; import Color from 'color'; +import type { Models } from '@appwrite.io/console'; export const stripe = writable(); -let paymentMethod: PaymentMethodData; +export const isStripeInitialized = writable(false); + let clientSecret: string; let elements: StripeElements; let paymentElement: StripeElement; - -export const isStripeInitialized = writable(false); +let paymentMethod: Models.PaymentMethod; export async function initializeStripe(node: HTMLElement) { if (!get(stripe)) return; @@ -116,12 +116,12 @@ export async function submitStripeCard(name: string, organizationId?: string) { } if (setupIntent && setupIntent.status === 'succeeded') { - const pm = setupIntent.payment_method as PaymentMethod | string | undefined; + const pm = setupIntent.payment_method as StripePaymentMethod | string | undefined; // If Stripe returned an expanded PaymentMethod object, check the card country. // If it returned a string id (common), `typeof pm === 'string'` and we skip this. if (typeof pm !== 'string' && pm?.card?.country === 'US') { // need to get state - return pm as PaymentMethod; + return pm as StripePaymentMethod; } // The backend expects a provider method ID (string). Extract the id @@ -130,7 +130,7 @@ export async function submitStripeCard(name: string, organizationId?: string) { if (typeof pm === 'string') { providerId = pm; } else { - providerId = (pm as PaymentMethod)?.id; + providerId = (pm as StripePaymentMethod)?.id; } if (!providerId) { diff --git a/src/routes/(console)/account/payments/editPaymentModal.svelte b/src/routes/(console)/account/payments/editPaymentModal.svelte index 7850cdea9a..5b1145f686 100644 --- a/src/routes/(console)/account/payments/editPaymentModal.svelte +++ b/src/routes/(console)/account/payments/editPaymentModal.svelte @@ -5,12 +5,12 @@ import { Dependencies } from '$lib/constants'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; - import type { PaymentMethodData } from '$lib/sdk/billing'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { Alert } from '@appwrite.io/pink-svelte'; + import type { Models } from '@appwrite.io/console'; export let show = false; - export let selectedPaymentMethod: PaymentMethodData; + export let selectedPaymentMethod: Models.PaymentMethod; export let isLinked = false; const currentYear = new Date().getFullYear(); let error: string; diff --git a/src/routes/(console)/account/payments/paymentMethods.svelte b/src/routes/(console)/account/payments/paymentMethods.svelte index 8e53a8d3da..53d3b270a5 100644 --- a/src/routes/(console)/account/payments/paymentMethods.svelte +++ b/src/routes/(console)/account/payments/paymentMethods.svelte @@ -2,7 +2,6 @@ import { CardGrid, CreditCardInfo, Empty } from '$lib/components'; import { Button } from '$lib/elements/forms'; import { paymentMethods } from '$lib/stores/billing'; - import type { PaymentMethodData } from '$lib/sdk/billing'; import { organizationList, type Organization } from '$lib/stores/organization'; import { base } from '$app/paths'; import EditPaymentModal from './editPaymentModal.svelte'; @@ -26,10 +25,11 @@ Tag, Typography } from '@appwrite.io/pink-svelte'; + import type { Models } from '@appwrite.io/console'; export let showPayment = false; let showDropdown = []; - let selectedMethod: PaymentMethodData; + let selectedMethod: Models.PaymentMethod; let selectedLinkedOrgs: Organization[] = []; let showDelete = false; let showEdit = false; @@ -37,9 +37,7 @@ $: orgList = $organizationList.teams as unknown as Organization[]; - $: filteredMethods = $paymentMethods?.paymentMethods.filter( - (method: PaymentMethodData) => !!method?.last4 - ); + $: filteredMethods = $paymentMethods?.paymentMethods.filter((method) => !!method?.last4); const isMethodLinkedToOrg = (methodId: string, org: Organization) => methodId === org.paymentMethodId || methodId === org.backupPaymentMethodId; diff --git a/src/routes/(console)/apply-credit/+page.svelte b/src/routes/(console)/apply-credit/+page.svelte index b7226b3e77..29b8c85df7 100644 --- a/src/routes/(console)/apply-credit/+page.svelte +++ b/src/routes/(console)/apply-credit/+page.svelte @@ -8,7 +8,6 @@ import { Button, Form, InputSelect, InputTags, InputText } from '$lib/elements/forms'; import { toLocaleDate } from '$lib/helpers/date'; import { Wizard } from '$lib/layout'; - import type { PaymentList } from '$lib/sdk/billing'; import { addNotification } from '$lib/stores/notifications'; import { organizationList, @@ -48,7 +47,7 @@ let formComponent: Form; let couponForm: Form; let isSubmitting = writable(false); - let methods: PaymentList; + let methods: Models.PaymentMethodList; let paymentMethodId: string; let collaborators: string[]; let taxId: string; diff --git a/src/routes/(console)/organization-[organization]/billing/+page.svelte b/src/routes/(console)/organization-[organization]/billing/+page.svelte index 99729b8e9a..271912fd04 100644 --- a/src/routes/(console)/organization-[organization]/billing/+page.svelte +++ b/src/routes/(console)/organization-[organization]/billing/+page.svelte @@ -9,7 +9,6 @@ import PaymentHistory from './paymentHistory.svelte'; import TaxId from './taxId.svelte'; import { failedInvoice, tierToPlan, upgradeURL, useNewPricingModal } from '$lib/stores/billing'; - import type { PaymentMethodData } from '$lib/sdk/billing'; import { onMount } from 'svelte'; import { page } from '$app/state'; import { confirmPayment } from '$lib/stores/stripe'; @@ -31,11 +30,11 @@ // why are these reactive? $: defaultPaymentMethod = data?.paymentMethods?.paymentMethods?.find( - (method: PaymentMethodData) => method.$id === organization?.paymentMethodId + (method) => method.$id === organization?.paymentMethodId ); $: backupPaymentMethod = data?.paymentMethods?.paymentMethods?.find( - (method: PaymentMethodData) => method.$id === organization?.backupPaymentMethodId + (method) => method.$id === organization?.backupPaymentMethodId ); onMount(async () => { diff --git a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte index 124518f1e3..6f45b4b94c 100644 --- a/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte +++ b/src/routes/(console)/organization-[organization]/billing/paymentMethods.svelte @@ -8,7 +8,6 @@ import { type Organization } from '$lib/stores/organization'; import { Button } from '$lib/elements/forms'; import { hasStripePublicKey, isCloud } from '$lib/system'; - import type { PaymentList, PaymentMethodData } from '$lib/sdk/billing'; import DeleteOrgPayment from './deleteOrgPayment.svelte'; import ReplaceCard from './replaceCard.svelte'; import EditPaymentModal from '$routes/(console)/account/payments/editPaymentModal.svelte'; @@ -33,17 +32,18 @@ IconSwitchHorizontal, IconTrash } from '@appwrite.io/pink-icons-svelte'; + import type { Models } from '@appwrite.io/console'; export let organization: Organization; - export let methods: PaymentList; + export let methods: Models.PaymentMethodList; - let showPayment = false; let showEdit = false; let showDelete = false; + let showPayment = false; let showReplace = false; let isSelectedBackup = false; - let backupPaymentMethod: PaymentMethodData; - let defaultPaymentMethod: PaymentMethodData; + let backupPaymentMethod: Models.PaymentMethod; + let defaultPaymentMethod: Models.PaymentMethod; async function addPaymentMethod(paymentMethodId: string) { try { diff --git a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte index ea4cc7d267..05551918fb 100644 --- a/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte +++ b/src/routes/(console)/organization-[organization]/billing/replaceCard.svelte @@ -7,23 +7,23 @@ import { Dependencies } from '$lib/constants'; import { setPaymentMethod, submitStripeCard } from '$lib/stores/stripe'; import { onMount } from 'svelte'; - import type { PaymentList, PaymentMethodData } from '$lib/sdk/billing'; import { addNotification } from '$lib/stores/notifications'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { PaymentBoxes } from '$lib/components/billing'; - import type { PaymentMethod } from '@stripe/stripe-js'; + import type { PaymentMethod as StripePaymentMethod } from '@stripe/stripe-js'; + import type { Models } from '@appwrite.io/console'; export let organization: Organization; export let show = false; export let isBackup = false; - export let methods: PaymentList; + export let methods: Models.PaymentMethodList; let name: string; let error: string = null; let selectedPaymentMethodId: string; let showState: boolean = false; let state: string = ''; - let paymentMethod: PaymentMethod | null = null; + let paymentMethod: StripePaymentMethod | null = null; onMount(async () => { if (!organization.paymentMethodId && !organization.backupPaymentMethodId) { @@ -48,19 +48,19 @@ if (showState && !state) { throw Error('Please select a state'); } - let method: PaymentMethodData; + let method: Models.PaymentMethod; if (showState) { method = await setPaymentMethod(paymentMethod.id, name, state); } else { const card = await submitStripeCard(name, organization.$id); if (card && Object.hasOwn(card, 'id')) { - if ((card as PaymentMethod).card?.country === 'US') { - paymentMethod = card as PaymentMethod; + if ((card as StripePaymentMethod).card?.country === 'US') { + paymentMethod = card as StripePaymentMethod; showState = true; return; } } else if (card && Object.hasOwn(card, '$id')) { - method = card as PaymentMethodData; + method = card as Models.PaymentMethod; } } selectedPaymentMethodId = method.$id; diff --git a/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte b/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte index 65e217d2c6..ab7384d568 100644 --- a/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte +++ b/src/routes/(console)/organization-[organization]/billing/retryPaymentModal.svelte @@ -3,7 +3,7 @@ import { FakeModal } from '$lib/components'; import { Button } from '$lib/elements/forms'; import { Dependencies } from '$lib/constants'; - import type { Invoice, PaymentMethodData } from '$lib/sdk/billing'; + import type { Invoice } from '$lib/sdk/billing'; import { addNotification } from '$lib/stores/notifications'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { page } from '$app/state'; @@ -21,18 +21,21 @@ import { getApiEndpoint, sdk } from '$lib/stores/sdk'; import { formatCurrency } from '$lib/helpers/numbers'; import { base } from '$app/paths'; - import type { PaymentMethod } from '@stripe/stripe-js'; + import type { PaymentMethod as StripePaymentMethod } from '@stripe/stripe-js'; + import type { Models } from '@appwrite.io/console'; export let show = false; export let invoice: Invoice; + + let name: string; + let state: string = ''; let error: string = null; + let setAsDefault = false; let isButtonDisabled = false; - let name: string; let paymentMethodId: string; - let setAsDefault = false; let showState: boolean = false; - let state: string = ''; - let paymentMethod: PaymentMethod | null = null; + let paymentMethod: StripePaymentMethod | null = null; + const endpoint = getApiEndpoint(); onMount(async () => { @@ -60,15 +63,15 @@ if (showState && !state) { throw Error('Please select a state'); } - let method: PaymentMethodData; + let method: Models.PaymentMethod; if (showState) { method = await setPaymentMethod(paymentMethod.id, name, state); } else { const card = await submitStripeCard(name, $organization.$id); // When Stripe returns an expanded PaymentMethod for US cards, we need state. - if (Object.hasOwn(card, 'id') && (card as PaymentMethod)?.card) { - if ((card as PaymentMethod).card?.country === 'US') { - paymentMethod = card as PaymentMethod; + if (Object.hasOwn(card, 'id') && (card as StripePaymentMethod)?.card) { + if ((card as StripePaymentMethod).card?.country === 'US') { + paymentMethod = card as StripePaymentMethod; showState = true; return; } @@ -76,7 +79,7 @@ // Otherwise, we expect an Appwrite PaymentMethodData with `$id`. if (Object.hasOwn(card, '$id')) { - method = card as PaymentMethodData; + method = card as Models.PaymentMethod; } } const card = await sdk.forConsole.billing.getPaymentMethod(method.$id); diff --git a/src/routes/(console)/organization-[organization]/billing/wizard/paymentDetails.svelte b/src/routes/(console)/organization-[organization]/billing/wizard/paymentDetails.svelte index fd27def7e0..7ee8a49b65 100644 --- a/src/routes/(console)/organization-[organization]/billing/wizard/paymentDetails.svelte +++ b/src/routes/(console)/organization-[organization]/billing/wizard/paymentDetails.svelte @@ -1,7 +1,6 @@ {#if estimation} diff --git a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte index dab95d83a3..25a97956de 100644 --- a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte +++ b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte @@ -15,15 +15,15 @@ import { tierToPlan } from '$lib/stores/billing'; import { Table, Tabs, Alert } from '@appwrite.io/pink-svelte'; import DeleteOrganizationEstimation from './deleteOrganizationEstimation.svelte'; - import type { EstimationDeleteOrganization, InvoiceList } from '$lib/sdk/billing'; + import type { Models } from '@appwrite.io/console'; export let showDelete = false; - export let invoices: InvoiceList; - let error: string = null; + export let invoices: Models.InvoiceList; + let error: string = null; let selectedTab = 'projects'; let organizationName: string = null; - let estimation: EstimationDeleteOrganization; + let estimation: Models.EstimationDeleteOrganization; async function deleteOrg() { try { @@ -112,7 +112,8 @@ This action is irreversible. {/if}

- {#if estimation && (estimation.unpaidInvoices.length > 0 || estimation.grossAmount > 0)} + + {#if estimation && (estimation.unpaidInvoices.length > 0 || estimation.unpaidInvoices.some((invoice) => invoice.grossAmount > 0))} {:else} {#if $projects.total > 0} diff --git a/src/routes/(console)/organization-[organization]/settings/invoicesTable.svelte b/src/routes/(console)/organization-[organization]/settings/invoicesTable.svelte index 84b7ca6093..514e8a575a 100644 --- a/src/routes/(console)/organization-[organization]/settings/invoicesTable.svelte +++ b/src/routes/(console)/organization-[organization]/settings/invoicesTable.svelte @@ -1,5 +1,4 @@ {#if $organization?.$id && $organization?.billingPlan === BillingPlan.FREE && $readOnly && !hideBillingHeaderRoutes.includes(page.url.pathname)} + title={`${$organization.name} usage has reached the ${billingIdToPlan($organization.billingPlan).name} plan limit`}> - Usage for the {$organization.name} organization has reached the limits of the {tierToPlan( + Usage for the {$organization.name} organization has reached the limits of the {billingIdToPlan( $organization.billingPlan ).name} plan. Consider upgrading to increase your resource usage. diff --git a/src/lib/components/billing/emptyCardCloud.svelte b/src/lib/components/billing/emptyCardCloud.svelte index b83676f28d..0ca7071967 100644 --- a/src/lib/components/billing/emptyCardCloud.svelte +++ b/src/lib/components/billing/emptyCardCloud.svelte @@ -1,21 +1,33 @@ - + {#if children} + {@render children()} + {:else} Upgrade to add {service} - Upgrade to a {tierToPlan(BillingPlan.PRO).name} plan to add {service} to your organization + Upgrade to a {proPlanName} plan to add {service} to your organization