diff --git a/README.md b/README.md index 5b962db..9396cd3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Reed Vogt ## Features +### User Features + 1. **Search Functionality** Users can search for their favorite cards by name. The search functionality returns all the cards matching the search query, helping users quickly find the desired cards to add to their decks. @@ -38,6 +40,84 @@ Reed Vogt The collection section of the app provides users a variety of statistics about their collection performance as well as specific cards which enable users to make advanced insights into trends and patterns. +### Developer Features + +1. **Backend Cronjob** + + The backend of the application is integrated with a cronjob that updates the card database every 10 minutes, ensuring that the application is always up-to-date with the latest cards. + +2. **Secure Payment Processing** + + The application is integrated with Stripe, enabling developers to leverage the secure payment processing capabilities of Stripe. + +3. **Responsive Design** + + The application is built with a responsive design, enabling developers to leverage the vast ecosystem of responsive design libraries and packages. + +4. **Secure File Conversion** + + The application is integrated with Convertio, enabling developers to leverage the secure file conversion capabilities of Convertio. + +### Frontend Technologies + +1. **React** + + The application is built with React, enabling developers to leverage the vast ecosystem of React libraries and packages. + +2. **Stripe** + + The application is integrated with Stripe, enabling developers to leverage the secure payment processing capabilities of Stripe. + +3. **mui** + + The application is built with mui, enabling developers to leverage the vast ecosystem of mui libraries and packages. + +4. **Convertio** + + The application is integrated with Convertio, enabling developers to leverage the secure file conversion capabilities of Convertio. + +5. **YGOProDeck-api** + +The application is built with YGOProDeck-api, enabling developers to leverage the vast ecosystem of YGOProDeck-api libraries and packages. + +6. **MongoDB** + + The application is built with MongoDB, enabling developers to leverage the vast ecosystem of MongoDB libraries and packages. + +7. **Netlify** + + The application is deployed with Netlify, enabling developers to leverage the vast ecosystem of Netlify libraries and packages. + +8. **Nivo Charts** + + The application is built with Nivo Charts, enabling developers to leverage the vast ecosystem of Nivo Charts libraries and packages. + +### Backend Technologies + +1. **Node.js** + + The application is built with Node.js, enabling developers to leverage the vast ecosystem of Node.js libraries and packages. + +2. **Express.js** + + The application is built with Express.js, enabling developers to leverage the vast ecosystem of Express.js libraries and packages. + +3. **MongoDB** + + The application is built with MongoDB, enabling developers to leverage the vast ecosystem of MongoDB libraries and packages. + +4. **Netlify** + + The application is deployed with Netlify, enabling developers to leverage the vast ecosystem of Netlify libraries and packages. + +5. **Heroku** + + The application is deployed with Heroku, enabling developers to leverage the vast ecosystem of Heroku libraries and packages. + +6. **Cronjob** + + The application is integrated with a cronjob that updates the card database every 24 hours, ensuring that the application is always up-to-date with the latest cards. + ## Acceptance Tests To ensure the best user experience and seamless functionality, the following acceptance tests are in place: @@ -64,7 +144,7 @@ To ensure the best user experience and seamless functionality, the following acc ## Installation -To get started with TCG eCommerce-frontEnd, follow these steps: +To get started with the enhanced card store, follow these steps: 1. Clone the repository with `git clone https://github.com/your_username_/Project-Name.git`. 2. Navigate to the project directory with `cd Project-Name`. @@ -102,4 +182,9 @@ Project Repo: - [React](https://reactjs.org/) - [Stripe](https://stripe.com/) +- [mui](https://mui.com/) - [Convertio](https://convertio.co/download/bde422f6082917756106e52b556e7245cfcfbe/) +- [YGOProDeck-api](https://ygoprodeck.com/api-guide/) +- [MongoDB](https://cloud.mongodb.com/v2#/org/641ca5d870f5f76cbe646c47/projects) +- [Netlify](https://app.netlify.com/teams/reedoooo/overview) +- [Nivo Charts](https://nivo.rocks/) diff --git a/package.json b/package.json index e4ea0cf..07a9e96 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@emotion/styled": "^11.11.0", "@fortawesome/fontawesome-free": "^6.4.0", "@mui/icons-material": "^5.14.1", + "@mui/joy": "^5.0.0-beta.16", "@mui/material": "^5.14.1", "@mui/styles": "^5.14.13", "@mui/system": "^5.14.1", diff --git a/src/App.js b/src/App.js index 2f7d1a1..6868565 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,11 @@ // Note: Main App Component import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import { + BrowserRouter as Router, + Route, + Routes, + useNavigate, +} from 'react-router-dom'; import { Helmet } from 'react-helmet'; import { debounce } from 'lodash'; @@ -22,6 +27,7 @@ import { // ThreeJsCube, // CardDeckAnimation, NotFoundPage, + LoginPage, } from './pages'; import { @@ -35,44 +41,32 @@ import { usePageContext, } from './context'; import { AppContainer } from './pages/pageStyles/StyledComponents'; +import { MainContent } from './components/headings/navigation/styled'; const App = () => { const { fetchAllCollectionsForUser, selectedCollection } = useCollectionStore(); const { fetchAllDecksForUser, selectedDeck } = useDeckStore(); + const { fetchUserCart } = useCartStore(); const { user } = useUserContext(); - const { logout } = useAuthContext(); - const { isLoading, setIsLoading } = useUtilityContext(); - const { isPageLoading, setIsPageLoading } = usePageContext(); + const { logout, 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 logoutTimerRef = useRef(null); - - const handleUserActivity = debounce(() => { - if (logoutTimerRef.current) clearTimeout(logoutTimerRef.current); - logoutTimerRef.current = setTimeout(logout, 1800000); // 30 minutes - }, 500); - - const debouncedLogout = useCallback( - debounce(() => { - if (logoutTimerRef.current) { - clearTimeout(logoutTimerRef.current); - } - logoutTimerRef.current = setTimeout(logout, 1800000); // 30 minutes - }, 500), - [logout] // Dependency for useCallback - ); - - // Call this function to reset the logout timer - const resetLogoutTimer = useCallback(() => { - debouncedLogout(); - }, [debouncedLogout]); + // const [toolbarHeight, setToolbarHeight] = useState('64px'); // Default height const handleLoginSuccess = (isLoggedIn, userId) => { setShowLoginDialog(false); setIsPageLoading(false); - setIsLoading(false); + // setIsLoading(false); if (isLoggedIn && userId) { resetLogoutTimer(); } @@ -96,6 +90,7 @@ const App = () => { }, [userId, resetLogoutTimer]); useEffect(() => { + // Fetch all collections and decks for the user if (userId) { Promise.all([ fetchAllCollectionsForUser(), @@ -103,69 +98,110 @@ const App = () => { // fetchUserCart(), ]) .catch((error) => console.error('Error fetching data:', error)) - .finally(() => setIsLoading(false) && setIsPageLoading(false)); + .finally(() => setIsPageLoading(false)); + } + }, [userId, fetchAllCollectionsForUser, fetchAllDecksForUser]); + + useEffect(() => { + // Check if loading takes more than 45 seconds + if (isPageLoading) { + loadingTimeoutRef.current = setTimeout(() => { + handleLoadingTimeout(); + navigate('/login'); + }, 45000); // 45 seconds + } + + // Clear the timeout if loading finishes or when unmounting + return () => { + if (loadingTimeoutRef.current) { + clearTimeout(loadingTimeoutRef.current); + } + }; + }, [isPageLoading, navigate, handleLoadingTimeout]); + + useEffect(() => { + // if the user is redirected to the login page, show the login dialog and set the loading state to false + if (window.location.pathname === '/login') { + setShowLoginDialog(true); + setIsPageLoading(false); + // setIsLoading(false); } - }, [userId, fetchAllCollectionsForUser, fetchAllDecksForUser, fetchUserCart]); + }, []); + + // useEffect(() => { + // if (toolbarRef.current) { + // setToolbarHeight(`${toolbarRef.current.clientHeight}px`); + // } + // }, []); return ( <> - {/* Helmet Configuration */} - {isLoading || isPageLoading ? ( - + + + + + {' '} + {displaySplashPage()} + {!userId ? ( + setShowLoginDialog(false)} + onLogin={handleLoginSuccess} + /> ) : ( - <> - setShowLoginDialog(false)} - onLogin={handleLoginSuccess} - /> - -
- - } /> - } /> - } /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - } /> - {/* } /> */} - {/* } /> */} - } />{' '} - {/* 404 Not Found Route */} - - {/*