Paywall button

This commit is contained in:
Sergey Garin 2024-05-21 19:32:53 +03:00
parent a3c345d281
commit 5ddece8c5e
6 changed files with 84 additions and 28 deletions

View File

@ -4,13 +4,17 @@ import * as tw from 'tailwind-merge'
import Check from 'enso-assets/check_mark.svg'
import type * as text from '#/text'
import * as textProvider from '#/providers/TextProvider'
import SvgMask from '#/components/SvgMask'
/**
*
*/
export interface PaywallBulletPointsProps {
readonly bulletPoints: string[]
readonly bulletPointsTextId: text.TextId
readonly className?: string
}
@ -18,7 +22,12 @@ export interface PaywallBulletPointsProps {
*
*/
export function PaywallBulletPoints(props: PaywallBulletPointsProps) {
const { bulletPoints, className } = props
const { bulletPointsTextId, className } = props
const { getText } = textProvider.useText()
const bulletPoints = getText(bulletPointsTextId)
.split(';')
.map(bulletPoint => bulletPoint.trim())
if (bulletPoints.length === 0) {
return null

View File

@ -7,27 +7,77 @@
import * as React from 'react'
import PaywallBlocked from 'enso-assets/lock.svg'
import LockIcon from 'enso-assets/lock.svg'
import * as button from '#/components/AriaComponents'
import * as appUtils from '#/appUtils'
import * as billingHooks from '#/hooks/billing'
import * as textProvider from '#/providers/TextProvider'
import * as ariaComponents from '#/components/AriaComponents'
import SvgMask from '#/components/SvgMask'
import { PaywallBulletPoints } from './PaywallBulletPoints'
/**
* Props of the PaywallButton component
*/
export type PaywallButtonProps = button.ButtonProps & {}
export type PaywallButtonProps = ariaComponents.ButtonProps & {
readonly feature: billingHooks.PaywallFeatureName
}
/**
* PaywallButton component
*/
export function PaywallButton(props: PaywallButtonProps) {
const { size = 'medium', variant = 'primary' } = props
const { size = 'medium', variant = 'primary', feature, ...buttonProps } = props
const { getText } = textProvider.useText()
const { getFeature } = billingHooks.usePaywallFeatures()
const { bulletPointsTextId, level, name, descriptionTextId } = getFeature(feature)
const levelLabel = getText(level.label)
const isEnterprise = level === billingHooks.PAYWALL_LEVELS.enterprise
return (
<button.Button
variant={variant}
size={size}
rounding="full"
icon={PaywallBlocked}
iconPosition="end"
/>
<ariaComponents.DialogTrigger>
<ariaComponents.Button
variant={variant}
size={size}
rounding="full"
icon={PaywallBlocked}
iconPosition="start"
tooltip={getText('paywallScreenDescription', levelLabel)}
{...buttonProps}
/>
<ariaComponents.Dialog type="modal" title={getText(name)}>
<div className="flex flex-col">
<div className="mb-2 flex flex-col items-center justify-center">
<div className="flex w-full items-center gap-1 text-sm font-normal">
<SvgMask src={LockIcon} role="presentation" className="h-4 w-4" />
{getText('paywallAvailabilityLevel', levelLabel)}
</div>
</div>
<p className="text-base text-primary/60">{getText(descriptionTextId)}</p>
<PaywallBulletPoints bulletPointsTextId={bulletPointsTextId} className="my-4" />
<ariaComponents.Button
variant="primary"
size="medium"
rounding="xlarge"
className="mt-2"
href={appUtils.SUBSCRIBE_PATH}
>
{isEnterprise ? getText('contactSales') : getText('learnMore')}
</ariaComponents.Button>
</div>
</ariaComponents.Dialog>
</ariaComponents.DialogTrigger>
)
}

View File

@ -21,6 +21,7 @@ import * as ariaComponents from '#/components/AriaComponents'
import SvgMask from '#/components/SvgMask'
import { PaywallBulletPoints } from './PaywallBulletPoints'
import { PaywallButton } from './PaywallButton'
/**
* Props for a {@link PaywallScreen}.
@ -55,23 +56,21 @@ export function PaywallScreen(props: PaywallScreenProps) {
{getText('paywallScreenTitle')}
</aria.Text>
<PaywallBulletPoints
bulletPoints={getText(bulletPointsTextId).split(';')}
className="mb-6 mt-4"
/>
<PaywallBulletPoints bulletPointsTextId={bulletPointsTextId} className="mb-6 mt-4" />
<p className="text-sm font-normal text-gray-600">
{getText('paywallScreenDescription', levelLabel)}
</p>
<ariaComponents.Button
<PaywallButton
feature={feature}
variant="primary"
size="medium"
className="mt-3"
href={appUtils.SUBSCRIBE_PATH + '?plan=' + level.name}
// href={appUtils.SUBSCRIBE_PATH + '?plan=' + level.name}
>
{getText('upgradeTo', levelLabel)}
</ariaComponents.Button>
</PaywallButton>
</div>
)
}

View File

@ -68,13 +68,7 @@ const PAYWALL_FEATURES_LABELS: Record<PaywallFeatureName, text.TextId> = {
interface BasicFeatureConfiguration {
readonly level: PaywallLevel
readonly bulletPointsTextId: `${PaywallFeatureName}FeatureBulletPoints`
}
/**
* Plan configuration.
*/
interface PlanConfiguration<T extends BasicFeatureConfiguration> {
readonly features: Record<PaywallFeatureName, T>
readonly descriptionTextId: `${PaywallFeatureName}FeatureDescription`
}
/**
@ -90,6 +84,7 @@ const PAYWALL_CONFIGURATION: Record<PaywallFeatureName, BasicFeatureConfiguratio
userGroups: {
level: PAYWALL_LEVELS.solo,
bulletPointsTextId: 'userGroupsFeatureBulletPoints',
descriptionTextId: 'userGroupsFeatureDescription',
},
}

View File

@ -7,4 +7,6 @@
export * from './paywallHooks'
export * from './paywallFeaturesHooks'
// eslint-disable-next-line no-restricted-syntax
export type { PaywallFeatureName } from './FeaturesConfiguration'
export type { PaywallFeatureName, PaywallLevel } from './FeaturesConfiguration'
// eslint-disable-next-line no-restricted-syntax
export { PAYWALL_LEVELS } from './FeaturesConfiguration'

View File

@ -622,5 +622,6 @@
"paywallAvailabilityLevel": "Available on $0 plan",
"userGroupsFeatureLabel": "User Groups",
"userGroupsFeatureBulletPoints": "Create user groups to manage permissions;Assign user groups to assets;Assign users to groups"
"userGroupsFeatureBulletPoints": "Create user groups to manage permissions;Assign user groups to assets;Assign users to groups",
"userGroupsFeatureDescription": "Get fine-grained control over who can access your assets by creating user groups and assigning them to assets. Assign users to groups to manage their permissions."
}