2023-07-25 20:27:29 +03:00
|
|
|
import { createContext, useCallback, useContext, useLayoutEffect, useState } from 'react';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-25 20:27:29 +03:00
|
|
|
import { type ErrorInfo } from '../components/BackendError';
|
|
|
|
import useLocalStorage from '../hooks/useLocalStorage';
|
2023-07-26 23:11:00 +03:00
|
|
|
import { type DataCallback, getAuth, postLogin, postLogout, postSignup } from '../utils/backendAPI';
|
|
|
|
import { ICurrentUser, IUserLoginData, IUserProfile, IUserSignupData } from '../utils/models';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface IAuthContext {
|
|
|
|
user: ICurrentUser | undefined
|
2023-07-26 23:11:00 +03:00
|
|
|
login: (data: IUserLoginData, callback?: DataCallback) => void
|
|
|
|
logout: (callback?: DataCallback) => void
|
|
|
|
signup: (data: IUserSignupData, callback?: DataCallback<IUserProfile>) => void
|
2023-07-15 17:46:19 +03:00
|
|
|
loading: boolean
|
|
|
|
error: ErrorInfo
|
|
|
|
setError: (error: ErrorInfo) => void
|
|
|
|
}
|
|
|
|
|
2023-07-25 00:20:37 +03:00
|
|
|
const AuthContext = createContext<IAuthContext | null>(null);
|
|
|
|
export const useAuth = () => {
|
|
|
|
const context = useContext(AuthContext);
|
|
|
|
if (!context) {
|
|
|
|
throw new Error(
|
|
|
|
'useAuth has to be used within <AuthState.Provider>'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return context;
|
|
|
|
}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface AuthStateProps {
|
|
|
|
children: React.ReactNode
|
|
|
|
}
|
|
|
|
|
|
|
|
export const AuthState = ({ children }: AuthStateProps) => {
|
|
|
|
const [user, setUser] = useLocalStorage<ICurrentUser | undefined>('user', undefined);
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const [error, setError] = useState<ErrorInfo>(undefined);
|
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
const reload = useCallback(
|
|
|
|
(callback?: () => void) => {
|
|
|
|
getAuth({
|
2023-07-25 20:27:29 +03:00
|
|
|
onError: () => { setUser(undefined); },
|
2023-07-26 23:11:00 +03:00
|
|
|
onSuccess: currentUser => {
|
|
|
|
if (currentUser.id) {
|
|
|
|
setUser(currentUser);
|
2023-07-15 17:57:25 +03:00
|
|
|
} else {
|
2023-07-26 23:11:00 +03:00
|
|
|
setUser(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
}
|
2023-07-26 23:11:00 +03:00
|
|
|
if (callback) callback();
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}, [setUser]
|
|
|
|
);
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
function login(data: IUserLoginData, callback?: DataCallback) {
|
2023-07-15 17:46:19 +03:00
|
|
|
setError(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
postLogin({
|
2023-07-26 23:11:00 +03:00
|
|
|
data: data,
|
2023-07-15 17:57:25 +03:00
|
|
|
showError: true,
|
2023-07-26 23:11:00 +03:00
|
|
|
setLoading: setLoading,
|
2023-07-25 20:27:29 +03:00
|
|
|
onError: error => { setError(error); },
|
2023-07-26 23:11:00 +03:00
|
|
|
onSuccess: newData => reload(() => { if (callback) callback(newData); })
|
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
function logout(callback?: DataCallback) {
|
2023-07-15 17:46:19 +03:00
|
|
|
setError(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
postLogout({
|
|
|
|
showError: true,
|
2023-07-26 23:11:00 +03:00
|
|
|
onSuccess: newData => reload(() => { if (callback) callback(newData); })
|
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
function signup(data: IUserSignupData, callback?: DataCallback<IUserProfile>) {
|
2023-07-15 17:46:19 +03:00
|
|
|
setError(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
postSignup({
|
2023-07-26 23:11:00 +03:00
|
|
|
data: data,
|
2023-07-15 17:57:25 +03:00
|
|
|
showError: true,
|
2023-07-26 23:11:00 +03:00
|
|
|
setLoading: setLoading,
|
2023-07-25 20:27:29 +03:00
|
|
|
onError: error => { setError(error); },
|
2023-07-26 23:11:00 +03:00
|
|
|
onSuccess: newData => reload(() => { if (callback) callback(newData); })
|
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-25 00:20:37 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-07-26 23:11:00 +03:00
|
|
|
reload();
|
|
|
|
}, [reload])
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
return (
|
|
|
|
<AuthContext.Provider
|
|
|
|
value={{ user, login, logout, signup, loading, error, setError }}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</AuthContext.Provider>
|
|
|
|
);
|
2023-07-25 20:27:29 +03:00
|
|
|
};
|