2
0

fix: 🐛 UpgradeModal ending with a dot

This commit is contained in:
Baptiste Arnaud
2022-04-05 14:55:19 +02:00
parent 786908e9cf
commit 1fb4328938
11 changed files with 8 additions and 8 deletions

View File

@ -0,0 +1,13 @@
import { Button, ButtonProps } from '@chakra-ui/react'
import * as React from 'react'
export const ActionButton = (props: ButtonProps) => (
<Button
colorScheme="blue"
size="lg"
w="full"
fontWeight="extrabold"
py={{ md: '8' }}
{...props}
/>
)

View File

@ -0,0 +1,28 @@
import { Box, BoxProps, useColorModeValue } from '@chakra-ui/react'
import * as React from 'react'
import { CardBadge } from './CardBadge'
export interface CardProps extends BoxProps {
isPopular?: boolean
}
export const Card = (props: CardProps) => {
const { children, isPopular, ...rest } = props
return (
<Box
bg={useColorModeValue('white', 'gray.700')}
position="relative"
px="6"
pb="6"
pt="16"
overflow="hidden"
shadow="lg"
maxW="md"
width="100%"
{...rest}
>
{isPopular && <CardBadge>Popular</CardBadge>}
{children}
</Box>
)
}

View File

@ -0,0 +1,30 @@
import { Flex, FlexProps, Text, useColorModeValue } from '@chakra-ui/react'
import * as React from 'react'
export const CardBadge = (props: FlexProps) => {
const { children, ...flexProps } = props
return (
<Flex
bg={useColorModeValue('green.500', 'green.200')}
position="absolute"
right={-20}
top={6}
width="240px"
transform="rotate(45deg)"
py={2}
justifyContent="center"
alignItems="center"
{...flexProps}
>
<Text
fontSize="xs"
textTransform="uppercase"
fontWeight="bold"
letterSpacing="wider"
color={useColorModeValue('white', 'gray.800')}
>
{children}
</Text>
</Flex>
)
}

View File

@ -0,0 +1,68 @@
import {
Flex,
Heading,
List,
ListIcon,
ListItem,
Text,
useColorModeValue,
VStack,
} from '@chakra-ui/react'
import { CheckIcon } from 'assets/icons'
import * as React from 'react'
import { Card, CardProps } from './Card'
export interface PricingCardData {
features: string[]
name: string
price: string
}
interface PricingCardProps extends CardProps {
data: PricingCardData
button: React.ReactElement
}
export const PricingCard = (props: PricingCardProps) => {
const { data, button, ...rest } = props
const { features, price, name } = data
const accentColor = useColorModeValue('blue.500', 'blue.200')
return (
<Card rounded={{ sm: 'xl' }} {...rest}>
<VStack spacing={6}>
<Heading size="md" fontWeight="extrabold">
{name}
</Heading>
</VStack>
<Flex
align="flex-end"
justify="center"
fontWeight="extrabold"
color={accentColor}
my="8"
>
<Heading size="3xl" fontWeight="inherit" lineHeight="0.9em">
{price}
</Heading>
<Text fontWeight="inherit" fontSize="2xl">
/ mo
</Text>
</Flex>
<List spacing="4" mb="8" maxW="30ch" mx="auto">
{features.map((feature, index) => (
<ListItem fontWeight="medium" key={index}>
<ListIcon
fontSize="xl"
as={CheckIcon}
marginEnd={2}
color={accentColor}
/>
{feature}
</ListItem>
))}
</List>
{button}
</Card>
)
}

View File

@ -0,0 +1,102 @@
import { useEffect, useState } from 'react'
import {
Alert,
AlertIcon,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Stack,
} from '@chakra-ui/react'
import { PricingCard } from './PricingCard'
import { ActionButton } from './ActionButton'
import { pay } from 'services/stripe'
import { useUser } from 'contexts/UserContext'
export enum LimitReached {
BRAND = 'Remove branding',
CUSTOM_DOMAIN = 'Custom domain',
FOLDER = 'Create folders',
}
type UpgradeModalProps = {
type?: LimitReached
isOpen: boolean
onClose: () => void
}
export const UpgradeModal = ({ type, onClose, isOpen }: UpgradeModalProps) => {
const { user } = useUser()
const [payLoading, setPayLoading] = useState(false)
const [currency, setCurrency] = useState<'usd' | 'eur'>('usd')
useEffect(() => {
setCurrency(
navigator.languages.find((l) => l.includes('fr')) ? 'eur' : 'usd'
)
}, [])
let limitLabel
switch (type) {
case LimitReached.BRAND: {
limitLabel = "You can't hide Typebot brand on the Basic plan"
break
}
case LimitReached.CUSTOM_DOMAIN: {
limitLabel = "You can't add your domain with the Basic plan"
break
}
case LimitReached.FOLDER: {
limitLabel = "You can't create folders with the basic plan"
}
}
const handlePayClick = async () => {
if (!user) return
setPayLoading(true)
await pay(user, currency)
}
return (
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>Upgrade to Pro plan</ModalHeader>
<ModalCloseButton />
<ModalBody as={Stack} spacing={6} alignItems="center">
{limitLabel && (
<Alert status="warning" rounded="md">
<AlertIcon />
{limitLabel}
</Alert>
)}
<PricingCard
data={{
price: currency === 'eur' ? '25€' : '$30',
name: 'Pro plan',
features: [
'Branding removed',
'View incomplete submissions',
'In-depth drop off analytics',
'Custom domains',
'Organize typebots in folders',
'Unlimited uploads',
'Custom Google Analytics events',
],
}}
button={
<ActionButton onClick={handlePayClick} isLoading={payLoading}>
Upgrade now
</ActionButton>
}
/>
</ModalBody>
<ModalFooter />
</ModalContent>
</Modal>
)
}

View File

@ -0,0 +1 @@
export { UpgradeModal } from './UpgradeModal'