2
0
Files
bot/apps/builder/components/shared/modals/UpgradeModal/UpgradeModal.tsx

201 lines
5.0 KiB
TypeScript
Raw Normal View History

import { useEffect, useState } from 'react'
import {
2022-05-13 15:22:44 -07:00
Heading,
Modal,
ModalBody,
2022-05-13 15:22:44 -07:00
Text,
ModalContent,
ModalFooter,
ModalOverlay,
Stack,
2022-05-13 15:22:44 -07:00
ListItem,
UnorderedList,
ListIcon,
chakra,
Tooltip,
ListProps,
Button,
HStack,
useToast,
} from '@chakra-ui/react'
import { pay } from 'services/stripe'
import { useUser } from 'contexts/UserContext'
2022-05-13 15:22:44 -07:00
import { Plan } from 'db'
import { useWorkspace } from 'contexts/WorkspaceContext'
import { TypebotLogo } from 'assets/logos'
import { CheckIcon } from 'assets/icons'
import { toTitleCase } from 'utils'
export enum LimitReached {
BRAND = 'Remove branding',
CUSTOM_DOMAIN = 'Custom domain',
FOLDER = 'Create folders',
}
type UpgradeModalProps = {
type?: LimitReached
isOpen: boolean
onClose: () => void
2022-05-13 15:22:44 -07:00
plan?: Plan
}
2022-05-13 15:22:44 -07:00
export const UpgradeModal = ({
onClose,
isOpen,
plan = Plan.PRO,
}: UpgradeModalProps) => {
const { user } = useUser()
const { workspace, refreshWorkspace } = useWorkspace()
const [payLoading, setPayLoading] = useState(false)
const [currency, setCurrency] = useState<'usd' | 'eur'>('usd')
const toast = useToast()
useEffect(() => {
setCurrency(
navigator.languages.find((l) => l.includes('fr')) ? 'eur' : 'usd'
)
}, [])
const handlePayClick = async () => {
2022-05-13 15:22:44 -07:00
if (!user || !workspace) return
setPayLoading(true)
const response = await pay({
customerId: workspace.stripeId ?? undefined,
2022-05-13 15:22:44 -07:00
user,
currency,
plan: plan === Plan.TEAM ? 'team' : 'pro',
workspaceId: workspace.id,
})
setPayLoading(false)
if (response?.newPlan) {
refreshWorkspace({ plan: response.newPlan })
toast({
status: 'success',
title: 'Upgrade success!',
description: `Workspace successfully upgraded to ${toTitleCase(
response.newPlan
)} plan 🎉`,
})
}
}
return (
2022-05-13 15:22:44 -07:00
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
2022-05-13 15:22:44 -07:00
<ModalBody as={Stack} pt="10">
{plan === Plan.PRO ? (
<PersonalProPlanContent currency={currency} />
) : (
<TeamPlanContent currency={currency} />
)}
2022-05-13 15:22:44 -07:00
</ModalBody>
<ModalFooter>
<HStack>
<Button colorScheme="gray" onClick={onClose}>
Cancel
</Button>
<Button
onClick={handlePayClick}
isLoading={payLoading}
colorScheme="blue"
>
Upgrade
</Button>
</HStack>
</ModalFooter>
</ModalContent>
</Modal>
)
}
const PersonalProPlanContent = ({ currency }: { currency: 'eur' | 'usd' }) => {
return (
<Stack spacing="4">
<TypebotLogo boxSize="30px" />
<Heading fontSize="2xl">
Upgrade to <chakra.span color="orange.400">Personal Pro</chakra.span>{' '}
plan
</Heading>
<Text>For solo creator who want to do even more.</Text>
<Heading>
{currency === 'eur' ? '39€' : '$39'}
<chakra.span fontSize="md">/ month</chakra.span>
</Heading>
<Text fontWeight="bold">Everything in Personal, plus:</Text>
<FeatureList
features={[
'Branding removed',
'View incomplete submissions',
'In-depth drop off analytics',
'Unlimited custom domains',
'Organize typebots in folders',
'Unlimited uploads',
]}
/>
</Stack>
)
}
const TeamPlanContent = ({ currency }: { currency: 'eur' | 'usd' }) => {
return (
<Stack spacing="4">
<TypebotLogo boxSize="30px" />
<Heading fontSize="2xl">
Upgrade to <chakra.span color="purple.400">Team</chakra.span> plan
</Heading>
<Text>For teams to build typebots together in one spot.</Text>
<Heading>
{currency === 'eur' ? '99€' : '$99'}
<chakra.span fontSize="md">/ month</chakra.span>
</Heading>
<Text fontWeight="bold">
<Tooltip
label={
<FeatureList
features={[
'Branding removed',
'View incomplete submissions',
'In-depth drop off analytics',
'Custom domains',
'Organize typebots in folders',
'Unlimited uploads',
2022-05-13 15:22:44 -07:00
]}
spacing="0"
/>
}
hasArrow
placement="top"
>
<chakra.span textDecoration="underline" cursor="pointer">
Everything in Pro
</chakra.span>
</Tooltip>
, plus:
</Text>
<FeatureList
features={[
'Unlimited team members',
'Collaborative workspace',
'Custom roles',
]}
/>
</Stack>
)
}
2022-05-13 15:22:44 -07:00
const FeatureList = ({
features,
...props
}: { features: string[] } & ListProps) => (
<UnorderedList listStyleType="none" spacing={2} {...props}>
{features.map((feat) => (
<ListItem key={feat}>
<ListIcon as={CheckIcon} />
{feat}
</ListItem>
))}
</UnorderedList>
)