181 lines
4.0 KiB
TypeScript
181 lines
4.0 KiB
TypeScript
'use client'
|
|
|
|
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'
|
|
|
|
import { User } from '../../payload-types'
|
|
import { gql, USER } from './gql'
|
|
import { rest } from './rest'
|
|
import { AuthContext, Create, ForgotPassword, Login, Logout, ResetPassword } from './types'
|
|
|
|
const Context = createContext({} as AuthContext)
|
|
|
|
export const AuthProvider: React.FC<{ children: React.ReactNode; api?: 'rest' | 'gql' }> = ({
|
|
children,
|
|
api = 'rest',
|
|
}) => {
|
|
const [user, setUser] = useState<User | null>()
|
|
|
|
const create = useCallback<Create>(
|
|
async args => {
|
|
if (api === 'rest') {
|
|
const user = await rest(`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users`, args)
|
|
setUser(user)
|
|
return user
|
|
}
|
|
|
|
if (api === 'gql') {
|
|
const { createUser: user } = await gql(`mutation {
|
|
createUser(data: { email: "${args.email}", password: "${args.password}", firstName: "${args.firstName}", lastName: "${args.lastName}" }) {
|
|
${USER}
|
|
}
|
|
}`)
|
|
|
|
setUser(user)
|
|
return user
|
|
}
|
|
},
|
|
[api],
|
|
)
|
|
|
|
const login = useCallback<Login>(
|
|
async args => {
|
|
if (api === 'rest') {
|
|
const user = await rest(`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users/login`, args)
|
|
setUser(user)
|
|
return user
|
|
}
|
|
|
|
if (api === 'gql') {
|
|
const { loginUser } = await gql(`mutation {
|
|
loginUser(email: "${args.email}", password: "${args.password}") {
|
|
user {
|
|
${USER}
|
|
}
|
|
exp
|
|
}
|
|
}`)
|
|
|
|
setUser(loginUser?.user)
|
|
return loginUser?.user
|
|
}
|
|
},
|
|
[api],
|
|
)
|
|
|
|
const logout = useCallback<Logout>(async () => {
|
|
if (api === 'rest') {
|
|
await rest(`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users/logout`)
|
|
setUser(null)
|
|
return
|
|
}
|
|
|
|
if (api === 'gql') {
|
|
await gql(`mutation {
|
|
logoutUser
|
|
}`)
|
|
|
|
setUser(null)
|
|
}
|
|
}, [api])
|
|
|
|
// On mount, get user and set
|
|
useEffect(() => {
|
|
const fetchMe = async () => {
|
|
if (api === 'rest') {
|
|
const user = await rest(
|
|
`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users/me`,
|
|
{},
|
|
{
|
|
method: 'GET',
|
|
},
|
|
)
|
|
setUser(user)
|
|
}
|
|
|
|
if (api === 'gql') {
|
|
const { meUser } = await gql(`query {
|
|
meUser {
|
|
user {
|
|
${USER}
|
|
}
|
|
exp
|
|
}
|
|
}`)
|
|
|
|
setUser(meUser.user)
|
|
}
|
|
}
|
|
|
|
fetchMe()
|
|
}, [api])
|
|
|
|
const forgotPassword = useCallback<ForgotPassword>(
|
|
async args => {
|
|
if (api === 'rest') {
|
|
const user = await rest(
|
|
`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users/forgot-password`,
|
|
args,
|
|
)
|
|
setUser(user)
|
|
return user
|
|
}
|
|
|
|
if (api === 'gql') {
|
|
const { forgotPasswordUser } = await gql(`mutation {
|
|
forgotPasswordUser(email: "${args.email}")
|
|
}`)
|
|
|
|
return forgotPasswordUser
|
|
}
|
|
},
|
|
[api],
|
|
)
|
|
|
|
const resetPassword = useCallback<ResetPassword>(
|
|
async args => {
|
|
if (api === 'rest') {
|
|
const user = await rest(
|
|
`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users/reset-password`,
|
|
args,
|
|
)
|
|
setUser(user)
|
|
return user
|
|
}
|
|
|
|
if (api === 'gql') {
|
|
const { resetPasswordUser } = await gql(`mutation {
|
|
resetPasswordUser(password: "${args.password}", token: "${args.token}") {
|
|
user {
|
|
${USER}
|
|
}
|
|
}
|
|
}`)
|
|
|
|
setUser(resetPasswordUser.user)
|
|
return resetPasswordUser.user
|
|
}
|
|
},
|
|
[api],
|
|
)
|
|
|
|
return (
|
|
<Context.Provider
|
|
value={{
|
|
user,
|
|
setUser,
|
|
login,
|
|
logout,
|
|
create,
|
|
resetPassword,
|
|
forgotPassword,
|
|
}}
|
|
>
|
|
{children}
|
|
</Context.Provider>
|
|
)
|
|
}
|
|
|
|
type UseAuth<T = User> = () => AuthContext // eslint-disable-line no-unused-vars
|
|
|
|
export const useAuth: UseAuth = () => useContext(Context)
|