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 12, 2024
1 parent f6cfec4 commit d0f25fc
Show file tree
Hide file tree
Showing 24 changed files with 908 additions and 260 deletions.
289 changes: 101 additions & 188 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 @@ -67,6 +67,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
1 change: 1 addition & 0 deletions src/__tests__/productList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Provider from '@/app/providers';
import Page from '@/app/products/page';
import { useRouter } from 'next/navigation';

jest.setTimeout(15000)
const queryClient = new QueryClient();
const ProductListTest = () => {
const { data } = useQuery<any>({
Expand Down
30 changes: 30 additions & 0 deletions src/__tests__/reviewPopupHook.test.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 ReviewPopup from '@/hooks/reviewPopup';

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

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

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

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

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

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

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

expect(result.current.isReviewPopupOpen).toBe(false);
});
});
30 changes: 30 additions & 0 deletions src/__tests__/wiishlistOverlayHook.test.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);
});
});
26 changes: 26 additions & 0 deletions src/__tests__/wishlistSlice.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// userWishlistSlice.test.ts

import { AnyAction } from 'redux';
import { createStore } from '@reduxjs/toolkit';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import userWishlistReducer, { handleWishlistCount, userWishlistSlice } from '@/redux/slices/wishlistSlice'; // Adjust the import path as per your project structure

// Mocking axios request module
jest.mock('@/utils/axios', () => ({
get: jest.fn()
}));

describe('userWishlistSlice', () => {
let store: any;

beforeEach(() => {
store = createStore(userWishlistReducer);
});
it('should handle handleWishlistCount reducer', () => {
const previousState = { wishNumber: 0 };//@ts-ignore
const newState = userWishlistReducer(previousState, { type: handleWishlistCount.type, payload: 5 });
expect(newState.wishNumber).toEqual(5);
});

});
49 changes: 24 additions & 25 deletions src/app/products/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,26 @@ import Card from '@/components/Card';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
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 { RootState, useAppDispatch, useAppSelector } from '@/redux/store';
import { handleUserAddCart } from '@/redux/slices/userCartSlice';
import { handleWishlistCount } from '@/redux/slices/wishlistSlice';
import request from '@/utils/axios';
import { showToast } from '@/helpers/toast';
import ReviewWrapper from '@/components/ReviewsWrapper';
//import StripeProvider from '@/components/StripeProvider';

function Page() {
const { wishNumber } = useAppSelector(
(state: RootState) => state.wishlist
)
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const { id } = useParams();
const handleSwiper = (swiper: any) => {
setThumbsSwiper(swiper);
};
const _id: string = id.toLocaleString();
const { data, isLoading, error } = useQuery<any>({
const { data, isLoading, error , refetch} = useQuery<any>({
queryKey: ['product', id],
queryFn: async () => {
try {
Expand All @@ -59,6 +64,17 @@ function Page() {
const productId = data.product.id;
dispatch(handleUserAddCart({ productPrice, productId }));
};
const handleAddRemoveWish = async(event: { preventDefault: () => void; })=>{
event.preventDefault();
const response:any = await request.post('/wishes', { productId:id });
if(response.status == 200 || response.status == 203){
const { status } = response;
dispatch(handleWishlistCount(status == 200 ? await wishNumber + 1 : await wishNumber - 1));
showToast(response.message, 'success')
}
console.log('this is response', response)

}
return (
<div>
{/* // <StripeProvider> */}
Expand Down Expand Up @@ -146,7 +162,7 @@ function Page() {
</div>
<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">
<div className="p-3 rounded-full bg-gray-200 hover:bg-green-500 hover:text-white cursor-pointer" onClick={handleAddRemoveWish}>
<FaRegHeart />
</div>
<div className="p-3 rounded-full bg-gray-200 hover:bg-green-500 hover:text-white cursor-pointer">
Expand All @@ -158,7 +174,7 @@ function Page() {
</div>
</div>
<span className="font-medium text-2xl text-blue-300 mt-2">
<span className="font-bold text-3xl">{productPrice}</span>{' '}
<span className="font-bold text-3xl">{productPrice.toLocaleString()}</span>{' '}
RWF
</span>
</div>
Expand Down Expand Up @@ -201,27 +217,10 @@ function Page() {
</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 font-bold">No ratings yet.</p>
)}
</div>
<ReviewWrapper productId={_id.trim()} refetch={refetch} reviews={reviews} />
</div>
</div>

</div>
)}
</>
Expand Down
2 changes: 2 additions & 0 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
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
8 changes: 5 additions & 3 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'),
});
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
Expand Down Expand Up @@ -65,7 +65,7 @@ const BuyerOrdersList = () => {
header: 'Price',
accessorFn: row => row.Product.productPrice,
cell: (row: any) => <>
<span> {row.row.original.Product.productPrice}</span> <span>{ row.row.original.Product.productCurrency}</span>
<span> {row.row.original.Product.productPrice.toLocaleString()}</span> <span>{ row.row.original.Product.productCurrency}</span>
</>
},
{
Expand Down Expand Up @@ -162,13 +162,15 @@ const BuyerOrdersList = () => {
))}
</tbody>
</table>
{ordersData.length > 6 ?
<div className='flex gap-2 w-full justify-center mt-5 py-5 cursor-pointer'>
< div className='flex gap-3' >
<BackButton handle={() => table.previousPage()} isDisabled={!table.getCanPreviousPage()} />
{table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
< BackButton handle={() => table.nextPage()} isDisabled={!table.getCanNextPage()} rotate />
</div>
</div>
:""}
</>
</div>
</div >
Expand Down
Loading

0 comments on commit d0f25fc

Please sign in to comment.