diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-04-05 09:46:31 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-04-05 09:46:31 +0700 |
| commit | 38c9fbb245aeb315e90f42c281a17257a5eeb122 (patch) | |
| tree | 38022c794bd87997ea38c7f946cf13598b65ec96 | |
| parent | bd65a11a9f6ed0589ccdf86745abbf12b17816e9 (diff) | |
forgot and reset password
| -rw-r--r-- | src/lib/auth/components/Activate.jsx | 2 | ||||
| -rw-r--r-- | src/lib/product/components/ProductSearch.jsx | 4 | ||||
| -rw-r--r-- | src/pages/activate.jsx | 19 | ||||
| -rw-r--r-- | src/pages/api/forgot-password.js | 26 | ||||
| -rw-r--r-- | src/pages/forgot-password.jsx | 122 | ||||
| -rw-r--r-- | src/pages/index.jsx | 14 | ||||
| -rw-r--r-- | src/pages/reset-password.jsx | 135 |
7 files changed, 272 insertions, 50 deletions
diff --git a/src/lib/auth/components/Activate.jsx b/src/lib/auth/components/Activate.jsx index 5e95de8a..717e178b 100644 --- a/src/lib/auth/components/Activate.jsx +++ b/src/lib/auth/components/Activate.jsx @@ -153,7 +153,7 @@ const Activate = () => { /> <button type='submit' - disabled={email != ''} + disabled={!email} className='btn-yellow font-semibold mt-4 w-full' > {isLoading ? 'Loading...' : 'Aktivasi'} diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 77c75e05..8e68d62d 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -28,12 +28,12 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { const productRows = productSearch.data?.responseHeader.params.rows const productFound = productSearch.data?.response.numFound - const brands = productSearch.data?.facetCounts?.facetFields?.manufactureNameS?.filter((value, index) => { + const brands = productSearch.data?.facetCounts?.facetFields?.manufactureName?.filter((value, index) => { if (index % 2 === 0) { return true } }) - const categories = productSearch.data?.facetCounts?.facetFields?.categoryNameS?.filter( + const categories = productSearch.data?.facetCounts?.facetFields?.categoryName?.filter( (value, index) => { if (index % 2 === 0) { return true diff --git a/src/pages/activate.jsx b/src/pages/activate.jsx index 7f4b6056..48d9c4d3 100644 --- a/src/pages/activate.jsx +++ b/src/pages/activate.jsx @@ -1,13 +1,28 @@ import Seo from '@/core/components/Seo' import SimpleFooter from '@/core/components/elements/Footer/SimpleFooter' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' import ActivateComponent from '@/lib/auth/components/Activate' export default function Activate() { return ( <> <Seo title='Aktivasi Akun Indoteknik.com' /> - <ActivateComponent /> - <SimpleFooter /> + <MobileView> + <ActivateComponent /> + <SimpleFooter /> + </MobileView> + + <DesktopView> + <BasicLayout> + <div className='container mx-auto'> + <div className='w-1/2 mx-auto'> + <ActivateComponent /> + </div> + </div> + </BasicLayout> + </DesktopView> </> ) } diff --git a/src/pages/api/forgot-password.js b/src/pages/api/forgot-password.js new file mode 100644 index 00000000..68bf381f --- /dev/null +++ b/src/pages/api/forgot-password.js @@ -0,0 +1,26 @@ +import odooApi from '@/core/api/odooApi' +import mailer from '@/core/utils/mailer' + +export default async function handler(req, res) { + try { + const { email } = req.body + let result = await odooApi('POST', '/api/v1/user/forgot-password', { email }) + if (result.success) { + mailer.sendMail({ + from: 'sales@indoteknik.com', + to: result.user.email, + subject: 'Permintaan Reset Password Akun Indoteknik', + html: ` + <h1>Permintaan Reset Password Akun Indoteknik</h1> + <br> + <p>Reset password akun anda melalui link berikut: <a href="${process.env.SELF_HOST}/reset-password?token=${result.token}">Reset Password Akun</a></p> + ` + }) + } + delete result.user + delete result.token + res.status(200).json(result) + } catch (error) { + res.status(400).json({ error: error.message }) + } +} diff --git a/src/pages/forgot-password.jsx b/src/pages/forgot-password.jsx index eb5c5185..6211d237 100644 --- a/src/pages/forgot-password.jsx +++ b/src/pages/forgot-password.jsx @@ -2,63 +2,99 @@ import Alert from '@/core/components/elements/Alert/Alert' import SimpleFooter from '@/core/components/elements/Footer/SimpleFooter' import Link from '@/core/components/elements/Link/Link' import BasicLayout from '@/core/components/layouts/BasicLayout' +import DesktopView from '@/core/components/views/DesktopView' import MobileView from '@/core/components/views/MobileView' import IndoteknikLogo from '@/images/logo.png' +import axios from 'axios' import Image from 'next/image' -import { useRouter } from 'next/router' import { useState } from 'react' export default function ForgotPassword() { - const router = useRouter() - const { token } = router.query + return ( + <> + <MobileView> + <FormComponent /> + <SimpleFooter /> + </MobileView> + <DesktopView> + <BasicLayout> + <div className='container mx-auto'> + <div className='w-1/2 mx-auto'> + <FormComponent /> + </div> + </div> + </BasicLayout> + </DesktopView> + </> + ) +} + +const FormComponent = () => { const [isLoading, setIsLoading] = useState(false) - const [alert, setAlert] = useState() + const [alert, setAlert] = useState(null) - const [email, setEmail] = useState(router.query?.email || '') + const [email, setEmail] = useState('') - const forgotPasswordRequest = () => {} + const forgotPasswordRequest = async (e) => { + e.preventDefault() + setIsLoading(true) + let submitRequest = await axios.post( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/forgot-password`, + { + email + } + ) + setIsLoading(false) + if (submitRequest.data.success) { + setAlert({ + children: <>Mohon cek email anda untuk reset password akun Indoteknik</>, + type: 'success' + }) + } else { + setAlert({ + children: ( + <> + Email tersebut belum terdaftar,{' '} + <Link className='text-gray_r-12 inline-block' href='/register'> + daftar sekarang + </Link> + . + </> + ), + type: 'info' + }) + } + } return ( - <> - <MobileView> - <div className='p-6 pt-10 flex flex-col items-center min-h-screen'> - <Link href='/'> - <Image src={IndoteknikLogo} alt='Logo Indoteknik' width={150} height={50} /> - </Link> - - <h1 className='text-2xl mt-4 font-semibold text-center'> - Lupa Kata Sandi Akun Indoteknik - </h1> + <div className='p-6 pt-10 md:px-0 flex flex-col items-center min-h-screen'> + <Link href='/'> + <Image src={IndoteknikLogo} alt='Logo Indoteknik' width={150} height={50} /> + </Link> - {alert && ( - <Alert className='text-center mt-4' type={alert.type}> - {alert.children} - </Alert> - )} + <h1 className='text-2xl mt-4 font-semibold text-center'>Lupa Kata Sandi Akun Indoteknik</h1> - <form onSubmit={forgotPasswordRequest} className='mt-6 w-full'> - <input - type='email' - id='email' - className='form-input w-full text-center' - value={email} - onChange={(e) => setEmail(e.target.value)} - placeholder='Masukan alamat email' - autoFocus - /> - <button - type='submit' - disabled={email != ''} - className='btn-yellow font-semibold mt-4 w-full' - > - {isLoading ? 'Loading...' : 'Kirim Permintaan'} - </button> - </form> - </div> + {alert && ( + <Alert className='text-center mt-4' type={alert.type}> + {alert.children} + </Alert> + )} - <SimpleFooter /> - </MobileView> - </> + <form onSubmit={forgotPasswordRequest} className='mt-6 w-full'> + <input + type='email' + id='email' + className='form-input w-full text-center' + value={email} + onChange={(e) => setEmail(e.target.value)} + placeholder='Masukan alamat email' + autoFocus + /> + <button type='submit' disabled={!email || isLoading} className='btn-yellow font-semibold mt-4 w-full'> + {isLoading ? 'Loading...' : 'Kirim Permintaan'} + </button> + </form> + </div> ) } diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 1102cc1b..2a996b5d 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -3,9 +3,12 @@ import ImageSkeleton from '@/core/components/elements/Skeleton/ImageSkeleton' import PopularProductSkeleton from '@/lib/home/components/Skeleton/PopularProductSkeleton' import MobileView from '@/core/components/views/MobileView' import DesktopView from '@/core/components/views/DesktopView' -import { useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import { NextSeo } from 'next-seo' import Seo from '@/core/components/Seo' +import { useQuery } from 'react-query' +import odooApi from '@/core/api/odooApi' +import Image from '@/core/components/elements/Image/Image' const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) @@ -26,6 +29,9 @@ const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeI }) export default function Home() { + const fetchSecondHeroBanner = async () => await odooApi('GET', '/api/v1/banner?type=index-b-2') + const secondHeroBanner = useQuery('secondHeroBanner', fetchSecondHeroBanner) + const bannerRef = useRef(null) const wrapperRef = useRef(null) @@ -51,7 +57,11 @@ export default function Home() { <DesktopView> <div className='container mx-auto'> <div className='flex h-[360px]' ref={wrapperRef} onLoad={handleOnLoad}> - <div className='w-3/12'></div> + <div className='w-3/12'> + {secondHeroBanner.isFetched && ( + <Image src={secondHeroBanner.data[0].image} alt={secondHeroBanner.data[0].name} /> + )} + </div> <div className='w-6/12 px-1' ref={bannerRef}> <HeroBanner /> </div> diff --git a/src/pages/reset-password.jsx b/src/pages/reset-password.jsx new file mode 100644 index 00000000..a4aa2201 --- /dev/null +++ b/src/pages/reset-password.jsx @@ -0,0 +1,135 @@ +import Alert from '@/core/components/elements/Alert/Alert' +import SimpleFooter from '@/core/components/elements/Footer/SimpleFooter' +import Link from '@/core/components/elements/Link/Link' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' +import Image from 'next/image' +import { useRouter } from 'next/router' +import { useRef, useState } from 'react' +import IndoteknikLogo from '@/images/logo.png' +import odooApi from '@/core/api/odooApi' +import { setAuth } from '@/core/utils/auth' + +export default function ResetPassword() { + return ( + <> + <MobileView> + <FormComponent /> + <SimpleFooter /> + </MobileView> + + <DesktopView> + <BasicLayout> + <div className='container mx-auto'> + <div className='w-1/2 mx-auto'> + <FormComponent /> + </div> + </div> + </BasicLayout> + </DesktopView> + </> + ) +} + +const FormComponent = () => { + const router = useRouter() + const { token = '' } = router.query + + const password = useRef(null) + const retypePassword = useRef(null) + + const [isLoading, setIsLoading] = useState(false) + const [isValidPassword, setIsValidPassword] = useState(false) + const [alert, setAlert] = useState(null) + + const checkValidPassword = () => { + const passwordVal = password.current.value + const retypePasswordVal = retypePassword.current.value + if (passwordVal == retypePasswordVal) { + setIsValidPassword(true) + } else { + setIsValidPassword(false) + } + } + + const resetPasswordRequest = async (e) => { + e.preventDefault() + setIsLoading(true) + const result = await odooApi('POST', '/api/v1/user/reset-password', { token }) + setIsLoading(false) + password.current.value = '' + retypePassword.current.value = '' + if (result.success) { + setAuth(result.user) + setAlert({ + children: ( + <> + Berhasil melakukan reset password,{' '} + <Link className='text-gray_r-12 inline-block' href='/'> + kembali ke halaman utama + </Link> + </> + ), + type: 'success' + }) + } else { + setAlert({ + children: ( + <> + Gagal melakukan reset password, token tidak ditemukan. Buat permintaan reset password{' '} + <Link className='text-gray_r-12 inline-block' href='/forgot-password'> + disini + </Link> + </> + ), + type: 'info' + }) + } + } + + return ( + <div className='p-6 pt-10 md:px-0 flex flex-col items-center min-h-screen'> + <Link href='/'> + <Image src={IndoteknikLogo} alt='Logo Indoteknik' width={150} height={50} /> + </Link> + + <h1 className='text-2xl mt-4 font-semibold text-center'>Reset Kata Sandi Akun Indoteknik</h1> + + {alert && ( + <Alert className='text-center mt-4' type={alert.type}> + {alert.children} + </Alert> + )} + + <form onSubmit={resetPasswordRequest} className='mt-6 w-full'> + <input + type='password' + id='password' + className='form-input w-full text-center' + ref={password} + onChange={checkValidPassword} + placeholder='Masukan kata sandi baru' + autoFocus + /> + + <input + type='password' + id='retypePassword' + className='form-input w-full text-center mt-4' + ref={retypePassword} + onChange={checkValidPassword} + placeholder='Masukan kembali kata sandi baru' + /> + + <button + type='submit' + disabled={!isValidPassword || isLoading} + className='btn-yellow font-semibold mt-4 w-full' + > + {isLoading ? 'Loading...' : 'Reset Password'} + </button> + </form> + </div> + ) +} |
