0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

feat(console): support open stripe payment management page from console (#4213)

This commit is contained in:
Xiao Yijun 2023-07-24 15:46:34 +08:00 committed by GitHub
parent 46eafc9881
commit d90d81688e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 9 deletions

View file

@ -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-70aa370", "@logto/cloud": "0.2.5-8065345",
"@logto/connector-kit": "workspace:^1.1.1", "@logto/connector-kit": "workspace:^1.1.1",
"@logto/core-kit": "workspace:^2.0.1", "@logto/core-kit": "workspace:^2.0.1",
"@logto/language-kit": "workspace:^1.0.0", "@logto/language-kit": "workspace:^1.0.0",

View file

@ -1,11 +1,14 @@
import { useContext } from 'react';
import { Trans, useTranslation } from 'react-i18next'; import { Trans, useTranslation } from 'react-i18next';
import Tip from '@/assets/icons/tip.svg'; import Tip from '@/assets/icons/tip.svg';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button'; import Button from '@/ds-components/Button';
import DynamicT from '@/ds-components/DynamicT'; import DynamicT from '@/ds-components/DynamicT';
import IconButton from '@/ds-components/IconButton'; import IconButton from '@/ds-components/IconButton';
import TextLink from '@/ds-components/TextLink'; import TextLink from '@/ds-components/TextLink';
import { ToggleTip } from '@/ds-components/Tip'; import { ToggleTip } from '@/ds-components/Tip';
import useSubscribe from '@/hooks/use-subscribe';
import * as styles from './index.module.scss'; import * as styles from './index.module.scss';
@ -15,6 +18,9 @@ type Props = {
}; };
function BillInfo({ cost, isManagePaymentVisible }: Props) { function BillInfo({ cost, isManagePaymentVisible }: Props) {
const { currentTenantId } = useContext(TenantsContext);
const { visitManagePaymentPage } = useSubscribe();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
return ( return (
@ -50,7 +56,7 @@ function BillInfo({ cost, isManagePaymentVisible }: Props) {
<Button <Button
title="subscription.manage_payment" title="subscription.manage_payment"
onClick={() => { onClick={() => {
// Todo @xiaoyijun Management payment void visitManagePaymentPage(currentTenantId);
}} }}
/> />
)} )}

View file

@ -10,6 +10,7 @@ import FormField from '@/ds-components/FormField';
import InlineNotification from '@/ds-components/InlineNotification'; import InlineNotification from '@/ds-components/InlineNotification';
import ModalLayout from '@/ds-components/ModalLayout'; import ModalLayout from '@/ds-components/ModalLayout';
import useInvoices from '@/hooks/use-invoices'; import useInvoices from '@/hooks/use-invoices';
import useSubscribe from '@/hooks/use-subscribe';
import * as modalStyles from '@/scss/modal.module.scss'; import * as modalStyles from '@/scss/modal.module.scss';
import { getLatestUnpaidInvoice } from '@/utils/subscription'; import { getLatestUnpaidInvoice } from '@/utils/subscription';
@ -21,6 +22,7 @@ function PaymentOverdueModal() {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { currentTenant, currentTenantId } = useContext(TenantsContext); const { currentTenant, currentTenantId } = useContext(TenantsContext);
const { data: invoices, error } = useInvoices(currentTenantId); const { data: invoices, error } = useInvoices(currentTenantId);
const { visitManagePaymentPage } = useSubscribe();
const isLoadingInvoices = !invoices && !error; const isLoadingInvoices = !invoices && !error;
const latestUnpaidInvoice = useMemo(() => { const latestUnpaidInvoice = useMemo(() => {
@ -68,7 +70,7 @@ function PaymentOverdueModal() {
type="primary" type="primary"
title="upsell.payment_overdue_modal.update_payment" title="upsell.payment_overdue_modal.update_payment"
onClick={() => { onClick={() => {
// Todo: @xiaoyijun Update payment void visitManagePaymentPage(currentTenantId);
}} }}
/> />
</> </>

View file

@ -2,7 +2,7 @@ import { nanoid } from 'nanoid';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useCloudApi } from '@/cloud/hooks/use-cloud-api'; import { toastResponseError, useCloudApi } from '@/cloud/hooks/use-cloud-api';
import { type CreateTenantData } from '@/components/CreateTenantModal/type'; import { type CreateTenantData } from '@/components/CreateTenantModal/type';
import { checkoutStateQueryKey, checkoutSuccessCallbackPath } from '@/consts/subscriptions'; import { checkoutStateQueryKey, checkoutSuccessCallbackPath } from '@/consts/subscriptions';
import { createLocalCheckoutSession } from '@/utils/checkout'; import { createLocalCheckoutSession } from '@/utils/checkout';
@ -72,9 +72,27 @@ const useSubscribe = () => {
}); });
}; };
const visitManagePaymentPage = async (tenantId: string) => {
try {
const { redirectUri } = await cloudApi.post('/api/tenants/:tenantId/stripe-customer-portal', {
params: {
tenantId,
},
body: {
callbackUrl: window.location.href,
},
});
window.location.assign(redirectUri);
} catch (error: unknown) {
void toastResponseError(error);
}
};
return { return {
subscribe, subscribe,
cancelSubscription, cancelSubscription,
visitManagePaymentPage,
}; };
}; };

