mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): retrieve latest invoice id from stripe (#4563)
refactor(console): replace invoice url link with API call replace invoice url link with API call
This commit is contained in:
parent
71f7977b9c
commit
fc252b56f0
4 changed files with 35 additions and 14 deletions
|
@ -26,7 +26,7 @@
|
||||||
"@fontsource/roboto-mono": "^5.0.0",
|
"@fontsource/roboto-mono": "^5.0.0",
|
||||||
"@jest/types": "^29.5.0",
|
"@jest/types": "^29.5.0",
|
||||||
"@logto/app-insights": "workspace:^1.3.1",
|
"@logto/app-insights": "workspace:^1.3.1",
|
||||||
"@logto/cloud": "0.2.5-444ed49",
|
"@logto/cloud": "0.2.5-d434baa",
|
||||||
"@logto/connector-kit": "workspace:^1.1.1",
|
"@logto/connector-kit": "workspace:^1.1.1",
|
||||||
"@logto/core-kit": "workspace:^2.1.0",
|
"@logto/core-kit": "workspace:^2.1.0",
|
||||||
"@logto/language-kit": "workspace:^1.0.0",
|
"@logto/language-kit": "workspace:^1.0.0",
|
||||||
|
|
|
@ -2,12 +2,12 @@ import useSWR from 'swr';
|
||||||
|
|
||||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||||
import { type InvoicesResponse } from '@/cloud/types/router';
|
import { type InvoicesResponse } from '@/cloud/types/router';
|
||||||
import { isCloud } from '@/consts/env';
|
|
||||||
|
|
||||||
const useInvoices = (tenantId: string) => {
|
const useInvoices = (tenantId: string) => {
|
||||||
const cloudApi = useCloudApi();
|
const cloudApi = useCloudApi();
|
||||||
|
|
||||||
const swrResponse = useSWR<InvoicesResponse, Error>(
|
const swrResponse = useSWR<InvoicesResponse, Error>(
|
||||||
isCloud && `/api/tenants/${tenantId}/invoices`,
|
`/api/tenants/${tenantId}/invoices`,
|
||||||
async () => cloudApi.get('/api/tenants/:tenantId/invoices', { params: { tenantId } })
|
async () => cloudApi.get('/api/tenants/:tenantId/invoices', { params: { tenantId } })
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { withAppInsights } from '@logto/app-insights/react';
|
import { withAppInsights } from '@logto/app-insights/react';
|
||||||
import { conditional } from '@silverhand/essentials';
|
import { conditional } from '@silverhand/essentials';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useContext, useMemo } from 'react';
|
import { useCallback, useContext, useMemo } from 'react';
|
||||||
|
|
||||||
|
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||||
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
|
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
|
||||||
import ItemPreview from '@/components/ItemPreview';
|
import ItemPreview from '@/components/ItemPreview';
|
||||||
import PageMeta from '@/components/PageMeta';
|
import PageMeta from '@/components/PageMeta';
|
||||||
|
@ -16,6 +17,7 @@ import { formatPeriod } from '@/utils/subscription';
|
||||||
import InvoiceStatusTag from './InvoiceStatusTag';
|
import InvoiceStatusTag from './InvoiceStatusTag';
|
||||||
|
|
||||||
function BillingHistory() {
|
function BillingHistory() {
|
||||||
|
const cloudApi = useCloudApi();
|
||||||
const { currentTenantId } = useContext(TenantsContext);
|
const { currentTenantId } = useContext(TenantsContext);
|
||||||
const { data: invoices, error } = useInvoices(currentTenantId);
|
const { data: invoices, error } = useInvoices(currentTenantId);
|
||||||
const isLoadingInvoices = !invoices && !error;
|
const isLoadingInvoices = !invoices && !error;
|
||||||
|
@ -25,6 +27,20 @@ function BillingHistory() {
|
||||||
[invoices]
|
[invoices]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const openStripeHostedInvoicePage = useCallback(
|
||||||
|
async (invoiceId: string) => {
|
||||||
|
const { hostedInvoiceUrl } = await cloudApi.get(
|
||||||
|
'/api/tenants/:tenantId/invoices/:invoiceId/hosted-invoice-url',
|
||||||
|
{
|
||||||
|
params: { tenantId: currentTenantId, invoiceId },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
window.open(hostedInvoiceUrl, '_blank');
|
||||||
|
},
|
||||||
|
[cloudApi, currentTenantId]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PageMeta titleKey={['tenants.tabs.billing_history', 'tenants.title']} />
|
<PageMeta titleKey={['tenants.tabs.billing_history', 'tenants.title']} />
|
||||||
|
@ -35,13 +51,11 @@ function BillingHistory() {
|
||||||
{
|
{
|
||||||
title: <DynamicT forKey="subscription.billing_history.invoice_column" />,
|
title: <DynamicT forKey="subscription.billing_history.invoice_column" />,
|
||||||
dataIndex: 'planName',
|
dataIndex: 'planName',
|
||||||
render: ({ planName, hostedInvoiceUrl, periodStart, periodEnd }) => {
|
render: ({ planName, periodStart, periodEnd }) => {
|
||||||
return (
|
return (
|
||||||
<ItemPreview
|
<ItemPreview
|
||||||
title={formatPeriod({ periodStart, periodEnd, displayYear: true })}
|
title={formatPeriod({ periodStart, periodEnd, displayYear: true })}
|
||||||
subtitle={conditional(planName && <PlanName name={planName} />)}
|
subtitle={conditional(planName && <PlanName name={planName} />)}
|
||||||
to={conditional(hostedInvoiceUrl)}
|
|
||||||
toTarget="_blank"
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -70,11 +84,8 @@ function BillingHistory() {
|
||||||
]}
|
]}
|
||||||
isLoading={isLoadingInvoices}
|
isLoading={isLoadingInvoices}
|
||||||
placeholder={<EmptyDataPlaceholder />}
|
placeholder={<EmptyDataPlaceholder />}
|
||||||
rowClickHandler={({ hostedInvoiceUrl }) => {
|
rowClickHandler={({ id }) => {
|
||||||
if (!hostedInvoiceUrl) {
|
void openStripeHostedInvoicePage(id);
|
||||||
return;
|
|
||||||
}
|
|
||||||
window.open(hostedInvoiceUrl, '_blank');
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2834,8 +2834,8 @@ importers:
|
||||||
specifier: workspace:^1.3.1
|
specifier: workspace:^1.3.1
|
||||||
version: link:../app-insights
|
version: link:../app-insights
|
||||||
'@logto/cloud':
|
'@logto/cloud':
|
||||||
specifier: 0.2.5-444ed49
|
specifier: 0.2.5-d434baa
|
||||||
version: 0.2.5-444ed49(zod@3.20.2)
|
version: 0.2.5-d434baa(zod@3.20.2)
|
||||||
'@logto/connector-kit':
|
'@logto/connector-kit':
|
||||||
specifier: workspace:^1.1.1
|
specifier: workspace:^1.1.1
|
||||||
version: link:../toolkit/connector-kit
|
version: link:../toolkit/connector-kit
|
||||||
|
@ -7320,6 +7320,16 @@ packages:
|
||||||
- zod
|
- zod
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@logto/cloud@0.2.5-d434baa(zod@3.20.2):
|
||||||
|
resolution: {integrity: sha512-VmWpqFzpWBrzJPQLvfe0bb7/XjF3lxs/rPbLt3zqBjGPtDXM9FAUn1m/gPbTwzXi5PxGOjlbD7jTl+3+1u4/NQ==}
|
||||||
|
engines: {node: ^18.12.0}
|
||||||
|
dependencies:
|
||||||
|
'@silverhand/essentials': 2.8.4
|
||||||
|
'@withtyped/server': 0.12.9(zod@3.20.2)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- zod
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@logto/js@2.1.1:
|
/@logto/js@2.1.1:
|
||||||
resolution: {integrity: sha512-PHikheavVK+l4ivgtzi14p184hEPgXjqQEAom1Gme1MZoopx+WlwxvHSEQBsmyvVqRtI0oiojhoU5tgYi1FKJw==}
|
resolution: {integrity: sha512-PHikheavVK+l4ivgtzi14p184hEPgXjqQEAom1Gme1MZoopx+WlwxvHSEQBsmyvVqRtI0oiojhoU5tgYi1FKJw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in a new issue