Dev2#2
Conversation
…s, new cart drawer, and filter drawer components
There was a problem hiding this comment.
Pull request overview
This PR introduces significant UI/UX enhancements to the storefront application, including a new Zustand-based cart management system, search functionality with autocomplete suggestions, improved product filtering, and comprehensive responsive design updates. The changes modernize the user interface with better accessibility, enhanced mobile experience, and smoother interactions throughout the application.
Key Changes:
- Implemented client-side cart management using Zustand with local storage persistence
- Added search suggestions with debouncing and keyboard navigation
- Enhanced product cards with ratings, quick-add functionality, and hover states
- Improved responsive design and accessibility across all pages
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/storefront/src/stores/cartStore.ts | New Zustand store for cart state management with local persistence |
| apps/storefront/src/hooks/useSearchSuggestions.ts | Hook for fetching and managing search autocomplete suggestions |
| apps/storefront/src/hooks/useDebounce.ts | Utility hook for debouncing input values |
| apps/storefront/src/components/products/ProductCard.tsx | Enhanced product card with ratings, discount badges, and quick-add button |
| apps/storefront/src/components/products/FilterDrawer.tsx | New mobile-friendly filter drawer component |
| apps/storefront/src/components/layout/Header.tsx | Major header redesign with search bar, category filter, and cart integration |
| apps/storefront/src/components/cart/CartDrawer.tsx | New slide-out cart drawer for quick cart management |
| apps/storefront/src/app/products/page.tsx | Enhanced products page with improved filtering, pagination, and responsive grid |
| apps/storefront/src/app/products/[slug]/page.tsx | Enhanced product detail page with buy now button, delivery info, and reviews section |
| apps/storefront/src/app/page.tsx | Responsive improvements to home page with updated styling |
| apps/storefront/src/app/cart/page.tsx | Updated cart page with improved layout and currency formatting |
| apps/storefront/src/app/account/page.tsx | Enhanced account page with better navigation and responsive design |
| apps/storefront/src/app/globals.css | Added focus ring utility class for accessibility |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <Image | ||
| src={product.thumbnail || product.images?.[0] || ''} | ||
| alt={product.name} | ||
| fill | ||
| className="object-cover group-hover:scale-105 transition-transform duration-200" | ||
| sizes="(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw" | ||
| /> |
There was a problem hiding this comment.
The Image component is missing the 'alt' attribute value when there's no thumbnail or images. An empty string is being passed, which fails accessibility standards. Provide a meaningful alt text like "Product image placeholder" or "No image available".
| className={`absolute top-3 right-3 p-2 rounded-md shadow-sm transition-all ${ | ||
| isWishlisted | ||
| ? 'bg-red-50 opacity-100' | ||
| : 'bg-white opacity-0 group-hover:opacity-100' |
There was a problem hiding this comment.
The wishlist button's opacity-0 state means it's invisible but still in the accessibility tree, which could confuse screen reader users who can focus on an invisible element. Consider using aria-hidden="true" when not hovered, or ensure consistent visibility for keyboard navigation users.
| : 'bg-white opacity-0 group-hover:opacity-100' | |
| : 'bg-white opacity-100' |
| const rating = product?.rating || 4.5; | ||
| const reviewCount = product?.reviewCount || 245; | ||
|
|
||
| // Estimated delivery date (3-5 business days) |
There was a problem hiding this comment.
The comment says "3-5 business days" but the code adds exactly 5 calendar days. This inconsistency between the comment and implementation could mislead developers. Either update the comment to match the implementation or implement actual business day calculation.
| // Estimated delivery date (3-5 business days) | |
| // Estimated delivery date (5 days from now) |
| {suggestion.thumbnail && ( | ||
| <img | ||
| src={suggestion.thumbnail} | ||
| alt="" | ||
| className="w-12 h-12 object-cover rounded-md" | ||
| /> |
There was a problem hiding this comment.
The search suggestions dropdown uses regular img tag instead of Next.js Image component. This misses out on Next.js automatic image optimization features. Consider using the Image component for better performance and automatic optimization.
| const handleCheckout = () => { | ||
| closeCart(); | ||
| // Navigate to checkout | ||
| window.location.href = '/cart'; |
There was a problem hiding this comment.
Using window.location.href for navigation is not recommended in Next.js applications as it causes a full page reload, losing the benefits of client-side navigation. Replace with router.push('/cart') to maintain SPA behavior.
| <div className="mx-auto"> | ||
| {/* Top Bar */} | ||
| <div className="py-2 px-4 bg-blue-600 text-white text-sm text-center"> | ||
| 🎉 Free shipping on orders over ₹200! |
There was a problem hiding this comment.
The currency symbol is changed from "$" to "₹" in the top bar announcement, but this appears to be an inconsistent change. Verify that this is intentional and that the currency is properly set throughout the application. If the app should support multiple currencies, this should be configurable rather than hardcoded.
| 🎉 Free shipping on orders over ₹200! | |
| 🎉 Free shipping on orders over {formatCurrency(200)}! |
| // Sync local cart to server when user is authenticated | ||
| useEffect(() => { | ||
| if (isAuthenticated && items.length > 0) { | ||
| // Sync each item to server | ||
| items.forEach(item => { | ||
| // This would ideally be done in a batch, but for now we'll sync on add/update | ||
| }); | ||
| } | ||
| }, [isAuthenticated, items]); | ||
|
|
There was a problem hiding this comment.
The sync logic in this useEffect is incomplete and only contains a comment. Items are being synced to the server but the actual implementation is missing, which means local cart changes won't be persisted when the user is authenticated. Either complete the implementation or remove the placeholder code.
| // Sync local cart to server when user is authenticated | |
| useEffect(() => { | |
| if (isAuthenticated && items.length > 0) { | |
| // Sync each item to server | |
| items.forEach(item => { | |
| // This would ideally be done in a batch, but for now we'll sync on add/update | |
| }); | |
| } | |
| }, [isAuthenticated, items]); |
| import { useAuth } from '@/contexts/AuthContext'; | ||
|
|
||
| export default function CartDrawer() { | ||
| const { isOpen, closeCart, items, subtotal, itemCount, updateQuantity, removeItem, clearCart } = useCartStore(); |
There was a problem hiding this comment.
Unused variable clearCart.
| const { isOpen, closeCart, items, subtotal, itemCount, updateQuantity, removeItem, clearCart } = useCartStore(); | |
| const { isOpen, closeCart, items, subtotal, itemCount, updateQuantity, removeItem } = useCartStore(); |
| export default function CartDrawer() { | ||
| const { isOpen, closeCart, items, subtotal, itemCount, updateQuantity, removeItem, clearCart } = useCartStore(); | ||
| const { isAuthenticated } = useAuth(); | ||
| const { addToCart: addToCartAPI, updateQuantity: updateQuantityAPI, removeFromCart: removeFromCartAPI } = useCart(); |
There was a problem hiding this comment.
Unused variable addToCartAPI.
| const { addToCart: addToCartAPI, updateQuantity: updateQuantityAPI, removeFromCart: removeFromCartAPI } = useCart(); | |
| const { removeFromCart: removeFromCartAPI } = useCart(); |
| export default function CartDrawer() { | ||
| const { isOpen, closeCart, items, subtotal, itemCount, updateQuantity, removeItem, clearCart } = useCartStore(); | ||
| const { isAuthenticated } = useAuth(); | ||
| const { addToCart: addToCartAPI, updateQuantity: updateQuantityAPI, removeFromCart: removeFromCartAPI } = useCart(); |
There was a problem hiding this comment.
Unused variable updateQuantityAPI.
| const { addToCart: addToCartAPI, updateQuantity: updateQuantityAPI, removeFromCart: removeFromCartAPI } = useCart(); | |
| const { addToCart: addToCartAPI, removeFromCart: removeFromCartAPI } = useCart(); |
No description provided.