import { Stack, Heading, chakra, HStack, Menu, MenuButton, Button, MenuList, MenuItem, Text, Tooltip, Flex, Tag, useColorModeValue, } from '@chakra-ui/react' import { ChevronLeftIcon } from '@/components/icons' import { Plan } from '@typebot.io/prisma' import { useEffect, useState } from 'react' import { isDefined, parseNumberWithCommas } from '@typebot.io/lib' import { chatsLimit, computePrice, formatPrice, getChatsLimit, getStorageLimit, storageLimit, } from '@typebot.io/lib/pricing' import { FeaturesList } from './FeaturesList' import { MoreInfoTooltip } from '@/components/MoreInfoTooltip' import { useI18n, useScopedI18n } from '@/locales' import { Workspace } from '@typebot.io/schemas' type Props = { workspace: Pick< Workspace, | 'additionalChatsIndex' | 'additionalStorageIndex' | 'plan' | 'customChatsLimit' | 'customStorageLimit' | 'stripeId' > currentSubscription: { isYearly?: boolean } currency?: 'usd' | 'eur' isLoading: boolean isYearly: boolean onPayClick: (props: { selectedChatsLimitIndex: number selectedStorageLimitIndex: number }) => void } export const ProPlanPricingCard = ({ workspace, currentSubscription, currency, isLoading, isYearly, onPayClick, }: Props) => { const t = useI18n() const scopedT = useScopedI18n('billing.pricingCard') const [selectedChatsLimitIndex, setSelectedChatsLimitIndex] = useState() const [selectedStorageLimitIndex, setSelectedStorageLimitIndex] = useState() useEffect(() => { if ( isDefined(selectedChatsLimitIndex) || isDefined(selectedStorageLimitIndex) ) return if (workspace.plan !== Plan.PRO) { setSelectedChatsLimitIndex(0) setSelectedStorageLimitIndex(0) return } setSelectedChatsLimitIndex(workspace.additionalChatsIndex ?? 0) setSelectedStorageLimitIndex(workspace.additionalStorageIndex ?? 0) }, [ selectedChatsLimitIndex, selectedStorageLimitIndex, workspace.additionalChatsIndex, workspace.additionalStorageIndex, workspace?.plan, ]) const workspaceChatsLimit = workspace ? getChatsLimit(workspace) : undefined const workspaceStorageLimit = workspace ? getStorageLimit(workspace) : undefined const isCurrentPlan = chatsLimit[Plan.PRO].graduatedPrice[selectedChatsLimitIndex ?? 0] .totalIncluded === workspaceChatsLimit && storageLimit[Plan.PRO].graduatedPrice[selectedStorageLimitIndex ?? 0] .totalIncluded === workspaceStorageLimit && isYearly === currentSubscription?.isYearly const getButtonLabel = () => { if ( selectedChatsLimitIndex === undefined || selectedStorageLimitIndex === undefined ) return '' if (workspace?.plan === Plan.PRO) { if (isCurrentPlan) return scopedT('upgradeButton.current') if ( selectedChatsLimitIndex !== workspace.additionalChatsIndex || selectedStorageLimitIndex !== workspace.additionalStorageIndex ) return t('update') } return t('upgrade') } const handlePayClick = async () => { if ( selectedChatsLimitIndex === undefined || selectedStorageLimitIndex === undefined ) return onPayClick({ selectedChatsLimitIndex, selectedStorageLimitIndex, }) } const price = computePrice( Plan.PRO, selectedChatsLimitIndex ?? 0, selectedStorageLimitIndex ?? 0, isYearly ? 'yearly' : 'monthly' ) ?? NaN return ( {scopedT('pro.mostPopularLabel')} {scopedT('heading', { plan: ( Pro ), })} {scopedT('pro.description')} {formatPrice(price, currency)} {scopedT('perMonth')} } hasArrow placement="top" > {scopedT('pro.everythingFromStarter')} {scopedT('plus')} } size="sm" isLoading={selectedChatsLimitIndex === undefined} > {selectedChatsLimitIndex !== undefined ? parseNumberWithCommas( chatsLimit.PRO.graduatedPrice[ selectedChatsLimitIndex ].totalIncluded ) : undefined} {chatsLimit.PRO.graduatedPrice.map((price, index) => ( setSelectedChatsLimitIndex(index)} > {parseNumberWithCommas(price.totalIncluded)} ))} {' '} {scopedT('chatsPerMonth')} {scopedT('chatsTooltip')} , } size="sm" isLoading={selectedStorageLimitIndex === undefined} > {selectedStorageLimitIndex !== undefined ? parseNumberWithCommas( storageLimit.PRO.graduatedPrice[ selectedStorageLimitIndex ].totalIncluded ) : undefined} {storageLimit.PRO.graduatedPrice.map((price, index) => ( setSelectedStorageLimitIndex(index)} > {parseNumberWithCommas(price.totalIncluded)} ))} {' '} {scopedT('storageLimit')} {scopedT('storageLimitTooltip')} , scopedT('pro.customDomains'), scopedT('pro.analytics'), ]} /> {isYearly && workspace.stripeId && !isCurrentPlan && ( You pay {formatPrice(price * 12, currency)} / year )} ) }