summaryrefslogtreecommitdiff
path: root/src-migrate/modules/promo/components/Voucher.tsx
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2024-08-20 16:12:25 +0700
committerit-fixcomart <it@fixcomart.co.id>2024-08-20 16:12:25 +0700
commit5c5eef9d62efd83f52f7c37dacb94d50ff7cb915 (patch)
tree7fdef4f99f0f42e2d99a40bfd5b81f1ca5f4ef30 /src-migrate/modules/promo/components/Voucher.tsx
parent004a9a644aed65d5c02263f19cce8b7c3000f354 (diff)
parent6d302bb338e26810a7f90326b84086217f1f4ae0 (diff)
Merge branch 'release' into Feature/category-management
Diffstat (limited to 'src-migrate/modules/promo/components/Voucher.tsx')
-rw-r--r--src-migrate/modules/promo/components/Voucher.tsx160
1 files changed, 160 insertions, 0 deletions
diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx
new file mode 100644
index 00000000..e5877e51
--- /dev/null
+++ b/src-migrate/modules/promo/components/Voucher.tsx
@@ -0,0 +1,160 @@
+import { useMemo, useState, useEffect } from 'react';
+import { useQuery } from 'react-query';
+import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react';
+import { getVoucherAll } from '~/services/voucher';
+import style from '../styles/voucher.module.css';
+import Image from 'next/image';
+import { useToast } from '@chakra-ui/react';
+import useDevice from '@/core/hooks/useDevice';
+import useAuth from '@/core/hooks/useAuth';
+import { getVoucher } from '../../../../src/lib/checkout/api/getVoucher';
+
+interface Auth {
+ id: string;
+}
+interface Voucher {
+ id: string;
+ image: string;
+ name: string;
+ description: string;
+ code: string;
+}
+
+const VoucherComponent = () => {
+ const [listVouchers, setListVouchers] = useState<Voucher[] | null>(null);
+ const [loadingVoucher, setLoadingVoucher] = useState(true);
+ const { isMobile } = useDevice();
+ const auth = useAuth() as unknown as Auth;
+ const toast = useToast();
+
+ useEffect(() => {
+ if (!listVouchers && auth?.id) {
+ (async () => {
+ try {
+ const dataVoucher = await getVoucher(auth.id);
+ setListVouchers(dataVoucher);
+ } finally {
+ setLoadingVoucher(false);
+ }
+ })();
+ }
+ }, [auth?.id, listVouchers]);
+
+ const voucherQuery = useQuery({
+ queryKey: ['voucher.all-voucher'],
+ queryFn: getVoucherAll,
+ });
+
+ const swiperVoucher: SwiperProps = {
+ autoplay: {
+ delay: 6000,
+ disableOnInteraction: false,
+ },
+ loop: false,
+ className: 'h-[160px] w-full',
+ slidesPerView: isMobile ? 1.2 : 3.2,
+ spaceBetween: 2,
+ };
+
+ const dataVouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]);
+
+ const vouchers = auth?.id? listVouchers : dataVouchers;
+
+
+ const copyText = (text: string) => {
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ navigator.clipboard.writeText(text)
+ .then(() => {
+ toast({
+ title: 'Salin ke papan klip',
+ description: 'Kode voucher berhasil disalin',
+ status: 'success',
+ duration: 3000,
+ isClosable: true,
+ position: 'top',
+ })
+ })
+ .catch(() => {
+ fallbackCopyTextToClipboard(text);
+ });
+ } else {
+ fallbackCopyTextToClipboard(text);
+ }
+ }
+
+ const fallbackCopyTextToClipboard = (text: string) => {
+ const textArea = document.createElement("textarea");
+ textArea.value = text;
+ // Tambahkan style untuk menyembunyikan textArea secara visual
+ textArea.style.position = 'fixed';
+ textArea.style.top = '0';
+ textArea.style.left = '0';
+ textArea.style.width = '2em';
+ textArea.style.height = '2em';
+ textArea.style.padding = '0';
+ textArea.style.border = 'none';
+ textArea.style.outline = 'none';
+ textArea.style.boxShadow = 'none';
+ textArea.style.background = 'transparent';
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+ try {
+ document.execCommand('copy');
+ toast({
+ title: 'Salin ke papan klip',
+ description: 'Kode voucher berhasil disalin',
+ status: 'success',
+ duration: 3000,
+ isClosable: true,
+ position: 'top',
+ })
+ } catch (err) {
+ console.error('Fallback: Oops, unable to copy', err);
+ }
+ document.body.removeChild(textArea);
+ }
+
+ 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}</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>
+ )}
+ </>
+ )
+}
+
+export default VoucherComponent