Skip to content

Commit

Permalink
Refactor and Optimize AuthProvider in Frontend
Browse files Browse the repository at this point in the history
- Streamlined state management in AuthProvider by consolidating the use of `useState` and `useCookies` for a single source of truth.
- Simplified state updates in `executeAuthAction` to reduce unnecessary re-renders. Considered the use of a reducer for grouped state management.
- Enhanced Axios interceptor setup in `useEffect` for better handling of authorization headers, including cleanup logic to prevent memory leaks.
- Optimized `resetLogoutTimer` and `logout` functions to reduce complexity and dependency recalculations.
- Eliminated redundant `loginStatus` state, relying on individual states like `isLoggedIn`, `authUser`, etc.
- Adjusted `useEffect` hooks to respond only to relevant changes in cookies, preventing unnecessary updates.
- Updated `useEffect` dependency arrays to include only necessary dependencies and improve performance.
- Removed the debugging `useEffect` in preparation for production deployment.

These changes aim to enhance the performance, readability, and maintainability of the frontend authentication logic, ensuring a more efficient and reliable user authentication experience.
  • Loading branch information
reedoooo committed Jan 12, 2024
1 parent 383adf2 commit 877660a
Show file tree
Hide file tree
Showing 92 changed files with 4,534 additions and 2,822 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
251 changes: 155 additions & 96 deletions src/Main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import {
LoginPage,
} from './pages';
import {
useUserContext,
useCollectionStore,
useDeckStore,
useAuthContext,
usePageContext,
useMode,
} from './context';
import { AppContainer } from './pages/pageStyles/StyledComponents';
import { useCookies } from 'react-cookie';
import useDialog from './context/hooks/useDialog';
import useSnackBar from './context/hooks/useSnackBar';

