forked from crowetic/commerce
65 lines
1.5 KiB
TypeScript
65 lines
1.5 KiB
TypeScript
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
|
|
}
|