View file

@ -5,6 +5,7 @@ import { TenantsContext } from '@/contexts/TenantsProvider';
import DynamicT from '@/ds-components/DynamicT'; import DynamicT from '@/ds-components/DynamicT';
import InlineNotification from '@/ds-components/InlineNotification'; import InlineNotification from '@/ds-components/InlineNotification';
import useInvoices from '@/hooks/use-invoices'; import useInvoices from '@/hooks/use-invoices';
import useSubscribe from '@/hooks/use-subscribe';
import { getLatestUnpaidInvoice } from '@/utils/subscription'; import { getLatestUnpaidInvoice } from '@/utils/subscription';
type Props = { type Props = {
@ -13,6 +14,7 @@ type Props = {
function PaymentOverdueNotification({ className }: Props) { function PaymentOverdueNotification({ className }: Props) {
const { currentTenantId } = useContext(TenantsContext); const { currentTenantId } = useContext(TenantsContext);
const { visitManagePaymentPage } = useSubscribe();
const { data: invoices, error } = useInvoices(currentTenantId); const { data: invoices, error } = useInvoices(currentTenantId);
const isLoadingInvoices = !invoices && !error; const isLoadingInvoices = !invoices && !error;
const latestUnpaidInvoice = useMemo( const latestUnpaidInvoice = useMemo(
@ -30,7 +32,7 @@ function PaymentOverdueNotification({ className }: Props) {
action="subscription.update_payment" action="subscription.update_payment"
className={className} className={className}
onClick={() => { onClick={() => {
// Todo @xiaoyijun manage payment void visitManagePaymentPage(currentTenantId);
}} }}
> >
<DynamicT <DynamicT

View file

@ -2755,8 +2755,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-70aa370 specifier: 0.2.5-8065345
version: 0.2.5-70aa370(zod@3.20.2) version: 0.2.5-8065345(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
@ -7220,8 +7220,8 @@ packages:
- zod - zod
dev: true dev: true
/@logto/cloud@0.2.5-70aa370(zod@3.20.2): /@logto/cloud@0.2.5-8065345(zod@3.20.2):
resolution: {integrity: sha512-V5fIsbotJ8+L6Q+R9PnLjspvuccDKpukpLz/uHRUv4SYDo8U5MAcC680T2TGiROtMjWqnb0vd6WHuqXZ9XWTcw==} resolution: {integrity: sha512-qZWtGd2InkSddNPt3lKO0Ti/UZtQvzul5R7uJbnZgl0xiIpoMYEiHVI9gXQ8O+V47qtPpkS3ykTb2zj4K4Sk+w==}
engines: {node: ^18.12.0} engines: {node: ^18.12.0}
dependencies: dependencies:
'@silverhand/essentials': 2.7.0 '@silverhand/essentials': 2.7.0
@ -16235,6 +16235,7 @@ packages:
/node-gyp-build-optional-packages@5.0.7: /node-gyp-build-optional-packages@5.0.7:
resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==} resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==}
hasBin: true hasBin: true
requiresBuild: true
dev: true dev: true
optional: true optional: true