Skip to content

Commit

Permalink
Merge pull request #994 from ShivanshPlays/main
Browse files Browse the repository at this point in the history
Add dynamic product fetching and summary to cart page and option of moving a product to cart from wishlist.+minor changes in contributting and ,envexample files
  • Loading branch information
mdazfar2 authored Oct 27, 2024
2 parents b26b57b + b1c1643 commit e18f642
Show file tree
Hide file tree
Showing 13 changed files with 493 additions and 240 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ SMTP_USER=your email
SMTP_PASS=you email app password (not gmail password, create an app password from gmail)

NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your cloudinary id
NEXT_PUBLIC_CLOUDINARY_CLOUD_PRESET=your cloudinary preset

NEXT_PUBLIC_BASE_URL=base url of the hosted website/development server

NEXT_PUBLIC_BASE_Cover=url of default image (should be from cloudinary)

4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,6 @@ npm run build
>
> **PRs that have been open for a duration exceeding 45 days will be automatically closed, so please plan accordingly.**
>
>**Additionally, PRs that are improperly linted or have a failing build will not be merged. Ensure that your code passes linting checks and builds successfully before submitting your PR.**
>**Additionally, PRs that are improperly linted or have a failing build will not be merged. Ensure that your code passes linting checks and builds successfully before submitting your PR.**
>**Don't forget to check .env.example for better insight of the environment variable**
67 changes: 60 additions & 7 deletions actions/cart-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"use server"

import prismadb from "@/lib/prismadb";
import { Prisma } from "@prisma/client";
// import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
import { Cart, Prisma } from "@prisma/client";

export async function CartPost(
data: FormData
): Promise<{ success: boolean; error?: string }> {
): Promise<{ success: boolean; data?: Cart, error?: string }> {
const productId = data.get("productid") as string;
const userId = data.get("userid") as string;

console.log(productId,userId)
try {
const res = await prismadb.cart.create({
data: {
Expand All @@ -18,8 +18,8 @@ export async function CartPost(
},
});

console.log(res);
return { success: true };
// console.log(res);
return { success: true,data:res };
} catch (err) {
if (err instanceof Prisma.PrismaClientKnownRequestError) {
console.log("Prisma error in post cart item route:", err.message);
Expand All @@ -28,7 +28,60 @@ export async function CartPost(
error: err.message,
};
}
console.log(err);
// console.log(err);
return { success: false, error: "An unexpected error occurred." };
}
}
}


export async function CartGetByUser(
userId: string
): Promise<{ success: boolean; data?: any; error?: string }> {
// console.log("contrl")
try {
const res = await prismadb.cart.findMany({
where: {
userId,
},
include: {
product: {
include: {
images: true,
},
},
},
});

// console.log(res);
return { success: true, data: res };
} catch (err) {
console.log(err);

return { success: false, error: "An unexpected error occurred." };
}
}

export async function CartDeleteProduct(
Id: string,
): Promise<{ success: boolean; error?: string }> {

// console.log(Id);
try {
const res = await prismadb.cart.deleteMany({
where: {
id:Id
},
});

if(res.count==0){
return {success:false, error:"item does not exist on the wishlist"}
}
console.log(res);
// console.log(res)
return { success: true}; // Include success and return the data
} catch (err) {
// console.log(err);

return { success: false, error: "An unexpected error occurred while deleting" };
}
}
30 changes: 15 additions & 15 deletions actions/wishlist-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,22 @@ export async function WishlistDeleteProduct(
}
}

export async function WishlistSpecificEntry(
userId:string
,productId:string): Promise<{ success: boolean; error?: string }> {

const res=await prismadb.wishlist.findUnique({
where:{
userId_productId:{
userId,
productId
}
}
})
// export async function WishlistSpecificEntry(
// userId:string
// ,productId:string): Promise<{ success: boolean; error?: string }> {

// console.log(res);
// const res=await prismadb.wishlist.findUnique({
// where:{
// userId_productId:{
// userId,
// productId
// }
// }
// })

return {success:true}
// // console.log(res);

// return {success:true}


}
// }
113 changes: 66 additions & 47 deletions app/(Customer)/Cart/components/cart-item.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,77 @@
"use client"

import { orderItemProps } from "@/app/(Customer)/MyOrders/components/orderItem";
import Image from "next/image";
// import { cartProps } from "../page";
import { Button } from "@/components/ui/button";
import { X } from "lucide-react";
import toast from "react-hot-toast";
import { CartDeleteProduct } from "@/actions/cart-actions";
import { cartProps, useCart } from "@/context/cartContext";


