Skip to content

Commit 6c9de0a

Browse files
Merge pull request #1738 from appwrite/fix-budget-limit-alert
Feat: show budget limit alert
2 parents a66aa3f + ff0b9e8 commit 6c9de0a

File tree

5 files changed

+61
-5
lines changed

5 files changed

+61
-5
lines changed

src/lib/components/heading.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,10 @@
2121
{id}>
2222
<slot />
2323
</svelte:element>
24+
25+
<style>
26+
:target {
27+
padding-top: 120px;
28+
margin-top: -120px;
29+
}
30+
</style>

src/lib/stores/billing.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { organization, type Organization, type OrganizationError } from './organ
3232
import { canSeeBilling } from './roles';
3333
import { sdk } from './sdk';
3434
import { user } from './user';
35+
import BudgetLimitAlert from '$routes/(console)/organization-[organization]/budgetLimitAlert.svelte';
3536

3637
export type Tier = 'tier-0' | 'tier-1' | 'tier-2' | 'auto-1' | 'cont-1' | 'ent-1';
3738

@@ -64,6 +65,11 @@ export const plansInfo = derived(page, ($page) => $page.data.plansInfo as PlansM
6465
export const daysLeftInTrial = writable<number>(0);
6566
export const readOnly = writable<boolean>(false);
6667

68+
export const showBudgetAlert = derived(
69+
page,
70+
($page) => ($page.data.organization?.billingLimits.budgetLimit ?? 0) >= 100
71+
);
72+
6773
export function getRoleLabel(role: string) {
6874
return roles.find((r) => r.value === role)?.label ?? role;
6975
}
@@ -264,12 +270,26 @@ export function calculateTrialDay(org: Organization) {
264270
}
265271

266272
export async function checkForUsageLimit(org: Organization) {
267-
if (org?.billingPlan !== BillingPlan.FREE) {
273+
if (!org?.billingLimits) {
268274
readOnly.set(false);
269275
return;
270276
}
271-
if (!org?.billingLimits) {
272-
readOnly.set(false);
277+
if (org?.billingPlan !== BillingPlan.FREE) {
278+
const { budgetLimit } = org?.billingLimits ?? {};
279+
280+
if (!budgetLimit || budgetLimit < 100) {
281+
readOnly.set(false);
282+
return;
283+
}
284+
285+
headerAlert.add({
286+
id: 'budgetLimit',
287+
component: BudgetLimitAlert,
288+
show: true,
289+
importance: 10
290+
});
291+
292+
readOnly.set(true);
273293
return;
274294
}
275295
const { bandwidth, documents, executions, storage, users } = org?.billingLimits ?? {};

src/lib/stores/organization.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export type BillingLimits = {
4545
executions: number;
4646
storage: number;
4747
users: number;
48+
budgetLimit: number;
4849
};
4950

5051
export const newOrgModal = writable<boolean>(false);

src/routes/(console)/organization-[organization]/billing/budgetCap.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
budget,
2727
$organization.budgetAlerts
2828
);
29-
invalidate(Dependencies.ORGANIZATION);
29+
await invalidate(Dependencies.ORGANIZATION);
3030
addNotification({
3131
type: 'success',
3232
isHtml: true,
@@ -51,7 +51,7 @@
5151

5252
<Form onSubmit={updateBudget}>
5353
<CardGrid>
54-
<Heading tag="h2" size="6">Budget cap</Heading>
54+
<Heading id="update-budget" tag="h2" size="6">Budget cap</Heading>
5555

5656
<p class="text">
5757
Restrict your resource usage by setting a budget cap. Cap usage is reset at the
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts">
2+
import { page } from '$app/stores';
3+
import { BillingPlan } from '$lib/constants';
4+
import { Button } from '$lib/elements/forms';
5+
import { organization } from '$lib/stores/organization';
6+
import { HeaderAlert } from '$lib/layout';
7+
import { hideBillingHeaderRoutes, readOnly, showBudgetAlert } from '$lib/stores/billing';
8+
import { base } from '$app/paths';
9+
10+
$: redirectUrl = `${base}/organization-${$organization.$id}/billing#update-budget`;
11+
</script>
12+
13+
{#if $showBudgetAlert && $organization?.$id && $organization?.billingPlan !== BillingPlan.FREE && $readOnly && !hideBillingHeaderRoutes.includes($page.url.pathname)}
14+
<HeaderAlert type="error" title="Budget limit reached">
15+
<svelte:fragment>
16+
This organization has reached its budget limit and is now blocked. To continue using
17+
Appwrite services, update the budget limit.
18+
</svelte:fragment>
19+
<svelte:fragment slot="buttons">
20+
<Button href={`${base}/organization-${$organization.$id}/usage`} text fullWidthMobile>
21+
<span class="text">View usage</span>
22+
</Button>
23+
<Button secondary fullWidthMobile href={redirectUrl}>
24+
<span class="text">Update limit</span>
25+
</Button>
26+
</svelte:fragment>
27+
</HeaderAlert>
28+
{/if}

0 commit comments

Comments
 (0)