🐛 Remove delete result cascade
This commit is contained in:
committed by
Baptiste Arnaud
parent
30dff2d5d7
commit
3c803b1345
61
apps/builder/assets/logos/StripeClimateLogo.tsx
Normal file
61
apps/builder/assets/logos/StripeClimateLogo.tsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { Icon, IconProps } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const StripeClimateLogo = (props: IconProps) => (
|
||||||
|
<Icon
|
||||||
|
width="24px"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<linearGradient
|
||||||
|
id="StripeClimate-gradient-a"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="16"
|
||||||
|
y1="20.6293"
|
||||||
|
x2="16"
|
||||||
|
y2="7.8394"
|
||||||
|
gradientTransform="matrix(1 0 0 -1 0 34)"
|
||||||
|
>
|
||||||
|
<stop offset="0" stop-color="#00d924" />
|
||||||
|
<stop offset="1" stop-color="#00cb1b" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
d="M0 10.82h32c0 8.84-7.16 16-16 16s-16-7.16-16-16z"
|
||||||
|
fill="url(#StripeClimate-gradient-a)"
|
||||||
|
/>
|
||||||
|
<linearGradient
|
||||||
|
id="StripeClimate-gradient-b"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="24"
|
||||||
|
y1="28.6289"
|
||||||
|
x2="24"
|
||||||
|
y2="17.2443"
|
||||||
|
gradientTransform="matrix(1 0 0 -1 0 34)"
|
||||||
|
>
|
||||||
|
<stop offset=".1562" stop-color="#009c00" />
|
||||||
|
<stop offset="1" stop-color="#00be20" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
d="M32 10.82c0 2.21-1.49 4.65-5.41 4.65-3.42 0-7.27-2.37-10.59-4.65 3.52-2.43 7.39-5.63 10.59-5.63C29.86 5.18 32 8.17 32 10.82z"
|
||||||
|
fill="url(#StripeClimate-gradient-b)"
|
||||||
|
/>
|
||||||
|
<linearGradient
|
||||||
|
id="StripeClimate-gradient-c"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="8"
|
||||||
|
y1="16.7494"
|
||||||
|
x2="8"
|
||||||
|
y2="29.1239"
|
||||||
|
gradientTransform="matrix(1 0 0 -1 0 34)"
|
||||||
|
>
|
||||||
|
<stop offset="0" stop-color="#ffe37d" />
|
||||||
|
<stop offset="1" stop-color="#ffc900" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
d="M0 10.82c0 2.21 1.49 4.65 5.41 4.65 3.42 0 7.27-2.37 10.59-4.65-3.52-2.43-7.39-5.64-10.59-5.64C2.14 5.18 0 8.17 0 10.82z"
|
||||||
|
fill="url(#StripeClimate-gradient-c)"
|
||||||
|
/>
|
||||||
|
</Icon>
|
||||||
|
)
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Stack, HStack, Text } from '@chakra-ui/react'
|
import { Stack, HStack, Text } from '@chakra-ui/react'
|
||||||
|
import { StripeClimateLogo } from 'assets/logos/StripeClimateLogo'
|
||||||
import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
|
import { NextChakraLink } from 'components/nextChakra/NextChakraLink'
|
||||||
import { useUser } from 'contexts/UserContext'
|
import { useUser } from 'contexts/UserContext'
|
||||||
import { useWorkspace } from 'contexts/WorkspaceContext'
|
import { useWorkspace } from 'contexts/WorkspaceContext'
|
||||||
@@ -63,7 +64,21 @@ export const ChangePlanForm = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={6}>
|
||||||
|
<HStack maxW="500px">
|
||||||
|
<StripeClimateLogo />
|
||||||
|
<Text fontSize="xs" color="gray.500">
|
||||||
|
Typebot is contributing 1% of your subscription to remove CO₂ from the
|
||||||
|
atmosphere.{' '}
|
||||||
|
<NextChakraLink
|
||||||
|
href="https://climate.stripe.com/5VCRAq"
|
||||||
|
isExternal
|
||||||
|
textDecor="underline"
|
||||||
|
>
|
||||||
|
More info.
|
||||||
|
</NextChakraLink>
|
||||||
|
</Text>
|
||||||
|
</HStack>
|
||||||
<HStack alignItems="stretch" spacing="4" w="full">
|
<HStack alignItems="stretch" spacing="4" w="full">
|
||||||
<StarterPlanContent
|
<StarterPlanContent
|
||||||
initialChatsLimitIndex={
|
initialChatsLimitIndex={
|
||||||
@@ -94,9 +109,8 @@ export const ChangePlanForm = () => {
|
|||||||
isExternal
|
isExternal
|
||||||
textDecor="underline"
|
textDecor="underline"
|
||||||
>
|
>
|
||||||
Let me know
|
Let's chat!
|
||||||
</NextChakraLink>
|
</NextChakraLink>
|
||||||
.
|
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
const typebots = await prisma.typebot.deleteMany({
|
const typebots = await prisma.typebot.deleteMany({
|
||||||
where: canWriteTypebot(typebotId, user),
|
where: canWriteTypebot(typebotId, user),
|
||||||
})
|
})
|
||||||
|
await prisma.result.updateMany({
|
||||||
|
where: { typebot: canWriteTypebot(typebotId, user) },
|
||||||
|
data: { isArchived: true },
|
||||||
|
})
|
||||||
return res.send({ typebots })
|
return res.send({ typebots })
|
||||||
}
|
}
|
||||||
if (req.method === 'PUT') {
|
if (req.method === 'PUT') {
|
||||||
|
|||||||
@@ -30,6 +30,17 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
members: { some: { userId: user.id, role: WorkspaceRole.ADMIN } },
|
members: { some: { userId: user.id, role: WorkspaceRole.ADMIN } },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
await prisma.result.updateMany({
|
||||||
|
where: {
|
||||||
|
typebot: {
|
||||||
|
workspace: {
|
||||||
|
id,
|
||||||
|
members: { some: { userId: user.id, role: WorkspaceRole.ADMIN } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: { isArchived: true },
|
||||||
|
})
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
message: 'success',
|
message: 'success',
|
||||||
})
|
})
|
||||||
|
|||||||
61
apps/landing-page/assets/logos/StripeClimateLogo.tsx
Normal file
61
apps/landing-page/assets/logos/StripeClimateLogo.tsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { Icon, IconProps } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const StripeClimateLogo = (props: IconProps) => (
|
||||||
|
<Icon
|
||||||
|
width="24px"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<linearGradient
|
||||||
|
id="StripeClimate-gradient-a"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="16"
|
||||||
|
y1="20.6293"
|
||||||
|
x2="16"
|
||||||
|
y2="7.8394"
|
||||||
|
gradientTransform="matrix(1 0 0 -1 0 34)"
|
||||||
|
>
|
||||||
|
<stop offset="0" stop-color="#00d924" />
|
||||||
|
<stop offset="1" stop-color="#00cb1b" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
d="M0 10.82h32c0 8.84-7.16 16-16 16s-16-7.16-16-16z"
|
||||||
|
fill="url(#StripeClimate-gradient-a)"
|
||||||
|
/>
|
||||||
|
<linearGradient
|
||||||
|
id="StripeClimate-gradient-b"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="24"
|
||||||
|
y1="28.6289"
|
||||||
|
x2="24"
|
||||||
|
y2="17.2443"
|
||||||
|
gradientTransform="matrix(1 0 0 -1 0 34)"
|
||||||
|
>
|
||||||
|
<stop offset=".1562" stop-color="#009c00" />
|
||||||
|
<stop offset="1" stop-color="#00be20" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
d="M32 10.82c0 2.21-1.49 4.65-5.41 4.65-3.42 0-7.27-2.37-10.59-4.65 3.52-2.43 7.39-5.63 10.59-5.63C29.86 5.18 32 8.17 32 10.82z"
|
||||||
|
fill="url(#StripeClimate-gradient-b)"
|
||||||
|
/>
|
||||||
|
<linearGradient
|
||||||
|
id="StripeClimate-gradient-c"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="8"
|
||||||
|
y1="16.7494"
|
||||||
|
x2="8"
|
||||||
|
y2="29.1239"
|
||||||
|
gradientTransform="matrix(1 0 0 -1 0 34)"
|
||||||
|
>
|
||||||
|
<stop offset="0" stop-color="#ffe37d" />
|
||||||
|
<stop offset="1" stop-color="#ffc900" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
d="M0 10.82c0 2.21 1.49 4.65 5.41 4.65 3.42 0 7.27-2.37 10.59-4.65-3.52-2.43-7.39-5.64-10.59-5.64C2.14 5.18 0 8.17 0 10.82z"
|
||||||
|
fill="url(#StripeClimate-gradient-c)"
|
||||||
|
/>
|
||||||
|
</Icon>
|
||||||
|
)
|
||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
chakra,
|
chakra,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
HStack,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { HelpCircleIcon } from 'assets/icons/HelpCircleIcon'
|
import { HelpCircleIcon } from 'assets/icons/HelpCircleIcon'
|
||||||
import { Footer } from 'components/common/Footer'
|
import { Footer } from 'components/common/Footer'
|
||||||
@@ -26,6 +27,7 @@ import { ActionButton } from 'components/PricingPage/PricingCard/ActionButton'
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { formatPrice, prices } from 'utils'
|
import { formatPrice, prices } from 'utils'
|
||||||
import { Plan } from 'db'
|
import { Plan } from 'db'
|
||||||
|
import { StripeClimateLogo } from 'assets/logos/StripeClimateLogo'
|
||||||
|
|
||||||
const Pricing = () => {
|
const Pricing = () => {
|
||||||
const [starterPrice, setStarterPrice] = useState('$39')
|
const [starterPrice, setStarterPrice] = useState('$39')
|
||||||
@@ -54,173 +56,208 @@ const Pricing = () => {
|
|||||||
</DarkMode>
|
</DarkMode>
|
||||||
|
|
||||||
<VStack spacing={'24'} mt={[20, 32]} w="full">
|
<VStack spacing={'24'} mt={[20, 32]} w="full">
|
||||||
<Stack align="center" spacing="6">
|
<Stack align="center" spacing="12" w="full">
|
||||||
<Heading fontSize="6xl">Plans fit for you</Heading>
|
<VStack>
|
||||||
<Text maxW="900px" fontSize="xl" textAlign="center">
|
<Heading fontSize="6xl">Plans fit for you</Heading>
|
||||||
Whether you're a{' '}
|
<Text maxW="900px" fontSize="xl" textAlign="center">
|
||||||
<Text as="span" color="orange.200" fontWeight="bold">
|
Whether you're a{' '}
|
||||||
solo business owner
|
<Text as="span" color="orange.200" fontWeight="bold">
|
||||||
</Text>{' '}
|
solo business owner
|
||||||
or a{' '}
|
</Text>{' '}
|
||||||
<Text as="span" color="blue.200" fontWeight="bold">
|
or a{' '}
|
||||||
growing startup
|
<Text as="span" color="blue.200" fontWeight="bold">
|
||||||
|
growing startup
|
||||||
|
</Text>
|
||||||
|
, Typebot is here to help you build high-performing bots for the
|
||||||
|
right price. Pay for as little or as much usage as you need.
|
||||||
</Text>
|
</Text>
|
||||||
, Typebot is here to help you build high-performing bots for the
|
</VStack>
|
||||||
right price. Pay for as little or as much usage as you need.
|
|
||||||
|
<HStack
|
||||||
|
maxW="500px"
|
||||||
|
spacing="4"
|
||||||
|
bgColor="gray.800"
|
||||||
|
p="4"
|
||||||
|
rounded="md"
|
||||||
|
>
|
||||||
|
<StripeClimateLogo />
|
||||||
|
<Text fontSize="sm">
|
||||||
|
Typebot is contributing 1% of your subscription to remove CO₂
|
||||||
|
from the atmosphere.{' '}
|
||||||
|
<NextChakraLink
|
||||||
|
href="https://climate.stripe.com/5VCRAq"
|
||||||
|
isExternal
|
||||||
|
textDecor="underline"
|
||||||
|
>
|
||||||
|
More info.
|
||||||
|
</NextChakraLink>
|
||||||
|
</Text>
|
||||||
|
</HStack>
|
||||||
|
<Stack
|
||||||
|
direction={['column', 'row']}
|
||||||
|
alignItems={['stretch']}
|
||||||
|
spacing={10}
|
||||||
|
px={[4, 0]}
|
||||||
|
w="full"
|
||||||
|
maxW="1200px"
|
||||||
|
>
|
||||||
|
<PricingCard
|
||||||
|
data={{
|
||||||
|
price: 'Free',
|
||||||
|
name: 'Personal',
|
||||||
|
features: [
|
||||||
|
'Unlimited typebots',
|
||||||
|
'300 chats included',
|
||||||
|
'Native integrations',
|
||||||
|
'Webhooks',
|
||||||
|
'Custom Javascript & CSS',
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
button={
|
||||||
|
<NextChakraLink
|
||||||
|
href="https://app.typebot.io/register"
|
||||||
|
_hover={{ textDecor: 'none' }}
|
||||||
|
>
|
||||||
|
<ActionButton variant="outline">Get started</ActionButton>
|
||||||
|
</NextChakraLink>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<PricingCard
|
||||||
|
data={{
|
||||||
|
price: starterPrice,
|
||||||
|
name: 'Starter',
|
||||||
|
featureLabel: 'Everything in Personal, plus:',
|
||||||
|
features: [
|
||||||
|
<Text key="seats">
|
||||||
|
<chakra.span fontWeight="bold">2 seats</chakra.span>{' '}
|
||||||
|
included
|
||||||
|
</Text>,
|
||||||
|
<>
|
||||||
|
<Text>
|
||||||
|
<chakra.span fontWeight="bold">2,000 chats</chakra.span>{' '}
|
||||||
|
included
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
hasArrow
|
||||||
|
placement="top"
|
||||||
|
label="A chat is counted whenever a user starts a discussion. It is
|
||||||
|
independant of the number of messages he sends and receives."
|
||||||
|
>
|
||||||
|
<chakra.span cursor="pointer" h="7">
|
||||||
|
<HelpCircleIcon />
|
||||||
|
</chakra.span>
|
||||||
|
</Tooltip>
|
||||||
|
</>,
|
||||||
|
<>
|
||||||
|
<Text>
|
||||||
|
<chakra.span fontWeight="bold">2 GB chats</chakra.span>{' '}
|
||||||
|
included
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
hasArrow
|
||||||
|
placement="top"
|
||||||
|
label="You accumulate storage for every file that your user upload
|
||||||
|
into your bot. If you delete the result, it will free up the
|
||||||
|
space."
|
||||||
|
>
|
||||||
|
<chakra.span cursor="pointer" h="7">
|
||||||
|
<HelpCircleIcon />
|
||||||
|
</chakra.span>
|
||||||
|
</Tooltip>
|
||||||
|
</>,
|
||||||
|
'Branding removed',
|
||||||
|
'Collect files from users',
|
||||||
|
'Create folders',
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
borderWidth="1px"
|
||||||
|
borderColor="orange.200"
|
||||||
|
button={
|
||||||
|
<NextChakraLink
|
||||||
|
href={`https://app.typebot.io/register?subscribePlan=${Plan.STARTER}`}
|
||||||
|
_hover={{ textDecor: 'none' }}
|
||||||
|
>
|
||||||
|
<ActionButton>Subscribe now</ActionButton>
|
||||||
|
</NextChakraLink>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<PricingCard
|
||||||
|
data={{
|
||||||
|
price: proPrice,
|
||||||
|
name: 'Pro',
|
||||||
|
featureLabel: 'Everything in Starter, plus:',
|
||||||
|
features: [
|
||||||
|
<Text key="seats">
|
||||||
|
<chakra.span fontWeight="bold">5 seats</chakra.span>{' '}
|
||||||
|
included
|
||||||
|
</Text>,
|
||||||
|
<>
|
||||||
|
<Text>
|
||||||
|
<chakra.span fontWeight="bold">
|
||||||
|
10,000 chats
|
||||||
|
</chakra.span>{' '}
|
||||||
|
included
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
hasArrow
|
||||||
|
placement="top"
|
||||||
|
label="A chat is counted whenever a user starts a discussion. It is
|
||||||
|
independant of the number of messages he sends and receives."
|
||||||
|
>
|
||||||
|
<chakra.span cursor="pointer" h="7">
|
||||||
|
<HelpCircleIcon />
|
||||||
|
</chakra.span>
|
||||||
|
</Tooltip>
|
||||||
|
</>,
|
||||||
|
<>
|
||||||
|
<Text>
|
||||||
|
<chakra.span fontWeight="bold">10 GB chats</chakra.span>{' '}
|
||||||
|
included
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Tooltip
|
||||||
|
hasArrow
|
||||||
|
placement="top"
|
||||||
|
label="You accumulate storage for every file that your user upload
|
||||||
|
into your bot. If you delete the result, it will free up the
|
||||||
|
space."
|
||||||
|
>
|
||||||
|
<chakra.span cursor="pointer" h="7">
|
||||||
|
<HelpCircleIcon />
|
||||||
|
</chakra.span>
|
||||||
|
</Tooltip>
|
||||||
|
</>,
|
||||||
|
'Custom domains',
|
||||||
|
'In-depth analytics',
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
borderWidth="3px"
|
||||||
|
borderColor="blue.200"
|
||||||
|
button={
|
||||||
|
<NextChakraLink
|
||||||
|
href={`https://app.typebot.io/register?subscribePlan=${Plan.PRO}`}
|
||||||
|
_hover={{ textDecor: 'none' }}
|
||||||
|
>
|
||||||
|
<ActionButton>Subscribe now</ActionButton>
|
||||||
|
</NextChakraLink>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Text fontSize="lg">
|
||||||
|
Need custom limits? Specific features?{' '}
|
||||||
|
<NextChakraLink
|
||||||
|
href={'https://typebot.io/enterprise-lead-form'}
|
||||||
|
isExternal
|
||||||
|
textDecor="underline"
|
||||||
|
>
|
||||||
|
Let's chat!
|
||||||
|
</NextChakraLink>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack
|
|
||||||
direction={['column', 'row']}
|
|
||||||
alignItems={['stretch']}
|
|
||||||
spacing={10}
|
|
||||||
px={[4, 0]}
|
|
||||||
w="full"
|
|
||||||
maxW="1200px"
|
|
||||||
>
|
|
||||||
<PricingCard
|
|
||||||
data={{
|
|
||||||
price: 'Free',
|
|
||||||
name: 'Personal',
|
|
||||||
features: [
|
|
||||||
'Unlimited typebots',
|
|
||||||
'300 chats included',
|
|
||||||
'Native integrations',
|
|
||||||
'Webhooks',
|
|
||||||
'Custom Javascript & CSS',
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
button={
|
|
||||||
<NextChakraLink
|
|
||||||
href="https://app.typebot.io/register"
|
|
||||||
_hover={{ textDecor: 'none' }}
|
|
||||||
>
|
|
||||||
<ActionButton variant="outline">Get started</ActionButton>
|
|
||||||
</NextChakraLink>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<PricingCard
|
|
||||||
data={{
|
|
||||||
price: starterPrice,
|
|
||||||
name: 'Starter',
|
|
||||||
featureLabel: 'Everything in Personal, plus:',
|
|
||||||
features: [
|
|
||||||
<Text key="seats">
|
|
||||||
<chakra.span fontWeight="bold">2 seats</chakra.span>{' '}
|
|
||||||
included
|
|
||||||
</Text>,
|
|
||||||
<>
|
|
||||||
<Text>
|
|
||||||
<chakra.span fontWeight="bold">2,000 chats</chakra.span>{' '}
|
|
||||||
included
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
placement="top"
|
|
||||||
label="A chat is counted whenever a user starts a discussion. It is
|
|
||||||
independant of the number of messages he sends and receives."
|
|
||||||
>
|
|
||||||
<chakra.span cursor="pointer" h="7">
|
|
||||||
<HelpCircleIcon />
|
|
||||||
</chakra.span>
|
|
||||||
</Tooltip>
|
|
||||||
</>,
|
|
||||||
<>
|
|
||||||
<Text>
|
|
||||||
<chakra.span fontWeight="bold">2 GB chats</chakra.span>{' '}
|
|
||||||
included
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
placement="top"
|
|
||||||
label="You accumulate storage for every file that your user upload
|
|
||||||
into your bot. If you delete the result, it will free up the
|
|
||||||
space."
|
|
||||||
>
|
|
||||||
<chakra.span cursor="pointer" h="7">
|
|
||||||
<HelpCircleIcon />
|
|
||||||
</chakra.span>
|
|
||||||
</Tooltip>
|
|
||||||
</>,
|
|
||||||
'Branding removed',
|
|
||||||
'Collect files from users',
|
|
||||||
'Create folders',
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
borderWidth="1px"
|
|
||||||
borderColor="orange.200"
|
|
||||||
button={
|
|
||||||
<NextChakraLink
|
|
||||||
href={`https://app.typebot.io/register?subscribePlan=${Plan.STARTER}`}
|
|
||||||
_hover={{ textDecor: 'none' }}
|
|
||||||
>
|
|
||||||
<ActionButton>Subscribe now</ActionButton>
|
|
||||||
</NextChakraLink>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<PricingCard
|
|
||||||
data={{
|
|
||||||
price: proPrice,
|
|
||||||
name: 'Pro',
|
|
||||||
featureLabel: 'Everything in Starter, plus:',
|
|
||||||
features: [
|
|
||||||
<Text key="seats">
|
|
||||||
<chakra.span fontWeight="bold">5 seats</chakra.span>{' '}
|
|
||||||
included
|
|
||||||
</Text>,
|
|
||||||
<>
|
|
||||||
<Text>
|
|
||||||
<chakra.span fontWeight="bold">10,000 chats</chakra.span>{' '}
|
|
||||||
included
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
placement="top"
|
|
||||||
label="A chat is counted whenever a user starts a discussion. It is
|
|
||||||
independant of the number of messages he sends and receives."
|
|
||||||
>
|
|
||||||
<chakra.span cursor="pointer" h="7">
|
|
||||||
<HelpCircleIcon />
|
|
||||||
</chakra.span>
|
|
||||||
</Tooltip>
|
|
||||||
</>,
|
|
||||||
<>
|
|
||||||
<Text>
|
|
||||||
<chakra.span fontWeight="bold">10 GB chats</chakra.span>{' '}
|
|
||||||
included
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
hasArrow
|
|
||||||
placement="top"
|
|
||||||
label="You accumulate storage for every file that your user upload
|
|
||||||
into your bot. If you delete the result, it will free up the
|
|
||||||
space."
|
|
||||||
>
|
|
||||||
<chakra.span cursor="pointer" h="7">
|
|
||||||
<HelpCircleIcon />
|
|
||||||
</chakra.span>
|
|
||||||
</Tooltip>
|
|
||||||
</>,
|
|
||||||
'Custom domains',
|
|
||||||
'In-depth analytics',
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
borderWidth="3px"
|
|
||||||
borderColor="blue.200"
|
|
||||||
button={
|
|
||||||
<NextChakraLink
|
|
||||||
href={`https://app.typebot.io/register?subscribePlan=${Plan.PRO}`}
|
|
||||||
_hover={{ textDecor: 'none' }}
|
|
||||||
>
|
|
||||||
<ActionButton>Subscribe now</ActionButton>
|
|
||||||
</NextChakraLink>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
<VStack maxW="1200px" w="full" spacing={[12, 20]} px="4">
|
<VStack maxW="1200px" w="full" spacing={[12, 20]} px="4">
|
||||||
<Stack w="full" spacing={10} display={['none', 'flex']}>
|
<Stack w="full" spacing={10} display={['none', 'flex']}>
|
||||||
<Heading>Compare plans & features</Heading>
|
<Heading>Compare plans & features</Heading>
|
||||||
@@ -244,6 +281,38 @@ const Pricing = () => {
|
|||||||
const Faq = () => {
|
const Faq = () => {
|
||||||
return (
|
return (
|
||||||
<Accordion w="full" allowToggle defaultIndex={0}>
|
<Accordion w="full" allowToggle defaultIndex={0}>
|
||||||
|
<AccordionItem>
|
||||||
|
<Heading as="h2">
|
||||||
|
<AccordionButton py="6">
|
||||||
|
<Box flex="1" textAlign="left" fontSize="2xl">
|
||||||
|
What happens once I reach the monthly chats limit?
|
||||||
|
</Box>
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
</Heading>
|
||||||
|
<AccordionPanel pb={4}>
|
||||||
|
You will receive an email notification once you reached 80% of this
|
||||||
|
limit. Then, once you reach 100%, the bot will be closed to new users.
|
||||||
|
Upgrading your limit will automatically reopen the bot.
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem>
|
||||||
|
<Heading as="h2">
|
||||||
|
<AccordionButton py="6">
|
||||||
|
<Box flex="1" textAlign="left" fontSize="2xl">
|
||||||
|
What happens once I reach the storage limit?
|
||||||
|
</Box>
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
</Heading>
|
||||||
|
<AccordionPanel pb={4}>
|
||||||
|
You will receive an email notification once you reached 80% of this
|
||||||
|
limit. Then, once you reach 100%, your users will still be able to
|
||||||
|
chat with your bot but their uploads won't be stored anymore. You will
|
||||||
|
need to upgrade the limit or free up some space to continue collecting
|
||||||
|
your users' files.
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<Heading as="h2">
|
<Heading as="h2">
|
||||||
<AccordionButton py="6">
|
<AccordionButton py="6">
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ const checkStorageLimit = async (typebotId: string) => {
|
|||||||
})
|
})
|
||||||
if (!typebot?.workspace) throw new Error('Workspace not found')
|
if (!typebot?.workspace) throw new Error('Workspace not found')
|
||||||
const { workspace } = typebot
|
const { workspace } = typebot
|
||||||
console.log(typebot.workspaceId)
|
|
||||||
const {
|
const {
|
||||||
_sum: { storageUsed: totalStorageUsed },
|
_sum: { storageUsed: totalStorageUsed },
|
||||||
} = await prisma.answer.aggregate({
|
} = await prisma.answer.aggregate({
|
||||||
|
|||||||
@@ -4,14 +4,7 @@ import { ChatGroup } from './ChatGroup'
|
|||||||
import { useFrame } from 'react-frame-component'
|
import { useFrame } from 'react-frame-component'
|
||||||
import { setCssVariablesValue } from '../services/theme'
|
import { setCssVariablesValue } from '../services/theme'
|
||||||
import { useAnswers } from '../contexts/AnswersContext'
|
import { useAnswers } from '../contexts/AnswersContext'
|
||||||
import {
|
import { Group, Edge, PublicTypebot, Theme, VariableWithValue } from 'models'
|
||||||
Group,
|
|
||||||
Edge,
|
|
||||||
PublicTypebot,
|
|
||||||
Theme,
|
|
||||||
VariableWithValue,
|
|
||||||
Block,
|
|
||||||
} from 'models'
|
|
||||||
import { byId, isDefined, isInputBlock, isNotDefined } from 'utils'
|
import { byId, isDefined, isInputBlock, isNotDefined } from 'utils'
|
||||||
import { animateScroll as scroll } from 'react-scroll'
|
import { animateScroll as scroll } from 'react-scroll'
|
||||||
import { LinkedTypebot, useTypebot } from 'contexts/TypebotContext'
|
import { LinkedTypebot, useTypebot } from 'contexts/TypebotContext'
|
||||||
@@ -80,7 +73,6 @@ export const ConversationContainer = ({
|
|||||||
}
|
}
|
||||||
const nextGroup = currentTypebot.groups.find(byId(nextEdge.to.groupId))
|
const nextGroup = currentTypebot.groups.find(byId(nextEdge.to.groupId))
|
||||||
if (!nextGroup) return onCompleted()
|
if (!nextGroup) return onCompleted()
|
||||||
console.log(nextGroup, nextEdge)
|
|
||||||
const startBlockIndex = nextEdge.to.blockId
|
const startBlockIndex = nextEdge.to.blockId
|
||||||
? nextGroup.blocks.findIndex(byId(nextEdge.to.blockId))
|
? nextGroup.blocks.findIndex(byId(nextEdge.to.blockId))
|
||||||
: 0
|
: 0
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "Result" DROP CONSTRAINT "Result_typebotId_fkey";
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Result" ADD CONSTRAINT "Result_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE NO ACTION ON UPDATE CASCADE;
|
||||||
@@ -212,7 +212,7 @@ model Result {
|
|||||||
isCompleted Boolean
|
isCompleted Boolean
|
||||||
hasStarted Boolean?
|
hasStarted Boolean?
|
||||||
isArchived Boolean?
|
isArchived Boolean?
|
||||||
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
|
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: NoAction)
|
||||||
answers Answer[]
|
answers Answer[]
|
||||||
logs Log[]
|
logs Log[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ const prisma = new PrismaClient()
|
|||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
await injectFakeResults(prisma)({
|
await injectFakeResults(prisma)({
|
||||||
count: 150,
|
count: 200,
|
||||||
typebotId: 'cl89sq4vb030109laivd9ck97',
|
typebotId: 'cl8hl08xt009909l6pwqenf63',
|
||||||
isChronological: false,
|
isChronological: false,
|
||||||
idPrefix: 'batch2',
|
fakeStorage: 3 * 1024 * 1024 * 1024,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user