-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement Responsive Chart Component with Aspect Ratio
- Introduced `CardLinearChart` component using the `nivo` library to render card data as a linear chart. - Added `ResponsiveSquare` component to maintain aspect ratio and responsiveness of the chart across various device sizes. - Integrated `usePageContext` for managing loading states during data fetch and rendering. - Enhanced `CardChart` container to dynamically calculate and update chart dimensions on window resize for improved UX. - Applied aspect ratio control in `CardChart` to ensure the chart stays within container boundaries without distortion. - Styled the components using MUI `styled` API with theme considerations for consistent UX. - Ensured error handling with `ErrorBoundary` for a safer, more reliable application experience. The above enhancements aim to provide a seamless and visually consistent charting experience across the app while ensuring data is represented accurately and responsively.
- Loading branch information
Showing
116 changed files
with
5,508 additions
and
3,210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,369 +1,14 @@ | ||
// // Note: Main App Component | ||
// import React, { useCallback, useEffect, useRef, useState } from 'react'; | ||
// import { | ||
// BrowserRouter as Router, | ||
// Route, | ||
// Routes, | ||
// useNavigate, | ||
// } from 'react-router-dom'; | ||
// import { Helmet } from 'react-helmet'; | ||
// App.js | ||
import React from 'react'; | ||
import Main from './Main'; | ||
import WithPageProvider from './context/WithPageProvider'; | ||
|
||
// // Component Imports | ||
// import Header from './components/headings/header/Header'; | ||
// import PrivateRoute from './components/reusable/PrivateRoute'; | ||
// import LoginDialog from './components/dialogs/LoginDialog'; | ||
|
||
// // Page Imports | ||
// import { | ||
// HomePage, | ||
// StorePage, | ||
// CartPage, | ||
// ProfilePage, | ||
// CollectionPage, | ||
// DeckBuilderPage, | ||
// NotFoundPage, | ||
// LoginPage, | ||
// } from './pages'; | ||
|
||
// import { | ||
// useUserContext, | ||
// useCollectionStore, | ||
// useDeckStore, | ||
// useCartStore, | ||
// useCardImages, | ||
// useAuthContext, | ||
// usePageContext, | ||
// } from './context'; | ||
// import { AppContainer } from './pages/pageStyles/StyledComponents'; | ||
|
||
// const App = () => { | ||
// const { fetchAllCollectionsForUser } = useCollectionStore(); | ||
// const { fetchAllDecksForUser } = useDeckStore(); | ||
// const { fetchUserCart } = useCartStore(); | ||
// const { user } = useUserContext(); | ||
// const { logoutTimerRef, resetLogoutTimer } = useAuthContext(); | ||
// const { | ||
// isPageLoading, | ||
// setIsPageLoading, | ||
// displaySplashPage, | ||
// handleLoadingTimeout, | ||
// } = usePageContext(); | ||
// const navigate = useNavigate(); | ||
// const loadingTimeoutRef = useRef(null); | ||
// const userId = user?.id; | ||
// const [showLoginDialog, setShowLoginDialog] = useState(!userId); | ||
// // const [toolbarHeight, setToolbarHeight] = useState('64px'); // Default height | ||
|
||
// const handleLoginSuccess = (isLoggedIn, userId) => { | ||
// setShowLoginDialog(false); | ||
// setIsPageLoading(false); | ||
// if (isLoggedIn && userId) { | ||
// resetLogoutTimer(); | ||
// } | ||
// }; | ||
|
||
// useEffect(() => { | ||
// if (userId) { | ||
// window.addEventListener('mousemove', resetLogoutTimer); | ||
// window.addEventListener('keypress', resetLogoutTimer); | ||
// } | ||
|
||
// return () => { | ||
// window.removeEventListener('mousemove', resetLogoutTimer); | ||
// window.removeEventListener('keypress', resetLogoutTimer); | ||
// if (logoutTimerRef.current) { | ||
// clearTimeout(logoutTimerRef.current); | ||
// } | ||
// }; | ||
// }, [userId, resetLogoutTimer]); | ||
|
||
// useEffect(() => { | ||
// console.log('useEffect triggered for fetch data'); | ||
|
||
// const fetchData = async () => { | ||
// try { | ||
// if (userId && typeof userId === 'string') { | ||
// console.log('Fetching user data'); | ||
// await Promise.all([ | ||
// fetchAllCollectionsForUser(), | ||
// fetchAllDecksForUser(), | ||
// // fetchUserCart(), | ||
// ]); | ||
// } | ||
// } catch (error) { | ||
// console.error('Error fetching data:', error); | ||
// } finally { | ||
// setIsPageLoading(false); | ||
// } | ||
// }; | ||
|
||
// fetchData(); | ||
// }, [userId, fetchAllCollectionsForUser, fetchAllDecksForUser]); | ||
|
||
// useEffect(() => { | ||
// if (isPageLoading) { | ||
// loadingTimeoutRef.current = setTimeout(() => { | ||
// handleLoadingTimeout(); | ||
// navigate('/login'); | ||
// }, 45000); // 45 seconds | ||
// } | ||
// return () => { | ||
// if (loadingTimeoutRef.current) { | ||
// clearTimeout(loadingTimeoutRef.current); | ||
// } | ||
// }; | ||
// }, [isPageLoading, navigate, handleLoadingTimeout]); | ||
|
||
// useEffect(() => { | ||
// if (window.location.pathname === '/login') { | ||
// setShowLoginDialog(true); | ||
// setIsPageLoading(false); | ||
// // setIsLoading(false); | ||
// } | ||
// }, []); | ||
// return ( | ||
// <> | ||
// <Helmet> | ||
// <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
// <link | ||
// rel="preconnect" | ||
// href="https://fonts.gstatic.com" | ||
// crossOrigin="true" | ||
// /> | ||
// <link | ||
// href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" | ||
// rel="stylesheet" | ||
// /> | ||
// </Helmet>{' '} | ||
// {displaySplashPage()} | ||
// {!userId ? ( | ||
// <LoginDialog | ||
// open={showLoginDialog} | ||
// onClose={() => setShowLoginDialog(false)} | ||
// onLogin={handleLoginSuccess} | ||
// /> | ||
// ) : ( | ||
// <AppContainer> | ||
// <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> | ||
// {/* <Footer /> */} | ||
// </AppContainer> | ||
// )} | ||
// </> | ||
// ); | ||
// }; | ||
|
||
// export default App; | ||
// Note: Main App Component | ||
import React, { useEffect, useRef, useState } from 'react'; | ||
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; | ||
import { Helmet } from 'react-helmet'; | ||
|
||
// Component and Page Imports | ||
import Header from './components/headings/header/Header'; | ||
import PrivateRoute from './components/reusable/PrivateRoute'; | ||
import LoginDialog from './components/dialogs/LoginDialog'; | ||
import { | ||
HomePage, | ||
StorePage, | ||
CartPage, | ||
ProfilePage, | ||
CollectionPage, | ||
DeckBuilderPage, | ||
NotFoundPage, | ||
LoginPage, | ||
} from './pages'; | ||
|
||
// Context Hooks | ||
import { | ||
useUserContext, | ||
useCollectionStore, | ||
useDeckStore, | ||
useAuthContext, | ||
usePageContext, | ||
} from './context'; | ||
import { AppContainer } from './pages/pageStyles/StyledComponents'; | ||
// Call the higher-order component function outside the component function | ||
// to avoid remounting on every render | ||
const WrappedMain = WithPageProvider(Main); | ||
|
||
const App = () => { | ||
const { user, fetchUserCart } = useUserContext(); | ||
const { fetchAllCollectionsForUser } = useCollectionStore(); | ||
const { fetchAllDecksForUser } = useDeckStore(); | ||
const { logoutTimerRef, resetLogoutTimer } = useAuthContext(); | ||
const { | ||
isPageLoading, | ||
setIsPageLoading, | ||
displaySplashPage, | ||
handleLoadingTimeout, | ||
} = usePageContext(); | ||
|
||
const userId = user?.id; | ||
const [showLoginDialog, setShowLoginDialog] = useState(!userId); | ||
const loadingTimeoutRef = useRef(null); | ||
|
||
const setupEventListeners = () => { | ||
window.addEventListener('mousemove', resetLogoutTimer); | ||
window.addEventListener('keypress', resetLogoutTimer); | ||
}; | ||
|
||
const removeEventListeners = () => { | ||
window.removeEventListener('mousemove', resetLogoutTimer); | ||
window.removeEventListener('keypress', resetLogoutTimer); | ||
}; | ||
|
||
const fetchData = async () => { | ||
try { | ||
await Promise.all([ | ||
fetchAllCollectionsForUser(), | ||
fetchAllDecksForUser(), | ||
// Consider uncommenting if cart data is required immediately | ||
// fetchUserCart(), | ||
]); | ||
} catch (error) { | ||
console.error('Error fetching data:', error); | ||
} finally { | ||
setIsPageLoading(false); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
if (userId) setupEventListeners(); | ||
return () => { | ||
removeEventListeners(); | ||
if (logoutTimerRef.current) clearTimeout(logoutTimerRef.current); | ||
}; | ||
}, [userId, resetLogoutTimer]); | ||
|
||
useEffect(() => { | ||
if (userId) fetchData(); | ||
}, [userId]); | ||
|
||
useEffect(() => { | ||
if (isPageLoading) { | ||
loadingTimeoutRef.current = setTimeout(() => { | ||
handleLoadingTimeout(); | ||
}, 45000); // 45 seconds timeout | ||
} | ||
return () => clearTimeout(loadingTimeoutRef.current); | ||
}, [isPageLoading, handleLoadingTimeout]); | ||
|
||
useEffect(() => { | ||
if (window.location.pathname === '/login') { | ||
setShowLoginDialog(true); | ||
setIsPageLoading(false); | ||
} | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<Helmet> | ||
<link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
<link | ||
rel="preconnect" | ||
href="https://fonts.gstatic.com" | ||
crossOrigin="true" | ||
/> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" | ||
rel="stylesheet" | ||
/> | ||
</Helmet>{' '} | ||
{displaySplashPage()} | ||
{!userId ? ( | ||
<LoginDialog | ||
open={showLoginDialog} | ||
onClose={() => setShowLoginDialog(false)} | ||
onLogin={(isLoggedIn, userId) => setShowLoginDialog(false)} | ||
/> | ||
) : ( | ||
<AppContainer> | ||
<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> | ||
</AppContainer> | ||
)} | ||
</> | ||
); | ||
return <WrappedMain />; | ||
}; | ||
|
||
export default App; |
Oops, something went wrong.