115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
import React, { createContext, ReactNode, useContext, useEffect, useMemo, useState } from "react";
|
|
import { useNavigate } from "react-router";
|
|
import { Credentials, TokenData, User } from "./Types";
|
|
import { fetchUserById, logIn, tokenStatus } from "./Api";
|
|
import jwt_decode from "jwt-decode";
|
|
|
|
interface AuthContextType {
|
|
user?: User;
|
|
loading: boolean;
|
|
isAirline: boolean;
|
|
error?: any;
|
|
login: (credentials: Credentials) => void;
|
|
signUp: (email: string, name: string, password: string) => void;
|
|
logout: () => void;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextType>(
|
|
{} as AuthContextType
|
|
);
|
|
|
|
export function AuthProvider({
|
|
children,
|
|
}: {
|
|
children: ReactNode;
|
|
}): JSX.Element {
|
|
const [user, setUser] = useState<User>();
|
|
const [error, setError] = useState<any>();
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
const [loadingInitial, setLoadingInitial] = useState<boolean>(true);
|
|
const [isAirline, setIsAirline] = useState(false);
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (error) setError(undefined);
|
|
}, [window.location.pathname]);
|
|
|
|
useEffect(() => {
|
|
const existingToken = localStorage.getItem("token");
|
|
if (existingToken) {
|
|
let airline
|
|
try {
|
|
airline = (jwt_decode(existingToken) as TokenData).airline;
|
|
setIsAirline(airline)
|
|
} catch (err) {
|
|
setLoadingInitial(false);
|
|
logout()
|
|
return;
|
|
}
|
|
|
|
tokenStatus(existingToken)
|
|
.then((res) => fetchUserById(res.id)
|
|
.then((res) => setUser(res))
|
|
.catch((_error) => { })
|
|
.finally(() => setLoadingInitial(false))
|
|
)
|
|
.catch((_error) => {
|
|
setLoadingInitial(false)
|
|
logout()
|
|
})
|
|
// .finally(() => setLoadingInitial(false));
|
|
} else {
|
|
setLoadingInitial(false)
|
|
}
|
|
}, []);
|
|
|
|
function login(credentials: Credentials) {
|
|
setLoading(true);
|
|
const tokens = logIn(credentials)
|
|
.then((x) => {
|
|
localStorage.setItem("token", x.access_token);
|
|
const airline = (jwt_decode(x.access_token) as TokenData).airline;
|
|
setIsAirline(airline)
|
|
const user = fetchUserById(x.user_id as number)
|
|
.then(y => {
|
|
setUser(y);
|
|
navigate("/home")
|
|
})
|
|
.catch((error) => setError(error))
|
|
.finally(() => setLoading(false));
|
|
})
|
|
.catch((error) => setError(error))
|
|
// .finally(() => setLoading(false));
|
|
}
|
|
|
|
function signUp(email: string, name: string, password: string) { }
|
|
|
|
function logout() {
|
|
localStorage.removeItem("token");
|
|
setUser(undefined);
|
|
navigate("/login")
|
|
}
|
|
|
|
const memoedValue = useMemo(
|
|
() => ({
|
|
user,
|
|
loading,
|
|
isAirline,
|
|
error,
|
|
login,
|
|
signUp,
|
|
logout,
|
|
}),
|
|
[user, isAirline, loading, error]
|
|
);
|
|
|
|
return (
|
|
<AuthContext.Provider value={memoedValue}>
|
|
{!loadingInitial && children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export default function useAuth() {
|
|
return useContext(AuthContext);
|
|
} |