import { FC, useState, useEffect, createContext, useContext, useRef, Dispatch, SetStateAction, } from 'react' import {LayoutSplashScreen} from '../../../../_res/layout/core' import {AuthModel, UserModel} from './_models' import * as authHelper from './AuthHelpers' import {getUserByToken} from './_requests' import {WithChildren} from '../../../../_res/helpers' type AuthContextProps = { auth: AuthModel | undefined saveAuth: (auth: AuthModel | undefined) => void currentUser: UserModel | undefined setCurrentUser: Dispatch> logout: () => void } const initAuthContextPropsState = { auth: authHelper.getAuth(), saveAuth: () => {}, currentUser: undefined, setCurrentUser: () => {}, logout: () => {}, } const AuthContext = createContext(initAuthContextPropsState) const useAuth = () => { return useContext(AuthContext) } const AuthProvider: FC = ({children}) => { const [auth, setAuth] = useState(authHelper.getAuth()) const [currentUser, setCurrentUser] = useState() const saveAuth = (auth: AuthModel | undefined) => { setAuth(auth) if (auth) { authHelper.setAuth(auth) } else { authHelper.removeAuth() } } const logout = () => { saveAuth(undefined) setCurrentUser(undefined) } return ( {children} ) } const AuthInit: FC = ({children}) => { const {auth, logout, setCurrentUser} = useAuth() const didRequest = useRef(false) const [showSplashScreen, setShowSplashScreen] = useState(true) // We should request user by authToken (IN OUR EXAMPLE IT'S API_TOKEN) before rendering the application useEffect(() => { const requestUser = async (apiToken: string) => { try { if (!didRequest.current) { // const {data} = await getUserByToken(apiToken) // if (data) { // setCurrentUser(data) // } if (localStorage.getItem('kt-auth-react-v')) { setCurrentUser(auth.profile) } } } catch (error) { console.error(error) if (!didRequest.current) { logout() } } finally { setShowSplashScreen(false) } return () => (didRequest.current = true) } if (auth && auth.session_token) { requestUser(auth.session_token) } else { logout() setShowSplashScreen(false) } // eslint-disable-next-line }, []) return showSplashScreen ? : <>{children} } export {AuthProvider, AuthInit, useAuth}