0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-04-07 23:01:25 -05:00

chore(console): fix add-on issues (#6470)

This commit is contained in:
Darcy Ye 2024-08-19 19:51:31 +08:00 committed by GitHub
parent 746aa5897b
commit e9b7b83aaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 29 additions and 17 deletions

View file

@ -17,6 +17,7 @@ import ModalLayout from '@/ds-components/ModalLayout';
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
import TextInput from '@/ds-components/TextInput';
import useApi from '@/hooks/use-api';
import useApplicationsUsage from '@/hooks/use-applications-usage';
import useCurrentUser from '@/hooks/use-current-user';
import TypeDescription from '@/pages/Applications/components/TypeDescription';
import modalStyles from '@/scss/modal.module.scss';
@ -56,7 +57,7 @@ function CreateForm({
defaultValues: { type: defaultCreateType, isThirdParty: isDefaultCreateThirdParty },
});
const {
currentSubscription: { isAddOnAvailable },
currentSubscription: { isAddOnAvailable, planId },
} = useContext(SubscriptionDataContext);
const { user } = useCurrentUser();
const { mutate: mutateGlobal } = useSWRConfig();
@ -72,6 +73,8 @@ function CreateForm({
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const api = useApi();
const { hasMachineToMachineAppsReachedLimit } = useApplicationsUsage();
const onSubmit = handleSubmit(
trySubmitSafe(async (data) => {
if (isSubmitting) {
@ -124,9 +127,14 @@ function CreateForm({
paywall={conditional(
isAddOnAvailable &&
watch('type') === ApplicationType.MachineToMachine &&
planId !== ReservedPlanId.Pro &&
ReservedPlanId.Pro
)}
hasAddOnTag={isAddOnAvailable && watch('type') === ApplicationType.MachineToMachine}
hasAddOnTag={
isAddOnAvailable &&
watch('type') === ApplicationType.MachineToMachine &&
hasMachineToMachineAppsReachedLimit
}
size={defaultCreateType ? 'medium' : 'large'}
footer={
<Footer

View file

@ -2,7 +2,7 @@ import { useContext, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import Tip from '@/assets/icons/tip.svg?react';
import { newPlansBlogLink } from '@/consts';
import { addOnPricingExplanationLink } from '@/consts';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button';
import DynamicT from '@/ds-components/DynamicT';
@ -44,7 +44,7 @@ function BillInfo({ cost, isManagePaymentVisible }: Props) {
a: (
<TextLink
className={styles.articleLink}
href={newPlansBlogLink}
href={addOnPricingExplanationLink}
targetBlank="noopener"
/>
),

View file

@ -4,7 +4,7 @@ import { type TFuncKey } from 'i18next';
import { useContext } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { newPlansBlogLink } from '@/consts';
import { addOnPricingExplanationLink } from '@/consts';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import InlineNotification from '@/ds-components/InlineNotification';
import TextLink from '@/ds-components/TextLink';
@ -70,7 +70,9 @@ function ChargeNotification({
});
}}
>
<Trans components={{ a: <TextLink href={newPlansBlogLink} targetBlank="noopener" /> }}>
<Trans
components={{ a: <TextLink href={addOnPricingExplanationLink} targetBlank="noopener" /> }}
>
{t('charge_notification_for_quota_limit', {
item: t(`add_on_quota_item.${quotaItemPhraseKey}`, {
...cond(

View file

@ -26,7 +26,8 @@ function PlanUsage({ periodicUsage: rawPeriodicUsage }: Props) {
} = useContext(SubscriptionDataContext);
const { currentTenant } = useContext(TenantsContext);
const { currentPeriodStart, currentPeriodEnd } = currentSubscriptionFromNewPricingModel;
const { currentPeriodStart, currentPeriodEnd, planId, isAddOnAvailable } =
currentSubscriptionFromNewPricingModel;
const periodicUsage = useMemo(
() =>
@ -48,9 +49,8 @@ function PlanUsage({ periodicUsage: rawPeriodicUsage }: Props) {
// Show all usages for Pro plan and only show MAU and token usage for Free plan
.filter(
(key) =>
currentSubscriptionFromNewPricingModel.planId === ReservedPlanId.Pro ||
(currentSubscriptionFromNewPricingModel.planId === ReservedPlanId.Free &&
(key === 'mauLimit' || key === 'tokenLimit'))
isAddOnAvailable ??
(planId === ReservedPlanId.Free && (key === 'mauLimit' || key === 'tokenLimit'))
)
.map((key) => ({
usage:
@ -61,7 +61,7 @@ function PlanUsage({ periodicUsage: rawPeriodicUsage }: Props) {
titleKey: `subscription.usage.${titleKeyMap[key]}`,
unitPrice: usageKeyPriceMap[key],
...conditional(
currentSubscriptionFromNewPricingModel.planId === ReservedPlanId.Pro && {
planId === ReservedPlanId.Pro && {
tooltipKey: `subscription.usage.${tooltipKeyMap[key]}`,
}
),
@ -91,8 +91,7 @@ function PlanUsage({ periodicUsage: rawPeriodicUsage }: Props) {
key={index}
className={classNames(
styles.cardItem,
currentSubscriptionFromNewPricingModel.planId === ReservedPlanId.Free &&
styles.freeUser
planId === ReservedPlanId.Free && styles.freeUser
)}
{...props}
/>

View file

@ -8,7 +8,6 @@ export const contactEmailLink = `mailto:${contactEmail}`;
export const reservationLink = 'https://cal.com/logto/30min';
export const trustAndSecurityLink = 'https://logto.io/trust-and-security';
export const pricingLink = 'https://logto.io/pricing';
export const newPlansBlogLink = 'https://blog.logto.io/logto-pricing-v2';
/** Docs link */
export const envTagsFeatureLink = '/docs/references/tenants/#tenant-type';

View file

@ -13,6 +13,7 @@ import ModalLayout from '@/ds-components/ModalLayout';
import TextInput from '@/ds-components/TextInput';
import TextLink from '@/ds-components/TextLink';
import useApi from '@/hooks/use-api';
import useApiResourcesUsage from '@/hooks/use-api-resources-usage';
import modalStyles from '@/scss/modal.module.scss';
import { trySubmitSafe } from '@/utils/form';
@ -40,6 +41,7 @@ function CreateForm({ onClose }: Props) {
} = useForm<FormData>();
const api = useApi();
const { hasReachedLimit } = useApiResourcesUsage();
const onSubmit = handleSubmit(
trySubmitSafe(async (data) => {
@ -67,7 +69,7 @@ function CreateForm({ onClose }: Props) {
title="api_resources.create"
subtitle="api_resources.subtitle"
paywall={conditional(planId !== ReservedPlanId.Pro && ReservedPlanId.Pro)}
hasAddOnTag={isAddOnAvailable}
hasAddOnTag={isAddOnAvailable && hasReachedLimit}
footer={<Footer isCreationLoading={isSubmitting} onClickCreate={onSubmit} />}
onClose={onClose}
>

View file

@ -74,7 +74,9 @@ function CurrentPlan({ periodicUsage: rawPeriodicUsage }: Props) {
<FormField title="subscription.next_bill">
<BillInfo cost={upcomingCost} isManagePaymentVisible={Boolean(upcomingCost)} />
</FormField>
<AddOnUsageChangesNotification className={styles.notification} />
{currentSubscription.isAddOnAvailable && (
<AddOnUsageChangesNotification className={styles.notification} />
)}
<MauLimitExceedNotification
periodicUsage={rawPeriodicUsage}
className={styles.notification}

View file

@ -130,7 +130,7 @@ function InviteMemberModal({ isOpen, onClose }: Props) {
size="large"
title="tenant_members.invite_modal.title"
paywall={conditional(planId !== ReservedPlanId.Pro && ReservedPlanId.Pro)}
hasAddOnTag={isAddOnAvailable}
hasAddOnTag={isAddOnAvailable && hasTenantMembersReachedLimit}
subtitle="tenant_members.invite_modal.subtitle"
footer={
conditional(