0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

feat(console): add paywall for organization template (#5679)

This commit is contained in:
Xiao Yijun 2024-04-11 17:28:39 +08:00 committed by GitHub
parent b3d94dd712
commit 6f670b0d1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 61 additions and 10 deletions

View file

@ -4,5 +4,12 @@
> *:not(:first-child) { > *:not(:first-child) {
margin-top: _.unit(4); margin-top: _.unit(4);
} }
.paywallCard {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
} }

View file

@ -1,17 +1,28 @@
import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact';
import { ReservedPlanId } from '@logto/schemas';
import { cond } from '@silverhand/essentials';
import classNames from 'classnames'; import classNames from 'classnames';
import { useState } from 'react'; import { useCallback, useContext, useState } from 'react';
import { Outlet } from 'react-router-dom'; import { Outlet } from 'react-router-dom';
import Research from '@/assets/icons/research.svg'; import Research from '@/assets/icons/research.svg';
import OrganizationEmptyDark from '@/assets/images/organization-empty-dark.svg';
import OrganizationEmpty from '@/assets/images/organization-empty.svg';
import Drawer from '@/components/Drawer'; import Drawer from '@/components/Drawer';
import PageMeta from '@/components/PageMeta'; import PageMeta from '@/components/PageMeta';
import { OrganizationTemplateTabs, organizationTemplateLink } from '@/consts'; import { OrganizationTemplateTabs, organizationTemplateLink } from '@/consts';
import { isCloud } from '@/consts/env';
import { subscriptionPage } from '@/consts/pages';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button'; import Button from '@/ds-components/Button';
import Card from '@/ds-components/Card';
import CardTitle from '@/ds-components/CardTitle'; import CardTitle from '@/ds-components/CardTitle';
import DynamicT from '@/ds-components/DynamicT'; import DynamicT from '@/ds-components/DynamicT';
import TabNav, { TabNavItem } from '@/ds-components/TabNav'; import TabNav, { TabNavItem } from '@/ds-components/TabNav';
import TablePlaceholder from '@/ds-components/Table/TablePlaceholder';
import useDocumentationUrl from '@/hooks/use-documentation-url'; import useDocumentationUrl from '@/hooks/use-documentation-url';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import * as pageLayout from '@/scss/page-layout.module.scss'; import * as pageLayout from '@/scss/page-layout.module.scss';
import Introduction from '../Organizations/Guide/Introduction'; import Introduction from '../Organizations/Guide/Introduction';
@ -23,6 +34,14 @@ const basePathname = '/organization-template';
function OrganizationTemplate() { function OrganizationTemplate() {
const { getDocumentationUrl } = useDocumentationUrl(); const { getDocumentationUrl } = useDocumentationUrl();
const [isGuideDrawerOpen, setIsGuideDrawerOpen] = useState(false); const [isGuideDrawerOpen, setIsGuideDrawerOpen] = useState(false);
const { currentPlan } = useContext(SubscriptionDataContext);
const { isDevTenant } = useContext(TenantsContext);
const isOrganizationsDisabled = isCloud && !currentPlan.quota.organizationsEnabled;
const { navigate } = useTenantPathname();
const handleUpgradePlan = useCallback(() => {
navigate(subscriptionPage);
}, [navigate]);
return ( return (
<div className={classNames(pageLayout.container, styles.container)}> <div className={classNames(pageLayout.container, styles.container)}>
@ -35,6 +54,7 @@ function OrganizationTemplate() {
href: getDocumentationUrl(organizationTemplateLink), href: getDocumentationUrl(organizationTemplateLink),
targetBlank: 'noopener', targetBlank: 'noopener',
}} }}
paywall={cond((isOrganizationsDisabled || isDevTenant) && ReservedPlanId.Pro)}
/> />
<Button <Button
icon={<Research />} icon={<Research />}
@ -55,15 +75,39 @@ function OrganizationTemplate() {
<Introduction isReadonly /> <Introduction isReadonly />
</Drawer> </Drawer>
</div> </div>
{isOrganizationsDisabled && (
<Card className={styles.paywallCard}>
<TablePlaceholder
title="organization_template.title"
description="organization_template.subtitle"
image={<OrganizationEmpty />}
imageDark={<OrganizationEmptyDark />}
action={
<Button
title="upsell.upgrade_plan"
type="primary"
size="large"
onClick={handleUpgradePlan}
/>
}
/>
</Card>
)}
{!isOrganizationsDisabled && (
<>
<TabNav> <TabNav>
<TabNavItem href={`${basePathname}/${OrganizationTemplateTabs.OrganizationRoles}`}> <TabNavItem href={`${basePathname}/${OrganizationTemplateTabs.OrganizationRoles}`}>
<DynamicT forKey="organization_template.roles.tab_name" /> <DynamicT forKey="organization_template.roles.tab_name" />
</TabNavItem> </TabNavItem>
<TabNavItem href={`${basePathname}/${OrganizationTemplateTabs.OrganizationPermissions}`}> <TabNavItem
href={`${basePathname}/${OrganizationTemplateTabs.OrganizationPermissions}`}
>
<DynamicT forKey="organization_template.permissions.tab_name" /> <DynamicT forKey="organization_template.permissions.tab_name" />
</TabNavItem> </TabNavItem>
</TabNav> </TabNav>
<Outlet /> <Outlet />
</>
)}
</div> </div>
); );
} }