Skip to content

Commit

Permalink
showing related product in productDetails page
Browse files Browse the repository at this point in the history
  • Loading branch information
sksabbirhossain committed Aug 27, 2023
1 parent 1be3daa commit 6d6ae06
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 43 deletions.
50 changes: 50 additions & 0 deletions src/components/ui/ProductDetailsSkeleton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react";

export const ProductDetailsSkeleton = () => {
return (
<div className="container mx-auto my-5">
<div
role="status"
className=" border-gray-100 border rounded-md shadow animate-pulse p-1 sm:grid sm:grid-cols-2 gap-4"
>
<div className="flex items-center justify-center h-96 mb-4 bg-gray-300 rounded">
<svg
className="w-10 h-10 text-gray-200 dark:text-gray-600"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 16 20"
>
<path d="M14.066 0H7v5a2 2 0 0 1-2 2H0v11a1.97 1.97 0 0 0 1.934 2h12.132A1.97 1.97 0 0 0 16 18V2a1.97 1.97 0 0 0-1.934-2ZM10.5 6a1.5 1.5 0 1 1 0 2.999A1.5 1.5 0 0 1 10.5 6Zm2.221 10.515a1 1 0 0 1-.858.485h-8a1 1 0 0 1-.9-1.43L5.6 10.039a.978.978 0 0 1 .936-.57 1 1 0 0 1 .9.632l1.181 2.981.541-1a.945.945 0 0 1 .883-.522 1 1 0 0 1 .879.529l1.832 3.438a1 1 0 0 1-.031.988Z" />
<path d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.98 2.98 0 0 0 .13 5H5Z" />
</svg>
</div>
<div className="">
<div className="h-3.5 bg-gray-200 rounded-full w-full mb-4"></div>
<div className="h-3.5 bg-gray-200 rounded-full w-48 mb-4"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="h-2 bg-gray-200 rounded-full mb-2.5"></div>
<div className="my-8 grid grid-cols-2 sm:gap-5">
<div className="h-8 w-auto bg-gray-200 rounded-md"></div>
<div className="h-8 w-auto bg-gray-200 rounded-md"></div>
</div>

<span className="sr-only">Loading...</span>
</div>
</div>
</div>
);
};
6 changes: 6 additions & 0 deletions src/features/product/productApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export const productApi = apiSlice.injectEndpoints({
url: `/product/product/${productId}`,
}),
}),
getProductByCategory: builder.query({
query: (categoryId) => ({
url: `/product/product-by-category/${categoryId}`,
}),
}),
addProduct: builder.mutation({
query: (data) => ({
url: "/product/add-product",
Expand Down Expand Up @@ -115,6 +120,7 @@ export const {
useGetProductsQuery,
useGetFeatureProductsQuery,
useGetProductQuery,
useGetProductByCategoryQuery,
useAddProductMutation,
useUpdateProductMutation,
useUpdateProductStatusMutation,
Expand Down
1 change: 1 addition & 0 deletions src/pages/User/Home/FeaturedProduct.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const FeaturedProduct = () => {
content = (
<p className="text-center uppercase font-medium">No Product found!</p>
);

if (!isError && !isLoading && products?.length > 0)
content = products.map((proudct) => (
<ProductCard key={proudct._id} product={proudct} />
Expand Down
95 changes: 63 additions & 32 deletions src/pages/User/ProductDetails/ProductDetails.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,104 @@
import React, { useState } from "react";
import React from "react";
import { toast } from "react-hot-toast";
import { useDispatch } from "react-redux";
import { useParams } from "react-router-dom";
import { ProductDetailsSkeleton } from "../../../components/ui/ProductDetailsSkeleton";
import { addToCart } from "../../../features/cart/addToCartSlice";
import { useGetProductQuery } from "../../../features/product/productApi";
import { setTitle } from "../../../utils/setTitle";
import { RelatedProduct } from "./RelatedProduct";

export const ProductDetails = () => {
const [quantity, setQuantity] = useState(1);
const { productId } = useParams();
const dispatch = useDispatch();

const {
data: product,
isLoading,
isSuccess,
isError,
} = useGetProductQuery(productId);

if (isLoading)
return (
<>
<ProductDetailsSkeleton />
</>
);

if (!isLoading && isError)
return (
<h3 className=" uppercase font-medium text-red-600">
something went wrong!
</h3>
);

if (!isError && !isLoading && isSuccess && product?.length === 0)
return (
<p className="text-center uppercase font-medium">No Product found!</p>
);

const { name, picture, price, category, description } = product || {};

const categoryId = category?._id;

//add to cart
const addToCartHandler = (item) => {
dispatch(addToCart(item));
toast.success("Product Add To Cart");
};


//set ppage title
setTitle("Product Details");
return (
<div className="container mx-auto my-7 px-2 sm:px-0">
<div className="grid grid-cols-1 md:grid-cols-2">
<div className="">
<img
src="https://media.istockphoto.com/id/1175355990/photo/stylish-blue-headphones-on-multi-colored-duo-tone-background-lighting.jpg?s=612x612&w=0&k=20&c=KV7myS20KOzfgRk8CYFSq0y31Sgcu2MLP5zCH1MpLYI="
src={`${process.env.REACT_APP_BASE_URL}/uploads/${picture}`}
alt="product"
className="rounded-md"
/>
</div>
<div className="space-y-3">
<h1 className="text-xl font-medium">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Similique,
repellendus?
</h1>
<p className="text-sm">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Illum,
voluptas! Consequuntur, labore! In nobis fugiat tempore nemo
laborum, at earum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Incidunt, ipsum, qui eaque velit totam est dolore
voluptates excepturi beatae sequi atque accusantium aperiam tenetur
eligendi aut laudantium suscipit? Quos, est.
</p>
<h1 className="text-xl font-medium">{name}</h1>
<p className="text-sm">{description}</p>
<p className="font-medium text-green-600">start</p>
<div className="flex justify-between items-center">
<p className="font-medium">Price: $100</p>
<div className="flex items-center">
<p className="font-medium">Price: ${price}</p>
{/* <div className="flex items-center">
<p className="font-medium">Quantity:</p>
<div className="flex bg-green-600 ml-3 rounded-md overflow-hidden">
<div className="flex bg-green-700 rounded-md overflow-hidden">
<button
disabled={quantity <= 1}
disabled={qty <= 1}
className="bg-green-900 text-white py-1 px-3"
onClick={() => setQuantity((pre) => pre - 1)}
onClick={() => decreaseProductQtyHandler(_id)}
>
{" "}
-{" "}
</button>
<input
type="number"
name="quantity"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
className=" w-14 bg-transparent text-gray-100 font-normal text-2xl text-center focus:outline-none"
/>
<span className=" w-10 bg-transparent text-gray-100 font-normal text-2xl text-center focus:outline-none">
{qty}
</span>
<button
className="bg-green-900 text-white py-1 px-3"
onClick={() => setQuantity((pre) => pre + 1)}
onClick={() => increaseProductQtyHandler(_id)}
>
{" "}
+{" "}
</button>
</div>
</div>
</div> */}
</div>
<button className="py-2 px-5 bg-green-800 text-white rounded-md hover:bg-green-600 duration-100 ease-linear">
<button
className="py-2 px-5 bg-green-800 text-white rounded-md hover:bg-green-600 duration-100 ease-linear"
onClick={() => addToCartHandler(product)}
>
Add To Cart
</button>
</div>
</div>
<RelatedProduct />
<RelatedProduct categoryId={categoryId} />
</div>
);
};
48 changes: 37 additions & 11 deletions src/pages/User/ProductDetails/RelatedProduct.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
import React, { useEffect, useState } from "react";
import React from "react";
import { ProductCardSkeleton } from "../../../components/ui/ProductCardSkeleton";
import { ContainerHeader } from "../../../components/user/ContainerHeader";
import { ProductCard } from "../../../components/user/ProductCard";
import { useGetProductByCategoryQuery } from "../../../features/product/productApi";

export const RelatedProduct = ({ categoryId }) => {
const {
data: products,
isLoading,
isSuccess,
isError,
} = useGetProductByCategoryQuery(categoryId);

let content;
if (isLoading)
content = (
<>
<ProductCardSkeleton />
</>
);

if (!isLoading && isError)
content = (
<h3 className=" uppercase font-medium text-red-600">
something went wrong!
</h3>
);

if (!isError && !isLoading && isSuccess && products?.length === 0)
content = (
<p className="text-center uppercase font-medium">No Product found!</p>
);

if (!isError && !isLoading && isSuccess && products?.length > 0)
content = products?.map((product) => (
<ProductCard key={product.id} product={product} />
));

export const RelatedProduct = () => {
const [product, setProudct] = useState([]);
useEffect(() => {
fetch("https://fakestoreapi.com/products")
.then((res) => res.json())
.then((data) => setProudct(data));
}, []);
return (
<div>
<ContainerHeader title={"Related Product!"} />
<div className=" mb-7 grid gird-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-x-2 gap-y-5">
{product?.map((product) => (
<ProductCard key={product.id} product={product} />
))}
{content}
</div>
</div>
);
Expand Down

0 comments on commit 6d6ae06

Please sign in to comment.