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
125
126
127
|
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'
import useDevice from '@/core/hooks/useDevice';
const Voucher = () => {
const { isMobile } = useDevice();
const toast = useToast();
const voucherQuery = useQuery({
queryKey: ['voucher.all-voucher'],
queryFn: getVoucher
})
const swiperVoucher: SwiperProps = {
autoplay: {
delay: 6000,
disableOnInteraction: false
},
loop: false,
className: 'h-[160px] w-full',
slidesPerView: isMobile ? 1.2 : 3,
spaceBetween: 16
}
const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]);
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 Voucher
|