Skip to content

Commit

Permalink
ft(wishlist):add-products-to-wishlist
Browse files Browse the repository at this point in the history
  • Loading branch information
kanu-cast committed Jul 5, 2024
1 parent 26436db commit cf47d0e
Show file tree
Hide file tree
Showing 15 changed files with 1,296 additions and 840 deletions.
1,317 changes: 708 additions & 609 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"@storybook/nextjs": "^8.1.3",
"@storybook/react": "^8.1.3",
"@storybook/test": "^8.1.3",
"@tanstack/react-query": "^5.40.1",
"@tanstack/react-table": "^8.17.3",
"@tanstack/react-query-devtools": "^5.44.0",
"@testing-library/dom": "^10.1.0",
"@testing-library/jest-dom": "^6.4.6",
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/productList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-quer
import SideBar from "@/components/Side"
import Provider from '@/app/providers';
import Page from '@/app/products/page';

jest.setTimeout(15000)
const queryClient = new QueryClient();
const ProductListTest = () => {
const { data } = useQuery<any>({
Expand Down
30 changes: 30 additions & 0 deletions src/__tests__/wiishlistOverlayHook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// WishlistOverlay.test.js

import { renderHook, act } from '@testing-library/react';
import useWishlistOverlay from '@/hooks/wishlistOverlay';

describe('useWishlistOverlay', () => {
it('should initialize with isOpen as false', () => {
const { result } = renderHook(() => useWishlistOverlay());

expect(result.current.isWishlistOverlayOpen).toBe(false);
});

it('should toggle isOpen when toggleWishlistSlider is called', () => {
const { result } = renderHook(() => useWishlistOverlay());

expect(result.current.isWishlistOverlayOpen).toBe(false);

act(() => {
result.current.toggleWishlistSlider();
});

expect(result.current.isWishlistOverlayOpen).toBe(true);

act(() => {
result.current.toggleWishlistSlider();
});

expect(result.current.isWishlistOverlayOpen).toBe(false);
});
});
206 changes: 5 additions & 201 deletions src/app/products/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,214 +1,18 @@
// 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/navigation';
import 'swiper/css/thumbs';
import { FreeMode, Navigation, Thumbs } from 'swiper/modules';
import Image from 'next/image'; //@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 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';
import { averageReviews } from '@/utils/averageReviews';
import { useAppDispatch } from '@/redux/store';
import { handleUserAddCart } from '@/redux/slices/userCartSlice';

function Page() {
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const { id } :any= useParams();
const handleSwiper = (swiper: any) => {
setThumbsSwiper(swiper);
};
const _id: string = id.toLocaleString();
const { data, isLoading, error } = useQuery<any>({
queryKey: ['product', id],
queryFn: async () => {
try {
const response: ProductType = (await Product.single(
_id,
)) as ProductType;
import ProductWrapper from '@/components/productWrapper';

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;
const dispatch = useAppDispatch();
const handleNewItem = () => {
const productId = data.product.id;
dispatch(handleUserAddCart({ productPrice, productId }));
};
function Page() {


return (
<div>
<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">
<Swiper
onSwiper={handleSwiper}
spaceBetween={10}
slidesPerView={4}
freeMode={true}
watchSlidesProgress={true}
modules={[FreeMode, Navigation, Thumbs]}
className="mySwiper mycss"
>
{productPictures.map((image: imageType) => {
return (
<SwiperSlide key={image.imgId}>
<img src={image.url} alt="image" />
</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>
<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">
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>
</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>
</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>
<ProductWrapper/>
<Footer />
</div>
);
Expand Down
7 changes: 4 additions & 3 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use client';
import React from 'react';
import { IoChevronBack } from 'react-icons/io5';
import { IoMdClose } from "react-icons/io";
import { MdClose } from "react-icons/md";

interface Properties {
name?: string;
handle?: () => void;
Expand Down Expand Up @@ -44,8 +45,8 @@ export const BackButton: React.FC<Properties> = ({ handle, isDisabled, rotate })
export const CloseButton: React.FC<Properties> = ({ handle, isDisabled, rotate }) => {
return (
<>
<button onClick={handle} disabled={isDisabled} className='rounded-[40px] w-[30px] h-[30px] flex justify-center items-center text-[30px] float-right'>
<IoMdClose />
<button onClick={handle} disabled={isDisabled} className='rounded-[40px] w-[30px] h-[30px] bg-white flex justify-center items-center text-[30px] float-right'>
<MdClose />
</button>
</>
)
Expand Down
4 changes: 2 additions & 2 deletions src/components/BuyerOrdersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React, { useEffect, useState } from 'react';
import ReviewProduct from './ReviewProductPopup';
import { useQuery } from "@tanstack/react-query";
import requestAxios from '@/utils/axios';
import request from '@/utils/axios';
import {
ColumnDef,
flexRender,
Expand Down Expand Up @@ -37,7 +37,7 @@ const BuyerOrdersList = () => {
const [orderId, setOrderId] = useState<string | null>(null);
const { isLoading, refetch, error, data } = useQuery<any>({
queryKey: ['BuyerOrdersList'],
queryFn: () => requestAxios.get('/orders'),
queryFn: () => request.get('/orders'),
});
console.log("----------------------------------------------------------------------",data)
const [pagination, setPagination] = useState<PaginationState>({
Expand Down
Loading

0 comments on commit cf47d0e

Please sign in to comment.