summaryrefslogtreecommitdiff
path: root/src-migrate/modules/account-activation/components/FormOTP.tsx
blob: cf4da2dbf3f4c5bd275d8fb7cddf7bab5f309449 (plain)
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
import { Button, HStack, PinInput, PinInputField, Spinner } from "@chakra-ui/react"
import { useRouter } from "next/router"
import { useEffect, useState } from "react"
import { useMutation } from "react-query"
import { useCountdown } from "usehooks-ts"
import { Modal } from "~/components/ui/modal"
import { setAuth } from "~/libs/auth"
import { ActivationOtpProps, ActivationReqProps } from "~/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 * 1,
    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)
      router.push((query?.redirect || '/') as string)
    }
  }, [mutationActivation.data, router, query.redirect])

  return (
    <Modal active={active} className="w-10/12 md:w-fit px-10" close={() => setActive(false)} 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>
            )
          }
        </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 flex flex-col items-center">
          {!mutationActivation.data?.activation && (
            <>
              {count > 0 && timeFormat(count)}

              {!mutationActivation.data?.activation && count == 0 && (
                <>
                  <div className="mb-3">Belum menerima kode apapun?</div>

                  <Button
                    onClick={() => mutationActivationReq.mutate({ email })}
                    disabled={mutationActivationReq.isLoading}
                  >
                    {mutationActivationReq.isLoading ? <Spinner size='sm' /> : 'Kirim Ulang'}
                  </Button>
                </>
              )}
            </>
          )}

        </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