feat(spa): display auto promotions discount in cart drawer
This commit is contained in:
1 parent
8cdecfd7de
commit
769afa37fd
1 file changed
+40
-3
@@ -124,6 +124,16 @@ function CartDrawerFooter({ subtotal, onClose }: { subtotal: number; onClose: ()
|
|||||||
const [discountAmount, setDiscountAmount] = React.useState<number>(0)
|
const [discountAmount, setDiscountAmount] = React.useState<number>(0)
|
||||||
const [isFreeShipping, setIsFreeShipping] = React.useState<boolean>(false)
|
const [isFreeShipping, setIsFreeShipping] = React.useState<boolean>(false)
|
||||||
const [couponValid, setCouponValid] = React.useState<boolean>(false)
|
const [couponValid, setCouponValid] = React.useState<boolean>(false)
|
||||||
|
const [activePromos, setActivePromos] = React.useState<any[]>([])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
fetch(`${API_BASE}/promotions/active`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (Array.isArray(data)) setActivePromos(data)
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
}, [])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const code = localStorage.getItem('homaroma_active_coupon')
|
const code = localStorage.getItem('homaroma_active_coupon')
|
||||||
@@ -132,7 +142,7 @@ function CartDrawerFooter({ subtotal, onClose }: { subtotal: number; onClose: ()
|
|||||||
fetch(`${API_BASE}/coupons/validate`, {
|
fetch(`${API_BASE}/coupons/validate`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ code, cartTotal: subtotal })
|
body: JSON.stringify({ code, cartTotal: subtotalAfterL2 })
|
||||||
})
|
})
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@@ -146,7 +156,7 @@ function CartDrawerFooter({ subtotal, onClose }: { subtotal: number; onClose: ()
|
|||||||
})
|
})
|
||||||
.catch(() => setCouponValid(false))
|
.catch(() => setCouponValid(false))
|
||||||
}
|
}
|
||||||
}, [subtotal])
|
}, [subtotal, activePromos])
|
||||||
|
|
||||||
const removeCoupon = () => {
|
const removeCoupon = () => {
|
||||||
localStorage.removeItem('homaroma_active_coupon')
|
localStorage.removeItem('homaroma_active_coupon')
|
||||||
@@ -156,7 +166,22 @@ function CartDrawerFooter({ subtotal, onClose }: { subtotal: number; onClose: ()
|
|||||||
setCouponValid(false)
|
setCouponValid(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate Level 1 Promo
|
||||||
|
const promoLevel1 = activePromos.find(p => p.level === 1 && subtotal >= p.minPurchase)
|
||||||
|
const promoLevel1Disc = promoLevel1
|
||||||
|
? (promoLevel1.type === 'PERCENTAGE' ? subtotal * (promoLevel1.value / 100) : promoLevel1.value)
|
||||||
|
: 0
|
||||||
|
|
||||||
|
const subtotalAfterL1 = Math.max(0, subtotal - promoLevel1Disc)
|
||||||
|
|
||||||
|
// Calculate Level 2 Promo
|
||||||
|
const promoLevel2 = activePromos.find(p => p.level === 2 && subtotalAfterL1 >= p.minPurchase)
|
||||||
|
const promoLevel2Disc = promoLevel2
|
||||||
|
? (promoLevel2.type === 'PERCENTAGE' ? subtotalAfterL1 * (promoLevel2.value / 100) : promoLevel2.value)
|
||||||
|
: 0
|
||||||
|
|
||||||
|
const subtotalAfterL2 = Math.max(0, subtotalAfterL1 - promoLevel2Disc)
|
||||||
|
const total = Math.max(0, subtotalAfterL2 - discountAmount)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-5 border-t border-spa-stone/10 bg-spa-light space-y-4">
|
<div className="p-5 border-t border-spa-stone/10 bg-spa-light space-y-4">
|
||||||
@@ -167,6 +192,18 @@ function CartDrawerFooter({ subtotal, onClose }: { subtotal: number; onClose: ()
|
|||||||
<span>ราคาสินค้า</span>
|
<span>ราคาสินค้า</span>
|
||||||
<span>{formatPrice(subtotal)}</span>
|
<span>{formatPrice(subtotal)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
{promoLevel1Disc > 0 && (
|
||||||
|
<div className="flex justify-between text-spa-forest font-medium">
|
||||||
|
<span>{promoLevel1?.name}</span>
|
||||||
|
<span>- {formatPrice(promoLevel1Disc)}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{promoLevel2Disc > 0 && (
|
||||||
|
<div className="flex justify-between text-spa-forest font-medium">
|
||||||
|
<span>{promoLevel2?.name}</span>
|
||||||
|
<span>- {formatPrice(promoLevel2Disc)}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{(discountAmount > 0 || isFreeShipping) && savedCoupon && (
|
{(discountAmount > 0 || isFreeShipping) && savedCoupon && (
|
||||||
<div className="flex justify-between text-spa-forest font-medium">
|
<div className="flex justify-between text-spa-forest font-medium">
|
||||||
<span className="flex items-center gap-1.5">
|
<span className="flex items-center gap-1.5">
|
||||||
@@ -194,7 +231,7 @@ function CartDrawerFooter({ subtotal, onClose }: { subtotal: number; onClose: ()
|
|||||||
)}
|
)}
|
||||||
<div className="flex justify-between font-bold text-base pt-2 border-t border-spa-stone/10 text-pop-black">
|
<div className="flex justify-between font-bold text-base pt-2 border-t border-spa-stone/10 text-pop-black">
|
||||||
<span>รวมสุทธิ</span>
|
<span>รวมสุทธิ</span>
|
||||||
<span className="text-rose-500">{formatPrice(Math.max(0, subtotal - discountAmount))}</span>
|
<span className="text-rose-500">{formatPrice(total)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user