Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/lib/components/estimatedCard.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import { Layout, Card } from '@appwrite.io/pink-svelte';

export let gap: 'none' | 'xxxs' | 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl' | 'xxxl' = 'l';
</script>

<Card.Base>
<Layout.Stack {gap}>
<slot />
</Layout.Stack>
</Card.Base>
1 change: 1 addition & 0 deletions src/lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ export { default as UsageCard } from './usageCard.svelte';
export { default as ViewToggle } from './viewToggle.svelte';
export { default as RegionEndpoint } from './regionEndpoint.svelte';
export { default as ExpirationInput } from './expirationInput.svelte';
export { default as EstimatedCard } from './estimatedCard.svelte';
6 changes: 3 additions & 3 deletions src/lib/sdk/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,21 +207,21 @@ export type AggregationTeam = {
* Aggregation billing plan
*/
plan: string;
projectBreakdown: ProjectBreakdown[]
projectBreakdown: ProjectBreakdown[];
};

export type ProjectBreakdown = {
$id: string;
name: string;
amount: number;
resources: InvoiceUsage[];
}
};

export type InvoiceUsage = {
resourceId: string;
value: number;
amount: number;
}
};

export type AvailableCredit = {
available: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@
availableCredit={data?.availableCredit}
currentPlan={data?.currentPlan}
currentAggregation={data?.billingAggregation}
currentInvoice={data?.billingInvoice} />
currentInvoice={data?.billingInvoice}
organizationUsage={data?.organizationUsage}
usageProjects={data?.usageProjects} />
<PaymentHistory />
<PaymentMethods organization={data?.organization} methods={data?.paymentMethods} />
<BillingAddress
Expand Down
58 changes: 51 additions & 7 deletions src/routes/(console)/organization-[organization]/billing/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { sdk } from '$lib/stores/sdk';
import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types';
import { isCloud } from '$lib/system';
import { Query } from '@appwrite.io/console';
import type { UsageProjectInfo } from '../store';
import type { OrganizationUsage } from '$lib/sdk/billing';

export const load: PageLoad = async ({ parent, depends }) => {
const { organization, scopes, currentPlan, countryList, locale } = await parent();
Expand Down Expand Up @@ -57,16 +60,27 @@ export const load: PageLoad = async ({ parent, depends }) => {
organization?.billingPlan !== BillingPlan.GITHUB_EDUCATION))
: false;

const [paymentMethods, addressList, billingAddress, availableCredit] = await Promise.all([
sdk.forConsole.billing.listPaymentMethods(),
sdk.forConsole.billing.listAddresses(),
billingAddressPromise,
areCreditsSupported ? sdk.forConsole.billing.getAvailableCredit(organization.$id) : null
]);
const [paymentMethods, addressList, billingAddress, availableCredit, organizationUsage] =
await Promise.all([
sdk.forConsole.billing.listPaymentMethods(),
sdk.forConsole.billing.listAddresses(),
billingAddressPromise,
areCreditsSupported
? sdk.forConsole.billing.getAvailableCredit(organization.$id)
: null,
sdk.forConsole.billing.listUsage(
organization.$id,
organization.billingCurrentInvoiceDate,
organization.billingNextInvoiceDate
)
]);

// make number
const credits = availableCredit ? availableCredit.available : null;

// Get project information for usage display
const usageProjects = organizationUsage ? await getUsageProjects(organizationUsage) : {};

return {
paymentMethods,
addressList,
Expand All @@ -76,6 +90,36 @@ export const load: PageLoad = async ({ parent, depends }) => {
billingInvoice,
areCreditsSupported,
countryList,
locale
locale,
organizationUsage,
usageProjects
};
};

// Get project names and regions for usage display
async function getUsageProjects(
usage: OrganizationUsage
): Promise<Record<string, UsageProjectInfo>> {
const projects: Record<string, UsageProjectInfo> = {};
const limit = 100;
const requests = [];

for (let index = 0; index < usage.projects.length; index += limit) {
const chunkIds = usage.projects.slice(index, index + limit).map((p) => p.projectId);
requests.push(
sdk.forConsole.projects.list([Query.limit(limit), Query.equal('$id', chunkIds)])
);
}

const responses = await Promise.all(requests);
for (const response of responses) {
for (const project of response.projects) {
projects[project.$id] = {
name: project.name,
region: project.region
};
}
}

return projects;
}
Loading
Loading