const CartItem:React.FC<orderItemProps> = ({
item
interface cartItemProps{
item:cartProps
}
const CartItem:React.FC<cartItemProps> = ({
item,
}) => {
const {handleRemove} = useCart();
const onDelete=async()=>{

// const cart=useCart();

// const onRemove=()=>{
// // cart.removeItem(data.id);
// }
const res=await CartDeleteProduct(item.id);

if(res.success){
toast.success("removed from cart");
handleRemove(item.id);
}
else{
toast.error(res.error||"error occured");
}

}


return (
<li className="flex py-6 h-40 border-b">
<div className="relative rounded-md overflow-hidden sm:h-48 sm:w-48">
<Image
width={1000}
height={1000}
src={item.image}
alt="product image"
className="object-cover h-32 w-32 rounded-lg object-center"
/>
</div>
<div className="relative ml-4 flex flex-1 flex-col justify-between sm:ml-6">
<div className="absolute z-10 right-0 top-0">
{/* <IconButton
onClick={onRemove}
icon={<X size={12}/>}
/> */}
</div>
<div className="relative pr-9 sm:grid sm:grid-cols-2 sm:gap-x-6 sm:pr-0">
<div className="flex justify-between">
<p className="text-lg font-semibold dark:text-gray-200">
{item.name}
</p>
</div>
<div className="mt-1 flex sm:justify-end text-sm">
<p className="text-gray-500 dark:text-gray-200">
{/* haha */}
{item.variant}
</p>
<p className="text-gray-500 ml-4 sm:mr-4 border-l border-gray-200 pl-4">
{/* nunu */}
{item.count}
</p>
</div>
<div className="dark:text-gray-200">{item.price}</div>

</div>
</div>
</li>
<li className="flex py-6 border-b h-auto sm:h-48">
{/* Image Section */}
<div className="relative rounded-md overflow-hidden ">
<Image
width={1000}
height={1000}
src={item.product.images[0].url}
alt={`${item.product.name} image`}
className="object-cover w-full h-full rounded-lg"
/>
</div>

{/* Product Details Section */}
<div className="flex-1 ml-4 sm:ml-6 flex flex-col justify-between">
<div className="flex justify-between items-start sm:items-center">
<p className="text-lg font-semibold dark:text-gray-200">
{item.product.name}
</p>

{/* Remove Button */}
<Button
className=" hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md"
aria-label="Remove product"
onClick={onDelete}
>
<X size={16} />
</Button>
</div>

{/* Description */}
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
{item.product.description}
</p>

{/* Price Section */}
<div className="mt-2 text-lg font-medium dark:text-gray-200">
{item.product.price}
</div>
</div>
</li>

);
}

Expand Down
18 changes: 15 additions & 3 deletions app/(Customer)/Cart/components/summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useCart } from "@/context/cartContext";
import { useSession } from "next-auth/react";
import { useState } from "react";

const Summary = () => {
const session=useSession()
console.log(session.data)
const [userDetails, updateUserDetails] = useState({
Fullname: "",
Fullname: session.data?.user.name,
Address: "",
Phone: "",
Email: ""
Email: session.data?.user.email
});

const {cartItems}=useCart();

const amount=cartItems.reduce((initial,value)=>{
return initial+value.product.price
},0);

const handleInputChange = (field: keyof typeof userDetails) => (e: React.ChangeEvent<HTMLInputElement>) => {
updateUserDetails({
...userDetails, // Spread the previous state
Expand Down Expand Up @@ -44,6 +54,7 @@ const Summary = () => {
placeholder="Name"
onChange={handleInputChange("Fullname")} // Call handleInputChange with the specific field
// data={userDetails.Fullname}
value={userDetails.Fullname}
/>
<Input
className="dark:bg-gray-800"
Expand All @@ -62,6 +73,7 @@ const Summary = () => {
placeholder="Email"
onChange={handleInputChange("Email")}
// data={userDetails.Email}
value={userDetails.Email}
/>
</div>
</div>
Expand All @@ -70,7 +82,7 @@ const Summary = () => {
<div className="text-base font-medium text-gray-900 dark:text-gray-100">Order Total</div>
{/* <Currency value={totalPrice} />
*/}
{566}
{amount}
</div>
</div>
<Button className="w-full bg-customTeal dark:bg-Green dark:text-gray-100 dark:hover:opacity-80 mt-6">
Expand Down
Loading

0 comments on commit e18f642

Please sign in to comment.