summaryrefslogtreecommitdiff
path: root/src-migrate/modules
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2024-06-28 03:26:38 +0000
committertrisusilo <tri.susilo@altama.co.id>2024-06-28 03:26:38 +0000
commitdef7fc2f1201286c44545e1305ca9f11eb16f3d0 (patch)
tree4c65db77b9aa28f3dd53ce514de9d918440c2887 /src-migrate/modules
parent98d4f9564bfba66687848b335026bddb6f4dc5b6 (diff)
parent936f7f9fb1c6951e02dd8a5f7e85fb8d39cc7e6a (diff)
Merged in promotion-program (pull request #140)
Promotion program Approved-by: trisusilo
Diffstat (limited to 'src-migrate/modules')
-rw-r--r--src-migrate/modules/product-promo/components/AddToCart.tsx52
-rw-r--r--src-migrate/modules/product-promo/components/Card.tsx204
-rw-r--r--src-migrate/modules/product-promo/components/Section.tsx2
-rw-r--r--src-migrate/modules/product-promo/styles/card.module.css12
4 files changed, 194 insertions, 76 deletions
diff --git a/src-migrate/modules/product-promo/components/AddToCart.tsx b/src-migrate/modules/product-promo/components/AddToCart.tsx
index 192dd231..87017c14 100644
--- a/src-migrate/modules/product-promo/components/AddToCart.tsx
+++ b/src-migrate/modules/product-promo/components/AddToCart.tsx
@@ -7,6 +7,9 @@ import { getAuth } from '~/libs/auth'
import { upsertUserCart } from '~/services/cart'
import { IPromotion } from '~/types/promotion'
+import DesktopView from '../../../../src/core/components/views/DesktopView';
+import MobileView from '../../../../src/core/components/views/MobileView';
+
type Props = {
promotion: IPromotion
}
@@ -55,21 +58,42 @@ const ProductPromoAddToCart = ({ promotion }: Props) => {
}, [status])
return (
- <Button
- colorScheme='yellow'
- px={2}
- w='110px'
- gap={1}
- isDisabled={status === 'loading'}
- onClick={handleButton}
- >
- {status === 'success' && <CheckIcon size={16} />}
- {status === 'loading' && <Spinner size='xs' mr={1.5} />}
- {status === 'idle' && <PlusIcon size={16} />}
+ <div>
+ <MobileView>
+ <Button
+ colorScheme='yellow'
+ px={2}
+ w='36px'
+ gap={1}
+ isDisabled={status === 'loading'}
+ onClick={handleButton}
+ >
+ {status === 'success' && <CheckIcon size={16} />}
+ {status === 'loading' && <Spinner size='xs' mr={1.5} />}
+ {status === 'idle' && <PlusIcon size={16} />}
+
+ {status === 'success' && <span>Berhasil</span>}
+ {/* {status !== 'success' && <span>Keranjang</span>} */}
+ </Button>
+ </MobileView>
+ <DesktopView>
+ <Button
+ colorScheme='yellow'
+ px={2}
+ w='110px'
+ gap={1}
+ isDisabled={status === 'loading'}
+ onClick={handleButton}
+ >
+ {status === 'success' && <CheckIcon size={16} />}
+ {status === 'loading' && <Spinner size='xs' mr={1.5} />}
+ {status === 'idle' && <PlusIcon size={16} />}
- {status === 'success' && <span>Berhasil</span>}
- {status !== 'success' && <span>Keranjang</span>}
- </Button>
+ {status === 'success' && <span>Berhasil</span>}
+ {status !== 'success' && <span>Keranjang</span>}
+ </Button>
+ </DesktopView>
+ </div>
)
}
diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx
index 59110098..56e29e38 100644
--- a/src-migrate/modules/product-promo/components/Card.tsx
+++ b/src-migrate/modules/product-promo/components/Card.tsx
@@ -16,38 +16,52 @@ import ProductPromoItem from './Item'
import ProductPromoAddToCart from "./AddToCart"
import ProductPromoCardCountdown from "./CardCountdown"
+import MobileView from '../../../../src/core/components/views/MobileView';
+import DesktopView from '../../../../src/core/components/views/DesktopView';
+
type Props = {
promotion: IPromotion
+
}
-const ProductPromoCard = ({ promotion }: Props) => {
+const ProductPromoCard = ({ promotion}: Props) => {
const [products, setProducts] = useState<IProductVariantPromo[]>([])
+ const [freeProducts, setFreeProducts] = useState<IProductVariantPromo[]>([])
+ const [error, setError] = useState<string | null>(null)
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)
+ try {
+ 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)
+ } catch (err) {
+ setError('Failed to fetch product variants.')
+ console.error(err)
}
- 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)
+ try {
+ 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)
+ } catch (err) {
+ setError('Failed to fetch free product variants.')
+ console.error(err)
}
- setFreeProducts(datas)
}
getFreeProducts()
@@ -63,62 +77,130 @@ const ProductPromoCard = ({ promotion }: Props) => {
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>
+ return (
+ <div>
+ <MobileView>
+ <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={1} rounded={6}>
+ {/* <div className={style.badgeType} > */}
+ {/* Paket {PROMO_CATEGORY[promotion.type.value].alias} */}
+ <InfoIcon className={style.badgeType} size={25} />
+ {/* </div> */}
+ </Tooltip>
+ </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} />
+ <Skeleton className={clsxm(style.productSection, { 'justify-center': allProducts.length === 2 })} isLoaded={allProducts.length > 0}>
+ {allProducts.map((product, index) => (
+ <React.Fragment key={product.id}>
+ <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.6 }}>
+ <ProductPromoItem
+ variant={product}
+ isFree={index + 1 > products.length && promotion.type.value === 'merchandise'}
+ // isFree={index + 1 > products.length }
+ />
+ </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>
+ </React.Fragment>
+ ))}
+ </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 className="text-[11px]">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>
- </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>
+ <ProductPromoAddToCart promotion={promotion} />
</div>
+
</div>
- <div>
- <ProductPromoAddToCart promotion={promotion} />
+ </div>
+ </div>
+ </MobileView>
+ <DesktopView>
+ <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) => (
+ <React.Fragment key={product.id}>
+ <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.6 }}>
+ <ProductPromoItem
+ variant={product}
+ isFree={index + 1 > products.length && promotion.type.value === 'merchandise'}
+ // isFree={index + 1 > products.length }
+ />
+ </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>
+ </React.Fragment>
+ ))}
+ </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>
+ </DesktopView>
</div>
+ // shouldRender && (
+
+ // )
)
}
-export default ProductPromoCard \ No newline at end of file
+export default ProductPromoCard
diff --git a/src-migrate/modules/product-promo/components/Section.tsx b/src-migrate/modules/product-promo/components/Section.tsx
index 5fc0da4c..4e8a7dd5 100644
--- a/src-migrate/modules/product-promo/components/Section.tsx
+++ b/src-migrate/modules/product-promo/components/Section.tsx
@@ -50,7 +50,7 @@ const ProductPromoSection = ({ productId }: Props) => {
>
{promotions?.data.map((promotion) => (
<div key={promotion.id} className="min-w-[400px] max-w-[400px]">
- <ProductPromoCard promotion={promotion} />
+ <ProductPromoCard promotion={promotion} />
</div>
))}
</Skeleton>
diff --git a/src-migrate/modules/product-promo/styles/card.module.css b/src-migrate/modules/product-promo/styles/card.module.css
index a2ad9af6..faa3b370 100644
--- a/src-migrate/modules/product-promo/styles/card.module.css
+++ b/src-migrate/modules/product-promo/styles/card.module.css
@@ -44,3 +44,15 @@
.totalItems {
@apply text-gray_r-9;
}
+
+@media only screen and (max-width: 384px) {
+ .basePrice {
+ @apply text-[13px];
+ }
+ .price{
+ @apply text-[15px];
+ }
+ .totalItems{
+ @apply text-[11px];
+ }
+ } \ No newline at end of file