(App.tsx): add support for auto login feature to improve user experience and reduce login friction

📝 (authContext.tsx): remove unused autoLogin function and refactor getUser function to improve code readability and maintainability
📝 (authContext.tsx): add getUser function to retrieve user data and improve user authentication flow
📝 (auth.ts): add getUser function to AuthContextType to improve type safety and provide a clear API for accessing user data
This commit is contained in:
cristhianzl 2024-04-09 15:45:28 -03:00
commit 82b80842dd
3 changed files with 46 additions and 51 deletions

View file

@ -1,9 +1,8 @@
import { useContext, useEffect, useState } from "react";
import "reactflow/dist/style.css";
import "./App.css";
import { ErrorBoundary } from "react-error-boundary";
import { useNavigate } from "react-router-dom";
import "reactflow/dist/style.css";
import "./App.css";
import ErrorAlert from "./alerts/error";
import NoticeAlert from "./alerts/notice";
import SuccessAlert from "./alerts/success";
@ -15,7 +14,7 @@ import {
FETCH_ERROR_MESSAGE,
} from "./constants/constants";
import { AuthContext } from "./contexts/authContext";
import { getGlobalVariables, getHealth } from "./controllers/API";
import { autoLogin, getGlobalVariables, getHealth } from "./controllers/API";
import Router from "./routes";
import useAlertStore from "./stores/alertStore";
import { useDarkStore } from "./stores/darkStore";
@ -38,8 +37,10 @@ export default function App() {
removeFromTempNotificationList(id);
};
const { isAuthenticated } = useContext(AuthContext);
const { isAuthenticated, login, setUserData, setAutoLogin, getUser } =
useContext(AuthContext);
const refreshFlows = useFlowsManagerStore((state) => state.refreshFlows);
const setLoading = useAlertStore((state) => state.setLoading);
const fetchApiData = useStoreStore((state) => state.fetchApiData);
const getTypes = useTypesStore((state) => state.getTypes);
const refreshVersion = useDarkStore((state) => state.refreshVersion);
@ -53,26 +54,46 @@ export default function App() {
const [isLoadingHealth, setIsLoadingHealth] = useState(false);
useEffect(() => {
refreshStars();
refreshVersion();
const isLoginPage = location.pathname.includes("login");
const fetchData = async () => {
if (isAuthenticated) {
try {
await getTypes();
refreshFlows();
const res = await getGlobalVariables();
setGlobalVariables(res);
checkHasStore();
fetchApiData();
} catch (error) {
console.error("Failed to fetch data:", error);
autoLogin()
.then(async (user) => {
if (user && user["access_token"]) {
user["refresh_token"] = "auto";
login(user["access_token"]);
setUserData(user);
setAutoLogin(true);
setLoading(false);
await Promise.all([refreshStars(), refreshVersion(), fetchData()]);
}
}
};
fetchData();
})
.catch(async () => {
setAutoLogin(false);
if (isAuthenticated && !isLoginPage) {
getUser();
await Promise.all([refreshStars(), refreshVersion(), fetchData()]);
} else {
setLoading(false);
useFlowsManagerStore.setState({ isLoading: false });
}
});
}, [isAuthenticated]);
const fetchData = async () => {
if (isAuthenticated) {
try {
await getTypes();
refreshFlows();
const res = await getGlobalVariables();
setGlobalVariables(res);
checkHasStore();
fetchApiData();
} catch (error) {
console.error("Failed to fetch data:", error);
}
}
};
useEffect(() => {
checkApplicationHealth();
// Timer to call getHealth every 5 seconds

View file

@ -1,13 +1,8 @@
import { createContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import Cookies from "universal-cookie";
import {
autoLogin as autoLoginApi,
getLoggedUser,
requestLogout,
} from "../controllers/API";
import { getLoggedUser, requestLogout } from "../controllers/API";
import useAlertStore from "../stores/alertStore";
import useFlowsManagerStore from "../stores/flowsManagerStore";
import { Users } from "../types/api";
import { AuthContextType } from "../types/contexts/auth";
@ -26,6 +21,7 @@ const initialValue: AuthContextType = {
setApiKey: () => {},
apiKey: null,
storeApiKey: () => {},
getUser: () => {},
};
export const AuthContext = createContext<AuthContextType>(initialValue);
@ -61,30 +57,6 @@ export function AuthProvider({ children }): React.ReactElement {
}
}, []);
useEffect(() => {
const isLoginPage = location.pathname.includes("login");
autoLoginApi()
.then((user) => {
if (user && user["access_token"]) {
user["refresh_token"] = "auto";
login(user["access_token"]);
setUserData(user);
setAutoLogin(true);
setLoading(false);
}
})
.catch((error) => {
setAutoLogin(false);
if (isAuthenticated && !isLoginPage) {
getUser();
} else {
setLoading(false);
useFlowsManagerStore.setState({ isLoading: false });
}
});
}, [autoLogin]);
function getUser() {
getLoggedUser()
.then((user) => {
@ -145,6 +117,7 @@ export function AuthProvider({ children }): React.ReactElement {
setApiKey,
apiKey,
storeApiKey,
getUser,
}}
>
{children}

View file

@ -15,4 +15,5 @@ export type AuthContextType = {
apiKey: string | null;
setApiKey: (apiKey: string | null) => void;
storeApiKey: (apiKey: string) => void;
getUser: () => void;
};