From 42db8887ccdc3cd4592bae694269b43a3654599f Mon Sep 17 00:00:00 2001 From: Utsavladia Date: Tue, 25 Jun 2024 13:55:53 +0530 Subject: [PATCH] added functionality of wishlist --- .../wishlist/components/wishlist-item.tsx | 53 +++++++++ app/(routes)/wishlist/page.tsx | 42 ++++++++ components/info.tsx | 101 +++++++++++------- components/navbar-actions.tsx | 25 +++-- hooks/use-wishlist.tsx | 43 ++++++++ 5 files changed, 215 insertions(+), 49 deletions(-) create mode 100644 app/(routes)/wishlist/components/wishlist-item.tsx create mode 100644 app/(routes)/wishlist/page.tsx create mode 100644 hooks/use-wishlist.tsx diff --git a/app/(routes)/wishlist/components/wishlist-item.tsx b/app/(routes)/wishlist/components/wishlist-item.tsx new file mode 100644 index 0000000..9d152f8 --- /dev/null +++ b/app/(routes)/wishlist/components/wishlist-item.tsx @@ -0,0 +1,53 @@ +import Image from "next/image"; +import { toast } from "react-hot-toast"; +import { X } from "lucide-react"; + +import IconButton from "@/components/ui/icon-button"; +import Currency from "@/components/ui/currency"; +import useWishlist from "@/hooks/use-wishlist"; +import { Product } from "@/types"; + +interface CartItemProps { + data: Product; +} + +const WishlistItem: React.FC = ({ data }) => { + const wishlist = useWishlist(); + + const onRemove = () => { + wishlist.removeItem(data.id); + }; + + return ( +
  • +
    + +
    +
    +
    + } /> +
    +
    +
    +

    {data.name}

    +
    + +
    +

    {data.color.name}

    +

    + {data.size.name} +

    +
    + +
    +
    +
  • + ); +}; + +export default WishlistItem; diff --git a/app/(routes)/wishlist/page.tsx b/app/(routes)/wishlist/page.tsx new file mode 100644 index 0000000..23e9e2d --- /dev/null +++ b/app/(routes)/wishlist/page.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { useEffect, useState } from "react"; + +import Container from "@/components/ui/container"; +import useWishlist from "@/hooks/use-wishlist"; + +import WishlistItem from "./components/wishlist-item"; + +const CartPage = () => { + const [isMounted, setIsMounted] = useState(false); + const wishlist = useWishlist(); + + useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) { + return null; + } + + return ( +
    + +
    +

    Your Wishlist

    +
    +
    +
      + {wishlist.items.map((item) => ( + + ))} +
    +
    +
    +
    +
    +
    + ); +}; + +export default CartPage; diff --git a/components/info.tsx b/components/info.tsx index f26abd0..dc35ee4 100644 --- a/components/info.tsx +++ b/components/info.tsx @@ -1,42 +1,55 @@ "use client"; -import { ShoppingCart, Trash2 } from "lucide-react"; +import { Heart, ShoppingCart, Trash2 } from "lucide-react"; -import Currency from "@/components/ui/currency"; +import Currency from "@/components/ui/currency"; import Button from "@/components/ui/button"; import { Product } from "@/types"; import useCart from "@/hooks/use-cart"; +import useWishlist from "@/hooks/use-wishlist"; import Rating from "./ui/ratings"; interface InfoProps { - data: Product -}; + data: Product; +} const Info: React.FC = ({ data }) => { const cart = useCart(); + const wishlist = useWishlist(); const onAddToCart = () => { cart.addItem(data); - } + }; const isInCart = cart.items.some((item) => item.id === data.id); - const onRemoveFromCart= () => { + const isInWishlist = wishlist.items.some((item) => item.id === data.id); + const onRemoveFromCart = () => { cart.removeItem(data.id); }; const onShare = () => { if (navigator.share) { - navigator.share({ - title: data.name, - text: `Check out this product: ${data.name}`, - url: window.location.href - }).then(() => console.log('Shared successfully')) - .catch((error) => console.error('Error sharing:', error)); + navigator + .share({ + title: data.name, + text: `Check out this product: ${data.name}`, + url: window.location.href, + }) + .then(() => console.log("Shared successfully")) + .catch((error) => console.error("Error sharing:", error)); + } else { + console.log("Web Share API is not supported in this browser."); + } + }; + + const toggleWishlist = () => { + if (isInWishlist) { + wishlist.removeItem(data.id); } else { - console.log('Web Share API is not supported in this browser.'); + wishlist.addItem(data); } }; - return ( + return (

    {data.name}

    @@ -48,40 +61,52 @@ const Info: React.FC = ({ data }) => {

    Size:

    -
    - {data?.size?.value} -
    +
    {data?.size?.value}

    Color:

    -
    +
    -
    -

    Color:

    - +
    +

    Color:

    +
    -
    - { - isInCart ? ( - - ) : - ( - - ) - } +
    + {isInCart ? ( + + ) : ( + + )} +
    ); -} - +}; + export default Info; diff --git a/components/navbar-actions.tsx b/components/navbar-actions.tsx index b3e9391..c12dcda 100644 --- a/components/navbar-actions.tsx +++ b/components/navbar-actions.tsx @@ -1,6 +1,6 @@ "use client"; -import { ShoppingBag } from "lucide-react"; +import { ShoppingBag, Heart } from "lucide-react"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; @@ -21,19 +21,22 @@ const NavbarActions = () => { return null; } - return ( -
    - +
    router.push("/wishlist")}> + +
    ); -} - -export default NavbarActions; \ No newline at end of file +}; + +export default NavbarActions; diff --git a/hooks/use-wishlist.tsx b/hooks/use-wishlist.tsx new file mode 100644 index 0000000..597797d --- /dev/null +++ b/hooks/use-wishlist.tsx @@ -0,0 +1,43 @@ +import { create } from "zustand"; +import { toast } from "react-hot-toast"; +import { persist, createJSONStorage } from "zustand/middleware"; + +import { Product } from "@/types"; +import { AlertTriangle } from "lucide-react"; + +interface WishlistStore { + items: Product[]; + addItem: (data: Product) => void; + removeItem: (id: string) => void; + removeAll: () => void; +} + +const useWishlist = create( + persist( + (set, get) => ({ + items: [], + addItem: (data: Product) => { + const currentItems = get().items; + const existingItem = currentItems.find((item) => item.id === data.id); + + if (existingItem) { + return toast("Item already in wishlist."); + } + + set({ items: [...get().items, data] }); + toast.success("Item added to wishlist."); + }, + removeItem: (id: string) => { + set({ items: [...get().items.filter((item) => item.id !== id)] }); + toast.success("Item removed from wishlist."); + }, + removeAll: () => set({ items: [] }), + }), + { + name: "wishlist-storage", + storage: createJSONStorage(() => localStorage), + } + ) +); + +export default useWishlist;