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
128
129
130
131
132
|
import { HStack, PinInput, PinInputField, Spinner } from "@chakra-ui/react"
import Link from "next/link"
import { useRouter } from "next/router"
import { useEffect, useState } from "react"
import { useMutation } from "react-query"
import { useCountdown } from "usehooks-ts"
import Modal from '~/common/components/elements/Modal'
import { setAuth } from "~/common/libs/auth"
import { ActivationOtpProps, ActivationReqProps } from "~/common/types/auth"
import { activationReq, activationUserOTP } from "~/services/auth"
const FormOTP = () => {
const router = useRouter()
const { query } = router
const [active, setActive] = useState<boolean>(false)
const [email, setEmail] = useState<string>('')
const [otp, setOtp] = useState<string>('')
const [count, { startCountdown, resetCountdown }] = useCountdown({
countStart: 60 * 3,
intervalMs: 1000,
})
useEffect(() => {
setEmail((query?.email || '') as string)
}, [query?.email])
useEffect(() => {
setActive(query?.activation === 'otp')
}, [query.activation])
useEffect(() => {
!!active && startCountdown()
}, [active, startCountdown])
const mutationActivationReq = useMutation({
mutationFn: (data: ActivationReqProps) => activationReq(data),
onSuccess: () => {
resetCountdown()
startCountdown()
}
})
const mutationActivation = useMutation({
mutationFn: (data: ActivationOtpProps) => activationUserOTP(data)
})
useEffect(() => {
if (otp.length === 4 && !mutationActivation.data?.activation) {
mutationActivation.mutate({ email, otp })
}
//eslint-disable-next-line
}, [otp])
useEffect(() => {
if (mutationActivation.data?.user) {
setAuth(mutationActivation.data.user)
}
}, [mutationActivation.data])
return (
<Modal active={active} className="w-10/12 md:w-fit px-10" mode="desktop">
<div className="pb-8 flex flex-col items-center">
<div className="text-title-sm font-medium mb-4">Masukan Kode OTP</div>
<HStack>
<PinInput size='lg' otp onChange={(val) => setOtp(val)}>
<PinInputField autoFocus />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
<div className="mt-4 text-center">
{mutationActivation.isLoading && <Spinner size='sm' />}
{!mutationActivation.isLoading &&
mutationActivation.data?.reason === 'INVALID_OTP' &&
(
<span className="text-red-700">Mohon maaf kode OTP yand anda masukan salah</span>
)
}
{mutationActivation.data?.activation && (
<span className="text-success-700">Akun anda berhasil diaktifkan, selamat berbelanja di Indoteknik.</span>
)}
</div>
{!mutationActivation.data?.activation && (
<div className="mt-4 text-center text-gray-700">
Kode verifikasi telah dikirimkan ke alamat email <span className="font-medium">{email}</span>. Silakan periksa kotak masuk atau folder spam.
</div>
)}
<div className="mt-4">
{!mutationActivation.data?.activation && (
<>
{count > 0 && timeFormat(count)}
{!mutationActivation.data?.activation && count == 0 && (
<button
className="text-red-700 underline"
type="button"
onClick={() => mutationActivationReq.mutate({ email })}
disabled={mutationActivationReq.isLoading}
>
{mutationActivationReq.isLoading ? <Spinner size='sm' /> : 'Kirim Ulang'}
</button>
)}
</>
)}
{mutationActivation.data?.activation && (
<Link href='/' className="text-success-700 underline">Kembali ke halaman utama</Link>
)}
</div>
</div>
</Modal>
)
}
const timeFormat = (time: number): string => {
const minute = Math.floor(time / 60);
const second = time % 60;
const minuteFormat = minute < 10 ? `0${minute}` : `${minute}`
const secondFormat = second < 10 ? `0${second}` : `${second}`
return `${minuteFormat}:${secondFormat}`
}
export default FormOTP
|