1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
import style from "../styles/card.module.css"
import React, { useEffect, useMemo, useState } from 'react'
import { InfoIcon, PlusIcon } from "lucide-react"
import { Skeleton, Tooltip } from '@chakra-ui/react'
import { motion } from "framer-motion"
import { PROMO_CATEGORY } from "~/constants/promotion"
import { getVariantById } from "~/services/productVariant"
import { IProductVariantPromo, IPromotion } from '~/types/promotion'
import formatCurrency from '~/libs/formatCurrency'
import clsxm from '~/libs/clsxm'
import ProductPromoItem from './Item'
import ProductPromoAddToCart from "./AddToCart"
import ProductPromoCardCountdown from "./CardCountdown"
type Props = {
promotion: IPromotion
}
const ProductPromoCard = ({ promotion }: Props) => {
const [products, setProducts] = useState<IProductVariantPromo[]>([])
useEffect(() => {
const getProducts = async () => {
const datas = []
for (const product of promotion.products) {
const res = await getVariantById(product.product_id)
res.data.qty = product.qty
datas.push(res.data)
}
setProducts(datas)
}
getProducts()
}, [promotion.products])
const [freeProducts, setFreeProducts] = useState<IProductVariantPromo[]>([])
useEffect(() => {
const getFreeProducts = async () => {
const datas = []
for (const product of promotion.free_products) {
const res = await getVariantById(product.product_id)
res.data.qty = product.qty
datas.push(res.data)
}
setFreeProducts(datas)
}
getFreeProducts()
}, [promotion.free_products])
const priceTotal = useMemo(() => {
let total = 0;
[...products, ...freeProducts].forEach((product) => {
total += product.price.price_discount * product.qty
})
return total
}, [products, freeProducts])
const allProducts = [...products, ...freeProducts]
return (
<div className={style.card}>
<ProductPromoCardCountdown promotion={promotion} />
<div className='px-4 mt-4 text-caption-1'>
<div className="flex justify-between items-center">
<div className={style.title}>{promotion.name}</div>
<Tooltip label={PROMO_CATEGORY[promotion.type.value].description} placement="top" bgColor='red.600' p={2} rounded={6}>
<div className={style.badgeType}>
Paket {PROMO_CATEGORY[promotion.type.value].alias}
<InfoIcon size={16} />
</div>
</Tooltip>
</div>
<Skeleton className={clsxm(style.productSection, { 'justify-center': allProducts.length === 2 })} isLoaded={allProducts.length > 0}>
{allProducts.map((product, index) => (
<>
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.6 }}>
<ProductPromoItem
variant={product}
isFree={index + 1 > products.length && promotion.type.value === 'merchandise'}
/>
</motion.div>
<motion.div initial={{ y: 30, opacity: 0 }} animate={{ y: 0, opacity: 1 }} transition={{ duration: 0.5, delay: 0.1 }}>
{index + 1 < allProducts.length && (
<div className="h-fit p-1 rounded-full border border-danger-500 text-danger-500 mt-[38px]">
<PlusIcon size={14} strokeWidth='2px' />
</div>
)}
</motion.div>
</>
))}
</Skeleton>
<div className={style.priceSection}>
<div className={style.priceCol}>
<Skeleton className={style.priceRow} isLoaded={priceTotal > 0}>
<span className={style.basePrice}>Rp{formatCurrency(priceTotal)}</span>
<span>Hemat <span className={style.savingAmt}>Rp {formatCurrency(priceTotal - promotion.price)}</span></span>
</Skeleton>
<div className={style.priceRow}>
<span className={style.price}>Rp{formatCurrency(promotion.price)}</span>
<span className={style.totalItems}>(Total {promotion.total_qty} barang)</span>
</div>
</div>
<div>
<ProductPromoAddToCart promotion={promotion} />
</div>
</div>
</div>
</div>
)
}
export default ProductPromoCard
|