mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): use useSWRImmutable
to avoid redundant subscrtipion data fetching (#4272)
This commit is contained in:
parent
8cba35d116
commit
56b0a2cd18
2 changed files with 45 additions and 55 deletions
|
@ -1,7 +1,9 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import ReactModal from 'react-modal';
|
||||
import useSWRImmutable from 'swr/immutable';
|
||||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import PlanUsage from '@/components/PlanUsage';
|
||||
import { contactEmailLink } from '@/consts';
|
||||
import { subscriptionPage } from '@/consts/pages';
|
||||
|
@ -10,9 +12,7 @@ import Button from '@/ds-components/Button';
|
|||
import FormField from '@/ds-components/FormField';
|
||||
import InlineNotification from '@/ds-components/InlineNotification';
|
||||
import ModalLayout from '@/ds-components/ModalLayout';
|
||||
import useSubscription from '@/hooks/use-subscription';
|
||||
import useSubscriptionPlan from '@/hooks/use-subscription-plan';
|
||||
import useSubscriptionUsage from '@/hooks/use-subscription-usage';
|
||||
import useSubscriptionPlans from '@/hooks/use-subscription-plans';
|
||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
|
||||
|
@ -22,55 +22,52 @@ import * as styles from './index.module.scss';
|
|||
|
||||
function MauExceededModal() {
|
||||
const { currentTenantId } = useContext(TenantsContext);
|
||||
const cloudApi = useCloudApi();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { navigate } = useTenantPathname();
|
||||
const [hasClosed, setHasClosed] = useState(false);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setHasClosed(true);
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
const { data: currentUsage, error: fetchUsageError } = useSubscriptionUsage(currentTenantId);
|
||||
const { data: currentSubscription, error: fetchSubscriptionError } =
|
||||
useSubscription(currentTenantId);
|
||||
const { data: currentPlan, error: fetchCurrentPlanError } = useSubscriptionPlan(currentTenantId);
|
||||
const { data: subscriptionPlans } = useSubscriptionPlans();
|
||||
|
||||
const isLoadingUsage = !currentUsage && !fetchUsageError;
|
||||
const isLoadingSubscription = !currentSubscription && !fetchSubscriptionError;
|
||||
const isLoadingCurrentPlan = !currentPlan && !fetchCurrentPlanError;
|
||||
const { data: currentSubscription } = useSWRImmutable(
|
||||
`/api/tenants/${currentTenantId}/subscription`,
|
||||
async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/subscription', { params: { tenantId: currentTenantId } })
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentUsage || !currentPlan || hasClosed) {
|
||||
return;
|
||||
const { data: currentUsage } = useSWRImmutable(
|
||||
`/api/tenants/${currentTenantId}/usage`,
|
||||
async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/usage', { params: { tenantId: currentTenantId } })
|
||||
);
|
||||
|
||||
const currentPlan =
|
||||
currentSubscription &&
|
||||
subscriptionPlans?.find((plan) => plan.id === currentSubscription.planId);
|
||||
|
||||
if (!currentPlan || !currentUsage || hasClosed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
quota: { mauLimit },
|
||||
name: planName,
|
||||
} = currentPlan;
|
||||
|
||||
if (mauLimit === null) {
|
||||
return;
|
||||
}
|
||||
const isMauExceeded = mauLimit !== null && currentUsage.activeUsers >= mauLimit;
|
||||
|
||||
if (currentUsage.activeUsers >= mauLimit) {
|
||||
setIsOpen(true);
|
||||
}
|
||||
}, [currentPlan, currentUsage, hasClosed]);
|
||||
|
||||
if (isLoadingUsage || isLoadingSubscription || isLoadingCurrentPlan) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!currentUsage || !currentSubscription || !currentPlan) {
|
||||
if (!isMauExceeded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReactModal
|
||||
isOpen
|
||||
shouldCloseOnEsc
|
||||
isOpen={isOpen}
|
||||
className={modalStyles.content}
|
||||
overlayClassName={modalStyles.overlay}
|
||||
onRequestClose={handleCloseModal}
|
||||
|
@ -97,7 +94,7 @@ function MauExceededModal() {
|
|||
<InlineNotification severity="error">
|
||||
<Trans
|
||||
components={{
|
||||
planName: <PlanName name={currentPlan.name} />,
|
||||
planName: <PlanName name={planName} />,
|
||||
}}
|
||||
>
|
||||
{t('upsell.mau_exceeded_modal.notification')}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { conditional } from '@silverhand/essentials';
|
||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useContext, useMemo, useState } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import ReactModal from 'react-modal';
|
||||
import useSWRImmutable from 'swr/immutable';
|
||||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { contactEmailLink } from '@/consts';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import Button from '@/ds-components/Button';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
import InlineNotification from '@/ds-components/InlineNotification';
|
||||
import ModalLayout from '@/ds-components/ModalLayout';
|
||||
import useInvoices from '@/hooks/use-invoices';
|
||||
import useSubscribe from '@/hooks/use-subscribe';
|
||||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
import { getLatestUnpaidInvoice } from '@/utils/subscription';
|
||||
|
@ -21,41 +22,33 @@ import * as styles from './index.module.scss';
|
|||
function PaymentOverdueModal() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { currentTenant, currentTenantId } = useContext(TenantsContext);
|
||||
const { data: invoices, error } = useInvoices(currentTenantId);
|
||||
const cloudApi = useCloudApi();
|
||||
const { data: invoicesResponse } = useSWRImmutable(
|
||||
`/api/tenants/${currentTenantId}/invoices`,
|
||||
async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/invoices', { params: { tenantId: currentTenantId } })
|
||||
);
|
||||
const { visitManagePaymentPage } = useSubscribe();
|
||||
const [isActionLoading, setIsActionLoading] = useState(false);
|
||||
const isLoadingInvoices = !invoices && !error;
|
||||
|
||||
const latestUnpaidInvoice = useMemo(() => {
|
||||
return conditional(invoices && getLatestUnpaidInvoice(invoices));
|
||||
}, [invoices]);
|
||||
const latestUnpaidInvoice = useMemo(
|
||||
() => conditional(invoicesResponse && getLatestUnpaidInvoice(invoicesResponse.invoices)),
|
||||
[invoicesResponse]
|
||||
);
|
||||
|
||||
const [hasClosed, setHasClosed] = useState(false);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setHasClosed(true);
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadingInvoices || hasClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (latestUnpaidInvoice) {
|
||||
setIsOpen(true);
|
||||
}
|
||||
}, [hasClosed, isLoadingInvoices, latestUnpaidInvoice]);
|
||||
|
||||
if (isLoadingInvoices || !latestUnpaidInvoice || hasClosed) {
|
||||
if (!invoicesResponse || !latestUnpaidInvoice || hasClosed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReactModal
|
||||
isOpen
|
||||
shouldCloseOnEsc
|
||||
isOpen={isOpen}
|
||||
className={modalStyles.content}
|
||||
overlayClassName={modalStyles.overlay}
|
||||
onRequestClose={handleCloseModal}
|
||||
|
|
Loading…
Reference in a new issue