mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: failed payment and bug fixes
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { Client } from '@appwrite.io/console';
|
||||
import type { Client, Query } from '@appwrite.io/console';
|
||||
import type { Organization } from '../stores/organization';
|
||||
import type { PaymentMethod } from '@stripe/stripe-js';
|
||||
|
||||
@@ -297,7 +297,7 @@ export class Billing {
|
||||
|
||||
async listInvoices(
|
||||
organizationId: string,
|
||||
queries: string[] = [],
|
||||
queries: Query[] = [],
|
||||
search = ''
|
||||
): Promise<InvoiceList> {
|
||||
const path = `/organizations/${organizationId}/invoices`;
|
||||
|
||||
@@ -3,10 +3,11 @@ import { derived, get } from 'svelte/store';
|
||||
import { sdk } from './sdk';
|
||||
import { limitRates } from '$lib/constants';
|
||||
import { organization } from './organization';
|
||||
import type { PaymentList } from '$lib/sdk/billing';
|
||||
|
||||
export type Tier = 'tier-0' | 'tier-1' | 'tier-2';
|
||||
|
||||
export const paymentMethods = derived(page, ($page) => $page.data.paymentMethods);
|
||||
export const paymentMethods = derived(page, ($page) => $page.data.paymentMethods as PaymentList);
|
||||
|
||||
export function tierToPlan(tier: Tier) {
|
||||
switch (tier) {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
TableHeader,
|
||||
TableRow
|
||||
} from '$lib/elements/table';
|
||||
import { paymentMethods } from './store';
|
||||
import { paymentMethods } from '$lib/stores/billing';
|
||||
import type { PaymentMethodData } from '$lib/sdk/billing';
|
||||
import { organizationList, type Organization } from '$lib/stores/organization';
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import { page } from '$app/stores';
|
||||
import { derived } from 'svelte/store';
|
||||
|
||||
export const paymentMethods = derived(page, ($page) => $page.data.paymentMethods);
|
||||
@@ -6,10 +6,14 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { toLocaleDate } from '$lib/helpers/date';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { goto } from '$app/navigation';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
onMount(() => {
|
||||
if (isCloud) {
|
||||
checkForTrialEnding();
|
||||
paymentExpired();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -30,6 +34,32 @@
|
||||
localStorage.setItem('trialEndingNotification', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: move this function
|
||||
async function paymentExpired() {
|
||||
if (localStorage.getItem('paymentExpiredNotification') === 'true') return;
|
||||
const payment = await sdk.forConsole.billing.getPaymentMethod(
|
||||
$organization.paymentMethodId
|
||||
);
|
||||
|
||||
if (payment.expired) {
|
||||
addNotification({
|
||||
type: 'info',
|
||||
isHtml: true,
|
||||
dismissible: false,
|
||||
message: `The default payment method for <b>${$organization.name}</b> has expired`,
|
||||
buttons: [
|
||||
{
|
||||
name: 'Update payment details',
|
||||
method: () => {
|
||||
goto(`${base}/console/account/payments`);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
localStorage.setItem('paymentExpiredNotification', 'true');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
||||
@@ -8,9 +8,27 @@
|
||||
import PaymentMethods from './paymentMethods.svelte';
|
||||
import AvailableCredit from './availableCredit.svelte';
|
||||
import PaymentHistory from './paymentHistory.svelte';
|
||||
import { Alert, Heading } from '$lib/components';
|
||||
import { paymentMethods } from '$lib/stores/billing';
|
||||
import type { PaymentMethodData } from '$lib/sdk/billing';
|
||||
|
||||
$: defaultPaymentMethod = $paymentMethods.paymentMethods.find(
|
||||
(method: PaymentMethodData) => method.$id === $organization.paymentMethodId
|
||||
);
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
{#if defaultPaymentMethod.failed}
|
||||
<Alert type="error">
|
||||
<svelte:fragment slot="title">
|
||||
The default payment method for {$organization.name} has expired
|
||||
</svelte:fragment>
|
||||
To avoid service disruptions in your projects, please update your payment details.
|
||||
</Alert>
|
||||
{/if}
|
||||
<div class="common-section">
|
||||
<Heading tag="h2" size="5">Billing</Heading>
|
||||
</div>
|
||||
<PlanSummary />
|
||||
<PaymentHistory />
|
||||
<PaymentMethods />
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load: PageLoad = async ({ params, parent, depends }) => {
|
||||
@@ -11,10 +10,6 @@ export const load: PageLoad = async ({ params, parent, depends }) => {
|
||||
depends(Dependencies.INVOICES);
|
||||
|
||||
return {
|
||||
paymentMethods: await sdk.forConsole.billing.listPaymentMethods(),
|
||||
creditList: await sdk.forConsole.billing.listCredits(params.organization),
|
||||
invoiceList: await sdk.forConsole.billing.listInvoices(params.organization, [
|
||||
Query.limit(5)
|
||||
])
|
||||
paymentMethods: await sdk.forConsole.billing.listPaymentMethods()
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,15 +13,25 @@
|
||||
TableRow
|
||||
} from '$lib/elements/table';
|
||||
import { toLocaleDate } from '$lib/helpers/date';
|
||||
import type { Credit } from '$lib/sdk/billing';
|
||||
import type { Credit, CreditList } from '$lib/sdk/billing';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
import { creditList } from './store';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let coupon: string = null;
|
||||
let offset = 0;
|
||||
let creditList: CreditList = {
|
||||
credits: [],
|
||||
total: 0
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
request();
|
||||
});
|
||||
|
||||
const limit = 5;
|
||||
|
||||
async function redeem() {
|
||||
try {
|
||||
@@ -45,8 +55,8 @@
|
||||
}
|
||||
|
||||
async function request() {
|
||||
$creditList = await sdk.forConsole.billing.listCredits($organization.$id, [
|
||||
Query.limit(5),
|
||||
creditList = await sdk.forConsole.billing.listCredits($organization.$id, [
|
||||
Query.limit(limit),
|
||||
Query.offset(offset)
|
||||
]);
|
||||
}
|
||||
@@ -55,7 +65,7 @@
|
||||
request();
|
||||
}
|
||||
|
||||
$: balance = $creditList?.credits?.reduce((acc: number, curr: Credit) => acc + curr.credits, 0);
|
||||
$: balance = creditList?.credits?.reduce((acc: number, curr: Credit) => acc + curr.credits, 0);
|
||||
</script>
|
||||
|
||||
<CardGrid>
|
||||
@@ -80,7 +90,7 @@
|
||||
</InputText>
|
||||
</FormList>
|
||||
</Form>
|
||||
{#if $creditList?.total}
|
||||
{#if creditList?.total}
|
||||
<Table noStyles noMargin>
|
||||
<TableHeader>
|
||||
<TableCellHead>Date Added</TableCellHead>
|
||||
@@ -88,7 +98,7 @@
|
||||
<TableCellHead>Amount</TableCellHead>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{#each $creditList.credits as credit}
|
||||
{#each creditList.credits as credit}
|
||||
<TableRow>
|
||||
<TableCellText title="date added">
|
||||
{toLocaleDate(credit.$createdAt)}
|
||||
@@ -104,8 +114,8 @@
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div class="u-flex u-main-space-between">
|
||||
<p class="text">Total results: {$creditList?.total}</p>
|
||||
<PaginationInline limit={5} bind:offset sum={$creditList?.total} hidePages />
|
||||
<p class="text">Total results: {creditList?.total}</p>
|
||||
<PaginationInline {limit} bind:offset sum={creditList?.total} hidePages />
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -20,17 +20,28 @@
|
||||
TableRow
|
||||
} from '$lib/elements/table';
|
||||
import { toLocaleDate } from '$lib/helpers/date';
|
||||
import type { InvoiceList } from '$lib/sdk/billing';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Query } from '@appwrite.io/console';
|
||||
import { invoiceList } from './store';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let showDropdown = [];
|
||||
let selectedInvoice: string;
|
||||
let offset = 0;
|
||||
|
||||
let offset = 0;
|
||||
let invoiceList: InvoiceList = {
|
||||
invoices: [],
|
||||
total: 0
|
||||
};
|
||||
let downloadLink: string;
|
||||
let viewLink: string;
|
||||
|
||||
const limit = 5;
|
||||
|
||||
onMount(async () => {
|
||||
request();
|
||||
});
|
||||
|
||||
async function download() {
|
||||
return await sdk.forConsole.billing.downloadInvoice(
|
||||
$page.params.organization,
|
||||
@@ -46,9 +57,10 @@
|
||||
}
|
||||
|
||||
async function request() {
|
||||
$invoiceList = await sdk.forConsole.billing.listInvoices($page.params.organization, [
|
||||
Query.limit(5),
|
||||
Query.offset(offset)
|
||||
invoiceList = await sdk.forConsole.billing.listInvoices($page.params.organization, [
|
||||
Query.limit(limit),
|
||||
Query.offset(offset),
|
||||
Query.orderDesc('$createdAt')
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -74,7 +86,7 @@
|
||||
payments.
|
||||
</p>
|
||||
<svelte:fragment slot="aside">
|
||||
{#if $invoiceList.total}
|
||||
{#if invoiceList.total}
|
||||
<Table noMargin noStyles>
|
||||
<TableHeader>
|
||||
<TableCellHead>Due Date</TableCellHead>
|
||||
@@ -84,7 +96,7 @@
|
||||
<TableCellHead width={40} />
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{#each $invoiceList?.invoices as invoice, i}
|
||||
{#each invoiceList?.invoices as invoice, i}
|
||||
{@const status = invoice.status}
|
||||
<TableRow>
|
||||
<TableCellText title="date">
|
||||
@@ -133,8 +145,8 @@
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div class="u-flex u-main-space-between">
|
||||
<p class="text">Total results: {$invoiceList?.total}</p>
|
||||
<PaginationInline limit={1} bind:offset sum={$invoiceList?.total} hidePages />
|
||||
<p class="text">Total results: {invoiceList?.total}</p>
|
||||
<PaginationInline {limit} bind:offset sum={invoiceList?.total} hidePages />
|
||||
</div>
|
||||
{:else}
|
||||
<EmptySearch cardOnly>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { page } from '$app/stores';
|
||||
import type { CreditList, InvoiceList, PaymentList } from '$lib/sdk/billing';
|
||||
import { derived, type Readable } from 'svelte/store';
|
||||
|
||||
export const paymentMethods: Readable<PaymentList> = derived(
|
||||
page,
|
||||
($page) => $page.data.paymentMethods
|
||||
);
|
||||
export const creditList: Readable<CreditList> = derived(page, ($page) => $page.data.creditList);
|
||||
export const invoiceList: Readable<InvoiceList> = derived(page, ($page) => $page.data.invoiceList);
|
||||
@@ -35,7 +35,7 @@
|
||||
<RegionCard
|
||||
name="region"
|
||||
bind:group={$createProject.region}
|
||||
value={region.name}
|
||||
value={region.$id}
|
||||
disabled={region.disabled}>
|
||||
<div
|
||||
class="u-flex u-flex-vertical u-gap-12 u-justify-main-center u-cross-center u-margin-inline-auto">
|
||||
|
||||
Reference in New Issue
Block a user