Skip to content

Commit

Permalink
fix buttons (#63)
Browse files Browse the repository at this point in the history
fix add to cart and favorites buttons
  • Loading branch information
mpohorenyi authored Dec 20, 2023
1 parent 3c4b2c0 commit e0ef3ac
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 107 deletions.
6 changes: 5 additions & 1 deletion src/modules/shared/AddToCart/AddToCart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import cn from 'classnames';
import styles from './AddToCart.module.scss';
Expand Down Expand Up @@ -29,6 +29,10 @@ export const AddToCart: React.FC<Props> = ({ productItem }) => {
}
};

useEffect(() => {
setIsSelected(cart.some((cartItem) => cartItem.id === productItem.id));
}, [cart, productItem.id]);

return (
<button
className={cn(styles.addToCart, {
Expand Down
96 changes: 51 additions & 45 deletions src/modules/shared/AddToFavourites/AddToFavourites.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,51 @@
import React, { useState } from 'react';
import cn from 'classnames';
import styles from './AddToFavourites.module.scss';
import { useAppDispatch, useAppSelector } from '../../../store/hooks';
import { actions as favouritiesActions }
from '../../../store/reducers/favoritesSlice';
import { Product } from '../../../types/Product';

type Props = {
productItem: Product;
};

export const AddToFavourites: React.FC<Props> = ({ productItem }) => {
const { isDarkTheme } = useAppSelector((state) => state.theme);
const { favorites } = useAppSelector((state) => state.favorites);
const dispatch = useAppDispatch();

const [isSelected, setIsSelected] = useState<boolean>(
!!favorites.find(favorite => favorite.id === productItem.id),
);

const handleFavouritiesButton = (product: Product) => {
if (isSelected) {
dispatch(favouritiesActions.remove(product.id));
setIsSelected(false);
} else {
dispatch(favouritiesActions.add(product));
setIsSelected(true);
}
};

return (
<button
type="button"
aria-label="Add to favourite"
className={cn(styles.addToFavourite, {
[styles.addToFavourite__DARK]: isDarkTheme,
[styles.addToFavourite__SELECTED]: isSelected,
[styles.addToFavourite__DARK__SELECTED]:
isSelected && isDarkTheme,
})}
onClick={() => handleFavouritiesButton(productItem)}
/>
);
};
import React, { useEffect, useState } from 'react';
import cn from 'classnames';
import styles from './AddToFavourites.module.scss';
import { useAppDispatch, useAppSelector } from '../../../store/hooks';
import { actions as favouritiesActions }
from '../../../store/reducers/favoritesSlice';
import { Product } from '../../../types/Product';

type Props = {
productItem: Product;
};

export const AddToFavourites: React.FC<Props> = ({ productItem }) => {
const { isDarkTheme } = useAppSelector((state) => state.theme);
const { favorites } = useAppSelector((state) => state.favorites);
const dispatch = useAppDispatch();

const [isSelected, setIsSelected] = useState<boolean>(
!!favorites.find(favorite => favorite.id === productItem.id),
);

const handleFavouritiesButton = (product: Product) => {
if (isSelected) {
dispatch(favouritiesActions.remove(product.id));
setIsSelected(false);
} else {
dispatch(favouritiesActions.add(product));
setIsSelected(true);
}
};

useEffect(() => {
setIsSelected(
favorites.some((favoritesItem) => favoritesItem.id === productItem.id),
);
}, [favorites, productItem.id]);

return (
<button
type="button"
aria-label="Add to favourite"
className={cn(styles.addToFavourite, {
[styles.addToFavourite__DARK]: isDarkTheme,
[styles.addToFavourite__SELECTED]: isSelected,
[styles.addToFavourite__DARK__SELECTED]:
isSelected && isDarkTheme,
})}
onClick={() => handleFavouritiesButton(productItem)}
/>
);
};
125 changes: 64 additions & 61 deletions src/store/reducers/cartSlice.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,64 @@
/* eslint-disable no-param-reassign */
import { PayloadAction, createSlice } from '@reduxjs/toolkit';

import { localClient } from '../../utils/localClient';
import { Product, ProductWithAmount } from '../../types/Product';

export interface CartState {
cart: ProductWithAmount[];
}

function prepareProductForCart(product: Product): ProductWithAmount {
return Object.assign(product, { amount: 1 });
}

const initialState: CartState = {
cart: localClient.read('cart') || localClient.init('cart', []),
};

const cartSlice = createSlice({
name: 'cart',
initialState,
reducers: {
add: (state, action: PayloadAction<Product>) => {
const preparedProduct = prepareProductForCart(action.payload);

state.cart.push(preparedProduct);
localClient.add('cart', preparedProduct);
},

remove: (state, action: PayloadAction<number>) => {
state.cart = state.cart.filter((item) => item.id !== action.payload);
localClient.delete('cart', action.payload);
},

increase: (state, action: PayloadAction<number>) => {
state.cart.forEach((item) => {
if (item.id === action.payload) {
item.amount += 1;
localClient.update('cart', item);
}
});
},

decrease: (state, action: PayloadAction<number>) => {
state.cart.forEach((item) => {
if (item.id === action.payload && item.amount > 1) {
item.amount -= 1;
localClient.update('cart', item);
}
});
},

clear: (state) => {
state.cart = [];
localClient.write('cart', []);
},
},
});

export default cartSlice.reducer;
export const { actions } = cartSlice;
/* eslint-disable no-param-reassign */
import { PayloadAction, createSlice } from '@reduxjs/toolkit';

import { localClient } from '../../utils/localClient';
import { Product, ProductWithAmount } from '../../types/Product';

export interface CartState {
cart: ProductWithAmount[];
}

function prepareProductForCart(product: Product): ProductWithAmount {
return {
...product,
amount: 1,
};
}

const initialState: CartState = {
cart: localClient.read('cart') || localClient.init('cart', []),
};

const cartSlice = createSlice({
name: 'cart',
initialState,
reducers: {
add: (state, action: PayloadAction<Product>) => {
const preparedProduct = prepareProductForCart(action.payload);

state.cart.push(preparedProduct);
localClient.add('cart', preparedProduct);
},

remove: (state, action: PayloadAction<number>) => {
state.cart = state.cart.filter((item) => item.id !== action.payload);
localClient.delete('cart', action.payload);
},

increase: (state, action: PayloadAction<number>) => {
state.cart.forEach((item) => {
if (item.id === action.payload) {
item.amount += 1;
localClient.update('cart', item);
}
});
},

decrease: (state, action: PayloadAction<number>) => {
state.cart.forEach((item) => {
if (item.id === action.payload && item.amount > 1) {
item.amount -= 1;
localClient.update('cart', item);
}
});
},

clear: (state) => {
state.cart = [];
localClient.write('cart', []);
},
},
});

export default cartSlice.reducer;
export const { actions } = cartSlice;

0 comments on commit e0ef3ac

Please sign in to comment.