initial commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
// MUI Imports
|
||||
import Chip from '@mui/material/Chip'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Button from '@mui/material/Button'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Type Imports
|
||||
import type { PricingPlanType } from '@/types/pages/pricingTypes'
|
||||
|
||||
type Props = {
|
||||
pricingPlan: 'monthly' | 'annually'
|
||||
data?: PricingPlanType
|
||||
}
|
||||
|
||||
const PlanDetails = ({ data, pricingPlan }: Props) => {
|
||||
return (
|
||||
<CardContent
|
||||
className={classnames('relative border rounded pli-5 pbs-[3.75rem] flex flex-col gap-5', {
|
||||
'border-primary': data?.popularPlan
|
||||
})}
|
||||
>
|
||||
{data?.popularPlan ? (
|
||||
<Chip
|
||||
color='primary'
|
||||
label='Popular'
|
||||
size='small'
|
||||
className='absolute block-start-4 inline-end-5'
|
||||
variant='tonal'
|
||||
/>
|
||||
) : null}
|
||||
<div className='flex justify-center'>
|
||||
<img
|
||||
src={data?.imgSrc}
|
||||
height={data?.imgHeight}
|
||||
width={data?.imgWidth}
|
||||
alt={`${data?.title.toLowerCase().replace(' ', '-')}-img`}
|
||||
/>
|
||||
</div>
|
||||
<div className='text-center flex flex-col gap-1'>
|
||||
<Typography variant='h4'>{data?.title}</Typography>
|
||||
<Typography>{data?.subtitle}</Typography>
|
||||
</div>
|
||||
<div className='relative mbe-4'>
|
||||
<div className='flex justify-center'>
|
||||
<Typography component='sup' className='self-start font-medium'>
|
||||
$
|
||||
</Typography>
|
||||
<Typography variant='h1' component='span' color='primary.main'>
|
||||
{pricingPlan === 'monthly' ? data?.monthlyPrice : data?.yearlyPlan.monthly}
|
||||
</Typography>
|
||||
<Typography component='sub' className='self-end font-medium'>
|
||||
/month
|
||||
</Typography>
|
||||
</div>
|
||||
{pricingPlan !== 'monthly' && data?.monthlyPrice !== 0 ? (
|
||||
<Typography
|
||||
variant='caption'
|
||||
className='absolute inline-end-1/2 translate-x-[50%]'
|
||||
>{`USD ${data?.yearlyPlan.annually}/year`}</Typography>
|
||||
) : null}
|
||||
</div>
|
||||
<div className='flex flex-col gap-4'>
|
||||
{data?.planBenefits.map((item: string, index: number) => (
|
||||
<div key={index} className='flex items-center gap-2'>
|
||||
<span className='inline-flex'>
|
||||
<i className='tabler-circle-filled text-[8px]' />
|
||||
</span>
|
||||
<Typography>{item}</Typography>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
fullWidth
|
||||
color={data?.currentPlan ? 'success' : 'primary'}
|
||||
variant={data?.popularPlan ? 'contained' : 'tonal'}
|
||||
>
|
||||
{data?.currentPlan ? 'Your Current Plan' : 'Upgrade'}
|
||||
</Button>
|
||||
</CardContent>
|
||||
)
|
||||
}
|
||||
|
||||
export default PlanDetails
|
||||
@@ -0,0 +1,83 @@
|
||||
// React Imports
|
||||
import { useState } from 'react'
|
||||
import type { ChangeEvent } from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import Chip from '@mui/material/Chip'
|
||||
import Switch from '@mui/material/Switch'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import InputLabel from '@mui/material/InputLabel'
|
||||
import Grid from '@mui/material/Grid2'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Type Imports
|
||||
import type { PricingPlanType } from '@/types/pages/pricingTypes'
|
||||
|
||||
// Component Imports
|
||||
import PlanDetails from './PlanDetails'
|
||||
import DirectionalIcon from '@components/DirectionalIcon'
|
||||
|
||||
const Pricing = ({ data }: { data?: PricingPlanType[] }) => {
|
||||
// States
|
||||
const [pricingPlan, setPricingPlan] = useState<'monthly' | 'annually'>('annually')
|
||||
|
||||
// Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
const handleChange = (e: ChangeEvent<{ checked: boolean }>) => {
|
||||
if (e.target.checked) {
|
||||
setPricingPlan('annually')
|
||||
} else {
|
||||
setPricingPlan('monthly')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='flex flex-col gap-6'>
|
||||
<div className='flex flex-col justify-center items-center gap-2'>
|
||||
<Typography variant='h3'>Pricing Plans</Typography>
|
||||
<div className='flex items-center text-center flex-col sm:mbe-[3.8rem]'>
|
||||
<Typography>
|
||||
All plans include 40+ advanced tools and features to boost your product. Choose the best plan to fit your
|
||||
needs.
|
||||
</Typography>
|
||||
</div>
|
||||
<div className='flex justify-center items-center relative mbs-0.5'>
|
||||
<InputLabel htmlFor='pricing-switch' className='cursor-pointer'>
|
||||
Monthly
|
||||
</InputLabel>
|
||||
<Switch id='pricing-switch' onChange={handleChange} checked={pricingPlan === 'annually'} />
|
||||
<InputLabel htmlFor='pricing-switch' className='cursor-pointer'>
|
||||
Annually
|
||||
</InputLabel>
|
||||
|
||||
<div
|
||||
className={classnames('flex absolute max-sm:hidden block-start-[-39px] translate-x-[35%]', {
|
||||
'right-full': theme.direction === 'rtl',
|
||||
'left-1/2': theme.direction !== 'rtl'
|
||||
})}
|
||||
>
|
||||
<DirectionalIcon
|
||||
ltrIconClass='tabler-corner-left-down'
|
||||
rtlIconClass='tabler-corner-right-down'
|
||||
className='mbs-2 mie-1 text-textDisabled'
|
||||
/>
|
||||
<Chip label='Save up to 10%' size='small' variant='tonal' color='primary' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Grid container spacing={6}>
|
||||
{data?.map((plan, index) => (
|
||||
<Grid size={{ xs: 12, md: 4 }} key={index}>
|
||||
<PlanDetails data={plan} pricingPlan={pricingPlan} />
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Pricing
|
||||
Reference in New Issue
Block a user