const Main = () => {
const [cookies] = useCookies(['authUser']);
Expand All @@ -40,57 +40,60 @@ const Main = () => {
const { loadingStatus, returnDisplay, setLoading } = usePageContext();
const { fetchAllCollectionsForUser } = useCollectionStore();
const { fetchAllDecksForUser } = useDeckStore();
// const navigate = useNavigate(); // Use the useNavigate hook
const handleSnackBar = useSnackBar()[1];

const [showLoginDialog, setShowLoginDialog] = useState(!isLoggedIn);
const { isLoginDialogOpen, openLoginDialog, closeLoginDialog } =
useDialog(handleSnackBar); // Assuming false represents the logged-in state

useEffect(() => {
if (!isLoggedIn) return;
if (!authUser) return;

const fetchData = async () => {
if (isLoggedIn && authUser) {
setLoading('isPageLoading', true);
try {
await Promise.all([
fetchAllCollectionsForUser(),
fetchAllDecksForUser(),
]);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading('isPageLoading', false);
}
}
};
fetchData();
}, [isLoggedIn, authUser, fetchAllCollectionsForUser, fetchAllDecksForUser]);
const routeConfig = [
{ path: '/', component: HomePage, isPrivate: false },
{ path: '/home', component: HomePage, isPrivate: false },
{ path: '/store', component: StorePage, isPrivate: false },
{ path: '/cart', component: CartPage, isPrivate: true },
{ path: '/userprofile', component: ProfilePage, isPrivate: true },
{ path: '/collection', component: CollectionPage, isPrivate: true },
{ path: '/deckbuilder', component: DeckBuilderPage, isPrivate: true },
{ path: '/profile', component: ProfilePage, isPrivate: false },
{ path: '/login', component: LoginPage, isPrivate: false },
{ path: '*', component: NotFoundPage, isPrivate: false },
];
// const [showLoginDialog, setShowLoginDialog] = useState(!isLoggedIn);
const fetchData = async () => {
setLoading('isPageLoading', true);
try {
await Promise.all([fetchAllCollectionsForUser(), fetchAllDecksForUser()]);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading('isPageLoading', false);
}
};
const renderHelmet = () => {
console.log('Rendering helmet...');
return (
<Helmet>
{/* Basic */}
<title>Your Website Title</title>
<meta name="description" content="Description of your site or page" />
<link rel="canonical" href="http://mysite.com/example" />
<link rel="icon" type="image/png" href="/favicon.png" sizes="16x16" />

// Manage logout timer reset
useEffect(() => {
if (isLoggedIn) resetLogoutTimer();
}, [isLoggedIn, resetLogoutTimer]);
{/* SEO */}
<meta name="keywords" content="your, tags" />
{/* Social Media */}
<meta property="og:title" content="Title Here" />
<meta property="og:description" content="Description Here" />
<meta
property="og:image"
content="http://mysite.com/path/to/image.jpg"
/>
<meta property="og:url" content="http://mysite.com" />
<meta name="twitter:card" content="summary_large_image" />

// Manage login dialog visibility
useEffect(() => {
if (isLoggedIn) {
setShowLoginDialog(false);
}
if (!isLoggedIn) {
setShowLoginDialog(true);
}
setShowLoginDialog(window.location.pathname === '/login' || !isLoggedIn);
}, [isLoggedIn]);
// useEffect(() => {
// // Redirects user to the homepage if they are already logged in
// if (isLoggedIn) {
// navigate('/');
// }
// }, [isLoggedIn, navigate]); // Add navigate to the dependency array
{/* Responsive and mobile */}
<meta name="viewport" content="width=device-width, initial-scale=1" />

return (
<>
<Helmet>
{/* Additional links and styles */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
Expand All @@ -101,59 +104,72 @@ const Main = () => {
href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap"
rel="stylesheet"
/>

{/* Specify language and character set */}
<html lang="en" />
<meta charSet="utf-8" />

{/* Scripts */}
{/* Example: Add a script needed for a service or functionality */}
{/* <script src="https://cdn.service.com/library.js"></script> */}
</Helmet>
{/* {loadingStatus?.isPageLoading && returnDisplay()} */}
{!authUser ? (
<LoginDialog
open={showLoginDialog}
onClose={() => setShowLoginDialog(false)}
onLogin={() => setShowLoginDialog(false)} // This might need to be updated based on the login logic
);
};
const renderRoutes = () => (
<Routes>
{routeConfig.map(({ path, component: Component, isPrivate }, index) => (
<Route
key={index}
path={path}
element={
isPrivate ? (
<PrivateRoute>
<Component />
</PrivateRoute>
) : (
<Component />
)
}
/>
))}
</Routes>
);
const renderLoginDialog = () => {
console.log('Auth user not found, rendering login dialog...', authUser);
return <LoginDialog />;
};
// useEffect(() => {
// if (isLoggedIn) {
// resetLogoutTimer();
// fetchData(); // Fetch data when the user is logged in
// }
// }, [isLoggedIn, resetLogoutTimer, fetchData]); // Remove authUser from dependencies

// useEffect(() => {
// // Manage login dialog based on isLoggedIn status
// if (isLoggedIn && isLoginDialogOpen) {
// closeLoginDialog();
// } else if (!isLoggedIn && !isLoginDialogOpen) {
// openLoginDialog();
// }
// }, [isLoggedIn, isLoginDialogOpen, openLoginDialog, closeLoginDialog]);

return (
<>
{renderHelmet()}
{!authUser ? (
renderLoginDialog()
) : (
<AppContainer>
{/* {authUser} */}

<Header />
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/home" element={<HomePage />} />
<Route path="/store" element={<StorePage />} />
<Route
path="/cart"
element={
<PrivateRoute>
<CartPage />
</PrivateRoute>
}
/>
<Route
path="/userprofile"
element={
<PrivateRoute>
<ProfilePage />
</PrivateRoute>
}
/>
<Route
path="/collection"
element={
<PrivateRoute>
<CollectionPage />
</PrivateRoute>
}
/>
<Route
path="/deckbuilder"
element={
<PrivateRoute>
<DeckBuilderPage />
</PrivateRoute>
}
/>
<Route path="/profile" element={<ProfilePage />} />
<Route path="/login" element={<LoginPage />} />
{/* <Route path="/threejs" element={<ThreeJsCube />} /> */}
{/* <Route path="/cardDeck" element={<CardDeckAnimation />} /> */}
<Route path="*" element={<NotFoundPage />} />{' '}
</Routes>
{/* {returnDisplay()} */}
{renderRoutes()}
{/* <Routes>
{renderRoutes(routeConfig)} {/* Use the renderRoutes function */}
{/* </Routes> */}
{/* {snackbar} */}
</AppContainer>
)}
</>
Expand All @@ -168,3 +184,46 @@ export default Main;
// if (logoutTimerRef.current) clearTimeout(logoutTimerRef.current);
// };
// }, [userId, resetLogoutTimer]);
// // Manage loading display
// useEffect(() => {
// if (!isLoggedIn) return;
// if (!authUser) return;

// const fetchData = async () => {
// if (isLoggedIn && authUser) {
// setLoading('isPageLoading', true);
// try {
// await Promise.all([
// fetchAllCollectionsForUser(),
// fetchAllDecksForUser(),
// ]);
// } catch (error) {
// console.error('Error fetching data:', error);
// } finally {
// setLoading('isPageLoading', false);
// }
// }
// };
// fetchData();
// }, [isLoggedIn, authUser, fetchAllCollectionsForUser, fetchAllDecksForUser]);
// // Manage logout timer reset
// useEffect(() => {
// if (isLoggedIn) resetLogoutTimer();
// }, [isLoggedIn, resetLogoutTimer]);
// // Manage login dialog visibility
// useEffect(() => {
// if (isLoggedIn && isLoginDialogOpen) {
// console.log('Closing login dialog...');
// closeLoginDialog();
// }
// if (!isLoggedIn && !isLoginDialogOpen) {
// console.log('Opening login dialog...');
// openLoginDialog();
// }
// // if (!isLoggedIn) {
// // }
// // setShowLoginDialog(
// // // window.location.pathname === '/login' ||
// // !isLoggedIn
// // );
// }, [isLoggedIn]);
Loading

0 comments on commit 877660a

Please sign in to comment.