mirror of
https://github.com/logto-io/logto.git
synced 2025-02-17 22:04:19 -05:00
chore(console): remove pricing feature switch (#4215)
This commit is contained in:
parent
d90d81688e
commit
aa6f9ae1a3
19 changed files with 44 additions and 114 deletions
|
@ -7,7 +7,6 @@ import { useMemo, useState } from 'react';
|
|||
import Modal from 'react-modal';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { isProduction } from '@/consts/env';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
import ModalLayout from '@/ds-components/ModalLayout';
|
||||
import type { RequestError } from '@/hooks/use-api';
|
||||
|
@ -144,8 +143,7 @@ function CreateConnectorForm({ onClose, isOpen: isFormOpen, type }: Props) {
|
|||
<>
|
||||
<div className={styles.standardLabel}>
|
||||
<DynamicT forKey="connectors.standard_connectors" />
|
||||
{/* Todo: @xiaoyijun remove this condition on subscription features ready. */}
|
||||
{!isProduction && <ProTag />}
|
||||
<ProTag />
|
||||
</div>
|
||||
<ConnectorRadioGroup
|
||||
name="group"
|
||||
|
|
|
@ -11,7 +11,6 @@ import CreateTenantHeaderIconDark from '@/assets/icons/create-tenant-header-dark
|
|||
import CreateTenantHeaderIcon from '@/assets/icons/create-tenant-header.svg';
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { type TenantResponse } from '@/cloud/types/router';
|
||||
import { isProduction } from '@/consts/env';
|
||||
import Button from '@/ds-components/Button';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
import ModalLayout from '@/ds-components/ModalLayout';
|
||||
|
@ -77,9 +76,7 @@ function CreateTenantModal({ isOpen, onClose, skipPlanSelection = false }: Props
|
|||
* Note: create tenant directly if it's from landing page,
|
||||
* since we want the user to get into the console as soon as possible
|
||||
*/
|
||||
const shouldSkipPlanSelection = skipPlanSelection || isProduction;
|
||||
|
||||
const onCreateClick = handleSubmit(shouldSkipPlanSelection ? createTenant : setTenantData);
|
||||
const onCreateClick = handleSubmit(skipPlanSelection ? createTenant : setTenantData);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { yes } from '@silverhand/essentials';
|
||||
|
||||
export const isProduction = process.env.NODE_ENV === 'production';
|
||||
export const isCloud = yes(process.env.IS_CLOUD);
|
||||
export const adminEndpoint = process.env.ADMIN_ENDPOINT;
|
||||
|
|
|
@ -3,7 +3,6 @@ import classNames from 'classnames';
|
|||
import Tick from '@/assets/icons/tick.svg';
|
||||
import { type TenantResponse } from '@/cloud/types/router';
|
||||
import PlanName from '@/components/PlanName';
|
||||
import { isProduction } from '@/consts/env';
|
||||
import { DropdownItem } from '@/ds-components/Dropdown';
|
||||
import useSubscriptionPlan from '@/hooks/use-subscription-plan';
|
||||
|
||||
|
@ -29,13 +28,11 @@ function TenantDropdownItem({ tenantData, isSelected, onClick }: Props) {
|
|||
<div className={styles.meta}>
|
||||
<div className={styles.name}>{name}</div>
|
||||
<TenantEnvTag tag={tag} />
|
||||
{!isProduction && <TenantStatusTag tenantId={id} className={styles.statusTag} />}
|
||||
<TenantStatusTag tenantId={id} className={styles.statusTag} />
|
||||
</div>
|
||||
<div className={styles.planName}>
|
||||
{tenantPlan ? <PlanName name={tenantPlan.name} /> : <Skeleton />}
|
||||
</div>
|
||||
{!isProduction && (
|
||||
<div className={styles.planName}>
|
||||
{tenantPlan ? <PlanName name={tenantPlan.name} /> : <Skeleton />}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Tick className={classNames(styles.checkIcon, isSelected && styles.visible)} />
|
||||
</DropdownItem>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Navigate, Outlet, useParams } from 'react-router-dom';
|
|||
import AppLoading from '@/components/AppLoading';
|
||||
import MauExceededModal from '@/components/MauExceededModal';
|
||||
import PaymentOverdueModal from '@/components/PaymentOverdueModal';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import useConfigs from '@/hooks/use-configs';
|
||||
import useScroll from '@/hooks/use-scroll';
|
||||
import useUserPreferences from '@/hooks/use-user-preferences';
|
||||
|
@ -37,10 +37,9 @@ export default function AppContent() {
|
|||
<Topbar className={conditional(scrollTop && styles.topbarShadow)} />
|
||||
<Outlet context={{ scrollableContent } satisfies AppContentOutletContext} />
|
||||
</div>
|
||||
{isCloud && <Broadcast />}
|
||||
{/* Todo: @xiaoyijun remove this condition on subscription features ready. */}
|
||||
{!isProduction && isCloud && (
|
||||
{isCloud && (
|
||||
<>
|
||||
<Broadcast />
|
||||
<MauExceededModal />
|
||||
<PaymentOverdueModal />
|
||||
</>
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
WebhookDetailsTabs,
|
||||
TenantSettingsTabs,
|
||||
} from '@/consts';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
|
||||
import ApiResourceDetails from '@/pages/ApiResourceDetails';
|
||||
import ApiResourcePermissions from '@/pages/ApiResourceDetails/ApiResourcePermissions';
|
||||
|
@ -149,12 +149,8 @@ function ConsoleContent() {
|
|||
<Route index element={<Navigate replace to={TenantSettingsTabs.Settings} />} />
|
||||
<Route path={TenantSettingsTabs.Settings} element={<TenantBasicSettings />} />
|
||||
<Route path={TenantSettingsTabs.Domains} element={<TenantDomainSettings />} />
|
||||
{!isProduction && (
|
||||
<>
|
||||
<Route path={TenantSettingsTabs.Subscription} element={<Subscription />} />
|
||||
<Route path={TenantSettingsTabs.BillingHistory} element={<BillingHistory />} />
|
||||
</>
|
||||
)}
|
||||
<Route path={TenantSettingsTabs.Subscription} element={<Subscription />} />
|
||||
<Route path={TenantSettingsTabs.BillingHistory} element={<BillingHistory />} />
|
||||
</Route>
|
||||
)}
|
||||
</Routes>
|
||||
|
|
|
@ -2,15 +2,12 @@ import useSWR from 'swr';
|
|||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { type InvoicesResponse } from '@/cloud/types/router';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
|
||||
const useInvoices = (tenantId: string) => {
|
||||
const cloudApi = useCloudApi();
|
||||
const swrResponse = useSWR<InvoicesResponse, Error>(
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
!isProduction && isCloud && `/api/tenants/${tenantId}/invoices`,
|
||||
isCloud && `/api/tenants/${tenantId}/invoices`,
|
||||
async () => cloudApi.get('/api/tenants/:tenantId/invoices', { params: { tenantId } })
|
||||
);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import useSWRImmutable from 'swr/immutable';
|
|||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { type SubscriptionPlanResponse } from '@/cloud/types/router';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import { reservedPlanIdOrder } from '@/consts/subscriptions';
|
||||
import { type SubscriptionPlan } from '@/types/subscriptions';
|
||||
import { addSupportQuotaToPlan } from '@/utils/subscription';
|
||||
|
@ -12,10 +12,7 @@ import { addSupportQuotaToPlan } from '@/utils/subscription';
|
|||
const useSubscriptionPlans = () => {
|
||||
const cloudApi = useCloudApi();
|
||||
const useSwrResponse = useSWRImmutable<SubscriptionPlanResponse[], Error>(
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
!isProduction && isCloud && '/api/subscription-plans',
|
||||
isCloud && '/api/subscription-plans',
|
||||
async () => cloudApi.get('/api/subscription-plans')
|
||||
);
|
||||
|
||||
|
|
|
@ -2,20 +2,15 @@ import useSWR from 'swr';
|
|||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { type SubscriptionUsage } from '@/cloud/types/router';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
|
||||
const useSubscriptionUsage = (tenantId: string) => {
|
||||
const cloudApi = useCloudApi();
|
||||
|
||||
return useSWR<SubscriptionUsage, Error>(
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
!isProduction && isCloud && `/api/tenants/${tenantId}/usage`,
|
||||
async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/usage', {
|
||||
params: { tenantId },
|
||||
})
|
||||
return useSWR<SubscriptionUsage, Error>(isCloud && `/api/tenants/${tenantId}/usage`, async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/usage', {
|
||||
params: { tenantId },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,19 +2,14 @@ import useSWR from 'swr';
|
|||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { type Subscription } from '@/cloud/types/router';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
|
||||
const useSubscription = (tenantId: string) => {
|
||||
const cloudApi = useCloudApi();
|
||||
return useSWR<Subscription, Error>(
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
!isProduction && isCloud && `/api/tenants/${tenantId}/subscription`,
|
||||
async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/subscription', {
|
||||
params: { tenantId },
|
||||
})
|
||||
return useSWR<Subscription, Error>(isCloud && `/api/tenants/${tenantId}/subscription`, async () =>
|
||||
cloudApi.get('/api/tenants/:tenantId/subscription', {
|
||||
params: { tenantId },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import ContactUsPhraseLink from '@/components/ContactUsPhraseLink';
|
|||
import PlanName from '@/components/PlanName';
|
||||
import QuotaGuardFooter from '@/components/QuotaGuardFooter';
|
||||
import { type ApiResource } from '@/consts';
|
||||
import { isProduction } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import Button from '@/ds-components/Button';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
|
@ -33,10 +32,7 @@ function CreateForm({ onClose }: Props) {
|
|||
const { currentTenantId } = useContext(TenantsContext);
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { data: currentPlan } = useSubscriptionPlan(currentTenantId);
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
const { data: allResources } = useSWR<ApiResource[]>(!isProduction && 'api/resources');
|
||||
const { data: allResources } = useSWR<ApiResource[]>('api/resources');
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ApplicationType } from '@logto/schemas';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { isProduction } from '@/consts/env';
|
||||
import Button from '@/ds-components/Button';
|
||||
import { applicationTypeI18nKey } from '@/types/applications';
|
||||
|
||||
|
@ -29,10 +28,7 @@ function ApplicationsPlaceholder({ onSelect }: Props) {
|
|||
title={t(`${applicationTypeI18nKey[type]}.title`)}
|
||||
subtitle={t(`${applicationTypeI18nKey[type]}.subtitle`)}
|
||||
description={t(`${applicationTypeI18nKey[type]}.description`)}
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
hasProTag={!isProduction && type === ApplicationType.MachineToMachine}
|
||||
hasProTag={type === ApplicationType.MachineToMachine}
|
||||
/>
|
||||
<Button
|
||||
className={styles.createButton}
|
||||
|
|
|
@ -6,7 +6,6 @@ import useSWR from 'swr';
|
|||
import ContactUsPhraseLink from '@/components/ContactUsPhraseLink';
|
||||
import PlanName from '@/components/PlanName';
|
||||
import QuotaGuardFooter from '@/components/QuotaGuardFooter';
|
||||
import { isProduction } from '@/consts/env';
|
||||
import { ReservedPlanId } from '@/consts/subscriptions';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import Button from '@/ds-components/Button';
|
||||
|
@ -23,10 +22,7 @@ function Footer({ selectedType, isLoading, onClickCreate }: Props) {
|
|||
const { currentTenantId } = useContext(TenantsContext);
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.upsell.paywall' });
|
||||
const { data: currentPlan } = useSubscriptionPlan(currentTenantId);
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
const { data: allApplications } = useSWR<Application[]>(!isProduction && 'api/applications');
|
||||
const { data: allApplications } = useSWR<Application[]>('api/applications');
|
||||
|
||||
const m2mAppCount = useMemo(
|
||||
() =>
|
||||
|
|
|
@ -6,7 +6,6 @@ import { useController, useForm } from 'react-hook-form';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import Modal from 'react-modal';
|
||||
|
||||
import { isProduction } from '@/consts/env';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
import ModalLayout from '@/ds-components/ModalLayout';
|
||||
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
|
||||
|
@ -113,20 +112,14 @@ function CreateForm({ isOpen, defaultCreateType, onClose }: Props) {
|
|||
<Radio
|
||||
key={type}
|
||||
value={type}
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
hasCheckIconForCard={isProduction || type !== ApplicationType.MachineToMachine}
|
||||
hasCheckIconForCard={type !== ApplicationType.MachineToMachine}
|
||||
>
|
||||
<TypeDescription
|
||||
type={type}
|
||||
title={t(`${applicationTypeI18nKey[type]}.title`)}
|
||||
subtitle={t(`${applicationTypeI18nKey[type]}.subtitle`)}
|
||||
description={t(`${applicationTypeI18nKey[type]}.description`)}
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
hasProTag={!isProduction && type === ApplicationType.MachineToMachine}
|
||||
hasProTag={type === ApplicationType.MachineToMachine}
|
||||
/>
|
||||
</Radio>
|
||||
))}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ossConsolePath } from '@logto/schemas';
|
|||
import { Navigate, Outlet, Route, Routes } from 'react-router-dom';
|
||||
import { SWRConfig } from 'swr';
|
||||
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import { checkoutSuccessCallbackPath } from '@/consts/subscriptions';
|
||||
import AppBoundary from '@/containers/AppBoundary';
|
||||
import AppContent, { RedirectToFirstItem } from '@/containers/AppContent';
|
||||
|
@ -48,7 +48,7 @@ export function ConsoleRoutes() {
|
|||
<Route element={<ProtectedRoutes />}>
|
||||
<Route path="handle-social" element={<HandleSocialCallback />} />
|
||||
<Route element={<TenantAccess />}>
|
||||
{!isProduction && isCloud && (
|
||||
{isCloud && (
|
||||
<Route path={checkoutSuccessCallbackPath} element={<CheckoutSuccessCallback />} />
|
||||
)}
|
||||
<Route element={<AppContent />}>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
|||
|
||||
import FreePlanNotificationImage from '@/assets/images/free-plan-notification-image.svg';
|
||||
import PlanName from '@/components/PlanName';
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import { ReservedPlanId } from '@/consts/subscriptions';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import Button from '@/ds-components/Button';
|
||||
|
@ -21,10 +21,6 @@ function FreePlanNotification() {
|
|||
const isLoadingSubscription = !currentSubscription && !error;
|
||||
|
||||
if (
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
isProduction ||
|
||||
!isCloud ||
|
||||
isLoadingSubscription ||
|
||||
!currentSubscription ||
|
||||
|
|
|
@ -6,7 +6,6 @@ import FormCard from '@/components/FormCard';
|
|||
import PageMeta from '@/components/PageMeta';
|
||||
import ProTag from '@/components/ProTag';
|
||||
import { contactEmailLink } from '@/consts';
|
||||
import { isProduction } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
import InlineNotification from '@/ds-components/InlineNotification';
|
||||
|
@ -37,10 +36,6 @@ function TenantDomainSettings() {
|
|||
}
|
||||
|
||||
const customDomainEnabled =
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
isProduction ||
|
||||
Boolean(currentPlan?.quota.customDomainEnabled) ||
|
||||
/**
|
||||
* Note: this is for tenants which already have a custom domain before we have subscription features.
|
||||
|
@ -52,7 +47,7 @@ function TenantDomainSettings() {
|
|||
<PageMeta titleKey={['tenants.tabs.domains', 'tenants.title']} />
|
||||
<FormCard
|
||||
title="domain.custom.custom_domain"
|
||||
tag={!isProduction && <ProTag />}
|
||||
tag={<ProTag />}
|
||||
description="domain.custom.custom_domain_description"
|
||||
learnMoreLink={getDocumentationUrl('docs/recipes/custom-domain')}
|
||||
>
|
||||
|
@ -65,7 +60,7 @@ function TenantDomainSettings() {
|
|||
onCustomDomainAdded={mutate}
|
||||
/>
|
||||
)}
|
||||
{!isProduction && !customDomain && !customDomainEnabled && (
|
||||
{!customDomain && !customDomainEnabled && (
|
||||
<InlineNotification
|
||||
hasIcon={false}
|
||||
severity="info"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
import { TenantSettingsTabs } from '@/consts';
|
||||
import { isProduction } from '@/consts/env';
|
||||
import CardTitle from '@/ds-components/CardTitle';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
import TabNav, { TabNavItem } from '@/ds-components/TabNav';
|
||||
|
@ -23,16 +22,12 @@ function TenantSettings() {
|
|||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Domains}`}>
|
||||
<DynamicT forKey="tenants.tabs.domains" />
|
||||
</TabNavItem>
|
||||
{!isProduction && (
|
||||
<>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Subscription}`}>
|
||||
<DynamicT forKey="tenants.tabs.subscription" />
|
||||
</TabNavItem>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.BillingHistory}`}>
|
||||
<DynamicT forKey="tenants.tabs.billing_history" />
|
||||
</TabNavItem>
|
||||
</>
|
||||
)}
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Subscription}`}>
|
||||
<DynamicT forKey="tenants.tabs.subscription" />
|
||||
</TabNavItem>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.BillingHistory}`}>
|
||||
<DynamicT forKey="tenants.tabs.billing_history" />
|
||||
</TabNavItem>
|
||||
</TabNav>
|
||||
<Outlet />
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { isCloud, isProduction } from '@/consts/env';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import { type SubscriptionPlan, type SubscriptionPlanQuota } from '@/types/subscriptions';
|
||||
|
||||
type HasReachedQuotaLimitParameters = {
|
||||
|
@ -8,15 +8,8 @@ type HasReachedQuotaLimitParameters = {
|
|||
};
|
||||
|
||||
export const hasReachedQuotaLimit = ({ quotaKey, usage, plan }: HasReachedQuotaLimitParameters) => {
|
||||
/**
|
||||
* Todo: @xiaoyijun remove this condition on subscription features ready.
|
||||
*/
|
||||
if (isProduction || !isCloud) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the plan is not loaded, guarded by backend APIs
|
||||
if (!plan) {
|
||||
if (!isCloud || !plan) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue