summaryrefslogtreecommitdiff
path: root/src-migrate/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src-migrate/modules')
-rw-r--r--src-migrate/modules/promo/components/Hero.tsx23
-rw-r--r--src-migrate/modules/promo/components/Voucher.tsx73
-rw-r--r--src-migrate/modules/promo/styles/voucher.module.css40
3 files changed, 129 insertions, 7 deletions
diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx
index 63524509..5470b93b 100644
--- a/src-migrate/modules/promo/components/Hero.tsx
+++ b/src-migrate/modules/promo/components/Hero.tsx
@@ -1,19 +1,21 @@
-import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react';
-import style from '../styles/hero.module.css';
-import 'swiper/css'
+import 'swiper/css';
+
import Image from 'next/image';
+import { useEffect, useMemo } from 'react';
import { useQuery } from 'react-query';
+import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react';
+
import { getBanner } from '~/services/banner';
+import style from '../styles/hero.module.css';
const swiperBanner: SwiperProps = {
autoplay: {
delay: 6000,
disableOnInteraction: false
},
- // modules: [Pagination, Autoplay],
- loop: true,
+ loop: false,
className: 'h-[400px] w-full',
- slidesPerView: 1.1,
+ slidesPerView: 1,
spaceBetween: 10
}
@@ -23,7 +25,14 @@ const Hero = () => {
queryFn: () => getBanner({ type: 'all-promo' })
})
- const banners = bannerQuery.data || []
+ const banners = useMemo(() => bannerQuery.data || [], [bannerQuery.data]);
+
+ useEffect(() => {
+ if (banners.length > 1) {
+ swiperBanner.slidesPerView = 1.1;
+ swiperBanner.loop = true;
+ }
+ }, [banners]);
return (
<div className={style['wrapper']}>
diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx
index 11742f9a..0706f044 100644
--- a/src-migrate/modules/promo/components/Voucher.tsx
+++ b/src-migrate/modules/promo/components/Voucher.tsx
@@ -1,9 +1,82 @@
+import { useMemo } from 'react'
+import { useQuery } from 'react-query'
+import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'
+import { getVoucher } from '~/services/voucher'
import style from '../styles/voucher.module.css'
+import Image from 'next/image'
+import { useToast } from '@chakra-ui/react'
+
+const swiperVoucher: SwiperProps = {
+ autoplay: {
+ delay: 6000,
+ disableOnInteraction: false
+ },
+ loop: false,
+ className: 'h-[160px] w-full',
+ slidesPerView: 3,
+ spaceBetween: 16
+}
const Voucher = () => {
+ const toast = useToast();
+ const voucherQuery = useQuery({
+ queryKey: ['voucher.all-voucher'],
+ queryFn: getVoucher
+ })
+
+ const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]);
+
+ const copyText = (text: string) => {
+ navigator.clipboard.writeText(text)
+ toast({
+ title: 'Salin ke papan klip',
+ description: 'Kode voucher berhasil disalin',
+ status: 'success',
+ duration: 3000,
+ isClosable: true,
+ position: 'bottom',
+ })
+ }
+
return (
<>
<div className={style['title']}>Pakai Voucher Belanja</div>
+
+ <div className='h-6' />
+
+ {voucherQuery.isLoading && (
+ <div className='grid grid-cols-3 gap-x-4 animate-pulse'>
+ {Array.from({ length: 3 }).map((_, index) => (
+ <div key={index} className='w-full h-[160px] bg-gray-200 rounded-xl' />
+ ))}
+ </div>
+ )}
+ {!voucherQuery.isLoading && (
+ <div className={style['voucher-section']}>
+ <Swiper {...swiperVoucher}>
+ {vouchers.map((voucher) => (
+ <SwiperSlide key={voucher.id} className='pb-2'>
+ <div className={style['voucher-card']}>
+ <Image src={voucher.image} alt={voucher.name} width={128} height={128} className={style['voucher-image']} />
+
+ <div className={style['voucher-content']}>
+ <div className={style['voucher-title']}>{voucher.name}</div>
+ <div className={style['voucher-desc']}>{voucher.description} Lorem ipsum dolor sit, amet consectetur adipisicing elit. Officiis magni nobis sint aspernatur soluta deserunt excepturi delectus corporis libero, voluptate odit! Cupiditate, quibusdam ipsa saepe voluptas repudiandae eum quaerat suscipit.</div>
+ <div className={style['voucher-bottom']}>
+ <div>
+ <div className={style['voucher-code-desc']}>Kode Promo</div>
+ <div className={style['voucher-code']}>{voucher.code}</div>
+ </div>
+ <button className={style['voucher-copy']} onClick={() => copyText(voucher.code)}>Salin</button>
+ </div>
+ </div>
+ </div>
+ </SwiperSlide>
+ ))}
+ </Swiper>
+ </div>
+ )}
+
</>
)
}
diff --git a/src-migrate/modules/promo/styles/voucher.module.css b/src-migrate/modules/promo/styles/voucher.module.css
index 22a3a0ac..24d3aac2 100644
--- a/src-migrate/modules/promo/styles/voucher.module.css
+++ b/src-migrate/modules/promo/styles/voucher.module.css
@@ -1,3 +1,43 @@
.title {
@apply text-h-sm md:text-h-lg font-semibold;
}
+
+.voucher-section {
+ @apply w-full;
+}
+
+.voucher-card {
+ @apply w-full h-full rounded-xl border border-gray-200 shadow-md p-4 flex gap-x-4;
+}
+
+.voucher-image {
+ @apply bg-gray-100 rounded-lg w-4/12 h-full object-contain object-center;
+}
+
+.voucher-content {
+ @apply flex-1 flex flex-col;
+}
+
+.voucher-title {
+ @apply font-medium text-body-1 leading-6 mb-1;
+}
+
+.voucher-desc {
+ @apply text-gray-800 line-clamp-2 text-caption-1;
+}
+
+.voucher-bottom {
+ @apply flex justify-between mt-auto;
+}
+
+.voucher-code-desc {
+ @apply text-gray-500 text-caption-1;
+}
+
+.voucher-code {
+ @apply text-red-700 font-medium;
+}
+
+.voucher-copy {
+ @apply bg-gray-200 hover:bg-danger-500 text-danger-500 hover:text-white transition-colors rounded-lg flex items-center justify-center px-6;
+}