From bc1479c384a9ab581f3ab5b45988ae0de3a0b756 Mon Sep 17 00:00:00 2001 From: Mehedi Date: Mon, 25 May 2026 12:38:44 +0600 Subject: [PATCH] review section updated --- src/layout/public/NavbarLayout.jsx | 4 +- .../public/public_Wishlist/WishlistView.jsx | 132 ++++++++++++++++++ src/router/components/RouteErrorBoundary.jsx | 43 ++++++ src/router/router.jsx | 13 +- 4 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 src/pages/public/public_Wishlist/WishlistView.jsx create mode 100644 src/router/components/RouteErrorBoundary.jsx diff --git a/src/layout/public/NavbarLayout.jsx b/src/layout/public/NavbarLayout.jsx index fa752fc..1fbac94 100644 --- a/src/layout/public/NavbarLayout.jsx +++ b/src/layout/public/NavbarLayout.jsx @@ -238,7 +238,7 @@ const NavbarLayout = () => { {searchOpen && ( -
+
{searchText.trim() ? ( <>
Suggestions
@@ -374,7 +374,7 @@ const NavbarLayout = () => { )} diff --git a/src/pages/public/public_Wishlist/WishlistView.jsx b/src/pages/public/public_Wishlist/WishlistView.jsx new file mode 100644 index 0000000..9c5967a --- /dev/null +++ b/src/pages/public/public_Wishlist/WishlistView.jsx @@ -0,0 +1,132 @@ +import React, { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { Heart, ShoppingBag, Trash2 } from 'lucide-react'; +import { addToCart, getWishlistItems, removeFromWishlist } from '../../../services/shopStorageService'; + +const WishlistView = () => { + const [wishlistItems, setWishlistItems] = useState([]); + + useEffect(() => { + setWishlistItems(getWishlistItems()); + + const refresh = () => setWishlistItems(getWishlistItems()); + window.addEventListener('storage', refresh); + window.addEventListener('esuuq:shop-updated', refresh); + + return () => { + window.removeEventListener('storage', refresh); + window.removeEventListener('esuuq:shop-updated', refresh); + }; + }, []); + + const removeItem = (id) => { + setWishlistItems(removeFromWishlist(id)); + }; + + const addItemToCart = (item) => { + addToCart(item, 1); + }; + + const clearAll = () => { + wishlistItems.slice().forEach((item) => removeFromWishlist(item.id)); + setWishlistItems([]); + }; + + return ( +
+
+
+
+
+ Public Wishlist +
+

+ Saved Items +

+

+ {wishlistItems.length} item(s) saved on this device. Browse, remove, or move them to cart anytime. +

+
+ + {wishlistItems.length > 0 ? ( + + ) : null} +
+ + {!wishlistItems.length ? ( +
+
+ +
+
Your public wishlist is empty
+
Tap the heart icon on any product to save it here.
+ + Continue Shopping + +
+ ) : ( +
+ {wishlistItems.map((item) => ( +
+ +
+ {item.image ? ( + {item.name} + ) : ( + {item.icon || '🛍'} + )} +
+ + +
+
+ {item.name} +
+
+ ${Number(item.price || 0).toFixed(2)} +
+ +
+ + +
+
+
+ ))} +
+ )} +
+
+ ); +}; + +export default WishlistView; diff --git a/src/router/components/RouteErrorBoundary.jsx b/src/router/components/RouteErrorBoundary.jsx new file mode 100644 index 0000000..9490b27 --- /dev/null +++ b/src/router/components/RouteErrorBoundary.jsx @@ -0,0 +1,43 @@ +import { isRouteErrorResponse, useRouteError } from 'react-router-dom'; + +const RouteErrorBoundary = () => { + const error = useRouteError(); + + const title = isRouteErrorResponse(error) + ? `${error.status} ${error.statusText || 'Route Error'}` + : 'Application Error'; + + const message = error instanceof Error + ? error.message + : isRouteErrorResponse(error) + ? error.data || 'Unable to load this page.' + : 'Unable to load this page. Please try again.'; + + return ( +
+
+
ESUUQ
+

{title}

+

{message}

+
+ + +
+
+
+ ); +}; + +export default RouteErrorBoundary; \ No newline at end of file diff --git a/src/router/router.jsx b/src/router/router.jsx index dc5acbf..e5d820a 100644 --- a/src/router/router.jsx +++ b/src/router/router.jsx @@ -4,6 +4,7 @@ import { createBrowserRouter, createRoutesFromElements, Route, useNavigate, useP import RootLayout from '../layout/public/RootLayout'; import LoadingFallback from './components/LoadingFallback'; import ProtectedRoute from './components/ProtectedRoute'; +import RouteErrorBoundary from './components/RouteErrorBoundary'; const Home = lazy(() => import('../pages/public/public_Home/Home')); const ContactView = lazy(() => import('../pages/public/public_contact/ContactView')); @@ -23,6 +24,7 @@ const SearchView = lazy(() => import('../pages/public/public_Search/SearchView') const ProductDetailsView = lazy( () => import('../pages/public/public_ProductDetails/ProductDetailsView') ); +const WishlistView = lazy(() => import('../pages/public/public_Wishlist/WishlistView')); // Account Pages const LoginView = lazy(() => import('../pages/auth/LoginView')); @@ -161,7 +163,7 @@ const AdminPlaceholder = ({ title, icon }) => ( const router = createBrowserRouter( createRoutesFromElements( <> - }> + } errorElement={}> } /> @@ -176,6 +178,7 @@ const router = createBrowserRouter( + {wrap(CartView)}} /> {wrap(UserView)} - }> + } errorElement={}> )} /> @@ -217,7 +220,7 @@ const router = createBrowserRouter( {wrap(AdminView)} - }> + } errorElement={}> )} /> @@ -237,7 +240,7 @@ const router = createBrowserRouter( {wrap(MerchantView)} - }> + } errorElement={}> )} /> )} /> @@ -256,7 +259,7 @@ const router = createBrowserRouter( {wrap(SubAdminView)} - }> + } errorElement={}>