Skip to content

Commit

Permalink
feat(feature)-improvsingleproductview-#187893630
Browse files Browse the repository at this point in the history
  • Loading branch information
kayigmb committed Jul 9, 2024
1 parent 7d8cb7c commit 354d575
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 141 deletions.
3 changes: 3 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ body {}
opacity: 1;
}

.mySwiper4 .swiper-slide-thumb-active {
opacity: 1;
}
.swiper-slide img {
display: block;
width: 100%;
Expand Down
293 changes: 153 additions & 140 deletions src/app/products/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
// BuyerProductView
'use client';
import React, { useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/free-mode';
import 'swiper/css/zoom';
import 'swiper/css/navigation';
import 'swiper/css/thumbs';
import { FreeMode, Navigation, Thumbs } from 'swiper/modules';
import Image from 'next/image'; //@ts-ignore
// @ts-ignore
import ReactStars from 'react-rating-stars-component';
import { MdOutlineShoppingCart } from 'react-icons/md';
import { FaRegHeart } from 'react-icons/fa6';
import { useParams } from 'next/navigation';
import { Product } from '@/utils/requests';
import {
ProductObj,
ProductType,
ReviewType,
imageType,
} from '@/types/Product';
import { ProductType, ReviewType, imageType } from '@/types/Product';
import Card from '@/components/Card';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import image from '../../../../public/product.png';
import { useQuery } from '@tanstack/react-query';
import ReviewCard from '@/components/ReviewCard';
import Button from '@/components/Button';
Expand All @@ -33,7 +27,7 @@ import { handleUserAddCart } from '@/redux/slices/userCartSlice';

function Page() {
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const { id } :any= useParams();
const { id } = useParams();
const handleSwiper = (swiper: any) => {
setThumbsSwiper(swiper);
};
Expand All @@ -45,176 +39,195 @@ function Page() {
const response: ProductType = (await Product.single(
_id,
)) as ProductType;

return response;
} catch (error) {
throw new Error('Error fetching product data');
}
},
});
if (isLoading) return <span>Loading...</span>;

if (error) return <span>Error: {error.message}</span>;

const {
productPictures,
productName,
productPrice,
productDescription,
reviews,
} = data.product;
console.log('this is reviews >>>>>>>>>', reviews);
console.log(' this is average reviews', productPictures);
const { relatedProducts } = data;
} = data?.product || {};
const { relatedProducts } = data || {};
const dispatch = useAppDispatch();
const handleNewItem = () => {
const productId = data.product.id;
dispatch(handleUserAddCart({ productPrice, productId }));
};

