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':