summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortrisusilo <tri.susilo@altama.co.id>2023-09-01 02:34:28 +0000
committertrisusilo <tri.susilo@altama.co.id>2023-09-01 02:34:28 +0000
commitda727c41d5221e13389005dbdff2706d3eb42842 (patch)
tree2abb9a8090306791a76069baff6c91c5e151d3b5 /src
parent7356bcc0d1b7bac8d05ac315fdcf2a46b3996e91 (diff)
parentdfdeedf7141c9191952bdb3005e2e91d2a495044 (diff)
Merged in Feature/google_sign_up (pull request #56)
Feature/google sign up
Diffstat (limited to 'src')
-rw-r--r--src/core/components/elements/Navbar/NavbarDesktop.jsx9
-rw-r--r--src/core/components/elements/Navbar/NavbarUserDropdown.jsx8
-rw-r--r--src/core/components/layouts/BasicLayout.jsx5
-rw-r--r--src/core/utils/auth.js4
-rw-r--r--src/lib/auth/components/LoginDesktop.jsx57
-rw-r--r--src/lib/auth/components/LoginMobile.jsx57
-rw-r--r--src/lib/auth/components/RegisterDesktop.jsx51
-rw-r--r--src/lib/auth/components/RegisterMobile.jsx50
-rw-r--r--src/lib/auth/hooks/useLogin.js19
-rw-r--r--src/pages/_app.jsx87
-rw-r--r--src/pages/api/auth/[...nextauth].js26
-rw-r--r--src/pages/my/menu.jsx9
12 files changed, 331 insertions, 51 deletions
diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx
index acd2d1ee..6fdea644 100644
--- a/src/core/components/elements/Navbar/NavbarDesktop.jsx
+++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx
@@ -10,15 +10,17 @@ import DesktopView from '../../views/DesktopView'
import dynamic from 'next/dynamic'
import IndoteknikLogo from '@/images/logo.png'
import Category from '@/lib/category/components/Category'
-import { useEffect, useState } from 'react'
+import { useContext, useEffect, useState } from 'react'
import useAuth from '@/core/hooks/useAuth'
import NavbarUserDropdown from './NavbarUserDropdown'
import { getCountCart } from '@/core/utils/cart'
import whatsappUrl from '@/core/utils/whatsappUrl'
import { useRouter } from 'next/router'
-import { getAuth } from '@/core/utils/auth'
+import { getAuth, setAuth } from '@/core/utils/auth'
import { createSlug, getIdFromSlug } from '@/core/utils/slug'
import productApi from '@/lib/product/api/productApi'
+import { useSession } from 'next-auth/react'
+import { AuthContext } from '@/pages/_app'
import { TopBannerSkeleton } from '../Skeleton/TopBannerSkeleton'
const Search = dynamic(() => import('./Search'))
@@ -28,6 +30,7 @@ const TopBanner = dynamic(() => import('./TopBanner'), {
const NavbarDesktop = () => {
const [isOpenCategory, setIsOpenCategory] = useState(false)
+ const {authenticated} = useContext(AuthContext)
const auth = useAuth()
const [cartCount, setCartCount] = useState(0)
@@ -36,7 +39,7 @@ const NavbarDesktop = () => {
const [payloadWA, setPayloadWa] = useState(null)
const router = useRouter()
-
+
useEffect(() => {
const handleCartChange = () => {
const cart = async () => {
diff --git a/src/core/components/elements/Navbar/NavbarUserDropdown.jsx b/src/core/components/elements/Navbar/NavbarUserDropdown.jsx
index 7848124c..b58be493 100644
--- a/src/core/components/elements/Navbar/NavbarUserDropdown.jsx
+++ b/src/core/components/elements/Navbar/NavbarUserDropdown.jsx
@@ -1,13 +1,15 @@
import { deleteAuth } from '@/core/utils/auth'
import Link from '../Link/Link'
import { useRouter } from 'next/router'
+import { signOut, useSession } from 'next-auth/react'
const NavbarUserDropdown = () => {
const router = useRouter()
- const logout = () => {
- deleteAuth()
- router.push('/login')
+ const logout = async () => {
+ deleteAuth().then(() => {
+ router.push('/login')
+ })
}
return (
diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx
index 2e98eb61..e737101a 100644
--- a/src/core/components/layouts/BasicLayout.jsx
+++ b/src/core/components/layouts/BasicLayout.jsx
@@ -6,10 +6,11 @@ import { useEffect, useState } from 'react'
import axios from 'axios'
import odooApi from '@/core/api/odooApi'
import { useRouter } from 'next/router'
-import { getURL } from 'next/dist/shared/lib/utils'
import productApi from '@/lib/product/api/productApi'
-import { getAuth } from '@/core/utils/auth'
+import { getAuth, setAuth } from '@/core/utils/auth'
import { createSlug, getIdFromSlug } from '@/core/utils/slug'
+import { useSession } from 'next-auth/react'
+import { setCookie } from 'cookies-next'
const Navbar = dynamic(() => import('../elements/Navbar/Navbar'))
const AnimationLayout = dynamic(() => import('./AnimationLayout'))
diff --git a/src/core/utils/auth.js b/src/core/utils/auth.js
index cddff2b8..03b20ae2 100644
--- a/src/core/utils/auth.js
+++ b/src/core/utils/auth.js
@@ -1,4 +1,5 @@
import { deleteCookie, getCookie, setCookie } from 'cookies-next'
+import { signOut } from 'next-auth/react'
/**
* Retrieves authentication data from cookie and returns it as an object.
@@ -27,7 +28,8 @@ const setAuth = (user) => {
*
* @returns {boolean} - Returns `true`.
*/
-const deleteAuth = () => {
+const deleteAuth = async() => {
+ await signOut()
deleteCookie('auth')
return true
}
diff --git a/src/lib/auth/components/LoginDesktop.jsx b/src/lib/auth/components/LoginDesktop.jsx
index 8ce2e4e3..42fa8896 100644
--- a/src/lib/auth/components/LoginDesktop.jsx
+++ b/src/lib/auth/components/LoginDesktop.jsx
@@ -3,11 +3,46 @@ import useLogin from '../hooks/useLogin'
import Link from '@/core/components/elements/Link/Link'
import PageContent from '@/lib/content/components/PageContent'
import Alert from '@/core/components/elements/Alert/Alert'
+import { useSession, signIn, SignOut } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useContext, useEffect, useState } from 'react'
+import { getAuth, setAuth } from '@/core/utils/auth'
+import { setCookie } from 'cookies-next'
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
+import Spinner from '@/core/components/elements/Spinner/Spinner'
+import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
+import odooApi from '@/core/api/odooApi'
const LoginDesktop = () => {
- const { handleSubmit, handleChangeInput, isLoading, isValid, alert, emailRef, passwordRef } =
+ const { handleSubmit, handleChangeInput, isLoading, isValid, alert, emailRef, passwordRef, handleGoogleSubmit } =
useLogin()
+ const router = useRouter()
+ const [query, setQuery] = useState(router?.query?.next || '/')
+ const { data: session } = useSession()
+
+ const handleGoogle = async () => {
+ const url = query != '/' ? '/login?source=google&next=' + query : '/login?source=google'
+ await signIn('google', { callbackUrl: url })
+ }
+ useEffect(() => {
+ if (session) {
+ handleGoogleSubmit(session)
+ }
+ }, [session])
+
+ if (router.query.source) {
+ return (
+ <BottomPopup active={true} close=''>
+ <div className='leading-7 text-gray_r-12/80 flex justify-center'>Mohon Tunggu</div>
+ <div className='container flex justify-center my-4'>
+ <LogoSpinner width={48} height={48} />
+ </div>
+ </BottomPopup>
+ )
+ }
+
return (
<DesktopView>
<div className='container mx-auto'>
@@ -60,6 +95,26 @@ const LoginDesktop = () => {
{!isLoading ? 'Masuk' : 'Loading...'}
</button>
</form>
+ <div className='flex items-center mt-3 mb-3'>
+ <hr className='flex-1' />
+ <p className='text-gray-400'>ATAU</p>
+ <hr className='flex-1' />
+ </div>
+
+ <button
+ type='submit'
+ className='border border-gray-500 p-2 rounded-md hover:bg-gray-100 w-full mt-2 flex items-center justify-center gap-x-2'
+ onClick={() => handleGoogle()}
+ >
+ <Image
+ src='/images/icons8-google.svg'
+ alt='google image'
+ className='h-7 w-7'
+ width={10}
+ height={10}
+ />
+ <p>Masuk dengan Google</p>
+ </button>
<div className='text-gray_r-11 mt-10'>
Belum punya akun Indoteknik?{' '}
diff --git a/src/lib/auth/components/LoginMobile.jsx b/src/lib/auth/components/LoginMobile.jsx
index b365330b..095f4174 100644
--- a/src/lib/auth/components/LoginMobile.jsx
+++ b/src/lib/auth/components/LoginMobile.jsx
@@ -5,10 +5,45 @@ import Alert from '@/core/components/elements/Alert/Alert'
import MobileView from '@/core/components/views/MobileView'
import useLogin from '../hooks/useLogin'
+import { useSession, signIn, SignOut } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { setCookie } from 'cookies-next'
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
+import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
+import odooApi from '@/core/api/odooApi'
+import { getAuth } from '@/core/utils/auth'
+
const LoginMobile = () => {
- const { handleSubmit, handleChangeInput, isLoading, isValid, alert, emailRef, passwordRef } =
+ const { handleSubmit, handleChangeInput, isLoading, isValid, alert, emailRef, passwordRef, handleGoogleSubmit } =
useLogin()
+ const router = useRouter()
+ const [query, setQuery] = useState(router?.query?.next || '/')
+ const { data: session } = useSession()
+ const auth = getAuth()
+
+ const handleGoogle = async () => {
+ const url = query != '/' ? '/login?source=google&next=' + query : '/login?source=google'
+ await signIn('google', { callbackUrl: url })
+ }
+ useEffect(() => {
+ if (session) {
+ handleGoogleSubmit(session)
+ }
+ }, [session])
+
+ if (router.query.source) {
+ return (
+ <BottomPopup active={true} close={true}>
+ <div className='leading-7 text-gray_r-12/80 flex justify-center'>Mohon Tunggu</div>
+ <div className='container flex justify-center my-4'>
+ <LogoSpinner width={48} height={48} />
+ </div>
+ </BottomPopup>
+ )
+ }
+
return (
<MobileView>
<div className='p-6 pt-10 flex flex-col items-center min-h-screen'>
@@ -56,6 +91,26 @@ const LoginMobile = () => {
{!isLoading ? 'Masuk' : 'Loading...'}
</button>
</form>
+ <div className='flex items-center mt-3 mb-3'>
+ <hr className='flex-1' />
+ <p className='text-gray-400'>ATAU</p>
+ <hr className='flex-1' />
+ </div>
+
+ <button
+ type='submit'
+ className='border border-gray-500 p-2 rounded-md hover:bg-gray-100 w-full mt-2 flex items-center justify-center gap-x-2'
+ onClick={() => handleGoogle()}
+ >
+ <Image
+ src='/images/icons8-google.svg'
+ alt='google image'
+ className='h-7 w-7'
+ width={10}
+ height={10}
+ />
+ <p>Masuk dengan Google</p>
+ </button>
<div className='text-gray_r-11 mt-4'>
Belum punya akun Indoteknik?{' '}
diff --git a/src/lib/auth/components/RegisterDesktop.jsx b/src/lib/auth/components/RegisterDesktop.jsx
index 93b505ab..a2bc98c2 100644
--- a/src/lib/auth/components/RegisterDesktop.jsx
+++ b/src/lib/auth/components/RegisterDesktop.jsx
@@ -5,6 +5,12 @@ import Alert from '@/core/components/elements/Alert/Alert'
import PageContent from '@/lib/content/components/PageContent'
import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
import ReCAPTCHA from 'react-google-recaptcha'
+import Image from 'next/image'
+import { useEffect } from 'react'
+import { setCookie } from 'cookies-next'
+import { signIn, useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
const RegisterDesktop = () => {
const {
@@ -21,6 +27,31 @@ const RegisterDesktop = () => {
tnd,
setTnd
} = useRegister()
+
+ const { data: session } = useSession()
+ const router = useRouter()
+
+ const handleGoogle = async () => {
+ await signIn('google', { callbackUrl: '/register?source=google' })
+ }
+
+ useEffect(() => {
+ if(session){
+ setCookie('auth', JSON.stringify(session?.odooUser))
+ router.push('/')
+ }
+ },[session])
+
+ if (router.query.source) {
+ return (
+ <BottomPopup active={true} close=''>
+ <div className='leading-7 text-gray_r-12/80 flex justify-center'>Mohon Tunggu</div>
+ <div className='container flex justify-center my-4'>
+ <LogoSpinner width={48} height={48} />
+ </div>
+ </BottomPopup>
+ )
+ }
return (
<DesktopView>
@@ -121,6 +152,26 @@ const RegisterDesktop = () => {
<PageContent path='/register#tnd'></PageContent>
</BottomPopup>
</div>
+ <div className='flex items-center mt-3 mb-3'>
+ <hr className='flex-1' />
+ <p className='text-gray-400'>ATAU</p>
+ <hr className='flex-1' />
+ </div>
+
+ <button
+ type='submit'
+ className='border border-gray-500 p-2 rounded-md hover:bg-gray-100 w-full mt-2 flex items-center justify-center gap-x-2'
+ onClick={() => handleGoogle()}
+ >
+ <Image
+ src='/images/icons8-google.svg'
+ alt='google image'
+ className='h-7 w-7'
+ width={10}
+ height={10}
+ />
+ <p>Daftar dengan Google</p>
+ </button>
<div className='text-gray_r-11 mt-10'>
Sudah punya akun Indoteknik?{' '}
diff --git a/src/lib/auth/components/RegisterMobile.jsx b/src/lib/auth/components/RegisterMobile.jsx
index da6efaf5..2e918a14 100644
--- a/src/lib/auth/components/RegisterMobile.jsx
+++ b/src/lib/auth/components/RegisterMobile.jsx
@@ -7,6 +7,11 @@ import MobileView from '@/core/components/views/MobileView'
import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
import PageContent from '@/lib/content/components/PageContent'
import ReCAPTCHA from 'react-google-recaptcha'
+import { signIn, useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { setCookie } from 'cookies-next'
+import { useEffect } from 'react'
+import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
const RegisterMobile = () => {
const {
@@ -24,6 +29,30 @@ const RegisterMobile = () => {
setTnd
} = useRegister()
+ const { data: session } = useSession()
+ const router = useRouter()
+
+ const handleGoogle = async () => {
+ await signIn('google', { callbackUrl: '/register?source=google' })
+ }
+
+ useEffect(() => {
+ if(session){
+ setCookie('auth', JSON.stringify(session?.odooUser))
+ router.push('/')
+ }
+ },[session])
+
+ if (router.query.source) {
+ return (
+ <BottomPopup active={true} close=''>
+ <div className='leading-7 text-gray_r-12/80 flex justify-center'>Mohon Tunggu</div>
+ <div className='container flex justify-center my-4'>
+ <LogoSpinner width={48} height={48} />
+ </div>
+ </BottomPopup>
+ )
+ }
return (
<MobileView>
<div className='p-6 pt-10 flex flex-col items-center min-h-screen'>
@@ -122,6 +151,27 @@ const RegisterMobile = () => {
</BottomPopup>
</div>
+ <div className='flex items-center mt-3 mb-3'>
+ <hr className='flex-1' />
+ <p className='text-gray-400'>ATAU</p>
+ <hr className='flex-1' />
+ </div>
+
+ <button
+ type='submit'
+ className='border border-gray-500 p-2 rounded-md hover:bg-gray-100 w-full mt-2 flex items-center justify-center gap-x-2'
+ onClick={() => handleGoogle()}
+ >
+ <Image
+ src='/images/icons8-google.svg'
+ alt='google image'
+ className='h-7 w-7'
+ width={10}
+ height={10}
+ />
+ <p>Daftar dengan Google</p>
+ </button>
+
<div className='text-gray_r-11 mt-4'>
Sudah punya akun Indoteknik?{' '}
<Link href='/login' className='inline'>
diff --git a/src/lib/auth/hooks/useLogin.js b/src/lib/auth/hooks/useLogin.js
index 1d5ff43d..34605614 100644
--- a/src/lib/auth/hooks/useLogin.js
+++ b/src/lib/auth/hooks/useLogin.js
@@ -3,6 +3,9 @@ import { setAuth } from '@/core/utils/auth'
import { useRouter } from 'next/router'
import { useRef, useState } from 'react'
import loginApi from '../api/loginApi'
+import odooApi from '@/core/api/odooApi'
+import { setCookie } from 'cookies-next'
+import { useSession } from 'next-auth/react'
const useLogin = () => {
const router = useRouter()
@@ -60,6 +63,19 @@ const useLogin = () => {
}
}
+ const handleGoogleSubmit = async (session) => {
+ const params = {
+ access_token: session.accessToken
+ }
+ const data = await odooApi('POST', '/api/v1/user/validate-sso', params)
+ if (data.isAuth) {
+ session.odooUser = data.user
+ setCookie('auth', JSON.stringify(session?.odooUser))
+ router.push(router?.query?.next ?? '/')
+ return
+ }
+ }
+
return {
handleChangeInput,
handleSubmit,
@@ -67,7 +83,8 @@ const useLogin = () => {
isValid,
alert,
emailRef,
- passwordRef
+ passwordRef,
+ handleGoogleSubmit
}
}
diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx
index 03147219..7f23b94b 100644
--- a/src/pages/_app.jsx
+++ b/src/pages/_app.jsx
@@ -6,16 +6,29 @@ import { AnimatePresence, motion } from 'framer-motion'
import { Toaster } from 'react-hot-toast'
import { QueryClient, QueryClientProvider } from 'react-query'
import useDevice from '@/core/hooks/useDevice'
-import { useEffect, useState } from 'react'
+import { createContext, useContext, useEffect, useState } from 'react'
import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
+import { SessionProvider } from 'next-auth/react'
+import { getAuth } from '@/core/utils/auth'
const queryClient = new QueryClient()
-function MyApp({ Component, pageProps }) {
+export const AuthContext = createContext({
+ authenticated : false,
+ setAuthenticated : (auth) => {}
+})
+
+function MyApp({ Component, pageProps: { session, ...pageProps } }) {
const router = useRouter()
const { isMobile } = useDevice()
const [animateLoader, setAnimateLoader] = useState(false)
+ const [authenticated, setAuthenticated] = useState(null)
+ const auth = getAuth()
+
+ // useEffect(() => {
+ // setAuthenticated(auth)
+ // }, [auth])
useEffect(() => {
const handleRouteChangeStart = () => setAnimateLoader(true)
@@ -48,41 +61,43 @@ function MyApp({ Component, pageProps }) {
}, [isMobile])
return (
- <>
- <AnimatePresence>
- {animateLoader && (
- <motion.div
- initial={{ opacity: 0 }}
- animate={{ opacity: 1 }}
- exit={{ opacity: 0 }}
- transition={{
- duration: 0.1
- }}
- className='fixed w-screen h-screen z-[500] bg-white flex justify-center items-center'
- >
- <LogoSpinner />
- </motion.div>
- )}
- </AnimatePresence>
- <Toaster
- position='top-center'
- containerStyle={toasterStyle}
- toastOptions={{
- duration: 3000,
- className: 'border border-gray_r-8'
- }}
- />
- <NextProgress color='#F01C21' options={{ showSpinner: false }} />
- <QueryClientProvider client={queryClient}>
- <AnimatePresence
- mode='popLayout'
- initial={false}
- onExitComplete={() => window.scrollTo(0, 0)}
- >
- {!animateLoader && <Component {...pageProps} key={router.asPath} />}
+ // <AuthContext.Provider value={{authenticated, setAuthenticated}}>
+ <SessionProvider session={session}>
+ <AnimatePresence>
+ {animateLoader && (
+ <motion.div
+ initial={{ opacity: 0 }}
+ animate={{ opacity: 1 }}
+ exit={{ opacity: 0 }}
+ transition={{
+ duration: 0.1
+ }}
+ className='fixed w-screen h-screen z-[500] bg-white flex justify-center items-center'
+ >
+ <LogoSpinner />
+ </motion.div>
+ )}
</AnimatePresence>
- </QueryClientProvider>
- </>
+ <Toaster
+ position='top-center'
+ containerStyle={toasterStyle}
+ toastOptions={{
+ duration: 3000,
+ className: 'border border-gray_r-8'
+ }}
+ />
+ <NextProgress color='#F01C21' options={{ showSpinner: false }} />
+ <QueryClientProvider client={queryClient}>
+ <AnimatePresence
+ mode='popLayout'
+ initial={false}
+ onExitComplete={() => window.scrollTo(0, 0)}
+ >
+ {!animateLoader && <Component {...pageProps} key={router.asPath} />}
+ </AnimatePresence>
+ </QueryClientProvider>
+ </SessionProvider>
+ // </AuthContext.Provider>
)
}
diff --git a/src/pages/api/auth/[...nextauth].js b/src/pages/api/auth/[...nextauth].js
new file mode 100644
index 00000000..3c433167
--- /dev/null
+++ b/src/pages/api/auth/[...nextauth].js
@@ -0,0 +1,26 @@
+import odooApi from '@/core/api/odooApi'
+import NextAuth from 'next-auth/next'
+import GoogleProvider from 'next-auth/providers/google'
+
+export default NextAuth({
+ providers: [
+ GoogleProvider({
+ clientId: process.env.GOOGLE_CLIENT_ID,
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET
+ })
+ ],
+ callbacks: {
+ async jwt({ token, account }) {
+ if (account) {
+ token.accessToken = account.access_token
+ }
+ return token
+ },
+ async session({ session, token, user }) {
+ session.accessToken = token.accessToken
+
+ return session
+ }
+ },
+ secret: process.env.JWT_SECRET
+})
diff --git a/src/pages/my/menu.jsx b/src/pages/my/menu.jsx
index c8e1e7e9..fb8e6b03 100644
--- a/src/pages/my/menu.jsx
+++ b/src/pages/my/menu.jsx
@@ -5,15 +5,18 @@ import useAuth from '@/core/hooks/useAuth'
import { deleteAuth } from '@/core/utils/auth'
import IsAuth from '@/lib/auth/components/IsAuth'
import { ChevronRightIcon, UserIcon } from '@heroicons/react/24/solid'
+import { signOut, useSession } from 'next-auth/react'
import { useRouter } from 'next/router'
export default function Menu() {
const auth = useAuth()
const router = useRouter()
+ const { data: session } = useSession()
const logout = () => {
- deleteAuth()
- router.push('/login')
+ deleteAuth().then(() => {
+ router.push('/login')
+ })
}
return (
@@ -62,7 +65,7 @@ export default function Menu() {
<LinkItem href='/my/address'>Daftar Alamat</LinkItem>
</div>
- <div onClick={logout} className='p-4 mt-2'>
+ <div onClick={() => logout()} className='p-4 mt-2'>
<button className='w-full btn-red'>Keluar Akun</button>
</div>
</div>