return (
<div>
{/* // <StripeProvider> */}
<Header />
<div className="w-full mb-5 mt-5 flex flex-col justify-center items-center">
<div className="w-2/3 flex flex-col justify-center items-center gap-5">
<div className="w-full flex">
<div className="w-1/2">
<div className="flex justify-center py-2">
{productPictures && productPictures.length > 0 ? (
<Swiper
spaceBetween={10}
navigation={true}
thumbs={{ swiper: thumbsSwiper }}
modules={[FreeMode, Navigation, Thumbs]}
className="mySwiper2"
>
{productPictures.map((image: imageType) => {
return (
<SwiperSlide key={image.imgId}>
<img src={image.url} alt="image" />
</SwiperSlide>
);
})}
</Swiper>
) : (
<Image src={image} alt={'no image found'} />
)}
</div>
<div className="w-full flex space-x-4 justify-start mt-3">
{productPictures && productPictures.length > 0 ? (
<div className="w-[500px] h-[15em] overflow-hidden">
<>
{isLoading ? (
<div className="min-h-screen w-full justify-center items-center flex">
<div className="border-t-4 border-b-4 border-blue-600 rounded-full w-20 h-20 animate-spin m-auto"></div>
</div>
) : (
<div className="w-[100%] my-5">
<div className="w-[100%] p-3 sm:w-[60%] m-auto">
<div className="w-[100%] gap-0 sm:gap-8 flex-col sm:flex-row flex">
<div className="w-[100%] sm:w-1/2">
<div className="flex justify-center py-2 ">
<Swiper
onSwiper={handleSwiper}
spaceBetween={10}
slidesPerView={4}
freeMode={true}
watchSlidesProgress={true}
navigation={true}
thumbs={{ swiper: thumbsSwiper }}
modules={[FreeMode, Navigation, Thumbs]}
className="mySwiper mycss"
className="rounded-lg min-w-[100%] box-border "
>
{productPictures.map((image: imageType) => {
return (
<SwiperSlide key={image.imgId}>
<img src={image.url} alt="image" />
</SwiperSlide>
);
})}
{[
...(!productPictures?.length
? [
{
imgId: 'fail Image',
url: '/product.png',
},
]
: productPictures),
].map((image: imageType) => (
<SwiperSlide
key={image.imgId}
className="w-[100%] rounded-lg shadow-lg"
>
<img
src={image.url}
alt="image"
className="h-[400px] object-cover min-w-[100%]"
onError={(e) =>
(e.currentTarget.src = '/product.png')
}
/>
</SwiperSlide>
))}
</Swiper>
</div>
) : (
<p className="text-red-500">no image found!</p>
)}
</div>
</div>
<div className="w-1/2 flex flex-col ml-10">
<div>
<h1 className="font-medium text-2xl">{productName}</h1>
</div>
<div className="flex flex-col gap-2">
<div className="flex gap-2">
<div className="p-3 rounded-full bg-gray-200 hover:bg-green-500 hover:text-white cursor-pointer">
<FaRegHeart />
<div className="w-full flex space-x-4 justify-start mt-3">
{productPictures && productPictures.length > 0 ? (
<div className="w-[100%] h-[5em] flex ">
<Swiper
onSwiper={handleSwiper}
spaceBetween={10}
slidesPerView={4}
freeMode={true}
watchSlidesProgress={true}
modules={[FreeMode, Navigation, Thumbs]}
className=" min-w-[100%] max-h-[80px] mySwiper4 object-cover"
>
{productPictures.map((image: imageType) => (
<SwiperSlide
key={image.imgId}
className="opacity-[0.4]"
>
<img
src={image.url}
alt="image"
className="h-[100%] text-left rounded-lg object-cover w-[100%]"
/>
</SwiperSlide>
))}
</Swiper>
</div>
) : (
<p className="text-red-500 capitalize">no image found!</p>
)}
</div>
</div>
<div className="w-full">
<div>
<h1 className="font-bold mt-5 text-2xl capitalize">
{productName}
</h1>
</div>
<div className="p-3 rounded-full bg-gray-200 hover:bg-green-500 hover:text-white cursor-pointer">
<MdOutlineShoppingCart
onClick={() => {
handleNewItem();
}}
<div className="flex flex-col gap-4">
<div className="flex gap-2 mt-5">
<div className="p-3 rounded-full bg-gray-200 hover:bg-green-500 hover:text-white cursor-pointer">
<FaRegHeart />
</div>
<div className="p-3 rounded-full bg-gray-200 hover:bg-green-500 hover:text-white cursor-pointer">
<MdOutlineShoppingCart
onClick={() => {
handleNewItem();
}}
/>
</div>
</div>
<span className="font-medium text-2xl text-blue-300 mt-2">
<span className="font-bold text-3xl">{productPrice}</span>{' '}
RWF
</span>
</div>
<div className="block mt-2">
<ReactStars
count={5}
value={averageReviews(reviews)}
isHalf={true}
size={30}
activeColor="#FFD700"
edit={false}
/>
</div>
<div className="flex flex-col gap-2">
<h2 className="font-bold text-2xl mt-2">Description:</h2>
<p className="w-full text-1xl">{productDescription}</p>
</div>
</div>
<span className="font-medium text-2xl text-blue-300">
RWF {productPrice}
</span>
</div>
<div className="block">
<ReactStars
count={5}
value={averageReviews(reviews)}
isHalf={true}
size={30}
activeColor="#ffd700"
edit={false}
/>
</div>
<div className="flex flex-col gap-2">
<h2 className="font-medium text-2xl">Description:</h2>
<p className="w-full text-1xl">{productDescription}</p>
<div className="w-[100%] sm:w-[100%] mt-[50px]">
<h2 className="font-bold text-2xl">Related products:</h2>
<div className="flex gap-5 mt-5 overflow-x-scroll hide-scrollbar">
{relatedProducts && relatedProducts.length > 0 ? (
relatedProducts.map((product: ProductType) => (
<Card
key={product.id}
id={product.id}
productPrice={product.productPrice}
productThumbnail={product.productThumbnail}
productDescription={product.productDescription}
reviews={product.reviews}
productName={product.productName}
/>
))
) : (
<p className="text-red-500 w-full flex self-center">
No related products available.
</p>
)}
</div>
</div>
</div>
</div>
<div className="w-full flex flex-col ">
<h2 className="font-medium text-2xl">Related products:</h2>
<div className="w-full">
<div className="product-grid flex justify-left gap-5 mt-5 mx-0">
{relatedProducts && relatedProducts.length > 0 ? (
relatedProducts.map((product: ProductType) => (
<Card
key={product.id}
id={product.id}
productPrice={product.productPrice}
productThumbnail={product.productThumbnail}
productDescription={product.productDescription}
reviews={product.reviews}
productName={product.productName}
/>
))
) : (
<p className="text-red-500 w-full flex self-center">
No related products available.
</p>
)}
<div className="w-full flex flex-col mt-10">
<div className="flex">
<h2 className="font-medium text-2xl mr-5">Reviews:</h2>
<Button name="Add Review" background="blue"></Button>
</div>
<div className="my-10">
{reviews && reviews.length > 0 ? (
reviews.map((review: ReviewType) => (
<ReviewCard
rating={review.rating}
feedback={review.feedback}
image={review.userProfile.profileImage}
firstName={review.userProfile.firstName}
lastName={review.userProfile.lastName}
/>
))
) : (
<p className="text-red-500 font-bold">No ratings yet.</p>
)}
</div>
</div>
</div>
</div>
<div className="w-full flex flex-col mt-10">
<div className="flex">
<h2 className="font-medium text-2xl mr-5">Reviews:</h2>
<Button name="Add Review" background="blue"></Button>
</div>
<div className="my-10">
{reviews && reviews.length > 0 ? (
reviews.map((review: ReviewType) => (
<ReviewCard
rating={review.rating}
feedback={review.feedback}
image={review.userProfile.profileImage}
firstName={review.userProfile.firstName}
lastName={review.userProfile.lastName}
/>
))
) : (
<p className="text-red-500">No ratings yet.</p>
)}
</div>
</div>
</div>
</div>
)}
</>
<Footer />
{/* </StripeProvider> */}
</div>
);
}

export default Page;
1 change: 0 additions & 1 deletion src/app/sellers/products_/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// BuyerProductView
'use client';


import React, { useState, useEffect } from "react";
import Image from 'next/image';
import { MdOutlineShoppingCart } from 'react-icons/md';
Expand Down

0 comments on commit 354d575

Please sign in to comment.