diff --git a/src/App.tsx b/src/App.tsx
index 010f3f0..038fc7d 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,9 +1,11 @@
import { Outlet } from 'react-router';
import { Header } from './components/Header';
import { Footer } from './components/Footer';
+import { useInitFavourites } from './hooks/useInitFavourites';
import { useInitialCart } from './hooks/useInitialCart';
const App = () => {
+ useInitFavourites();
useInitialCart();
return (
diff --git a/src/Root.tsx b/src/Root.tsx
index 782a511..2786007 100644
--- a/src/Root.tsx
+++ b/src/Root.tsx
@@ -3,6 +3,7 @@ import App from './App';
import CatalogPage from './pages/CatalogPage';
import NotFound from './pages/NotFound';
import ScrollToTop from './components/ScrollToTop';
+import { FavouritesPage } from './pages/FavouritesPage';
import { CartPage } from './pages/CartPage';
export const Root = () => (
@@ -21,6 +22,7 @@ export const Root = () => (
Accessories Page} />
+ } />
} />
} />
diff --git a/src/components/Card.tsx b/src/components/Card.tsx
index ca66ea5..f1c88cd 100644
--- a/src/components/Card.tsx
+++ b/src/components/Card.tsx
@@ -1,7 +1,12 @@
import classNames from 'classnames';
import { useState } from 'react';
import { FiHeart } from 'react-icons/fi';
-import { addItemToCart, useAppDispatch } from '../redux';
+import {
+ addItemToCart,
+ useAppDispatch,
+ toggleFavourite,
+ useAppSelector,
+} from '../redux';
import { Button } from './Button';
import { ProductProperties } from './ProductProperties';
import { IProduct } from '../types/Product';
@@ -11,8 +16,13 @@ type Props = {
};
export const Card = ({ product }: Props) => {
- const [favorite, setFavorite] = useState(false);
+ const { favouriteItems } = useAppSelector((state) => state.favourites);
const dispatch = useAppDispatch();
+ const [favorite, setFavorite] = useState(false);
+
+ const isFavourite = (id: string) =>
+ favouriteItems.some((item) => item._id === id);
+
const productProps = [
{
name: 'Screen',
@@ -28,7 +38,8 @@ export const Card = ({ product }: Props) => {
},
];
- const handleAddToFav = () => {
+ const handleToggleFav = (currentProduct: IProduct) => {
+ dispatch(toggleFavourite(currentProduct));
setFavorite(!favorite);
};
@@ -68,11 +79,11 @@ export const Card = ({ product }: Props) => {
'active:scale-95',
'flex justify-center items-center shrink-0 duration-300',
])}
- onClick={handleAddToFav}
+ onClick={() => handleToggleFav(product)}
>
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
index 98f2f6d..95a7c87 100644
--- a/src/components/Header.tsx
+++ b/src/components/Header.tsx
@@ -50,12 +50,12 @@ export const Header: React.FC = () => {
{
+ const dispatch = useAppDispatch();
+
+ useEffect(() => {
+ dispatch(getInitialFavourites());
+ }, []);
+};
diff --git a/src/pages/FavouritesPage.tsx b/src/pages/FavouritesPage.tsx
index 51c1a9d..c11cc21 100644
--- a/src/pages/FavouritesPage.tsx
+++ b/src/pages/FavouritesPage.tsx
@@ -1,27 +1,9 @@
-import React, { useEffect, useState } from 'react';
+import React from 'react';
import { Card } from '../components/Card';
-import axios from 'axios';
-import { IProduct } from '../types/Product';
+import { useAppSelector } from '../redux';
export const FavouritesPage: React.FC = () => {
- // #region rewrite to Redux
- const [products, setProducts] = useState([]);
- // #endregion
-
- // #region rewrite to RTQ Query
- useEffect(() => {
- axios
- .get('https://dreamteam.onrender.com/products', {
- params: { page: 1, perPage: 8 },
- })
- .then((res) => {
- setProducts(res.data.data);
- })
- .catch((e) => {
- throw new Error(e);
- });
- }, []);
- // #endregion
+ const favouriteItems = useAppSelector(state => state.favourites.favouriteItems);
return (
@@ -30,11 +12,11 @@ export const FavouritesPage: React.FC = () => {
FavouritesPage
- 5 items
+ {`${favouriteItems.length} items`}
- {products.map((pr) => (
+ {favouriteItems.map((pr) => (
))}
diff --git a/src/redux/index.ts b/src/redux/index.ts
index ec8673f..fff499e 100644
--- a/src/redux/index.ts
+++ b/src/redux/index.ts
@@ -1,9 +1,11 @@
import { configureStore } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
+import { favouritesSlice } from './slices/favouritesSlice';
import { cartSlice } from './slices/cartSlice';
const store = configureStore({
reducer: {
+ [favouritesSlice.name]: favouritesSlice.reducer,
[cartSlice.name]: cartSlice.reducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(),
@@ -11,6 +13,7 @@ const store = configureStore({
export { store };
+export * from './slices/favouritesSlice';
export * from './slices/cartSlice';
export type RootState = ReturnType;
export type AppDispatch = typeof store.dispatch;
diff --git a/src/redux/slices/favouritesSlice.tsx b/src/redux/slices/favouritesSlice.tsx
new file mode 100644
index 0000000..a8815bf
--- /dev/null
+++ b/src/redux/slices/favouritesSlice.tsx
@@ -0,0 +1,39 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { IProduct } from '../../types/Product';
+
+type InitialState = {
+ favouriteItems: IProduct[];
+};
+
+const initialState: InitialState = {
+ favouriteItems: [],
+};
+
+export const favouritesSlice = createSlice({
+ name: 'favourites',
+ initialState,
+ reducers: {
+ getInitialFavourites: (state) => {
+ state.favouriteItems = JSON.parse(
+ localStorage.getItem('favourite-items') || '[]',
+ ) as IProduct[];
+ },
+ toggleFavourite: (state, action) => {
+ const hasProductId = state.favouriteItems.some(
+ (favouriteItem) => favouriteItem._id === action.payload._id,
+ );
+
+ if (hasProductId) {
+ state.favouriteItems = state.favouriteItems.filter(
+ (favouriteItem) => favouriteItem._id !== action.payload._id,
+ );
+ localStorage.setItem('favourite-items', JSON.stringify(state.favouriteItems));
+ } else {
+ state.favouriteItems.push(action.payload);
+ localStorage.setItem('favourite-items', JSON.stringify(state.favouriteItems));
+ }
+ },
+ },
+});
+
+export const { toggleFavourite, getInitialFavourites } = favouritesSlice.actions;