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 { useCommerce } from '@lib/bigcommerce'
|
||||
import usePrice from '@lib/bigcommerce/use-price'
|
||||
import useUpdateItem from '@lib/bigcommerce/cart/use-update-item'
|
||||
import useRemoveItem from '@lib/bigcommerce/cart/use-remove-item'
|
||||
import { ChangeEvent, useEffect, useState } from 'react'
|
||||
import formatVariantPrice from 'utils/format-item-price'
|
||||
import styles from './CartItem.module.css'
|
||||
|
||||
const CartItem = ({
|
||||
@ -13,16 +12,14 @@ const CartItem = ({
|
||||
item: any
|
||||
currencyCode: string
|
||||
}) => {
|
||||
const { locale } = useCommerce()
|
||||
const { price } = usePrice({
|
||||
amount: item.extended_sale_price,
|
||||
baseAmount: item.extended_list_price,
|
||||
currencyCode,
|
||||
})
|
||||
const updateItem = useUpdateItem(item)
|
||||
const removeItem = useRemoveItem()
|
||||
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 data = await updateItem({ quantity: val })
|
||||
}
|
||||
|
@ -4,34 +4,26 @@ import { UserNav } from '@components/core'
|
||||
import { Button } from '@components/ui'
|
||||
import { ArrowLeft, Bag, Cross, Check } from '@components/icon'
|
||||
import { useUI } from '@components/ui/context'
|
||||
import { useCommerce } from '@lib/bigcommerce'
|
||||
import useCart from '@lib/bigcommerce/cart/use-cart'
|
||||
import usePrice from '@lib/bigcommerce/use-price'
|
||||
import CartItem from '../CartItem'
|
||||
import useOpenCheckout from '@lib/bigcommerce/cart/use-open-checkout'
|
||||
import formatPrice from 'utils/format-price'
|
||||
|
||||
const CartSidebarView: FC = () => {
|
||||
const { locale } = useCommerce()
|
||||
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 { closeSidebar } = useUI()
|
||||
const handleClose = () => closeSidebar()
|
||||
|
||||
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)
|
||||
|
||||
|
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