summaryrefslogtreecommitdiff
path: root/src-migrate/modules/account-activation/components
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-10-30 09:21:30 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-10-30 09:21:30 +0700
commite8c414325a1e32474e740cc6e7dca8396affc5e3 (patch)
treee84feb31cd8619d208b4558c5fcf30becc5337e0 /src-migrate/modules/account-activation/components
parent1694c12f75ad06c5e40d6f9a66e245c3e683146c (diff)
parentc82110f7d3a2f85de99045fde7b579e369f15b2c (diff)
Merge branch 'refactor/all' into development
Diffstat (limited to 'src-migrate/modules/account-activation/components')
-rw-r--r--src-migrate/modules/account-activation/components/FormEmail.tsx96
-rw-r--r--src-migrate/modules/account-activation/components/FormOTP.tsx127
-rw-r--r--src-migrate/modules/account-activation/components/FormToken.tsx75
3 files changed, 298 insertions, 0 deletions
diff --git a/src-migrate/modules/account-activation/components/FormEmail.tsx b/src-migrate/modules/account-activation/components/FormEmail.tsx
new file mode 100644
index 00000000..cd917bc9
--- /dev/null
+++ b/src-migrate/modules/account-activation/components/FormEmail.tsx
@@ -0,0 +1,96 @@
+import { Alert, AlertIcon } from "@chakra-ui/react"
+import Link from "next/link"
+import { useRouter } from "next/router"
+import { ChangeEvent, useEffect, useState } from "react"
+import { useMutation } from "react-query"
+import Modal from "~/common/components/elements/Modal"
+import { useRegisterStore } from "~/common/stores/useRegisterStore"
+import { ActivationReqProps } from "~/common/types/auth"
+import { activationReq } from "~/services/auth"
+
+const FormEmail = () => {
+ const router = useRouter()
+ const { query } = router
+ const [active, setActive] = useState<boolean>(false)
+ const [isBtnDisabled, setIsBtnDisabled] = useState<boolean>(true)
+ const [email, setEmail] = useState<string>('')
+
+ const { form } = useRegisterStore()
+
+ useEffect(() => {
+ if (form) setEmail(form?.email)
+ }, [form])
+
+ useEffect(() => {
+ setIsBtnDisabled(email === '')
+ }, [email])
+
+ useEffect(() => {
+ setActive(query?.activation === 'email')
+ }, [query.activation])
+
+ const mutation = useMutation({
+ mutationFn: (data: ActivationReqProps) => activationReq(data)
+ })
+
+ const handleSubmit = (e: ChangeEvent<HTMLFormElement>) => {
+ e.preventDefault()
+ mutation.data = undefined
+ mutation.mutate({ email })
+ }
+
+ useEffect(() => {
+ if (mutation.data?.activation_request === true) {
+ const urlParams = new URLSearchParams({
+ activation: 'otp',
+ email
+ })
+ router.push(`${router.route}?${urlParams}`)
+ }
+ }, [mutation.data?.activation_request, router, email])
+
+ return (
+ <Modal active={active} mode="desktop" close={() => router.push(router.route)} title="Aktivasi Akun">
+ <form onSubmit={handleSubmit} className="py-3 flex flex-col items-center gap-y-4">
+ {
+ mutation.data !== undefined &&
+ !mutation.data?.activation_request &&
+ (
+ <Alert status="warning">
+ <AlertIcon />
+ {mutation.data?.reason === 'ACTIVE' && 'Akun sudah aktif.'}
+ {mutation.data?.reason === 'NOT_FOUND' && 'Akun tidak ditemukan.'}
+
+ {mutation.data?.reason === 'ACTIVE' && (
+ <Link href="/login" className="ml-1 text-yellow-700 underline">Klik untuk masuk akun anda</Link>
+ )}
+
+ {mutation.data?.reason === 'NOT_FOUND' && (
+ <Link href="/register" className="ml-1 text-yellow-700 underline">Klik untuk daftar akun baru</Link>
+ )}
+ </Alert>
+ )
+ }
+
+ <input
+ type="text"
+ className="form-input w-full"
+ placeholder="Masukan alamat email anda"
+ autoComplete="email"
+ value={email}
+ onChange={(e) => setEmail(e.target.value)}
+ autoFocus
+ />
+ <button
+ type="submit"
+ className="btn-yellow w-full"
+ disabled={isBtnDisabled || mutation.isLoading}
+ >
+ {mutation.isLoading ? 'Loading...' : 'Kirim Aktivasi'}
+ </button>
+ </form>
+ </Modal>
+ )
+}
+
+export default FormEmail \ No newline at end of file
diff --git a/src-migrate/modules/account-activation/components/FormOTP.tsx b/src-migrate/modules/account-activation/components/FormOTP.tsx
new file mode 100644
index 00000000..e38fa8fe
--- /dev/null
+++ b/src-migrate/modules/account-activation/components/FormOTP.tsx
@@ -0,0 +1,127 @@
+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 { 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])
+
+ // TODO: Save user to local storage
+
+ 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 \ No newline at end of file
diff --git a/src-migrate/modules/account-activation/components/FormToken.tsx b/src-migrate/modules/account-activation/components/FormToken.tsx
new file mode 100644
index 00000000..6af24413
--- /dev/null
+++ b/src-migrate/modules/account-activation/components/FormToken.tsx
@@ -0,0 +1,75 @@
+import { Alert, AlertDescription, AlertIcon, AlertTitle, Spinner } from "@chakra-ui/react"
+import { useRouter } from "next/router"
+import { useEffect, useState } from "react"
+import Link from "next/link"
+import { useMutation } from "react-query"
+
+import Modal from "~/common/components/elements/Modal"
+import { ActivationTokenProps } from "~/common/types/auth"
+import { activationUserToken } from "~/services/auth"
+
+const FormToken = () => {
+ const { query } = useRouter()
+ const [active, setActive] = useState<boolean>(false)
+
+ const mutation = useMutation({
+ mutationFn: (data: ActivationTokenProps) => activationUserToken(data),
+ })
+
+ useEffect(() => {
+ if (query?.activation === 'token' && typeof query?.token === 'string') {
+ mutation.mutate({ token: query.token })
+ setActive(true)
+ }
+ //eslint-disable-next-line
+ }, [query.activation, query.token])
+
+ // TODO: Save user to local storage
+
+ return (
+ <Modal active={active} mode="desktop">
+ <div className="pb-6 flex flex-col items-center gap-y-6">
+ {mutation.isLoading && (
+ <>
+ <Spinner size='lg' borderWidth='3px' />
+ <div className="text-h-sm">Mohon tunggu sedang memverifikasi akun</div>
+ </>
+ )}
+
+ {!mutation.isLoading && (
+ <Alert
+ status={mutation.data?.activation ? 'success' : 'error'}
+ flexDirection="column"
+ alignItems="center"
+ justifyContent="center"
+ textAlign="center"
+ height="200px"
+ bg="transparent"
+ >
+ <AlertIcon boxSize="40px" mr={0} />
+ <AlertTitle className="mt-4 mb-1 text-h-sm">
+ Aktivasi akun {mutation.data?.activation ? 'berhasil' : 'gagal'}
+ </AlertTitle>
+ <AlertDescription maxWidth="sm">
+ {mutation.data?.activation && (
+ <>
+ Akun anda berhasil diaktifkan, selamat berbelanja di Indoteknik.
+ <Link href='/' className="block mt-8 text-success-700 underline">Kembali ke halaman utama</Link>
+ </>
+ )}
+
+ {!mutation.data?.activation && mutation.data?.reason === 'INVALID_TOKEN' && (
+ <>
+ Token sudah kadaluwarsa, silahkan coba kembali.
+ <Link href='/register?activation=email' className="block mt-8 text-red-700 underline">Aktivasi Akun</Link>
+ </>
+ )}
+ </AlertDescription>
+ </Alert>
+ )}
+ </div>
+ </Modal>
+ )
+}
+
+export default FormToken \ No newline at end of file