generated from yun-cheng/my-react-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from yun-cheng/feat/home-page-pricing-card-fun…
…tionality feat(HomePage): add PricingCard funtionality
- Loading branch information
Showing
9 changed files
with
166 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const { VITE_COINGECKO_API_KEY } = import.meta.env | ||
|
||
type ResponseData = { | ||
'crypto-com-chain': { | ||
usd: number | ||
} | ||
} | ||
|
||
export default async function fetchCroPrice() { | ||
const response = await fetch( | ||
`https://api.coingecko.com/api/v3/simple/price?ids=crypto-com-chain&vs_currencies=usd&x_cg_demo_api_key=${VITE_COINGECKO_API_KEY}` | ||
) | ||
const data = (await response.json()) as ResponseData | ||
|
||
return data['crypto-com-chain'].usd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { atom } from 'jotai' | ||
|
||
const planPricing = [ | ||
{ | ||
pageViews: '10K', | ||
price: 8 | ||
}, | ||
{ | ||
pageViews: '50K', | ||
price: 12 | ||
}, | ||
{ | ||
pageViews: '100K', | ||
price: 16 | ||
}, | ||
{ | ||
pageViews: '500K', | ||
price: 24 | ||
}, | ||
{ | ||
pageViews: '1M', | ||
price: 36 | ||
} | ||
] | ||
|
||
export const planIdAtom = atom(2) | ||
|
||
export const isYearlyBillingAtom = atom(false) | ||
|
||
export const pageViewsAtom = atom(get => planPricing[get(planIdAtom)].pageViews) | ||
|
||
export const priceAtom = atom(get => { | ||
return ( | ||
planPricing[get(planIdAtom)].price * (get(isYearlyBillingAtom) ? 0.75 : 1) | ||
) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,27 @@ | ||
import { pageViewsAtom } from 'atoms/pricing' | ||
import { useAtomValue } from 'jotai' | ||
import type { HTMLAttributes } from 'react' | ||
import { forwardRef } from 'react' | ||
import cn from 'utils/cn' | ||
|
||
const PricingCardPageViews = forwardRef< | ||
HTMLDivElement, | ||
HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div | ||
ref={ref} | ||
className={cn( | ||
'font-extrabold tracking-[1.7px] sm:text-[14px] sm:tracking-[2px]', | ||
className | ||
)} | ||
{...props} | ||
> | ||
100K PAGEVIEWS | ||
</div> | ||
)) | ||
>(({ className, ...props }, ref) => { | ||
const pageViews = useAtomValue(pageViewsAtom) | ||
|
||
return ( | ||
<div | ||
ref={ref} | ||
className={cn( | ||
'font-extrabold tracking-[1.7px] sm:text-[14px] sm:tracking-[2px]', | ||
className | ||
)} | ||
{...props} | ||
> | ||
{pageViews} PAGEVIEWS | ||
</div> | ||
) | ||
}) | ||
|
||
export default PricingCardPageViews |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,56 @@ | ||
import { useQuery } from '@tanstack/react-query' | ||
import fetchCroPrice from 'api/fetchCroPrice' | ||
import { priceAtom } from 'atoms/pricing' | ||
import { useAtomValue } from 'jotai' | ||
import type { HTMLAttributes } from 'react' | ||
import { forwardRef } from 'react' | ||
import cn from 'utils/cn' | ||
|
||
const PricingCardPrice = forwardRef< | ||
HTMLDivElement, | ||
HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div ref={ref} className={className} {...props}> | ||
<div | ||
className={cn('-translate-x-px', 'flex items-center gap-[10px] sm:gap-2')} | ||
> | ||
<span className='text-[32px] font-extrabold leading-none -tracking-[.8px] text-dark-desaturated-blue sm:text-[40px] sm:-tracking-[1px]'> | ||
$16.00 | ||
</span> | ||
<span | ||
>(({ className, ...props }, ref) => { | ||
const price = useAtomValue(priceAtom) | ||
|
||
const { data: croToUsd } = useQuery({ | ||
queryKey: ['fetchCroPrice'], | ||
queryFn: fetchCroPrice, | ||
staleTime: 60_000 | ||
}) | ||
|
||
const croPrice = croToUsd ? Math.round(price / croToUsd).toString() : '' | ||
|
||
return ( | ||
<div ref={ref} className={className} {...props}> | ||
<div | ||
className={cn( | ||
'translate-y-px sm:translate-y-0', | ||
'text-[14px] sm:text-[16px]' | ||
'-translate-x-px', | ||
'flex items-center gap-[10px] sm:gap-2' | ||
)} | ||
> | ||
/ month | ||
</span> | ||
</div> | ||
<div | ||
className={cn( | ||
'mt-[2px] flex justify-end sm:mt-[7px]', | ||
'whitespace-pre-wrap text-[10px] tracking-[.2px] sm:text-[14px] sm:-tracking-[.4px]' | ||
)} | ||
> | ||
{`or ~32 CRO `} | ||
<span className='-translate-x-px sm:translate-x-0'>/ month</span> | ||
<span className='text-[32px] font-extrabold leading-none -tracking-[.8px] text-dark-desaturated-blue sm:text-[40px] sm:-tracking-[1px]'> | ||
${price}.00 | ||
</span> | ||
<span | ||
className={cn( | ||
'translate-y-px sm:translate-y-0', | ||
'text-[14px] sm:text-[16px]' | ||
)} | ||
> | ||
/ month | ||
</span> | ||
</div> | ||
<div | ||
className={cn( | ||
'mt-[2px] flex justify-end sm:mt-[7px]', | ||
'whitespace-pre-wrap text-[10px] tracking-[.2px] sm:text-[14px] sm:-tracking-[.4px]' | ||
)} | ||
> | ||
{`or ~${croPrice} CRO `} | ||
<span className='-translate-x-px sm:translate-x-0'>/ month</span> | ||
</div> | ||
</div> | ||
</div> | ||
)) | ||
) | ||
}) | ||
|
||
export default PricingCardPrice |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,24 @@ | ||
import { planIdAtom } from 'atoms/pricing' | ||
import { Slider } from 'components/ui/Slider' | ||
import { useAtom } from 'jotai' | ||
import { forwardRef, type HTMLAttributes } from 'react' | ||
import cn from 'utils/cn' | ||
|
||
const PriceCardSlider = forwardRef< | ||
HTMLDivElement, | ||
HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div ref={ref} className={cn('w-full', className)} {...props}> | ||
<Slider defaultValue={[2]} max={4} /> | ||
</div> | ||
)) | ||
>(({ className, ...props }, ref) => { | ||
const [planId, setPlanId] = useAtom(planIdAtom) | ||
|
||
const onValueChange = (value: number[]) => { | ||
setPlanId(value[0]) | ||
} | ||
|
||
return ( | ||
<div ref={ref} className={cn('w-full', className)} {...props}> | ||
<Slider value={[planId]} max={4} onValueChange={onValueChange} /> | ||
</div> | ||
) | ||
}) | ||
|
||
export default PriceCardSlider |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,46 @@ | ||
import { isYearlyBillingAtom } from 'atoms/pricing' | ||
import { Switch } from 'components/ui/Switch' | ||
import { useAtom } from 'jotai' | ||
import { forwardRef, type HTMLAttributes } from 'react' | ||
import cn from 'utils/cn' | ||
|
||
const PricingCardSwitch = forwardRef< | ||
HTMLDivElement, | ||
HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div | ||
ref={ref} | ||
className={cn('flex items-center justify-end', className)} | ||
{...props} | ||
> | ||
<div className='sm:-translate-y-px'>Monthly Billing</div> | ||
<Switch className='ml-[13px] mr-3 sm:ml-[17px] sm:mr-4' /> | ||
<div className={cn('sm:-translate-y-px', 'mr-[5px] sm:mr-[9px]')}> | ||
Yearly Billing | ||
</div> | ||
>(({ className, ...props }, ref) => { | ||
const [isYearlyBilling, setIsYearlyBilling] = useAtom(isYearlyBillingAtom) | ||
|
||
const onCheckedChange = (checked: boolean) => setIsYearlyBilling(checked) | ||
|
||
return ( | ||
<div | ||
className={cn( | ||
'-translate-y-px', | ||
'flex h-[19px] w-[42px] items-center justify-center rounded-lg bg-light-grayish-red sm:w-20', | ||
'text-[10px] font-extrabold text-light-red' | ||
)} | ||
ref={ref} | ||
className={cn('flex items-center justify-end', className)} | ||
{...props} | ||
> | ||
<div className='-translate-x-px'> | ||
<span className='hidden sm:block'>25% discount</span> | ||
<span className='block sm:hidden'>-25%</span> | ||
<div className='sm:-translate-y-px'>Monthly Billing</div> | ||
<Switch | ||
className='ml-[13px] mr-3 sm:ml-[17px] sm:mr-4' | ||
checked={isYearlyBilling} | ||
onCheckedChange={onCheckedChange} | ||
/> | ||
<div className={cn('sm:-translate-y-px', 'mr-[5px] sm:mr-[9px]')}> | ||
Yearly Billing | ||
</div> | ||
<div | ||
className={cn( | ||
'-translate-y-px', | ||
'flex h-[19px] w-[42px] items-center justify-center rounded-lg bg-light-grayish-red sm:w-20', | ||
'text-[10px] font-extrabold text-light-red' | ||
)} | ||
> | ||
<div className='-translate-x-px'> | ||
<span className='hidden sm:block'>25% discount</span> | ||
<span className='block sm:hidden'>-25%</span> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
)) | ||
) | ||
}) | ||
|
||
export default PricingCardSwitch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters