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( {} as AuthContextType ); export function AuthProvider({ children, }: { children: ReactNode; }): JSX.Element { const [user, setUser] = useState(); const [error, setError] = useState(); const [loading, setLoading] = useState(false); const [loadingInitial, setLoadingInitial] = useState(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 ( {!loadingInitial && children} ); } export default function useAuth() { return useContext(AuthContext); }