forked from crowetic/commerce
usePrice hook
This commit is contained in:
parent
a37c02ff57
commit
1629f718b0
@ -1,9 +1,8 @@
|
|||||||
import { Trash, Plus, Minus } from '@components/icon'
|
import { Trash, Plus, Minus } from '@components/icon'
|
||||||
import { useCommerce } from '@lib/bigcommerce'
|
import usePrice from '@lib/bigcommerce/use-price'
|
||||||
import useUpdateItem from '@lib/bigcommerce/cart/use-update-item'
|
import useUpdateItem from '@lib/bigcommerce/cart/use-update-item'
|
||||||
import useRemoveItem from '@lib/bigcommerce/cart/use-remove-item'
|
import useRemoveItem from '@lib/bigcommerce/cart/use-remove-item'
|
||||||
import { ChangeEvent, useEffect, useState } from 'react'
|
import { ChangeEvent, useEffect, useState } from 'react'
|
||||||
import formatVariantPrice from 'utils/format-item-price'
|
|
||||||
import styles from './CartItem.module.css'
|
import styles from './CartItem.module.css'
|
||||||
|
|
||||||
const CartItem = ({
|
const CartItem = ({
|
||||||
@ -13,16 +12,14 @@ const CartItem = ({
|
|||||||
item: any
|
item: any
|
||||||
currencyCode: string
|
currencyCode: string
|
||||||
}) => {
|
}) => {
|
||||||
const { locale } = useCommerce()
|
const { price } = usePrice({
|
||||||
|
amount: item.extended_sale_price,
|
||||||
|
baseAmount: item.extended_list_price,
|
||||||
|
currencyCode,
|
||||||
|
})
|
||||||
const updateItem = useUpdateItem(item)
|
const updateItem = useUpdateItem(item)
|
||||||
const removeItem = useRemoveItem()
|
const removeItem = useRemoveItem()
|
||||||
const [quantity, setQuantity] = useState(item.quantity)
|
const [quantity, setQuantity] = useState(item.quantity)
|
||||||
const { price } = formatVariantPrice({
|
|
||||||
listPrice: item.extended_list_price,
|
|
||||||
salePrice: item.extended_sale_price,
|
|
||||||
currencyCode,
|
|
||||||
locale,
|
|
||||||
})
|
|
||||||
const updateQuantity = async (val: number) => {
|
const updateQuantity = async (val: number) => {
|
||||||
const data = await updateItem({ quantity: val })
|
const data = await updateItem({ quantity: val })
|
||||||
}
|
}
|
||||||
|
@ -4,34 +4,26 @@ import { UserNav } from '@components/core'
|
|||||||
import { Button } from '@components/ui'
|
import { Button } from '@components/ui'
|
||||||
import { ArrowLeft, Bag, Cross, Check } from '@components/icon'
|
import { ArrowLeft, Bag, Cross, Check } from '@components/icon'
|
||||||
import { useUI } from '@components/ui/context'
|
import { useUI } from '@components/ui/context'
|
||||||
import { useCommerce } from '@lib/bigcommerce'
|
|
||||||
import useCart from '@lib/bigcommerce/cart/use-cart'
|
import useCart from '@lib/bigcommerce/cart/use-cart'
|
||||||
|
import usePrice from '@lib/bigcommerce/use-price'
|
||||||
import CartItem from '../CartItem'
|
import CartItem from '../CartItem'
|
||||||
import useOpenCheckout from '@lib/bigcommerce/cart/use-open-checkout'
|
import useOpenCheckout from '@lib/bigcommerce/cart/use-open-checkout'
|
||||||
import formatPrice from 'utils/format-price'
|
|
||||||
|
|
||||||
const CartSidebarView: FC = () => {
|
const CartSidebarView: FC = () => {
|
||||||
const { locale } = useCommerce()
|
|
||||||
const { data, isEmpty } = useCart()
|
const { data, isEmpty } = useCart()
|
||||||
|
const { price: subTotal } = usePrice(data && {
|
||||||
|
amount: data.base_amount,
|
||||||
|
currencyCode: data.currency.code,
|
||||||
|
})
|
||||||
|
const { price: total } = usePrice(data && {
|
||||||
|
amount: data.cart_amount,
|
||||||
|
currencyCode: data.currency.code,
|
||||||
|
})
|
||||||
const openCheckout = useOpenCheckout()
|
const openCheckout = useOpenCheckout()
|
||||||
const { closeSidebar } = useUI()
|
const { closeSidebar } = useUI()
|
||||||
const handleClose = () => closeSidebar()
|
const handleClose = () => closeSidebar()
|
||||||
|
|
||||||
const items = data?.line_items.physical_items ?? []
|
const items = data?.line_items.physical_items ?? []
|
||||||
const subTotal = data
|
|
||||||
? formatPrice({
|
|
||||||
amount: data.base_amount,
|
|
||||||
currencyCode: data.currency.code,
|
|
||||||
locale,
|
|
||||||
})
|
|
||||||
: 0
|
|
||||||
const total = data
|
|
||||||
? formatPrice({
|
|
||||||
amount: data.cart_amount,
|
|
||||||
currencyCode: data.currency.code,
|
|
||||||
locale,
|
|
||||||
})
|
|
||||||
: 0
|
|
||||||
|
|
||||||
console.log('CART', data, isEmpty)
|
console.log('CART', data, isEmpty)
|
||||||
|
|
||||||
|
2
lib/bigcommerce/use-price.tsx
Normal file
2
lib/bigcommerce/use-price.tsx
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from '../commerce/use-price'
|
||||||
|
export { default } from '../commerce/use-price'
|
64
lib/commerce/use-price.tsx
Normal file
64
lib/commerce/use-price.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { useMemo } from 'react'
|
||||||
|
import { useCommerce } from '.'
|
||||||
|
|
||||||
|
export function formatPrice({
|
||||||
|
amount,
|
||||||
|
currencyCode,
|
||||||
|
locale,
|
||||||
|
}: {
|
||||||
|
amount: number
|
||||||
|
currencyCode: string
|
||||||
|
locale: string
|
||||||
|
}) {
|
||||||
|
const formatCurrency = new Intl.NumberFormat(locale, {
|
||||||
|
style: 'currency',
|
||||||
|
currency: currencyCode,
|
||||||
|
})
|
||||||
|
|
||||||
|
return formatCurrency.format(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatVariantPrice({
|
||||||
|
amount,
|
||||||
|
baseAmount,
|
||||||
|
currencyCode,
|
||||||
|
locale,
|
||||||
|
}: {
|
||||||
|
baseAmount: number
|
||||||
|
amount: number
|
||||||
|
currencyCode: string
|
||||||
|
locale: string
|
||||||
|
}) {
|
||||||
|
const hasDiscount = baseAmount > amount
|
||||||
|
const formatDiscount = new Intl.NumberFormat(locale, { style: 'percent' })
|
||||||
|
const discount = hasDiscount
|
||||||
|
? formatDiscount.format((baseAmount - amount) / baseAmount)
|
||||||
|
: null
|
||||||
|
|
||||||
|
const price = formatPrice({ amount, currencyCode, locale })
|
||||||
|
const basePrice = hasDiscount
|
||||||
|
? formatPrice({ amount: baseAmount, currencyCode, locale })
|
||||||
|
: null
|
||||||
|
|
||||||
|
return { price, basePrice, discount }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function usePrice(
|
||||||
|
data?: {
|
||||||
|
amount: number
|
||||||
|
baseAmount?: number
|
||||||
|
currencyCode: string
|
||||||
|
} | null
|
||||||
|
) {
|
||||||
|
const { amount, baseAmount, currencyCode } = data ?? {}
|
||||||
|
const { locale } = useCommerce()
|
||||||
|
const value = useMemo(() => {
|
||||||
|
if (typeof amount !== 'number' || !currencyCode) return ''
|
||||||
|
|
||||||
|
return baseAmount
|
||||||
|
? formatVariantPrice({ amount, baseAmount, currencyCode, locale })
|
||||||
|
: formatPrice({ amount, currencyCode, locale })
|
||||||
|
}, [amount, baseAmount, currencyCode])
|
||||||
|
|
||||||
|
return typeof value === 'string' ? { price: value } : value
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
import formatPrice from './format-price'
|
|
||||||
|
|
||||||
export default function formatVariantPrice({
|
|
||||||
listPrice,
|
|
||||||
salePrice,
|
|
||||||
currencyCode,
|
|
||||||
locale,
|
|
||||||
}: {
|
|
||||||
listPrice: number
|
|
||||||
salePrice: number
|
|
||||||
currencyCode: string
|
|
||||||
locale: string
|
|
||||||
}) {
|
|
||||||
const hasDiscount = listPrice > salePrice
|
|
||||||
const formatDiscount = new Intl.NumberFormat(locale, { style: 'percent' })
|
|
||||||
const discount = hasDiscount
|
|
||||||
? formatDiscount.format((listPrice - salePrice) / listPrice)
|
|
||||||
: null
|
|
||||||
|
|
||||||
const price = formatPrice({ amount: salePrice, currencyCode, locale })
|
|
||||||
const compareAtPrice = hasDiscount
|
|
||||||
? formatPrice({ amount: listPrice, currencyCode, locale })
|
|
||||||
: null
|
|
||||||
|
|
||||||
return { price, compareAtPrice, discount }
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
export default function formatPrice({
|
|
||||||
amount,
|
|
||||||
currencyCode,
|
|
||||||
locale,
|
|
||||||
}: {
|
|
||||||
amount: number
|
|
||||||
currencyCode: string
|
|
||||||
locale: string
|
|
||||||
}) {
|
|
||||||
const formatCurrency = new Intl.NumberFormat(locale, {
|
|
||||||
style: 'currency',
|
|
||||||
currency: currencyCode,
|
|
||||||
})
|
|
||||||
|
|
||||||
return formatCurrency.format(amount)
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user