From 4258403f73e01a2a9f58450e9f174cb76c6b8d84 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sun, 14 Dec 2025 13:27:29 +0530 Subject: [PATCH] add: credits usage on org. add: usage on menu. add: member checks. --- src/lib/components/navbar.svelte | 8 +++ src/lib/sdk/billing.ts | 6 +++ .../+layout.svelte | 4 +- .../organization-[organization]/+layout.ts | 7 ++- .../usage/[[invoice]]/+page.svelte | 53 ++++++++++++++++++- .../usage/[[invoice]]/+page.ts | 6 ++- .../usage/[[invoice]]/ProjectBreakdown.svelte | 6 ++- 7 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/lib/components/navbar.svelte b/src/lib/components/navbar.svelte index dcdf4eaeed..8ed9e880da 100644 --- a/src/lib/components/navbar.svelte +++ b/src/lib/components/navbar.svelte @@ -30,6 +30,7 @@ } from '@appwrite.io/pink-svelte'; import { toggleCommandCenter } from '$lib/commandCenter/commandCenter.svelte'; import { + IconChartSquareBar, IconChevronRight, IconCreditCard, IconGlobeAlt, @@ -269,6 +270,13 @@ on:click={() => toggle()}> Domains + toggle()}> + Usage + {/if} diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 4b40877b6c..1cf9ebdf55 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -293,12 +293,16 @@ export type OrganizationUsage = { databasesReads: Array; databasesWrites: Array; imageTransformations: Array; + screenshotsGenerated: Array; + imagineCredits: Array; executionsTotal: number; filesStorageTotal: number; buildsStorageTotal: number; databasesReadsTotal: number; databasesWritesTotal: number; imageTransformationsTotal: number; + screenshotsGeneratedTotal: number; + imagineCreditsTotal: number; deploymentsStorageTotal: number; executionsMBSecondsTotal: number; buildsMBSecondsTotal: number; @@ -317,6 +321,8 @@ export type OrganizationUsage = { authPhoneTotal: number; authPhoneEstimate: number; imageTransformations: number; + screenshotsGenerated: number; + imagineCredits: number; }>; authPhoneTotal: number; authPhoneEstimate: number; diff --git a/src/routes/(console)/organization-[organization]/+layout.svelte b/src/routes/(console)/organization-[organization]/+layout.svelte index 7ea186b231..5220180066 100644 --- a/src/routes/(console)/organization-[organization]/+layout.svelte +++ b/src/routes/(console)/organization-[organization]/+layout.svelte @@ -57,4 +57,6 @@ - +{#if page.data.supportsMoreMembers} + +{/if} diff --git a/src/routes/(console)/organization-[organization]/+layout.ts b/src/routes/(console)/organization-[organization]/+layout.ts index 17878b5bd1..4ca9410644 100644 --- a/src/routes/(console)/organization-[organization]/+layout.ts +++ b/src/routes/(console)/organization-[organization]/+layout.ts @@ -64,6 +64,10 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { loadAvailableRegions(params.organization) ]); + const seatsAddon = currentPlan?.addons?.seats; + const canAddMembers = + !seatsAddon || (seatsAddon.supported ?? false) || (seatsAddon.limit ?? 0) > 1; + return { header: Header, breadcrumbs: Breadcrumbs, @@ -73,7 +77,8 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => { roles, scopes, countryList, - locale + locale, + supportsMoreMembers: canAddMembers }; } catch (e) { const newPrefs = { diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte index d3e74c2fbe..009cb159f5 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.svelte @@ -25,7 +25,8 @@ import { onMount } from 'svelte'; import type { UsageProjectInfo } from '../../store'; import { isFreePlan } from '$lib/helpers/billing'; - import { resolvedProfile } from '$lib/profiles/index.svelte'; + import { ProfileMode, resolvedProfile } from '$lib/profiles/index.svelte'; + import { page } from '$app/state'; export let data; @@ -114,6 +115,52 @@

{/if} + {#if resolvedProfile.id === ProfileMode.STUDIO} + + Credits + The total number of credits used across all projects in your organization. + + {#if data.organizationUsage.imagineCreditsTotal} + {@const current = data.organizationUsage.imagineCreditsTotal} + + [ + e.date, + e.value + ]) + ] + } + ]} /> + {#if projects?.length > 0} + + {/if} + {:else} + + + + No data to show + + + {/if} + + + {/if} + Bandwidth Calculated for all bandwidth used across all projects in your organization. Resets at the start @@ -550,7 +597,9 @@ - + {#if page.data.supportsMoreMembers} + + {/if}

Metrics are estimates updated every 24 hours and may not accurately reflect your invoice. diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts index 8fd36fadfc..d4ef063161 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/+page.ts @@ -34,7 +34,11 @@ export const load: PageLoad = async ({ params, parent }) => { databasesReadsTotal: null, databasesWritesTotal: null, imageTransformations: null, - imageTransformationsTotal: null + imageTransformationsTotal: null, + screenshotsGenerated: null, + screenshotsGeneratedTotal: null, + imagineCredits: null, + imagineCreditsTotal: null } }; } diff --git a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte index 98a0282821..5425002d99 100644 --- a/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte +++ b/src/routes/(console)/organization-[organization]/usage/[[invoice]]/ProjectBreakdown.svelte @@ -16,7 +16,9 @@ | 'authPhoneTotal' | 'databasesReads' | 'databasesWrites' - | 'imageTransformations'; + | 'imageTransformations' + | 'screenshotsGenerated' + | 'imagineCredits'; type Estimate = 'authPhoneEstimate'; @@ -89,6 +91,8 @@ switch (metric) { case 'imageTransformations': + case 'screenshotsGenerated': + case 'imagineCredits': case 'authPhoneTotal': return formatNumberWithCommas(value); case 'executions':