-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Add to wishlist and wishlist page
- Loading branch information
1 parent
64211a7
commit 7f56d7f
Showing
59 changed files
with
755 additions
and
233 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
"use server"; | ||
import Cart from "@/lib/models/Cart"; | ||
import dbConnect from "@/utils/dbConnect"; | ||
import { auth, currentUser } from "@clerk/nextjs/server"; | ||
|
||
dbConnect(); | ||
|
||
export const addToCart = async (productId) => { | ||
const { userId } = auth(); | ||
if (!userId) { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Unauthorized", | ||
status: 401, | ||
}) | ||
); | ||
} | ||
|
||
// Get the user email from the database using the logged-in user information | ||
const { emailAddresses } = await currentUser(); | ||
const email = emailAddresses[0].emailAddress; | ||
|
||
const cart = await Cart.findOne({ userEmail: email }); | ||
|
||
if (cart) { | ||
const productIndex = cart.products.findIndex(p => p.productId.toString() === productId); | ||
if (productIndex > -1) { | ||
cart.products[productIndex].quantity += 1; | ||
} else { | ||
cart.products.push({ productId, quantity: 1 }); | ||
} | ||
await cart.save(); | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Added to Cart Successfully", | ||
status: 200, | ||
}) | ||
); | ||
} | ||
|
||
const newCart = await Cart.create({ userEmail: email, products: [{ productId, quantity: 1 }] }); | ||
if (newCart) { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Added to Cart Successfully", | ||
status: 200, | ||
}) | ||
); | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Failed to add product to cart", | ||
status: 500, | ||
}) | ||
); | ||
} | ||
}; | ||
export const removeFromCart = async (productId) => { | ||
const { userId } = auth(); | ||
if (!userId) { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Unauthorized", | ||
status: 401, | ||
}) | ||
); | ||
} | ||
|
||
const { emailAddresses } = await currentUser(); | ||
const email = emailAddresses[0].emailAddress; | ||
|
||
const cart = await Cart.findOne({ userEmail: email }); | ||
|
||
if (cart) { | ||
const productIndex = cart.products.findIndex(p => p.productId.toString() === productId); | ||
if (productIndex > -1) { | ||
if (cart.products[productIndex].quantity > 1) { | ||
cart.products[productIndex].quantity -= 1; | ||
} else { | ||
cart.products.splice(productIndex, 1); | ||
} | ||
await cart.save(); | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Removed from Cart Successfully", | ||
status: 200, | ||
}) | ||
); | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Not Found in Cart", | ||
status: 404, | ||
}) | ||
); | ||
} | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Cart Not Found", | ||
status: 404, | ||
}) | ||
); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
"use server"; | ||
import WishList from "@/lib/models/WishList"; | ||
import dbConnect from "@/utils/dbConnect"; | ||
import { auth, currentUser } from "@clerk/nextjs/server"; | ||
|
||
dbConnect(); | ||
|
||
export const addToWishList = async (productId) => { | ||
const { userId } = auth(); | ||
if (!userId) { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Unauthorized", | ||
status: 401, | ||
}) | ||
); | ||
} | ||
|
||
const { emailAddresses } = await currentUser(); | ||
const email = emailAddresses[0].emailAddress; | ||
|
||
const wishlist = await WishList.findOne({ userEmail: email }); | ||
|
||
if (wishlist) { | ||
const productIndex = wishlist.products.findIndex( | ||
(p) => p.productId.toString() === productId | ||
); | ||
if (productIndex === -1) { | ||
wishlist.products.push({ productId }); | ||
await wishlist.save(); | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Added to Wishlist Successfully", | ||
status: 200, | ||
}) | ||
); | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Already in Wishlist", | ||
status: 400, | ||
}) | ||
); | ||
} | ||
} | ||
|
||
const newWishList = await WishList.create({ | ||
userEmail: email, | ||
products: [{ productId }], | ||
}); | ||
if (newWishList) { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Added to Wishlist Successfully", | ||
status: 200, | ||
}) | ||
); | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Failed to add product to wishlist", | ||
status: 500, | ||
}) | ||
); | ||
} | ||
}; | ||
export const removeFromWishList = async (productId) => { | ||
const { userId } = auth(); | ||
if (!userId) { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Unauthorized", | ||
status: 401, | ||
}) | ||
); | ||
} | ||
|
||
const { emailAddresses } = await currentUser(); | ||
const email = emailAddresses[0].emailAddress; | ||
|
||
const wishlist = await WishList.findOne({ userEmail: email }); | ||
|
||
if (wishlist) { | ||
const productIndex = wishlist.products.findIndex( | ||
(p) => p.productId.toString() === productId | ||
); | ||
if (productIndex > -1) { | ||
wishlist.products.splice(productIndex, 1); | ||
await wishlist.save(); | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Removed from Wishlist Successfully", | ||
status: 200, | ||
}) | ||
); | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Product Not Found in Wishlist", | ||
status: 404, | ||
}) | ||
); | ||
} | ||
} else { | ||
return JSON.parse( | ||
JSON.stringify({ | ||
message: "Wishlist Not Found", | ||
status: 404, | ||
}) | ||
); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// components/reuseable/CartItem.js | ||
|
||
import React from "react"; | ||
import RemoveFromCartButton from "./RemoveFromCartButton"; | ||
|
||
const CartItem = ({ id, name, images, description, price, quantity }) => { | ||
return ( | ||
<div className="cart-item w-[20rem] border p-4 flex flex-col gap-3"> | ||
<img src={images[0]} alt={name} className="w-full h-40 object-cover" /> | ||
<h2 className="text-xl font-semibold">{name}</h2> | ||
<p className="w-[15rem] line-clamp-2 text-ellipsis">{description}</p> | ||
<p className="font-bold">Price: ${price}</p> | ||
<p>Quantity: {quantity}</p> | ||
<div className="flex gap-3 mt-3"> | ||
<button className="btn bg-blue-500 text-white px-3 py-1 rounded"> | ||
Buy Now | ||
</button> | ||
<RemoveFromCartButton id={id} /> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default CartItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
"use client"; | ||
import { removeFromCart } from "@/actions/cart.actions"; | ||
import { useRouter } from "next/navigation"; | ||
import toast from "react-hot-toast"; | ||
|
||
const RemoveFromCartButton = ({ id }) => { | ||
const router = useRouter(); | ||
const handleRemove = async (id) => { | ||
try { | ||
const res = await removeFromCart(id); | ||
if (res.status === 200) { | ||
console.log(res); | ||
router.refresh(); | ||
return res; | ||
} else { | ||
throw new Error("Error when removing from cart"); | ||
} | ||
} catch (err) { | ||
console.log(err); | ||
return err; | ||
} | ||
}; | ||
return ( | ||
<button | ||
className="btn bg-red-500 text-white px-3 py-1 rounded" | ||
onClick={() => | ||
toast.promise(handleRemove(id), { | ||
loading: "Removing From cart", | ||
success: "Successfully Removed from cart", | ||
error: "Error when Removing From cart", | ||
}) | ||
} | ||
> | ||
Remove | ||
</button> | ||
); | ||
}; | ||
|
||
export default RemoveFromCartButton; |
Oops, something went wrong.