Skip to content

Add frontend-only wishlist feature with localStorage persistence#5

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/add-wishlist-feature-localstorage
Draft

Add frontend-only wishlist feature with localStorage persistence#5
Copilot wants to merge 2 commits into
mainfrom
copilot/add-wishlist-feature-localstorage

Conversation

Copy link
Copy Markdown

Copilot AI commented May 6, 2026

Adds a wishlist feature backed entirely by localStorage — no backend changes. Users can heart-toggle products from the product grid or a dedicated wishlist page, with state surviving page reloads.

Changes

  • WishlistContext.tsx — New context exposing wishlistIds: Set<number>, toggleWishlist, isWishlisted, wishlistCount; hydrates from and persists to localStorage["wishlist"]

  • Products.tsx — Heart SVG button in top-right of each product card image; filled green (text-primary) when wishlisted, outline gray otherwise; click stops propagation to avoid triggering the product modal

  • Wishlist.tsx — New page at /wishlist; reuses the same useQuery/axios fetch pattern as Products.tsx, filters to wishlisted IDs, shows empty-state copy when list is empty

  • App.tsx — Wraps app in <WishlistProvider> (alongside AuthProvider/ThemeProvider); adds /wishlist route

  • Navigation.tsx — "Wishlist" link visible only when isLoggedIn === true; count badge with aria-label when wishlistCount > 0

// WishlistContext — core toggle logic
const toggleWishlist = (productId: number) => {
  setWishlistIds(prev => {
    const next = new Set(prev);
    next.has(productId) ? next.delete(productId) : next.add(productId);
    return next;
  });
};
Original prompt

Wishlist Feature — Variation 1: Frontend-only localStorage

Add a wishlist feature that lets users save products for later. This variation stores the wishlist entirely in the browser using localStorage — no backend changes required.

What to implement

1. WishlistContext (frontend/src/context/WishlistContext.tsx)

  • A React context that manages wishlist state
  • Persist to and hydrate from localStorage under the key "wishlist"
  • Expose: wishlistIds: Set<number>, toggleWishlist(productId: number), isWishlisted(productId: number): boolean, and wishlistCount: number
  • Wrap the app in this provider inside frontend/src/App.tsx alongside the existing AuthProvider and ThemeProvider

2. Heart button on each product card (frontend/src/components/entity/product/Products.tsx)

  • Add a heart icon button (SVG) in the top-right corner of each product card image area
  • When wishlisted: filled heart in primary green (text-primary)
  • When not wishlisted: outline heart in gray
  • Clicking it calls toggleWishlist(product.productId), stop event propagation so it doesn't open the product modal
  • Accessible: aria-label="Add {name} to wishlist" / aria-label="Remove {name} from wishlist"

3. Wishlist page (frontend/src/components/wishlist/Wishlist.tsx)

  • Fetches all products using the same axios.get + useQuery pattern as Products.tsx
  • Filters to only show products whose productId is in wishlistIds
  • If empty, shows: "Your wishlist is empty — browse products to save items for later"
  • Same product card layout as Products.tsx with heart button still present (to remove items)
  • Uses useTheme() for dark/light mode, same Tailwind class patterns

4. Route and navigation

  • frontend/src/App.tsx: Add <Route path="/wishlist" element={<Wishlist />} />
  • frontend/src/components/Navigation.tsx: Add a "Wishlist" nav link visible only when isLoggedIn === true (use useAuth()), with a badge showing wishlistCount when > 0

Constraints

  • Follow existing code patterns: arrow function components, Tailwind CSS utility classes, useTheme() for dark/light mode
  • Do NOT modify any files in api/
  • The heart icon SVG uses stroke-based outline when not wishlisted, and filled when wishlisted

Copilot AI changed the title [WIP] Add wishlist feature using localStorage Add frontend-only wishlist feature with localStorage persistence May 6, 2026
Copilot AI requested a review from thomasiverson May 6, 2026 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants