| import React, { useState } from "react" |
| import "./App.css" |
| import { BrowserRouter as Router, Routes, Route, useLocation, useNavigate } from "react-router-dom" |
| import { Provider, useDispatch, useSelector } from "react-redux" |
| import store from "./store/store" |
| import { ToastContainer } from "react-toastify" |
| import "react-toastify/dist/ReactToastify.css" |
| import { motion, AnimatePresence } from "framer-motion" |
| import { setUser, setLoading, logout } from "./store/slices/authSlice"; |
| import { useEffect } from "react"; |
| import { useLogoutHandler } from "./hooks/useLogoutHandler"; |
|
|
| import Header from "./components/Header" |
| import MenuBar from "./components/MenuBar" |
| import Footer from "./components/Footer" |
| import Carousel from "./components/Carousel" |
| import ItemSection from "./components/ItemSection" |
|
|
| import LoadingScreen from "./components/LoadingScreen" |
| import ScrollToTop from "./components/ScrollToTop" |
|
|
| import LiveChat from "./components/LiveChat" |
| import AIChatAssistant from "./components/AIChatAssistant" |
|
|
| import Home from "./pages/Home" |
| import ProductDetail from "./pages/ProductDetail" |
| import ProductList from "./pages/ProductList" |
| import CartPage from "./pages/CartPage" |
| import LoginPage from "./pages/LoginPage" |
| import RegisterPage from "./pages/RegisterPage" |
| import ProfilePage from "./pages/ProfilePage" |
| import CheckoutPage from "./pages/CheckoutPage" |
|
|
| import WishlistPage from "./pages/WishlistPage" |
| import OrderPage from "./pages/OrderPage" |
| import AdminLoginPage from "./pages/AdminLoginPage" |
| import AdminDashboard from "./pages/AdminDashboard" |
|
|
| import FloatingElements from "./components/FloatingElements" |
| import ParticleBackground from "./components/ParticleBackground" |
|
|
| function AppContent() { |
| const [isLoading, setIsLoading] = useState(true) |
| const [showLiveChat, setShowLiveChat] = useState(false) |
| const [showAIAssistant, setShowAIAssistant] = useState(false) |
| const location = useLocation() |
| const navigate = useNavigate() |
| const dispatch = useDispatch(); |
| const { isLoggedIn, userData } = useSelector((state) => state.auth); |
| const authLoading = useSelector((state) => state.auth.loading); |
|
|
| useLogoutHandler(); |
|
|
| useEffect(() => { |
| const hydrateAuth = async () => { |
| dispatch(setLoading(true)); |
| try { |
| |
| const existingUserData = localStorage.getItem('userData'); |
| const existingToken = localStorage.getItem('token'); |
|
|
| if (existingUserData && existingToken) { |
| try { |
| const userData = JSON.parse(existingUserData); |
| |
| if (userData._id && userData.email) { |
| dispatch(setUser(userData)); |
| dispatch(setLoading(false)); |
| return; |
| } |
| } catch (e) { |
| console.error('Error parsing stored user data:', e); |
| |
| localStorage.removeItem('userData'); |
| localStorage.removeItem('token'); |
| } |
| } |
|
|
| dispatch(setLoading(false)); |
|
|
| } catch (e) { |
| console.error('Auth hydration error:', e); |
| localStorage.removeItem('userData'); |
| localStorage.removeItem('token'); |
| dispatch(setLoading(false)); |
| } |
| }; |
| hydrateAuth(); |
| }, [dispatch]); |
|
|
| const shouldHidePublicSections = |
| [ |
| "/login", |
| "/register", |
| "/cart", |
| "/checkout", |
| "/search", |
| "/productlist", |
| "/profile", |
| "/wishlist", |
| "/orders" |
| ].includes(location.pathname.toLowerCase()) || |
| location.pathname.startsWith("/product/"); |
|
|
| const hideHeader = location.pathname.startsWith("/admin/"); |
|
|
| React.useEffect(() => { |
| const timer = setTimeout(() => setIsLoading(false), 2000) |
| return () => clearTimeout(timer) |
| }, [setIsLoading]) |
|
|
| useEffect(() => { |
| if (!authLoading && !isLoggedIn) { |
| const protectedRoutes = ['/profile', '/wishlist', '/orders', '/checkout', '/cart']; |
| if (protectedRoutes.includes(location.pathname)) { |
| window.location.href = '/'; |
| } |
| } |
| }, [isLoggedIn, authLoading, location.pathname]); |
|
|
| if (isLoading || authLoading) { |
| return <LoadingScreen /> |
| } |
|
|
| return ( |
| <div> |
| |
| <FloatingElements /> |
| <ParticleBackground /> |
| <ToastContainer |
| |
| position="top-center" |
| toastClassName="Premium-toast" |
| progressClassName="Premium-progress" |
| hideProgressBar={false} |
| newestOnTop |
| closeOnClick |
| rtl={false} |
| pauseOnFocusLoss |
| draggable |
| pauseOnHover |
| /> |
| |
| {} |
| {!hideHeader && ( |
| <Header |
| onOpenLiveChat={() => setShowLiveChat(true)} |
| onOpenAIAssistant={() => setShowAIAssistant(true)} |
| /> |
| )} |
| |
| {} |
| {!hideHeader && !shouldHidePublicSections && ( |
| <> |
| <Carousel /> |
| <MenuBar /> |
| <ItemSection /> |
| <Footer /> |
| </> |
| )} |
|
|
| {} |
| <AnimatePresence mode="wait"> |
| <motion.div |
| key={location.pathname} |
| initial={{ opacity: 0, x: 20 }} |
| animate={{ opacity: 1, x: 0 }} |
| exit={{ opacity: 0, x: -20 }} |
| transition={{ duration: 0.4, ease: "easeInOut" }} |
| > |
| <Routes> |
| <Route path="/" element={<div />} /> |
| <Route path="/search" element={<Home />} /> |
| <Route |
| path="/product/:id" |
| element={ |
| <ProductDetail /> |
| } |
| /> |
| <Route |
| path="/productlist" |
| element={<ProductList />} |
| /> |
| <Route path="/cart" element={<CartPage />} /> |
| <Route path="/checkout" element={<CheckoutPage />} /> |
| <Route |
| path="/wishlist" |
| element={<WishlistPage />} |
| /> |
| <Route path="/orders" element={<OrderPage />} /> |
| <Route path="/login" element={<LoginPage />} /> |
| <Route path="/register" element={<RegisterPage />} /> |
| <Route path="/profile" element={<ProfilePage />} /> |
| <Route path="/admin/login" element={<AdminLoginPage />} /> |
| <Route path="/admin/dashboard" element={<AdminDashboard />} /> |
| |
| </Routes> |
| </motion.div> |
| </AnimatePresence> |
|
|
| { } |
| {!(location.pathname.toLowerCase() === "/profile") && <ScrollToTop />} |
| { } |
| <LiveChat key="livechat" isOpen={showLiveChat} setIsOpen={setShowLiveChat} /> |
| <AIChatAssistant key="aiassistant" isOpen={showAIAssistant} setIsOpen={setShowAIAssistant} style={{ bottom: '140px' }} /> |
| </div> |
| ) |
| } |
|
|
| function App() { |
| return ( |
| <Provider store={store}> |
| <Router> |
| <AppContent /> |
| </Router> |
| </Provider> |
| ) |
| } |
|
|
| export default App |