feat: 🛂 Restrict file upload input
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { Text, Tooltip } from '@chakra-ui/react'
|
import { HStack, Tag, Text, Tooltip } from '@chakra-ui/react'
|
||||||
|
import { useWorkspace } from 'contexts/WorkspaceContext'
|
||||||
import {
|
import {
|
||||||
BubbleBlockType,
|
BubbleBlockType,
|
||||||
InputBlockType,
|
InputBlockType,
|
||||||
@@ -7,10 +8,13 @@ import {
|
|||||||
BlockType,
|
BlockType,
|
||||||
} from 'models'
|
} from 'models'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { isFreePlan } from 'services/workspace'
|
||||||
|
|
||||||
type Props = { type: BlockType }
|
type Props = { type: BlockType }
|
||||||
|
|
||||||
export const BlockTypeLabel = ({ type }: Props): JSX.Element => {
|
export const BlockTypeLabel = ({ type }: Props): JSX.Element => {
|
||||||
|
const { workspace } = useWorkspace()
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'start':
|
case 'start':
|
||||||
return <Text>Start</Text>
|
return <Text>Start</Text>
|
||||||
@@ -46,7 +50,14 @@ export const BlockTypeLabel = ({ type }: Props): JSX.Element => {
|
|||||||
case InputBlockType.FILE:
|
case InputBlockType.FILE:
|
||||||
return (
|
return (
|
||||||
<Tooltip label="Upload Files">
|
<Tooltip label="Upload Files">
|
||||||
<Text>File</Text>
|
<HStack>
|
||||||
|
<Text>File</Text>
|
||||||
|
{isFreePlan(workspace) && (
|
||||||
|
<Tag colorScheme="orange" size="sm">
|
||||||
|
Pro
|
||||||
|
</Tag>
|
||||||
|
)}
|
||||||
|
</HStack>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
case LogicBlockType.SET_VARIABLE:
|
case LogicBlockType.SET_VARIABLE:
|
||||||
|
|||||||
@@ -9,30 +9,51 @@ import {
|
|||||||
MenuButton,
|
MenuButton,
|
||||||
MenuList,
|
MenuList,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
|
useDisclosure,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { ChevronLeftIcon } from 'assets/icons'
|
import { ChevronLeftIcon } from 'assets/icons'
|
||||||
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
|
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
|
||||||
|
import { useWorkspace } from 'contexts/WorkspaceContext'
|
||||||
|
import { Plan } from 'db'
|
||||||
|
import { InputBlockType } from 'models'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { timeSince } from 'services/utils'
|
import { timeSince } from 'services/utils'
|
||||||
|
import { isFreePlan } from 'services/workspace'
|
||||||
import { isNotDefined } from 'utils'
|
import { isNotDefined } from 'utils'
|
||||||
|
import { UpgradeModal } from '../modals/UpgradeModal'
|
||||||
|
import { LimitReached } from '../modals/UpgradeModal/UpgradeModal'
|
||||||
|
|
||||||
export const PublishButton = () => {
|
export const PublishButton = () => {
|
||||||
|
const { workspace } = useWorkspace()
|
||||||
const { push, query } = useRouter()
|
const { push, query } = useRouter()
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||||
const {
|
const {
|
||||||
isPublishing,
|
isPublishing,
|
||||||
isPublished,
|
isPublished,
|
||||||
publishTypebot,
|
publishTypebot,
|
||||||
publishedTypebot,
|
publishedTypebot,
|
||||||
restorePublishedTypebot,
|
restorePublishedTypebot,
|
||||||
|
typebot,
|
||||||
} = useTypebot()
|
} = useTypebot()
|
||||||
|
|
||||||
|
const hasInputFile = typebot?.groups
|
||||||
|
.flatMap((g) => g.blocks)
|
||||||
|
.some((b) => b.type === InputBlockType.FILE)
|
||||||
|
|
||||||
const handlePublishClick = () => {
|
const handlePublishClick = () => {
|
||||||
|
if (isFreePlan(workspace) && hasInputFile) return onOpen()
|
||||||
publishTypebot()
|
publishTypebot()
|
||||||
if (!publishedTypebot) push(`/typebots/${query.typebotId}/share`)
|
if (!publishedTypebot) push(`/typebots/${query.typebotId}/share`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HStack spacing="1px">
|
<HStack spacing="1px">
|
||||||
|
<UpgradeModal
|
||||||
|
plan={Plan.PRO}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
type={LimitReached.FILE_INPUT}
|
||||||
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
hasArrow
|
hasArrow
|
||||||
|
|||||||
@@ -25,11 +25,13 @@ import { TypebotLogo } from 'assets/logos'
|
|||||||
import { CheckIcon } from 'assets/icons'
|
import { CheckIcon } from 'assets/icons'
|
||||||
import { toTitleCase } from 'utils'
|
import { toTitleCase } from 'utils'
|
||||||
import { useToast } from 'components/shared/hooks/useToast'
|
import { useToast } from 'components/shared/hooks/useToast'
|
||||||
|
import { Info } from 'components/shared/Info'
|
||||||
|
|
||||||
export enum LimitReached {
|
export enum LimitReached {
|
||||||
BRAND = 'Remove branding',
|
BRAND = 'remove branding',
|
||||||
CUSTOM_DOMAIN = 'Custom domain',
|
CUSTOM_DOMAIN = 'add custom domain',
|
||||||
FOLDER = 'Create folders',
|
FOLDER = 'create folders',
|
||||||
|
FILE_INPUT = 'use file input blocks',
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpgradeModalProps = {
|
type UpgradeModalProps = {
|
||||||
@@ -42,6 +44,7 @@ type UpgradeModalProps = {
|
|||||||
export const UpgradeModal = ({
|
export const UpgradeModal = ({
|
||||||
onClose,
|
onClose,
|
||||||
isOpen,
|
isOpen,
|
||||||
|
type,
|
||||||
plan = Plan.PRO,
|
plan = Plan.PRO,
|
||||||
}: UpgradeModalProps) => {
|
}: UpgradeModalProps) => {
|
||||||
const { user } = useUser()
|
const { user } = useUser()
|
||||||
@@ -85,9 +88,9 @@ export const UpgradeModal = ({
|
|||||||
<ModalContent>
|
<ModalContent>
|
||||||
<ModalBody as={Stack} pt="10">
|
<ModalBody as={Stack} pt="10">
|
||||||
{plan === Plan.PRO ? (
|
{plan === Plan.PRO ? (
|
||||||
<PersonalProPlanContent currency={currency} />
|
<PersonalProPlanContent currency={currency} type={type} />
|
||||||
) : (
|
) : (
|
||||||
<TeamPlanContent currency={currency} />
|
<TeamPlanContent currency={currency} type={type} />
|
||||||
)}
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
@@ -110,9 +113,16 @@ export const UpgradeModal = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PersonalProPlanContent = ({ currency }: { currency: 'eur' | 'usd' }) => {
|
const PersonalProPlanContent = ({
|
||||||
|
currency,
|
||||||
|
type,
|
||||||
|
}: {
|
||||||
|
currency: 'eur' | 'usd'
|
||||||
|
type?: LimitReached
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Stack spacing="4">
|
<Stack spacing="4">
|
||||||
|
<Info>You need to upgrade your plan in order to {type}</Info>
|
||||||
<TypebotLogo boxSize="30px" />
|
<TypebotLogo boxSize="30px" />
|
||||||
<Heading fontSize="2xl">
|
<Heading fontSize="2xl">
|
||||||
Upgrade to <chakra.span color="orange.400">Personal Pro</chakra.span>{' '}
|
Upgrade to <chakra.span color="orange.400">Personal Pro</chakra.span>{' '}
|
||||||
@@ -138,9 +148,16 @@ const PersonalProPlanContent = ({ currency }: { currency: 'eur' | 'usd' }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const TeamPlanContent = ({ currency }: { currency: 'eur' | 'usd' }) => {
|
const TeamPlanContent = ({
|
||||||
|
currency,
|
||||||
|
type,
|
||||||
|
}: {
|
||||||
|
currency: 'eur' | 'usd'
|
||||||
|
type?: LimitReached
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Stack spacing="4">
|
<Stack spacing="4">
|
||||||
|
<Info>You need to upgrade your plan in order to {type}</Info>
|
||||||
<TypebotLogo boxSize="30px" />
|
<TypebotLogo boxSize="30px" />
|
||||||
<Heading fontSize="2xl">
|
<Heading fontSize="2xl">
|
||||||
Upgrade to <chakra.span color="purple.400">Team</chakra.span> plan
|
Upgrade to <chakra.span color="purple.400">Team</chakra.span> plan
|
||||||
|
|||||||
@@ -224,6 +224,16 @@ export const PlanComparisonTables = ({ prices, ...props }: Props) => {
|
|||||||
<CheckIcon />
|
<CheckIcon />
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
|
<Tr>
|
||||||
|
<Td>File upload inputs</Td>
|
||||||
|
<Td />
|
||||||
|
<Td>
|
||||||
|
<CheckIcon />
|
||||||
|
</Td>
|
||||||
|
<Td>
|
||||||
|
<CheckIcon />
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Td>Custom domains</Td>
|
<Td>Custom domains</Td>
|
||||||
<Td />
|
<Td />
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ const Pricing = () => {
|
|||||||
'In-depth drop off analytics',
|
'In-depth drop off analytics',
|
||||||
'Custom domains',
|
'Custom domains',
|
||||||
'Organize typebots in folders',
|
'Organize typebots in folders',
|
||||||
'Unlimited uploads',
|
'File upload input',
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
borderWidth="3px"
|
borderWidth="3px"
|
||||||
|
|||||||
Reference in New Issue
Block a user